Initialize swapped stack arena and implement 'aeis' ESIL stack emulation helper
This commit is contained in:
parent
3c784f62cf
commit
bd4db7b966
2 changed files with 123 additions and 15 deletions
|
|
@ -1269,6 +1269,101 @@ static void cmd_anal_info(RCore *core, const char *input) {
|
|||
}
|
||||
}
|
||||
|
||||
static void cmd_esil_stack (RCore *core, const char *input) {
|
||||
ut64 curoff = core->offset;
|
||||
ut64 stack_addr = 0x1f0000;
|
||||
ut64 stack_size = 0xf0000;
|
||||
ut64 stack_ptr = stack_addr+(stack_size/2);
|
||||
const char *sp;
|
||||
RCoreFile *cf;
|
||||
RFlagItem *fi;
|
||||
char uri[32];
|
||||
if (*input=='?') {
|
||||
eprintf ("Usage: [stackaddr] [stacksize] [stackptr]\n");
|
||||
eprintf ("Default: 0x100000 0xf0000 0x1e0000\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// arguments aeis [space] [size] [address]
|
||||
{
|
||||
char *s = strdup (input);
|
||||
int args = r_str_word_set0 (s);
|
||||
if (args>0) {
|
||||
ut64 fsz = r_io_size (core->io);
|
||||
stack_addr = r_num_math (core->num,
|
||||
r_str_word_get0 (s, 0));
|
||||
if (stack_addr<fsz) {
|
||||
stack_addr = fsz + (fsz%0xf000);
|
||||
stack_addr = 0x1000000;
|
||||
}
|
||||
if (args>1) {
|
||||
stack_size = r_num_math (core->num,
|
||||
r_str_word_get0 (s, 1));
|
||||
if (args>2) {
|
||||
stack_ptr = r_num_math (core->num,
|
||||
r_str_word_get0 (s, 2));
|
||||
}
|
||||
}
|
||||
if (stack_size<1)
|
||||
stack_size = 0xf0000;
|
||||
if (stack_ptr<stack_addr) {
|
||||
stack_ptr = stack_addr + (stack_size/2);
|
||||
}
|
||||
if (stack_ptr >= stack_addr+stack_size) {
|
||||
stack_ptr = stack_addr + stack_size;
|
||||
}
|
||||
}
|
||||
free (s);
|
||||
}
|
||||
|
||||
fi = r_flag_get (core->flags, "stack_fd");
|
||||
if (fi) {
|
||||
cf = r_core_file_get_by_fd (core, fi->offset);
|
||||
r_core_file_close (core, cf);
|
||||
r_flag_unset (core->flags, "stack", NULL);
|
||||
r_flag_unset (core->flags, "stack_fd", NULL);
|
||||
if (*input=='-') {
|
||||
eprintf ("Deinitialize\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (*input=='-') {
|
||||
eprintf ("Cannot deinitialize twice\n");
|
||||
return;
|
||||
}
|
||||
sp = r_reg_get_name (core->anal->reg,
|
||||
r_reg_get_name_idx ("sp"));
|
||||
if (!sp) {
|
||||
eprintf ("Unknown stack pointer register\n");
|
||||
sp = "esp";
|
||||
}
|
||||
{
|
||||
snprintf (uri, sizeof (uri), "malloc://%d", (int)stack_size);
|
||||
cf = r_core_file_open (core, uri, R_IO_RW, stack_addr);
|
||||
if (cf) {
|
||||
r_flag_set (core->flags, "stack_fd", cf->desc->fd, 1, 0);
|
||||
r_flag_set (core->flags, "stack", stack_addr, 1, 0);
|
||||
r_flag_set (core->flags, "stack_ptr", stack_ptr, 1, 0);
|
||||
r_reg_setv (core->anal->reg, sp, stack_ptr);
|
||||
r_reg_setv (core->dbg->reg, sp, stack_ptr);
|
||||
}
|
||||
}
|
||||
//r_core_cmdf (core, "f stack_fd=`on malloc://%d 0x%08"
|
||||
// PFMT64x"`", stack_size, stack_addr);
|
||||
//r_core_cmdf (core, "f stack=0x%08"PFMT64x, stack_addr);
|
||||
//r_core_cmdf (core, "dr %s=0x%08"PFMT64x, sp, stack_ptr);
|
||||
//r_debug_reg_set (core->dbg, sp, stack_ptr);
|
||||
//r_core_cmdf (core, "ar %s=0x%08"PFMT64x, sp, stack_ptr);
|
||||
//r_core_cmdf (core, "f %s=%s", sp, sp);
|
||||
r_core_seek (core, curoff, 0);
|
||||
/* stack */
|
||||
eprintf ("ADDR 0x%08"PFMT64x"\n", stack_addr);
|
||||
eprintf ("PTR 0x%08"PFMT64x"\n", stack_ptr);
|
||||
eprintf ("SZ 0x%08"PFMT64x"\n", stack_size);
|
||||
eprintf ("GET SP = 0x%x\n", (int)
|
||||
r_reg_getv (core->anal->reg, sp));
|
||||
}
|
||||
|
||||
static void cmd_anal_esil(RCore *core, const char *input) {
|
||||
RAnalEsil *esil = core->anal->esil;
|
||||
ut64 addr = core->offset;
|
||||
|
|
@ -1280,7 +1375,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
|||
switch (input[0]) {
|
||||
case 'r':
|
||||
// 'aer' is an alias for 'ar'
|
||||
cmd_anal_reg(core, input+1);
|
||||
cmd_anal_reg (core, input+1);
|
||||
case ' ':
|
||||
//r_anal_esil_eval (core->anal, input+1);
|
||||
if (!esil) {
|
||||
|
|
@ -1303,7 +1398,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
|||
else if (input[1] == 'u')
|
||||
until_addr = r_num_math(core->num, input + 2);
|
||||
|
||||
esil_step(core, until_addr, until_expr);
|
||||
esil_step (core, until_addr, until_expr);
|
||||
break;
|
||||
case 'c':
|
||||
// aec -> continue until ^C
|
||||
|
|
@ -1321,12 +1416,21 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
|||
core->anal->esil = NULL;
|
||||
break;
|
||||
case 'i':
|
||||
r_anal_esil_free (esil);
|
||||
// reinitialize
|
||||
esil = core->anal->esil = r_anal_esil_new ();
|
||||
romem = r_config_get_i (core->config, "esil.romem");
|
||||
stats = r_config_get_i (core->config, "esil.stats");
|
||||
r_anal_esil_setup (esil, core->anal, romem, stats); // setup io
|
||||
switch (input [1]) {
|
||||
case 's':
|
||||
cmd_esil_stack (core, input+2);
|
||||
break;
|
||||
case '?':
|
||||
cmd_esil_stack (core, "?");
|
||||
case 0:
|
||||
r_anal_esil_free (esil);
|
||||
// reinitialize
|
||||
esil = core->anal->esil = r_anal_esil_new ();
|
||||
romem = r_config_get_i (core->config, "esil.romem");
|
||||
stats = r_config_get_i (core->config, "esil.stats");
|
||||
r_anal_esil_setup (esil, core->anal, romem, stats); // setup io
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'k':
|
||||
switch (input[1]) {
|
||||
|
|
@ -1388,6 +1492,7 @@ static void cmd_anal_esil(RCore *core, const char *input) {
|
|||
const char* help_msg[] = {
|
||||
"Usage:", "ae[idesr?] [arg]", "ESIL code emulation",
|
||||
"aei", "", "initialize ESIL VM state",
|
||||
"aeis", "", "initialize ESIL VM stack (aeis- remove)",
|
||||
"aed", "", "deinitialize ESIL VM state",
|
||||
"ae", " [expr]", "evaluate ESIL expression",
|
||||
"aef", " [addr]", "emulate function",
|
||||
|
|
|
|||
|
|
@ -108,6 +108,9 @@ R_API RReg *r_reg_new() {
|
|||
reg->regset[i].arena = arena;
|
||||
//r_list_append (reg->regset[i].pool, arena);
|
||||
}
|
||||
/* swap arena back and forth to avoid lost reg sets */
|
||||
r_reg_arena_swap (reg, R_FALSE);
|
||||
r_reg_arena_swap (reg, R_FALSE);
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
|
@ -128,10 +131,9 @@ static const char *parse_alias (RReg *reg, char **tok, const int n) {
|
|||
if (n != 2)
|
||||
return "Invalid syntax";
|
||||
|
||||
role = r_reg_get_name_idx(tok[0] + 1);
|
||||
return r_reg_set_name(reg, role, tok[1]) ?
|
||||
NULL :
|
||||
"Invalid alias";
|
||||
role = r_reg_get_name_idx (tok[0] + 1);
|
||||
return r_reg_set_name (reg, role, tok[1]) ?
|
||||
NULL : "Invalid alias";
|
||||
}
|
||||
|
||||
// Sizes prepended with a dot are expressed in bits
|
||||
|
|
@ -266,13 +268,14 @@ R_API int r_reg_set_profile_string(RReg *reg, const char *str) {
|
|||
free(tok[i]);
|
||||
// Warn the user if something went wrong
|
||||
if (r) {
|
||||
eprintf("%s: Parse error @ line %d (%s)\n", __FUNCTION__, l, r);
|
||||
eprintf("%s: Parse error @ line %d (%s)\n",
|
||||
__FUNCTION__, l, r);
|
||||
// Clean up
|
||||
r_reg_free_internal (reg);
|
||||
return R_FALSE;
|
||||
}
|
||||
}
|
||||
} while(*p++);
|
||||
} while (*p++);
|
||||
|
||||
// Align to byte boundary if needed
|
||||
if (reg->size&7)
|
||||
|
|
@ -336,7 +339,7 @@ R_API RRegItem *r_reg_get(RReg *reg, const char *name, int type) {
|
|||
r_list_foreach (reg->regset[i].regs, iter, r) {
|
||||
if (r->name && !strcmp (r->name, name)) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
|||
Loading…
Reference in a new issue