Initial implementation of asm.emuwrite and asm.emu for CALL and UCALL

This commit is contained in:
pancake 2015-10-29 23:37:51 +01:00
parent 82eba162a9
commit ec2ac9c640
5 changed files with 89 additions and 36 deletions

View File

@ -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
}

View File

@ -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");

View File

@ -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);
}

View File

@ -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:

View File

@ -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;