From b894d95bf717a4944318fe7ac4c5ebda69529970 Mon Sep 17 00:00:00 2001 From: pancake Date: Thu, 12 Mar 2020 11:58:12 +0100 Subject: [PATCH] Implement aesB command to step until the given basic block ##anal --- libr/core/cmd_anal.c | 65 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index db9281ddaa..bbd81315c9 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -5413,25 +5413,26 @@ static bool cmd_aea(RCore* core, int mode, ut64 addr, int length) { return true; } -static void cmd_aespc(RCore *core, ut64 addr, int off) { +static void cmd_aespc(RCore *core, ut64 addr, ut64 until_addr, int off) { RAnalEsil *esil = core->anal->esil; int i, j = 0; - int instr_size = 0; ut8 *buf; RAnalOp aop = {0}; - int ret , bsize = R_MAX (64, core->blocksize); + int ret , bsize = R_MAX (4096, core->blocksize); const int mininstrsz = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_MIN_OP_SIZE); const int minopcode = R_MAX (1, mininstrsz); const char *pc = r_reg_get_name (core->dbg->reg, R_REG_NAME_PC); - RRegItem *r = r_reg_get (core->dbg->reg, pc, -1); int stacksize = r_config_get_i (core->config, "esil.stack.depth"); int iotrap = r_config_get_i (core->config, "esil.iotrap"); - unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size"); + ut64 addrsize = r_config_get_i (core->config, "esil.addr.size"); + // eprintf (" aesB %llx %llx %d\n", addr, until_addr, off); // 0x%08llx %d %s\n", aop.addr, ret, aop.mnemonic); if (!esil) { + eprintf ("Warning: cmd_espc: creating new esil instance\n"); if (!(esil = r_anal_esil_new (stacksize, iotrap, addrsize))) { return; } + core->anal->esil = esil; } buf = malloc (bsize); if (!buf) { @@ -5440,37 +5441,53 @@ static void cmd_aespc(RCore *core, ut64 addr, int off) { return; } if (addr == -1) { - addr = r_debug_reg_get (core->dbg, pc); + addr = r_reg_getv (core->dbg->reg, pc); } - ut64 curpc = addr; + (void)r_anal_esil_setup (core->anal->esil, core->anal, 0, 0, 0); // int romem, int stats, int nonull) { + ut64 cursp = r_reg_getv (core->dbg->reg, "SP"); ut64 oldoff = core->offset; + const ut64 flags = R_ANAL_OP_MASK_BASIC | R_ANAL_OP_MASK_HINT | R_ANAL_OP_MASK_ESIL | R_ANAL_OP_MASK_DISASM; for (i = 0, j = 0; j < off ; i++, j++) { if (r_cons_is_breaked ()) { break; } if (i >= (bsize - 32)) { i = 0; + eprintf ("Warning: Chomp\n"); } if (!i) { r_io_read_at (core->io, addr, buf, bsize); } - ret = r_anal_op (core->anal, &aop, addr, buf + i, bsize - i, R_ANAL_OP_MASK_BASIC | R_ANAL_OP_MASK_HINT); + if (addr == until_addr) { + break; + } + ret = r_anal_op (core->anal, &aop, addr, buf + i, bsize - i, flags); if (ret < 1) { eprintf ("Failed analysis at 0x%08"PFMT64x"\n", addr); break; } - instr_size += ret; + // skip calls and such + if (aop.type == R_ANAL_OP_TYPE_CALL) { + // nothing + } else { + r_reg_setv (core->anal->reg, "PC", aop.addr + aop.size); + r_reg_setv (core->dbg->reg, "PC", aop.addr + aop.size); + const char *e = R_STRBUF_SAFEGET (&aop.esil); + if (e && *e) { + eprintf (" 0x%08llx %d %s\n", aop.addr, ret, aop.mnemonic); + (void)r_anal_esil_parse (esil, e); + } + } int inc = (core->search->align > 0)? core->search->align - 1: ret - 1; if (inc < 0) { inc = minopcode; } i += inc; - addr += inc; + addr += ret; // aop.size; r_anal_op_fini (&aop); } - r_reg_set_value (core->dbg->reg, r, curpc); - r_core_esil_step (core, curpc + instr_size, NULL, NULL, false); r_core_seek (core, oldoff, 1); + r_reg_setv (core->dbg->reg, "SP", cursp); } static const char _handler_no_name[] = ""; @@ -5659,6 +5676,26 @@ static void cmd_anal_esil(RCore *core, const char *input) { } r_core_cmd0 (core, ".ar*"); break; + case 'B': // "aesB" + { + n = strchr (input + 2, ' '); + char *n2 = NULL; + if (n) { + n = (char *)r_str_trim_head_ro (n + 1); + } + if (n) { + n2 = strchr (n, ' '); + if (n2) { + *n2++ = 0; + } + ut64 off = r_num_math (core->num, n); + ut64 nth = n2?r_num_math (core->num, n2):1; + cmd_aespc (core, core->offset, off, (int)nth); + } else { + eprintf ("Usage: aesB [until-addr] [nth-opcodes] @ [from-addr]\n"); + } + } + break; case 'u': // "aesu" until_expr = NULL; until_addr = UT64_MAX; @@ -5728,7 +5765,7 @@ static void cmd_anal_esil(RCore *core, const char *input) { } adr = r_num_math (core->num, n + 1); off = r_num_math (core->num, n1 + 1); - cmd_aespc (core, adr, off); + cmd_aespc (core, adr, -1, off); break; case ' ': n = strchr (input, ' '); @@ -5737,7 +5774,7 @@ static void cmd_anal_esil(RCore *core, const char *input) { break; } off = r_num_math (core->num, n + 1); - cmd_aespc (core, -1, off); + cmd_aespc (core, -1, -1, off); break; default: r_core_esil_step (core, until_addr, until_expr, NULL, false);