Save and check the reg arena size when peekpoking (Fix tests_64923) ##crash

This commit is contained in:
pancake 2021-11-01 22:38:53 +01:00 committed by GitHub
parent d8cf7cfa02
commit 467ca68d48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 26 deletions

View File

@ -2136,18 +2136,18 @@ static char *get_body(RCore *core, ut64 addr, int size, int opts) {
return body;
}
static char *get_bb_body(RCore *core, RAnalBlock *b, int opts, RAnalFunction *fcn, bool emu, ut64 saved_gp, ut8 *saved_arena) {
static char *get_bb_body(RCore *core, RAnalBlock *b, int opts, RAnalFunction *fcn, bool emu, ut64 saved_gp, ut8 *saved_arena, int saved_arena_size) {
if (emu) {
core->anal->gp = saved_gp;
if (b->parent_reg_arena) {
r_reg_arena_poke (core->anal->reg, b->parent_reg_arena);
r_reg_arena_poke (core->anal->reg, b->parent_reg_arena, b->parent_reg_arena_size);
R_FREE (b->parent_reg_arena);
ut64 gp = r_reg_getv (core->anal->reg, "gp");
if (gp) {
core->anal->gp = gp;
}
} else {
r_reg_arena_poke (core->anal->reg, saved_arena);
r_reg_arena_poke (core->anal->reg, saved_arena, saved_arena_size);
}
}
if (b->parent_stackptr != INT_MAX) {
@ -2193,13 +2193,14 @@ static void get_bbupdate(RAGraph *g, RCore *core, RAnalFunction *fcn) {
bool emu = r_config_get_i (core->config, "asm.emu");
ut64 saved_gp = core->anal->gp;
ut8 *saved_arena = NULL;
int saved_arena_size = 0;
int saved_stackptr = core->anal->stackptr;
char *shortcut = 0;
int shortcuts = 0;
core->keep_asmqjmps = false;
if (emu) {
saved_arena = r_reg_arena_peek (core->anal->reg);
saved_arena = r_reg_arena_peek (core->anal->reg, &saved_arena_size);
}
if (!fcn) {
R_FREE (saved_arena);
@ -2212,7 +2213,7 @@ static void get_bbupdate(RAGraph *g, RCore *core, RAnalFunction *fcn) {
if (bb->addr == UT64_MAX) {
continue;
}
char *body = get_bb_body (core, bb, mode2opts (g), fcn, emu, saved_gp, saved_arena);
char *body = get_bb_body (core, bb, mode2opts (g), fcn, emu, saved_gp, saved_arena, saved_arena_size);
char *title = get_title (bb->addr);
if (shortcuts) {
@ -2240,7 +2241,7 @@ static void get_bbupdate(RAGraph *g, RCore *core, RAnalFunction *fcn) {
if (emu) {
core->anal->gp = saved_gp;
if (saved_arena) {
r_reg_arena_poke (core->anal->reg, saved_arena);
r_reg_arena_poke (core->anal->reg, saved_arena, saved_arena_size);
R_FREE (saved_arena);
}
}
@ -2327,6 +2328,7 @@ static int get_bbnodes(RAGraph *g, RCore *core, RAnalFunction *fcn) {
bool few = r_config_get_i (core->config, "graph.few");
int ret = false;
ut64 saved_gp = core->anal->gp;
int saved_arena_size = 0;
ut8 *saved_arena = NULL;
int saved_stackptr = core->anal->stackptr;
core->keep_asmqjmps = false;
@ -2335,7 +2337,7 @@ static int get_bbnodes(RAGraph *g, RCore *core, RAnalFunction *fcn) {
return false;
}
if (emu) {
saved_arena = r_reg_arena_peek (core->anal->reg);
saved_arena = r_reg_arena_peek (core->anal->reg, &saved_arena_size);
}
r_list_sort (fcn->bbs, (RListComparator) bbcmp);
RAnalBlock *curbb = NULL;
@ -2359,7 +2361,7 @@ static int get_bbnodes(RAGraph *g, RCore *core, RAnalFunction *fcn) {
if (few && !isbbfew (curbb, bb)) {
continue;
}
char *body = get_bb_body (core, bb, mode2opts (g), fcn, emu, saved_gp, saved_arena);
char *body = get_bb_body (core, bb, mode2opts (g), fcn, emu, saved_gp, saved_arena, saved_arena_size);
char *title = get_title (bb->addr);
char *color = (bb->color.r || bb->color.g || bb->color.b)? r_cons_rgb_str (NULL, -1, &bb->color): NULL;
RANode *node = r_agraph_add_node (g, title, body, color);
@ -2410,7 +2412,7 @@ cleanup:
if (emu) {
core->anal->gp = saved_gp;
if (saved_arena) {
r_reg_arena_poke (core->anal->reg, saved_arena);
r_reg_arena_poke (core->anal->reg, saved_arena, saved_arena_size);
R_FREE (saved_arena);
}
}

View File

@ -1049,14 +1049,15 @@ static bool cmd_anal_aaft(RCore *core) {
r_reg_arena_push (core->anal->reg);
r_reg_arena_zero (core->anal->reg);
r_core_cmd0 (core, "aei;aeim");
ut8 *saved_arena = r_reg_arena_peek (core->anal->reg);
int saved_arena_size = 0;
ut8 *saved_arena = r_reg_arena_peek (core->anal->reg, &saved_arena_size);
// Iterating Reverse so that we get function in top-bottom call order
r_list_foreach_prev (core->anal->fcns, it, fcn) {
int ret = r_core_seek (core, fcn->addr, true);
if (!ret) {
continue;
}
r_reg_arena_poke (core->anal->reg, saved_arena);
r_reg_arena_poke (core->anal->reg, saved_arena, saved_arena_size);
r_anal_esil_set_pc (core->anal->esil, fcn->addr);
r_core_anal_type_match (core, fcn);
if (r_cons_is_breaked ()) {

View File

@ -4178,8 +4178,8 @@ static void __printPattern(RCore *core, const char *_input) {
free (input);
}
static void pr_bb(RCore *core, RAnalFunction *fcn, RAnalBlock *b, bool emu, ut64 saved_gp, ut8 *saved_arena, char p_type, bool fromHere) {
bool show_flags = r_config_get_i (core->config, "asm.flags");
static void pr_bb(RCore *core, RAnalFunction *fcn, RAnalBlock *b, bool emu, ut64 saved_gp, ut8 *saved_arena, int saved_arena_size, char p_type, bool fromHere) {
bool show_flags = r_config_get_b (core->config, "asm.flags");
const char *orig_bb_middle = r_config_get (core->config, "asm.bbmiddle");
core->anal->gp = saved_gp;
if (fromHere) {
@ -4192,14 +4192,14 @@ static void pr_bb(RCore *core, RAnalFunction *fcn, RAnalBlock *b, bool emu, ut64
if (emu) {
if (b->parent_reg_arena) {
ut64 gp;
r_reg_arena_poke (core->anal->reg, b->parent_reg_arena);
r_reg_arena_poke (core->anal->reg, b->parent_reg_arena, b->parent_reg_arena_size);
R_FREE (b->parent_reg_arena);
gp = r_reg_getv (core->anal->reg, "gp");
if (gp) {
core->anal->gp = gp;
}
} else {
r_reg_arena_poke (core->anal->reg, saved_arena);
r_reg_arena_poke (core->anal->reg, saved_arena, saved_arena_size);
}
}
if (b->parent_stackptr != INT_MAX) {
@ -4435,20 +4435,21 @@ static void func_walk_blocks(RCore *core, RAnalFunction *f, char input, char typ
bool asm_lines = r_config_get_i (core->config, "asm.lines.jmp");
bool emu = r_config_get_i (core->config, "asm.emu");
ut64 saved_gp = 0;
int saved_arena_size = 0;
ut8 *saved_arena = NULL;
int saved_stackptr = core->anal->stackptr;
if (emu) {
saved_gp = core->anal->gp;
saved_arena = r_reg_arena_peek (core->anal->reg);
saved_arena = r_reg_arena_peek (core->anal->reg, &saved_arena_size);
}
r_config_set_i (core->config, "asm.lines.jmp", 0);
r_list_foreach (f->bbs, iter, b) {
pr_bb (core, f, b, emu, saved_gp, saved_arena, type_print, fromHere);
pr_bb (core, f, b, emu, saved_gp, saved_arena, saved_arena_size, type_print, fromHere);
}
if (emu) {
core->anal->gp = saved_gp;
if (saved_arena) {
r_reg_arena_poke (core->anal->reg, saved_arena);
r_reg_arena_poke (core->anal->reg, saved_arena, saved_arena_size);
R_FREE (saved_arena);
}
}

View File

@ -579,11 +579,11 @@ static void ds_print_esil_anal_fini(RDisasmState *ds) {
RCore *core = ds->core;
if (ds->show_emu && ds->esil_regstate) {
RCore* core = ds->core;
core->anal->last_disasm_reg = r_reg_arena_peek (core->anal->reg);
core->anal->last_disasm_reg = r_reg_arena_peek (core->anal->reg, &core->anal->last_disasm_reg_size);
const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
RRegSet *regset = r_reg_regset_get (ds->core->anal->reg, R_REG_TYPE_GPR);
if (ds->esil_regstate_size == regset->arena->size) {
r_reg_arena_poke (core->anal->reg, ds->esil_regstate);
if (ds->esil_regstate_size == regset->arena->size) {
r_reg_arena_poke (core->anal->reg, ds->esil_regstate, ds->esil_regstate_size);
}
r_reg_setv (core->anal->reg, pc, ds->esil_old_pc);
R_FREE (ds->esil_regstate);
@ -4697,7 +4697,7 @@ static void ds_print_esil_anal_init(RDisasmState *ds) {
if (core->anal->gp) {
r_reg_setv (core->anal->reg, "gp", core->anal->gp);
}
ds->esil_regstate = r_reg_arena_peek (core->anal->reg);
ds->esil_regstate = r_reg_arena_peek (core->anal->reg, &ds->esil_regstate_size);
RRegSet *regset = r_reg_regset_get (core->anal->reg, R_REG_TYPE_GPR);
if (ds->esil_regstate && regset) {
ds->esil_regstate_size = regset->arena->size;

View File

@ -624,6 +624,7 @@ typedef struct r_anal_t {
HtPP *ht_name_fun; // name => function
RReg *reg;
ut8 *last_disasm_reg;
int last_disasm_reg_size;
RSyscall *syscall;
int diff_ops;
double diff_thbb;
@ -927,6 +928,7 @@ typedef struct r_anal_bb_t {
ut16 *op_pos; // offsets of instructions in this block, count is ninstr - 1 (first is always 0)
ut8 *op_bytes;
ut8 *parent_reg_arena;
int parent_reg_arena_size;
int op_pos_size; // size of the op_pos array
int ninstr;
int stackptr;

View File

@ -226,8 +226,8 @@ R_API int r_reg_arena_push(RReg *reg);
R_API void r_reg_arena_pop(RReg *reg);
R_API void r_reg_arena_zero(RReg *reg);
R_API ut8 *r_reg_arena_peek(RReg *reg);
R_API void r_reg_arena_poke(RReg *reg, const ut8 *buf);
R_API ut8 *r_reg_arena_peek(RReg *reg, int *len);
R_API void r_reg_arena_poke(RReg *reg, const ut8 *buf, int len);
R_API ut8 *r_reg_arena_dup(RReg *reg, const ut8 *source);
R_API const char *r_reg_cond_to_string(int n);
R_API int r_reg_cond_from_string(const char *str);

View File

@ -263,7 +263,7 @@ R_API void r_reg_arena_zero(RReg *reg) {
}
}
R_API ut8 *r_reg_arena_peek(RReg *reg) {
R_API ut8 *r_reg_arena_peek(RReg *reg, int *size) {
RRegSet *regset = r_reg_regset_get (reg, R_REG_TYPE_GPR);
if (!reg || !regset || !regset->arena || (regset->arena->size < 1)) {
return NULL;
@ -273,14 +273,22 @@ R_API ut8 *r_reg_arena_peek(RReg *reg) {
return NULL;
}
memcpy (ret, regset->arena->bytes, regset->arena->size);
if (size) {
*size = regset->arena->size;
}
return ret;
}
R_API void r_reg_arena_poke(RReg *reg, const ut8 *ret) {
R_API void r_reg_arena_poke(RReg *reg, const ut8 *ret, int len) {
RRegSet *regset = r_reg_regset_get (reg, R_REG_TYPE_GPR);
if (!ret || !regset || !regset->arena || !regset->arena->bytes) {
return;
}
if (len > 0 && len != regset->arena->size) {
eprintf ("Invalid size of the arena bytes to poke (%d vs %d).\n",
len, regset->arena->size);
return;
}
memcpy (regset->arena->bytes, ret, regset->arena->size);
}