mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-21 23:01:03 +00:00
Initial implementation of asm.emuwrite and asm.emu for CALL and UCALL
This commit is contained in:
parent
82eba162a9
commit
ec2ac9c640
@ -2099,7 +2099,7 @@ static int is_string (const ut8 *buf, int size, int *len) {
|
||||
int i;
|
||||
if (size<1)
|
||||
return 0;
|
||||
if (size>3 && buf[0] &&!buf[1]&&buf[2]&&!buf[3]) {
|
||||
if (size>3 && buf[0] && !buf[1] && buf[2] && !buf[3]) {
|
||||
*len = 1; // XXX: TODO: Measure wide string length
|
||||
return 2; // is wide
|
||||
}
|
||||
|
@ -1279,6 +1279,7 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETPREF("asm.dwarf", "false", "Show dwarf comment at disassembly");
|
||||
SETPREF("asm.esil", "false", "Show ESIL instead of mnemonic");
|
||||
SETPREF("asm.emu", "false", "Run ESIL emulation analysis on disasm");
|
||||
SETPREF("asm.emuwrite", "false", "Allow asm.emu to modify memory (WARNING)");
|
||||
SETPREF("asm.filter", "true", "Replace numeric values by flags (e.g. 0x4003e0 -> sym.imp.printf)");
|
||||
SETPREF("asm.fcnlines", "true", "Show function boundary lines");
|
||||
SETPREF("asm.flags", "true", "Show flags");
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#define HASRETRY 1
|
||||
#define HAVE_LOCALS 1
|
||||
#define DEFAULT_NARGS 4
|
||||
|
||||
static const char* r_vline_a[] = {
|
||||
"|", // LINE_VERT
|
||||
@ -66,6 +67,7 @@ typedef struct r_disam_options_t {
|
||||
int asm_demangle;
|
||||
int show_offset;
|
||||
int show_emu;
|
||||
int show_emu_write;
|
||||
int show_section;
|
||||
int show_offseg;
|
||||
int show_flags;
|
||||
@ -308,6 +310,7 @@ static RDisasmState * handle_init_ds (RCore * core) {
|
||||
ds->show_offset = r_config_get_i (core->config, "asm.offset");
|
||||
ds->show_section = r_config_get_i (core->config, "asm.section");
|
||||
ds->show_emu = r_config_get_i (core->config, "asm.emu");
|
||||
ds->show_emu_write = r_config_get_i (core->config, "asm.emuwrite");
|
||||
ds->show_offseg = r_config_get_i (core->config, "asm.segoff");
|
||||
ds->show_flags = r_config_get_i (core->config, "asm.flags");
|
||||
ds->show_bytes = r_config_get_i (core->config, "asm.bytes");
|
||||
@ -2193,6 +2196,14 @@ static void handle_print_relocs (RCore *core, RDisasmState *ds) {
|
||||
static int likely = 0;
|
||||
static int show_slow = 0;
|
||||
|
||||
static int mymemwrite0(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mymemwrite1(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int myregwrite(RAnalEsil *esil, const char *name, ut64 val) {
|
||||
char str[64], *msg = NULL;
|
||||
ut32 *n32 = (ut32*)str;
|
||||
@ -2264,7 +2275,7 @@ static void handle_print_esil_anal_fini(RCore *core, RDisasmState *ds) {
|
||||
static void handle_print_esil_anal(RCore *core, RDisasmState *ds) {
|
||||
RAnalEsil *esil = core->anal->esil;
|
||||
const char *pc;
|
||||
int ioc;
|
||||
int i, ioc, nargs;
|
||||
if (!esil || !ds->show_comments) {
|
||||
return;
|
||||
}
|
||||
@ -2280,22 +2291,46 @@ static void handle_print_esil_anal(RCore *core, RDisasmState *ds) {
|
||||
r_reg_setv (core->anal->reg, pc, ds->at + ds->analop.size);
|
||||
show_slow = ds->show_slow; // hacky global
|
||||
esil->cb.hook_reg_write = myregwrite;
|
||||
if (ds->show_emu_write) {
|
||||
esil->cb.hook_mem_write = mymemwrite0;
|
||||
} else {
|
||||
esil->cb.hook_mem_write = mymemwrite1;
|
||||
}
|
||||
likely = 0;
|
||||
r_anal_esil_parse (esil, R_STRBUF_SAFEGET (&ds->analop.esil));
|
||||
r_anal_esil_stack_free (esil);
|
||||
if (ds->analop.type == R_ANAL_OP_TYPE_SWI) {
|
||||
char *s = cmd_syscall_dostr(core, -1);
|
||||
switch (ds->analop.type) {
|
||||
case R_ANAL_OP_TYPE_SWI: {
|
||||
char *s = cmd_syscall_dostr (core, -1);
|
||||
if (s) {
|
||||
r_cons_printf ("; %s", s);
|
||||
free (s);
|
||||
}
|
||||
}
|
||||
if (ds->analop.type == R_ANAL_OP_TYPE_CJMP) {
|
||||
} break;
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
if (likely) {
|
||||
r_cons_printf ("; likely");
|
||||
} else {
|
||||
r_cons_printf ("; unlikely");
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_UCALL:
|
||||
case R_ANAL_OP_TYPE_CALL:
|
||||
{
|
||||
ut64 pcv = r_reg_getv (core->anal->reg, pc);
|
||||
RAnalFunction *fcn = r_anal_get_fcn_at (core->anal, pcv, 0);
|
||||
if (fcn) {
|
||||
nargs = fcn->nargs;
|
||||
} else {
|
||||
nargs = DEFAULT_NARGS;
|
||||
}
|
||||
}
|
||||
r_cons_printf ("\n; CALL: ");
|
||||
for (i = 0; i < nargs; i++) {
|
||||
ut64 v = r_debug_arg_get (core->dbg, R_ANAL_CC_TYPE_STDCALL, i);
|
||||
r_cons_printf ("%s0x%"PFMT64x, i?", ":"", v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
r_config_set_i (core->config, "io.cache", ioc);
|
||||
}
|
||||
|
@ -12,7 +12,24 @@ R_API ut64 r_debug_arg_get (RDebug *dbg, int cctype, int num) {
|
||||
return r_debug_reg_get (dbg, reg);
|
||||
case R_ANAL_CC_TYPE_STDCALL:
|
||||
case R_ANAL_CC_TYPE_PASCAL:
|
||||
/* TODO: get from stack */
|
||||
{
|
||||
ut32 n32;
|
||||
ut64 n64;
|
||||
ut64 sp = r_debug_reg_get (dbg, "sp");
|
||||
if (dbg->bits == 64) {
|
||||
sp += 8; // skip return address, asume we are inside the call
|
||||
sp += 8 * num;
|
||||
dbg->iob.read_at (dbg->iob.io, sp, (ut8*)&n64, sizeof(ut64));
|
||||
// TODO: honor endianness of platform
|
||||
return (ut64)n64;
|
||||
} else {
|
||||
sp += 4; // skip return address, asume we are inside the call
|
||||
sp += 4 * num;
|
||||
dbg->iob.read_at (dbg->iob.io, sp, (ut8*)&n32, sizeof(ut32));
|
||||
// TODO: honor endianness of platform
|
||||
return (ut64)n32;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
snprintf (reg, 30, "a%d", num);
|
||||
@ -26,7 +43,7 @@ R_API bool r_debug_arg_set (RDebug *dbg, int cctype, int num, ut64 val) {
|
||||
case R_ANAL_CC_TYPE_NONE:
|
||||
case R_ANAL_CC_TYPE_SYSV:
|
||||
case R_ANAL_CC_TYPE_FASTCALL:
|
||||
sprintf (reg, 30, "a%d", num);
|
||||
snprintf (reg, 30, "a%d", num);
|
||||
return r_debug_reg_set (dbg, reg, val);
|
||||
case R_ANAL_CC_TYPE_STDCALL:
|
||||
case R_ANAL_CC_TYPE_PASCAL:
|
||||
|
@ -277,38 +277,38 @@ typedef struct r_anal_fcn_store_t {
|
||||
/* Store various function information,
|
||||
* variables, arguments, refs and even
|
||||
* description */
|
||||
typedef struct r_anal_type_function_t {
|
||||
char* name;
|
||||
char* dsc; // For producing nice listings
|
||||
ut32 size;
|
||||
int bits; // ((> bits 0) (set-bits bits))
|
||||
short type;
|
||||
/*item_list *rets; // Type of return value */
|
||||
short rets;
|
||||
short fmod; // static, inline or volatile?
|
||||
/* TODO: Change to RAnalCC ??? */
|
||||
short call; // calling convention
|
||||
char* attr; // __attribute__(()) list
|
||||
ut64 addr;
|
||||
int stack;
|
||||
int ninstr;
|
||||
int nargs; // Function arguments counter
|
||||
int depth;
|
||||
RAnalType *args; // list of arguments
|
||||
typedef struct r_anal_type_function_t {
|
||||
char* name;
|
||||
char* dsc; // For producing nice listings
|
||||
ut32 size;
|
||||
int bits; // ((> bits 0) (set-bits bits))
|
||||
short type;
|
||||
/*item_list *rets; // Type of return value */
|
||||
short rets;
|
||||
short fmod; // static, inline or volatile?
|
||||
/* TODO: Change to RAnalCC ??? */
|
||||
short call; // calling convention
|
||||
char* attr; // __attribute__(()) list
|
||||
ut64 addr;
|
||||
int stack;
|
||||
int ninstr;
|
||||
int nargs; // Function arguments counter
|
||||
int depth;
|
||||
RAnalType *args; // list of arguments
|
||||
#if USE_VARSUBS
|
||||
RAnalVarSub varsubs[R_ANAL_VARSUBS];
|
||||
RAnalVarSub varsubs[R_ANAL_VARSUBS];
|
||||
#endif
|
||||
ut8 *fingerprint; // TODO: make is fuzzy and smarter
|
||||
RAnalDiff *diff;
|
||||
RList *locs; // list of local variables
|
||||
//RList *locals; // list of local labels -> moved to anal->sdb_fcns
|
||||
RList *bbs;
|
||||
RList *vars;
|
||||
ut8 *fingerprint; // TODO: make is fuzzy and smarter
|
||||
RAnalDiff *diff;
|
||||
RList *locs; // list of local variables
|
||||
//RList *locals; // list of local labels -> moved to anal->sdb_fcns
|
||||
RList *bbs;
|
||||
RList *vars;
|
||||
#if FCN_OLD
|
||||
RList *refs;
|
||||
RList *xrefs;
|
||||
RList *refs;
|
||||
RList *xrefs;
|
||||
#endif
|
||||
} RAnalFunction;
|
||||
} RAnalFunction;
|
||||
|
||||
struct r_anal_type_t {
|
||||
char *name;
|
||||
|
Loading…
x
Reference in New Issue
Block a user