mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 13:19:54 +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;
|
||||
}
|
||||
|
||||
|
@ -311,20 +311,20 @@ static int try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, int depth, ut
|
||||
anal->iob.read_at (anal->iob.io, ptr, jmptbl, MAX_JMPTBL_SIZE);
|
||||
for (offs = 0; offs + sz - 1 < MAX_JMPTBL_SIZE; offs += sz) {
|
||||
switch (sz) {
|
||||
case 1:
|
||||
jmpptr = r_read_le8 (jmptbl + offs);
|
||||
case 1:
|
||||
jmpptr = r_read_le8 (jmptbl + offs);
|
||||
break;
|
||||
case 2:
|
||||
jmpptr = r_read_le16 (jmptbl + offs);
|
||||
case 2:
|
||||
jmpptr = r_read_le16 (jmptbl + offs);
|
||||
break;
|
||||
case 4:
|
||||
jmpptr = r_read_le32 (jmptbl + offs);
|
||||
case 4:
|
||||
jmpptr = r_read_le32 (jmptbl + offs);
|
||||
break;
|
||||
case 8:
|
||||
jmpptr = r_read_le32 (jmptbl + offs);
|
||||
case 8:
|
||||
jmpptr = r_read_le32 (jmptbl + offs);
|
||||
break; // XXX
|
||||
default:
|
||||
jmpptr = r_read_le64 (jmptbl + offs);
|
||||
default:
|
||||
jmpptr = r_read_le64 (jmptbl + offs);
|
||||
break;
|
||||
}
|
||||
if (!anal->iob.is_valid_offset (anal->iob.io, jmpptr, 0)) {
|
||||
@ -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') {
|
||||
@ -2333,7 +2347,7 @@ static void func_walk_blocks (RCore *core, RAnalFunction *f, char input, char ty
|
||||
RAnalBlock *b;
|
||||
RAnalFunction *tmp_func;
|
||||
RListIter *locs_it = NULL;
|
||||
|
||||
|
||||
if (f->fcn_locs) {
|
||||
locs_it = f->fcn_locs->head;
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -3955,13 +3971,13 @@ static int cmd_print(void *data, const char *input) {
|
||||
ut64 v = (ut64)r_read_ble16 (core->block + i, p->big_endian);
|
||||
if (p && p->colorfor) {
|
||||
a = p->colorfor (p->user, v, true);
|
||||
if (a && *a) {
|
||||
b = Color_RESET;
|
||||
} else {
|
||||
a = b = "";
|
||||
if (a && *a) {
|
||||
b = Color_RESET;
|
||||
} else {
|
||||
a = b = "";
|
||||
}
|
||||
} else {
|
||||
a = b = "";
|
||||
} else {
|
||||
a = b = "";
|
||||
}
|
||||
f = r_flag_get_at (core->flags, v, true);
|
||||
fn = NULL;
|
||||
@ -3998,13 +4014,13 @@ static int cmd_print(void *data, const char *input) {
|
||||
ut64 v = r_read_ble64 (core->block + i, p->big_endian);
|
||||
if (p && p->colorfor) {
|
||||
a = p->colorfor (p->user, v, true);
|
||||
if (a && *a) {
|
||||
b = Color_RESET;
|
||||
} else {
|
||||
a = b = "";
|
||||
if (a && *a) {
|
||||
b = Color_RESET;
|
||||
} else {
|
||||
a = b = "";
|
||||
}
|
||||
} else {
|
||||
a = b = "";
|
||||
} else {
|
||||
a = b = "";
|
||||
}
|
||||
f = r_flag_get_at (core->flags, v, true);
|
||||
fn = NULL;
|
||||
|
@ -360,7 +360,7 @@ static void ds_comment_esil(RDisasmState *ds, bool up, bool end, const char *for
|
||||
if (up) {
|
||||
ds_comment_lineup (ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
r_cons_printf_list (format, ap);
|
||||
va_end (ap);
|
||||
|
||||
@ -944,7 +944,7 @@ static void ds_show_xrefs(RDisasmState *ds) {
|
||||
}
|
||||
ds_pre_xrefs (ds);
|
||||
//those extra space to align
|
||||
ds_comment (ds, false, " %s; %s XREF from 0x%08"PFMT64x" (%s)%s\n",
|
||||
ds_comment (ds, false, " %s; %s XREF from 0x%08"PFMT64x" (%s)%s\n",
|
||||
COLOR (ds, pal_comment), r_anal_xrefs_type_tostring (refi->type),
|
||||
refi->addr, name, COLOR_RESET (ds));
|
||||
R_FREE (name);
|
||||
@ -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;
|
||||
@ -3123,10 +3123,10 @@ static void ds_print_esil_anal(RDisasmState *ds) {
|
||||
ds_comment_esil (ds, true, false, ds->pal_comment);
|
||||
}
|
||||
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 &&
|
||||
ds_comment_esil (ds, ds->show_color? false : true, false,
|
||||
"; %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;
|
||||
@ -3209,8 +3209,8 @@ 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);
|
||||
print_fcn_arg (core, arg_orig_c_type, arg_name,
|
||||
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