Implement aesB command to step until the given basic block ##anal

This commit is contained in:
pancake 2020-03-12 11:58:12 +01:00 committed by radare
parent 67bcc0db5d
commit b894d95bf7

View File

@ -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[] = "<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);