mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 21:29:49 +00:00
Fix #4554 stackptr calculation on pdr and graph
- blocks have their stackptr - inherit from parent when visited hierarchically (in pdr and graph) - add the global anal->stackptr as a starting value for disasm, defaults to 0
This commit is contained in:
parent
90feff3957
commit
d50ba765eb
@ -71,6 +71,7 @@ R_API RAnal *r_anal_new() {
|
||||
r_flag_bind_init (anal->flb);
|
||||
anal->reg = r_reg_new ();
|
||||
anal->last_disasm_reg = NULL;
|
||||
anal->stackptr = 0;
|
||||
anal->bits_ranges = r_list_newf (free);
|
||||
anal->lineswidth = 0;
|
||||
anal->fcns = r_anal_fcn_list_new ();
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <r_anal.h>
|
||||
#include <r_util.h>
|
||||
#include <r_list.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define DFLT_NINSTR 3
|
||||
|
||||
@ -23,6 +24,8 @@ R_API RAnalBlock *r_anal_bb_new() {
|
||||
bb->op_pos = R_NEWS0 (ut16, DFLT_NINSTR);
|
||||
bb->op_pos_size = DFLT_NINSTR;
|
||||
bb->parent_reg_arena = NULL;
|
||||
bb->stackptr = 0;
|
||||
bb->parent_stackptr = INT_MAX;
|
||||
return bb;
|
||||
}
|
||||
|
||||
|
@ -671,6 +671,10 @@ repeat:
|
||||
if (fcn->stack > 0 && (int)op.val > 0) {
|
||||
fcn->maxstack = fcn->stack;
|
||||
}
|
||||
bb->stackptr += op.stackptr;
|
||||
break;
|
||||
case R_ANAL_STACK_RESET:
|
||||
bb->stackptr = 0;
|
||||
break;
|
||||
// TODO: use fcn->stack to know our stackframe
|
||||
case R_ANAL_STACK_SET:
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "r_types.h"
|
||||
#include "r_util.h"
|
||||
#include "ht.h"
|
||||
#include <limits.h>
|
||||
|
||||
#define R_CORE_MAX_DISASM (1024*1024*8)
|
||||
|
||||
@ -2297,15 +2298,23 @@ static void pr_bb (RCore * core, RAnalFunction * fcn, RAnalBlock * b, bool emu,
|
||||
r_reg_arena_poke (core->anal->reg, saved_arena);
|
||||
}
|
||||
}
|
||||
if (b->parent_stackptr != INT_MAX) {
|
||||
core->anal->stackptr = b->parent_stackptr;
|
||||
}
|
||||
p_type == 'D'
|
||||
? r_core_cmdf (core, "pD %"PFMT64d" @0x%"PFMT64x, b->size, b->addr)
|
||||
: r_core_cmdf (core, "pI %"PFMT64d" @0x%"PFMT64x, b->size, b->addr);
|
||||
|
||||
if (b->jump != UT64_MAX) {
|
||||
if (b->jump > b->addr && emu && core->anal->last_disasm_reg != NULL) {
|
||||
if (b->jump > b->addr) {
|
||||
RAnalBlock * jumpbb = r_anal_bb_get_jumpbb (fcn, b);
|
||||
if (jumpbb && !jumpbb->parent_reg_arena) {
|
||||
jumpbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
if (jumpbb) {
|
||||
if (emu && core->anal->last_disasm_reg != NULL && !jumpbb->parent_reg_arena) {
|
||||
jumpbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
}
|
||||
if (jumpbb->parent_stackptr == INT_MAX) {
|
||||
jumpbb->parent_stackptr = core->anal->stackptr + b->stackptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_type == 'D') {
|
||||
@ -2313,10 +2322,15 @@ static void pr_bb (RCore * core, RAnalFunction * fcn, RAnalBlock * b, bool emu,
|
||||
}
|
||||
}
|
||||
if (b->fail != UT64_MAX) {
|
||||
if (b->fail > b->addr && emu && core->anal->last_disasm_reg != NULL) {
|
||||
if (b->fail > b->addr) {
|
||||
RAnalBlock * failbb = r_anal_bb_get_failbb (fcn, b);
|
||||
if (failbb && !failbb->parent_reg_arena) {
|
||||
failbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
if (failbb) {
|
||||
if (emu && core->anal->last_disasm_reg != NULL && !failbb->parent_reg_arena) {
|
||||
failbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
}
|
||||
if (failbb->parent_stackptr == INT_MAX) {
|
||||
failbb->parent_stackptr = core->anal->stackptr + b->stackptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_type == 'D') {
|
||||
@ -2389,6 +2403,7 @@ static void func_walk_blocks (RCore *core, RAnalFunction *f, char input, char ty
|
||||
bool emu = r_config_get_i (core->config, "asm.emu");
|
||||
ut64 saved_gp = 0;
|
||||
ut8 *saved_arena;
|
||||
int saved_stackptr = core->anal->stackptr;
|
||||
if (emu) {
|
||||
saved_gp = core->anal->gp;
|
||||
saved_arena = r_reg_arena_peek (core->anal->reg);
|
||||
@ -2418,6 +2433,7 @@ static void func_walk_blocks (RCore *core, RAnalFunction *f, char input, char ty
|
||||
R_FREE (saved_arena);
|
||||
}
|
||||
}
|
||||
core->anal->stackptr = saved_stackptr;
|
||||
r_config_set_i (core->config, "asm.lines", asm_lines);
|
||||
}
|
||||
}
|
||||
|
@ -1162,7 +1162,7 @@ static void ds_show_functions(RDisasmState *ds) {
|
||||
if (ds->show_fcnlines) {
|
||||
ds->pre = r_str_concat (ds->pre, " ");
|
||||
}
|
||||
ds->stackptr = 0;
|
||||
ds->stackptr = core->anal->stackptr;
|
||||
if (ds->show_vars) {
|
||||
char spaces[32];
|
||||
RAnalVar *var;
|
||||
@ -3124,9 +3124,9 @@ static void ds_print_esil_anal(RDisasmState *ds) {
|
||||
}
|
||||
ds_align_comment (ds);
|
||||
ds_comment_esil (ds, ds->show_color? false : true, false,
|
||||
"; %s%s%s(", r_str_get (fcn_type), (fcn_type && *fcn_type &&
|
||||
"; %s%s%s(", r_str_get (fcn_type), (fcn_type && *fcn_type &&
|
||||
fcn_type[strlen (fcn_type) - 1] == '*') ? "" : " ",
|
||||
r_str_get (key));
|
||||
r_str_get (key));
|
||||
if (!nargs) {
|
||||
ds_comment_esil (ds, false, true, "void)");
|
||||
break;
|
||||
@ -3210,7 +3210,7 @@ static void ds_print_esil_anal(RDisasmState *ds) {
|
||||
if (fmt) {
|
||||
//it may need ds_comment_esil
|
||||
print_fcn_arg (core, arg_orig_c_type, arg_name,
|
||||
fmt, arg_addr, on_stack);
|
||||
fmt, arg_addr, on_stack);
|
||||
ds_comment_esil (ds, false, false, i!=(nargs - 1)?", ":")");
|
||||
}
|
||||
free (arg_orig_c_type);
|
||||
@ -3439,6 +3439,7 @@ toro:
|
||||
len = ds->l = core->blocksize;
|
||||
}
|
||||
|
||||
ds->stackptr = core->anal->stackptr;
|
||||
r_cons_break_push (NULL, NULL);
|
||||
r_anal_build_range_on_hints (core->anal);
|
||||
for (i = idx = ret = 0; idx < len && ds->lines < ds->l; idx += inc, i++, ds->index += inc, ds->lines++) {
|
||||
@ -4254,6 +4255,7 @@ R_API int r_core_print_fcn_disasm(RPrint *p, RCore *core, ut64 addr, int l, int
|
||||
ds->len = r_anal_fcn_size (fcn);
|
||||
ds->addr = fcn->addr;
|
||||
ds->fcn = fcn;
|
||||
ds->stackptr = core->anal->stackptr;
|
||||
|
||||
r_list_foreach (fcn->bbs, bb_iter, bb) {
|
||||
r_list_add_sorted (bb_list, bb, cmpaddr);
|
||||
|
@ -1695,20 +1695,33 @@ static char *get_bb_body(RCore *core, RAnalBlock *b, int opts, RAnalFunction *fc
|
||||
r_reg_arena_poke (core->anal->reg, saved_arena);
|
||||
}
|
||||
}
|
||||
if (b->parent_stackptr != INT_MAX) {
|
||||
core->anal->stackptr = b->parent_stackptr;
|
||||
}
|
||||
char * body = get_body (core, b->addr, b->size, opts);
|
||||
if (b->jump != UT64_MAX) {
|
||||
if (b->jump > b->addr && emu && core->anal->last_disasm_reg != NULL) {
|
||||
if (b->jump > b->addr) {
|
||||
RAnalBlock * jumpbb = r_anal_bb_get_jumpbb (fcn, b);
|
||||
if (jumpbb && !jumpbb->parent_reg_arena) {
|
||||
jumpbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
if (jumpbb) {
|
||||
if (emu && core->anal->last_disasm_reg != NULL && !jumpbb->parent_reg_arena) {
|
||||
jumpbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
}
|
||||
if (jumpbb->parent_stackptr == INT_MAX) {
|
||||
jumpbb->parent_stackptr = core->anal->stackptr + b->stackptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (b->fail != UT64_MAX) {
|
||||
if (b->fail > b->addr && emu && core->anal->last_disasm_reg != NULL) {
|
||||
if (b->fail > b->addr) {
|
||||
RAnalBlock * failbb = r_anal_bb_get_failbb (fcn, b);
|
||||
if (failbb && !failbb->parent_reg_arena) {
|
||||
failbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
if (failbb) {
|
||||
if (emu && core->anal->last_disasm_reg != NULL && !failbb->parent_reg_arena) {
|
||||
failbb->parent_reg_arena = r_reg_arena_dup (core->anal->reg, core->anal->last_disasm_reg);
|
||||
}
|
||||
if (failbb->parent_stackptr == INT_MAX) {
|
||||
failbb->parent_stackptr = core->anal->stackptr + b->stackptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1725,6 +1738,7 @@ 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_stackptr = core->anal->stackptr;
|
||||
core->keep_asmqjmps = false;
|
||||
|
||||
if (emu) {
|
||||
@ -1763,6 +1777,7 @@ static void get_bbupdate(RAGraph *g, RCore *core, RAnalFunction *fcn) {
|
||||
R_FREE (saved_arena);
|
||||
}
|
||||
}
|
||||
core->anal->stackptr = saved_stackptr;
|
||||
}
|
||||
|
||||
/* build the RGraph inside the RAGraph g, starting from the Basic Blocks */
|
||||
@ -1775,6 +1790,7 @@ static int get_bbnodes(RAGraph *g, RCore *core, RAnalFunction *fcn) {
|
||||
int ret = false;
|
||||
ut64 saved_gp = core->anal->gp;
|
||||
ut8 *saved_arena = NULL;
|
||||
int saved_stackptr = core->anal->stackptr;
|
||||
core->keep_asmqjmps = false;
|
||||
|
||||
if (!fcn) {
|
||||
@ -1858,6 +1874,7 @@ cleanup:
|
||||
R_FREE (saved_arena);
|
||||
}
|
||||
}
|
||||
core->anal->stackptr = saved_stackptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -647,6 +647,7 @@ typedef struct r_anal_t {
|
||||
//RList *noreturn;
|
||||
RList /*RAnalRange*/ *bits_ranges;
|
||||
RListComparator columnSort;
|
||||
int stackptr;
|
||||
} RAnal;
|
||||
|
||||
typedef RAnalFunction *(* RAnalGetFcnIn)(RAnal *anal, ut64 addr, int type);
|
||||
@ -789,6 +790,8 @@ typedef struct r_anal_bb_t {
|
||||
struct r_anal_bb_t *jumpbb;
|
||||
RList /*struct r_anal_bb_t*/ *cases;
|
||||
ut8 *parent_reg_arena;
|
||||
int stackptr;
|
||||
int parent_stackptr;
|
||||
} RAnalBlock;
|
||||
|
||||
typedef enum {
|
||||
|
Loading…
Reference in New Issue
Block a user