mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-26 22:50:48 +00:00
Save and check the reg arena size when peekpoking (Fix tests_64923) ##crash
This commit is contained in:
parent
d8cf7cfa02
commit
467ca68d48
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 ()) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user