Implement afbr and * sub-variants to list return addresses of current function

This commit is contained in:
pancake 2016-06-17 02:49:41 +02:00
parent 9c21df9272
commit 911fef209a
5 changed files with 33 additions and 15 deletions

View File

@ -82,10 +82,9 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
}
if (oplen < 1) goto beach;
r_anal_bb_set_offset (bb, bb->ninstr, addr + idx - bb->addr);
r_anal_bb_set_offset (bb, bb->ninstr++, idx); //addr + idx - bb->addr);
idx += oplen;
bb->size += oplen;
bb->ninstr++;
#if R_ANAL_BB_HAS_OPS
r_list_append (bb->ops, op);
#endif
@ -166,8 +165,8 @@ R_API ut16 r_anal_bb_offset_inst(RAnalBlock *bb, int i) {
/* set the offset of the i-th instruction in the basicblock bb */
R_API void r_anal_bb_set_offset(RAnalBlock *bb, int i, ut16 v) {
// the offset of the instruction 0 is not stored because always 0
if (i > 0) {
// the offset 0 of the instruction 0 is not stored because always 0
if (i > 0 && v > 0) {
if (i >= bb->n_op_pos) {
ut16 *tmp_op_pos = realloc (bb->op_pos, (i * 2) * sizeof (*bb->op_pos));
if (!tmp_op_pos) return;

View File

@ -448,7 +448,7 @@ repeat:
}
// check if opcode is in another basic block
// in that case we break
if ((oplen = r_anal_op (anal, &op, addr+idx, buf+idx, len-idx)) < 1) {
if ((oplen = r_anal_op (anal, &op, addr + idx, buf + idx, len - idx)) < 1) {
VERBOSE_ANAL eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx);
if (idx == 0) {
gotoBeach (R_ANAL_RET_END);
@ -466,9 +466,8 @@ repeat:
}
}
if (!overlapped) {
r_anal_bb_set_offset (bb, bb->ninstr, addr + idx - bb->addr);
r_anal_bb_set_offset (bb, bb->ninstr++, addr + idx - bb->addr);
bb->size += oplen;
bb->ninstr++;
fcn->ninstr++;
// FITFCNSZ(); // defer this, in case this instruction is a branch delay entry
// fcn->size += oplen; /// XXX. must be the sum of all the bblocks

View File

@ -565,14 +565,13 @@ static int anal_fcn_list_bb(RCore *core, const char *input) {
int mode = 0;
ut64 addr;
if (*input && (input[1] == ' ' || !input[1])) {
if (*input == 'r')
mode = '*';
else mode = *input;
if (*input) {
mode = *input;
input++;
}
if (input && *input) {
addr = r_num_math (core->num, input);
const char *space = strchr (input, ' ');
if (space) {
addr = r_num_math (core->num, space + 1);
} else {
addr = core->offset;
}
@ -590,6 +589,21 @@ static int anal_fcn_list_bb(RCore *core, const char *input) {
r_list_sort (fcn->bbs, bb_cmp);
r_list_foreach (fcn->bbs, iter, b) {
switch (mode) {
case 'r':
if (b->jump == UT64_MAX) {
ut64 retaddr = b->addr;
if (b->op_pos) {
retaddr += b->op_pos[b->ninstr - 2];
}
if (!strcmp (input, "*")) {
r_cons_printf ("db 0x%08"PFMT64x"\n", retaddr);
} else if (!strcmp (input, "-*")) {
r_cons_printf ("db-0x%08"PFMT64x"\n", retaddr);
} else {
r_cons_printf ("0x%08"PFMT64x"\n", retaddr);
}
}
break;
case '*':
r_cons_printf ("f bb.%05" PFMT64x " = 0x%08" PFMT64x "\n",
b->addr & 0xFFFFF, b->addr);
@ -1134,7 +1148,13 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
break;
default:
case '?':
/* TODO: use r_core_help */
eprintf ("Usage: afb+ or afbb or afb\n"
/* TODO: move afbr into afr? */
" afbr - show addresses of return instructions in the function\n"
" .afbr* - set breakpoint on every return address of the fcn\n"
" .afbr-* - undo the above operation\n"
" afbj - show basic blocks information in JSON\n"
" afB [bits] - define asm.bits for given function\n"
" afb [addr] - list basic blocks of function (see afbq, afbj, afb*)\n"
" afb+ fcn_at bbat bbsz [jump] [fail] ([type] ([diff])) add bb to function @ fcnaddr\n");

View File

@ -2001,7 +2001,7 @@ static void r_core_cmd_bp(RCore *core, const char *input) {
eprintf ("Cannot set breakpoint at '%s'\n", input + 2);
}
} else {
eprintf ("Cannot place a breakpoint on unmapped memory. See dbg.bpinmaps\n");
eprintf ("Cannot place a breakpoint on 0x%08"PFMT64x" unmapped memory. See dbg.bpinmaps\n", addr);
}
}
break;

View File

@ -790,7 +790,7 @@ typedef struct r_anal_bb_t {
// offsets of instructions in this block
ut16 *op_pos;
// size of the op_pos array
int n_op_pos;
int n_op_pos; // XXX. isnt this the same as ninstr ?
ut8 *op_bytes;
ut8 op_sz;
ut64 eflags;