Skip to content

Commit

Permalink
Unify aea/aeA command logic and a little cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
trufae authored Sep 26, 2024
1 parent d25f859 commit 7821a3c
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 146 deletions.
183 changes: 72 additions & 111 deletions libr/core/cmd_anal.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ static RCoreHelpMessage help_msg_aea = {
"aeaw", " [ops]", "show regs written in N instructions",
"aean", " [ops]", "show regs not written in N instructions",
"aeaj", " [ops]", "show aea output in JSON format",
"aeA", " [len]", "show regs used in N bytes (subcommands are the same)",
"aeA", " [len]", "show regs used in N bytes (same subcommands as 'aea')",
"Legend:", "", "",
"I", "", "input registers (read before being set)",
"A", "", "all regs accessed",
Expand Down Expand Up @@ -7412,7 +7412,6 @@ static R_TH_LOCAL char *oldregread = NULL;
static R_TH_LOCAL RList *mymemxsr = NULL;
static R_TH_LOCAL RList *mymemxsw = NULL;

#define R_NEW_DUP(x) memcpy((void*)malloc (sizeof (x)), &(x), sizeof (x))
typedef struct {
ut64 addr;
int size;
Expand Down Expand Up @@ -7548,7 +7547,7 @@ static void showmem_json(RList *list, PJ *pj) {
pj_end (pj);
}

static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const char *esilexpr) {
static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const char *esilexpr, bool maxbytes) {
int ptr, ops, ops_end = 0, len, buf_sz;
ut64 addr_end;
AeaStats stats;
Expand All @@ -7563,7 +7562,7 @@ static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const ch
if (maxopsize < 1) {
maxopsize = 16;
}
if (mode & 1) {
if (maxbytes) {
// number of bytes / length
buf_sz = length;
} else {
Expand Down Expand Up @@ -7592,7 +7591,7 @@ static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const ch
free (buf);
return false;
}
# define hasNext(x) (x&1) ? (addr < addr_end) : (ops<ops_end)
# define hasNext() (maxbytes) ? (addr < addr_end) : (ops < ops_end)

mymemxsr = r_list_new ();
mymemxsw = r_list_new ();
Expand All @@ -7603,7 +7602,7 @@ static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const ch
esil->cb.hook_mem_read = mymemread;
esil->nowrite = true;
r_cons_break_push (NULL, NULL);
for (ops = ptr = 0; ptr < buf_sz && hasNext (mode); ops++, ptr += len) {
for (ops = ptr = 0; ptr < buf_sz && hasNext (); ops++, ptr += len) {
if (r_cons_is_breaked ()) {
break;
}
Expand Down Expand Up @@ -7658,28 +7657,19 @@ static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const ch
}
}
}
if ((mode >> 5) & 1) {
RListIter *iter;
AeaMemItem *n;
int c = 0;
r_cons_printf ("f-mem.*\n");
r_list_foreach (mymemxsr, iter, n) {
r_cons_printf ("f mem.read.%d 0x%08x @ 0x%08"PFMT64x"\n", c++, n->size, n->addr);
}
c = 0;
r_list_foreach (mymemxsw, iter, n) {
r_cons_printf ("f mem.write.%d 0x%08x @ 0x%08"PFMT64x"\n", c++, n->size, n->addr);
}
}

/* show registers used */
if ((mode >> 1) & 1) {
switch (mode) {
case 'r':
showregs (stats.regread);
} else if ((mode >> 2) & 1) {
break;
case 'w':
showregs (stats.regwrite);
} else if ((mode >> 3) & 1) {
break;
case 'n':
showregs (regnow);
} else if ((mode >> 4) & 1) {
break;
case 'j':
pj = r_core_pj_new (core);
if (!pj) {
free (regnow);
Expand Down Expand Up @@ -7714,9 +7704,23 @@ static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const ch
pj_end (pj);
r_cons_println (pj_string (pj));
pj_free (pj);
} else if ((mode >> 5) & 1) {
// nothing
} else {
break;
case '*':
{
RListIter *iter;
AeaMemItem *n;
int c = 0;
r_cons_printf ("f-mem.*\n");
r_list_foreach (mymemxsr, iter, n) {
r_cons_printf ("f mem.read.%d 0x%08x @ 0x%08"PFMT64x"\n", c++, n->size, n->addr);
}
c = 0;
r_list_foreach (mymemxsw, iter, n) {
r_cons_printf ("f mem.write.%d 0x%08x @ 0x%08"PFMT64x"\n", c++, n->size, n->addr);
}
}
break;
default:
if (!r_list_empty (stats.inputregs)) {
r_cons_printf (" I: ");
showregs (stats.inputregs);
Expand Down Expand Up @@ -7749,6 +7753,7 @@ static bool cmd_aea_stuff(RCore* core, int mode, ut64 addr, int length, const ch
r_cons_printf ("@W:");
showmem (mymemxsw);
}
break;
}

r_list_free (mymemxsr);
Expand Down Expand Up @@ -7783,7 +7788,7 @@ static void cmd_aespc(RCore *core, ut64 addr, ut64 until_addr, int ninstr) {
}
#endif
ut8 *buf = malloc (bsize);
if (!buf) {
if (R_UNLIKELY (!buf)) {
R_LOG_ERROR ("Cannot allocate %d byte(s)", bsize);
return;
}
Expand Down Expand Up @@ -7901,8 +7906,7 @@ static void r_anal_aefa(RCore *core, const char *arg) {
#endif
}

static void __core_anal_appcall(RCore *core, const char *input) {
// r_reg_arena_push (core->dbg->reg);
static void cmd_aeC(RCore *core, const char *input) {
RListIter *iter;
char *arg;
char *inp = strdup (input);
Expand All @@ -7921,8 +7925,6 @@ static void __core_anal_appcall(RCore *core, const char *input) {

r_reg_setv (core->anal->reg, "SP", sp);
free (inp);

// r_reg_arena_pop (core->dbg->reg);
}

static void cmd_debug_stack_init(RCore *core, int argc, char **argv, char **envp) {
Expand Down Expand Up @@ -8569,46 +8571,8 @@ static void cmd_aet(RCore *core, const char *input) {
}
}

// XXX same as aea but with bytes
static void cmd_aeA(RCore *core, const char *input) {
switch (input[1]) {
case '?':
r_core_cmd_help (core, help_msg_aea);
break;
case 'r':
cmd_aea_stuff (core, 1 + (1<<1), core->offset, r_num_math (core->num, input+2), NULL);
break;
case 'w':
cmd_aea_stuff (core, 1 + (1<<2), core->offset, r_num_math (core->num, input+2), NULL);
break;
case 'n':
cmd_aea_stuff (core, 1 + (1<<3), core->offset, r_num_math (core->num, input+2), NULL);
break;
case 'j':
cmd_aea_stuff (core, 1 + (1<<4), core->offset, r_num_math (core->num, input+2), NULL);
break;
case '*':
cmd_aea_stuff (core, 1 + (1<<5), core->offset, r_num_math (core->num, input+2), NULL);
break;
case 'f': {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, -1);
if (fcn) {
cmd_aea_stuff (core, 1, r_anal_function_min_addr (fcn), r_anal_function_linear_size (fcn), NULL);
}
break;
}
case 0:
case ' ':
cmd_aea_stuff (core, 1, core->offset, (int)r_num_math (core->num, input[1]? input + 2:input + 1), NULL);
break;
default:
r_core_return_invalid_command (core, "aeA", input[1]);
break;
}
}

// XXX same as aeA but with nops
static void cmd_aea(RCore *core, const char *input) {
static void cmd_aea(RCore *core, const char *input, bool maxbytes) {
RReg *reg = core->anal->reg;
ut64 pc = r_reg_getv (reg, "PC");
RAnalOp *op = r_core_anal_op (core, pc, 0);
Expand All @@ -8622,61 +8586,54 @@ static void cmd_aea(RCore *core, const char *input) {
r_core_cmd_help (core, help_msg_aea);
break;
case 'e': // "aeae"
cmd_aea_stuff (core, 0, core->offset, -1, r_str_trim_head_ro (input + 2));
cmd_aea_stuff (core, 0, core->offset, -1, r_str_trim_head_ro (input + 2), maxbytes);
break;
case 'r': // "aear"
cmd_aea_stuff (core, 1<<1, core->offset, r_num_math (core->num, input + 2), NULL);
break;
case 'w': // "aeaw"
cmd_aea_stuff (core, 1<<2, core->offset, r_num_math (core->num, input + 2), NULL);
break;
case 'n': // "aean"
cmd_aea_stuff (core, 1<<3, core->offset, r_num_math (core->num, input + 2), NULL);
break;
case 'j': // "aeaj"
cmd_aea_stuff (core, 1<<4, core->offset, r_num_math (core->num, input + 2), NULL);
break;
case '*': // "aea*"
cmd_aea_stuff (core, 1<<5, core->offset, r_num_math (core->num, input + 2), NULL);
break;
case 'B': { // "aeaB"
bool json = input[2] == 'j';
int a = json? 3: 2;
ut64 addr = (input[a] == ' ')? r_num_math (core->num, input + a): core->offset;
RList *l = r_anal_get_blocks_in (core->anal, addr);
RAnalBlock *b;
RListIter *iter;
r_list_foreach (l, iter, b) {
const int mode = json? (1<<4): 1;
cmd_aea_stuff (core, mode, b->addr, b->size, NULL);
break;
}
cmd_aea_stuff (core, input[1], core->offset, r_num_math (core->num, input + 2), NULL, maxbytes);
break;
}
case 'f': { // "aeaf"
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, -1);
if (fcn) {
switch (input[2]) {
case 'j': // "aeafj"
cmd_aea_stuff (core, 1<<4, r_anal_function_min_addr (fcn), r_anal_function_linear_size (fcn), NULL);
case 'B': // "aeaB"
{
bool json = input[2] == 'j';
int a = json? 3: 2;
ut64 addr = (input[a] == ' ')? r_num_math (core->num, input + a): core->offset;
RList *l = r_anal_get_blocks_in (core->anal, addr);
RAnalBlock *b;
RListIter *iter;
r_list_foreach (l, iter, b) {
cmd_aea_stuff (core, json? 'j': 0, b->addr, b->size, NULL, maxbytes);
break;
default:
cmd_aea_stuff (core, 1, r_anal_function_min_addr (fcn), r_anal_function_linear_size (fcn), NULL);
}
}
break;
case 'f': // "aeaf"
{
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, -1);
if (fcn) {
switch (input[2]) {
case 'j': // "aeafj"
cmd_aea_stuff (core, 'j', r_anal_function_min_addr (fcn), r_anal_function_linear_size (fcn), NULL, maxbytes);
break;
default:
cmd_aea_stuff (core, 0, r_anal_function_min_addr (fcn), r_anal_function_linear_size (fcn), NULL, maxbytes);
break;
}
break;
}
break;
}
}
break;
case 'b': { // "aeab"
RAnalBlock *bb = r_anal_bb_from_offset (core->anal, core->offset);
if (bb) {
switch (input[2]) {
case 'j': // "aeabj"
cmd_aea_stuff (core, 1 | (1<<4), bb->addr, bb->size, NULL);
cmd_aea_stuff (core, 'j', bb->addr, bb->size, NULL, maxbytes);
break;
default:
cmd_aea_stuff (core, 1, bb->addr, bb->size, NULL);
cmd_aea_stuff (core, 0, bb->addr, bb->size, NULL, maxbytes);
break;
}
}
Expand All @@ -8687,11 +8644,15 @@ static void cmd_aea(RCore *core, const char *input) {
{
const char *arg = input[1]? input + 2: "";
ut64 len = r_num_math (core->num, arg);
cmd_aea_stuff (core, 0, core->offset, len, NULL);
cmd_aea_stuff (core, 0, core->offset, len, NULL, maxbytes);
}
break;
default:
r_core_return_invalid_command (core, "aea", input[1]);
if (maxbytes) {
r_core_return_invalid_command (core, "aeA", input[1]);
} else {
r_core_return_invalid_command (core, "aea", input[1]);
}
break;
}
r_reg_setv (reg, "PC", pc);
Expand Down Expand Up @@ -8740,7 +8701,7 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) {
if (input[1] == '?') { // "aec?"
r_core_cmd_help (core, help_msg_aeC);
} else {
__core_anal_appcall (core, r_str_trim_head_ro (input + 1));
cmd_aeC (core, r_str_trim_head_ro (input + 1));
}
break;
case 'c': // "aec"
Expand Down Expand Up @@ -8972,10 +8933,10 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) {
cmd_aet (core, input);
break;
case 'A': // "aeA"
cmd_aeA (core, input);
cmd_aea (core, input, true);
break;
case 'a': // "aea"
cmd_aea (core, input);
cmd_aea (core, input, false);
break;
case 'x':
if (input[1] == ' ') { // "aex"
Expand Down
Loading

0 comments on commit 7821a3c

Please sign in to comment.