From 911fef209a7da9dee332edbe884bb7fdc476c0a4 Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 17 Jun 2016 02:49:41 +0200 Subject: [PATCH] Implement afbr and * sub-variants to list return addresses of current function --- libr/anal/bb.c | 7 +++---- libr/anal/fcn.c | 5 ++--- libr/core/cmd_anal.c | 32 ++++++++++++++++++++++++++------ libr/core/cmd_debug.c | 2 +- libr/include/r_anal.h | 2 +- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/libr/anal/bb.c b/libr/anal/bb.c index daf55797ad..e550194777 100644 --- a/libr/anal/bb.c +++ b/libr/anal/bb.c @@ -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; diff --git a/libr/anal/fcn.c b/libr/anal/fcn.c index 7d0c06f646..5f1fdd9e6b 100644 --- a/libr/anal/fcn.c +++ b/libr/anal/fcn.c @@ -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 diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index baa20868a8..ba9e9fba7c 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -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"); diff --git a/libr/core/cmd_debug.c b/libr/core/cmd_debug.c index 6b045826a6..d463e84cd7 100644 --- a/libr/core/cmd_debug.c +++ b/libr/core/cmd_debug.c @@ -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; diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 8da49107bd..18a20327e3 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -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;