Initial support for ESIL pins to emulate entire functions

This commit is contained in:
pancake 2015-06-30 10:50:46 +02:00
parent d6cb2ae553
commit 693ba387a0
6 changed files with 135 additions and 15 deletions

View File

@ -29,7 +29,7 @@ OBJLIBS+=cond.o value.o cc.o diff.o types.o fcnstore.o
OBJLIBS+=hint.o vm.o anal.o data.o xrefs.o esil.o sign.o
OBJLIBS+=anal_ex.o switch.o state.o cycles.o rpnesil.o
OBJLIBS+=esil_stats.o esil_trace.o flirt.o labels.o
OBJLIBS+=esil2reil.o
OBJLIBS+=esil2reil.o pin.o
OBJS=${STATIC_OBJS} ${OBJLIBS} ${CPARSE_OBJS}

View File

@ -96,6 +96,7 @@ R_API RAnal *r_anal_new() {
//anal->sdb_locals = sdb_ns (anal->sdb, "locals", 1);
anal->sdb_types = sdb_ns (anal->sdb, "types", 1);
anal->printf = (PrintfCallback) printf;
r_anal_pin_init (anal);
r_anal_type_init (anal);
r_anal_xrefs_init (anal);
anal->diff_thbb = R_ANAL_THRESHOLDBB;
@ -145,6 +146,7 @@ R_API RAnal *r_anal_free(RAnal *a) {
// might provoke double frees since this is used in r_anal_fcn_insert()
//r_listrange_free (a->fcnstore);
r_space_fini (&a->meta_spaces);
r_anal_pin_fini (a);
r_list_free (a->refs);
r_list_free (a->types);
r_reg_free (a->reg);

81
libr/anal/pin.c Normal file
View File

@ -0,0 +1,81 @@
/* radare - LGPL - Copyright 2015 - pancake, nibble */
#include <r_anal.h>
typedef void (*RAnalEsilPin)(RAnal *a);
// TODO: those hardcoded functions should go
/* default pins from libc */
static void pin_strlen(RAnal *a) {
// get a0 register
// read memory and interpret it as a string
// set a0 to the result of strlen;
eprintf ("esilpin: strlen\n");
}
static void pin_write(RAnal *a) {
// get a0 register for fd
// get a1 register for data
// get a2 register for len
// read len bytes from data and print them to screen + fd
// set a0 to the result of write;
eprintf ("esilpin: write\n");
}
/* pin api */
#define DB a->sdb_pins
R_API void r_anal_pin_init(RAnal *a) {
sdb_free (DB);
DB = sdb_new0();
sdb_ptr_set (DB, "strlen", pin_strlen, 0);
sdb_ptr_set (DB, "write", pin_write, 0);
}
R_API void r_anal_pin_fini(RAnal *a) {
sdb_free (DB);
}
R_API void r_anal_pin (RAnal *a, ut64 addr, const char *name) {
char buf[64];
const char *key = sdb_itoa (addr, buf, 16);
sdb_set (DB, key, name, 0);
}
R_API void r_anal_pin_unset (RAnal *a, ut64 addr) {
char buf[64];
const char *key = sdb_itoa (addr, buf, 16);
sdb_unset (DB, key, 0);
}
R_API int r_anal_pin_call(RAnal *a, ut64 addr) {
char buf[64];
const char *key, *name;
key = sdb_itoa (addr, buf, 16);
if (!key) return R_FALSE;
name = sdb_const_get (DB, key, NULL);
if (!name) return R_FALSE;
RAnalEsilPin fcnptr = (RAnalEsilPin *)sdb_ptr_get (DB, name, NULL);
if (fcnptr) {
fcnptr (a);
return R_TRUE;
}
return R_FALSE;
}
static int cb_list(void *user, const char *k, const char *v) {
RAnal *a = (RAnal*)user;
if (!strncmp (k, "0x", 2)) {
// bind
a->printf ("%s = %s\n", k, v);
} else {
// ptr
a->printf ("PIN %s\n", k);
}
return 1;
}
R_API void r_anal_pin_list(RAnal *a) {
sdb_foreach (DB, cb_list, a);
}

View File

@ -1273,9 +1273,7 @@ static void esil_step(RCore *core, ut64 until_addr, const char *until_expr) {
if (entries && r_list_length(entries)) {
entry = (RBinAddr *) r_list_pop (entries);
info = r_bin_get_info (core->bin);
if (info->has_va)
addr = entry->vaddr;
else addr = entry->paddr;
addr = info->has_va? entry->vaddr : entry->paddr;
//eprintf ("PC=entry0\n");
r_list_push (entries, entry);
} else {
@ -1288,6 +1286,10 @@ static void esil_step(RCore *core, ut64 until_addr, const char *until_expr) {
addr = r_reg_getv (core->anal->reg, name);
//eprintf ("PC=0x%llx\n", (ut64)addr);
}
if (r_anal_pin_call (core->anal, addr)) {
eprintf ("esil pin called\n");
return;
}
if (core->anal->esil->delay)
addr = core->anal->esil->delay_addr;
r_io_read_at (core->io, addr, code, sizeof (code));
@ -1295,7 +1297,7 @@ static void esil_step(RCore *core, ut64 until_addr, const char *until_expr) {
ret = r_anal_op (core->anal, &op, addr, code, sizeof (code));
core->anal->esil->delay = op.delay;
if (core->anal->esil->delay)
core->anal->esil->delay_addr = addr+op.size;
core->anal->esil->delay_addr = addr + op.size;
#if 0
eprintf ("RET %d\n", ret);
eprintf ("ADDR 0x%llx\n", addr);
@ -1494,6 +1496,13 @@ static void cmd_esil_mem (RCore *core, const char *input) {
}
static void cmd_anal_esil(RCore *core, const char *input) {
const char* help_msg[] = {
"Usage:", "aep[-c] ", " [...]",
"aepc", " [addr]", "change program counter for esil",
"aep", "-[addr]", "remove pin",
"aep", " [name] @ [addr]", "set pin",
"aep", "", "list pins",
NULL};
RAnalEsil *esil = core->anal->esil;
ut64 addr = core->offset;
int romem = r_config_get_i (core->config, "esil.romem");
@ -1503,15 +1512,33 @@ static void cmd_anal_esil(RCore *core, const char *input) {
RAnalOp *op;
switch (input[0]) {
case 'p': // "aep "
if (input[1] == ' ') {
// seek to this address
r_core_cmd0 (core, "aei"); // init vm
r_core_cmd0 (core, "aeim"); // init stack
r_core_cmdf (core, "ar pc=%s", input+2);
r_core_cmd0 (core, ".ar*");
} else {
eprintf ("Missing argument\n");
case 'p': // "aep"
switch (input[1]) {
case 'c':
if (input[2] == ' ') {
// seek to this address
r_core_cmd0 (core, "aei"); // init vm
r_core_cmd0 (core, "aeim"); // init stack
r_core_cmdf (core, "ar pc=%s", input+3);
r_core_cmd0 (core, ".ar*");
} else {
eprintf ("Missing argument\n");
}
break;
case 0:
r_anal_pin_list (core->anal);
break;
case '-':
if (input[2])
addr = r_num_math (core->num, input+2);
r_anal_pin_unset (core->anal, addr);
break;
case ' ':
r_anal_pin (core->anal, addr, input+2);
break;
default:
r_core_cmd_help (core, help_msg);
break;
}
break;
case 'r':

View File

@ -314,7 +314,7 @@ R_API int r_core_project_save(RCore *core, const char *file) {
r_cons_flush ();
{
char buf[1024];
snprintf (buf, sizeof (buf), "%s.d%sxrefs", prj, R_SYS_DIR);
snprintf (buf, sizeof (buf), "%s.d"R_SYS_DIR"xrefs", prj);
sdb_file (core->anal->sdb_xrefs, buf);
sdb_sync (core->anal->sdb_xrefs);
}

View File

@ -605,6 +605,7 @@ typedef struct r_anal_t {
Sdb *sdb; // root
Sdb *sdb_refs;
Sdb *sdb_fcns;
Sdb *sdb_pins;
#define DEPRECATE 1
#if DEPRECATE
Sdb *sdb_args; //
@ -1158,6 +1159,15 @@ R_API int r_anal_esil_fire_interrupt (RAnalEsil *esil, int interrupt);
R_API void r_anal_esil_mem_ro(RAnalEsil *esil, int mem_readonly);
R_API void r_anal_esil_stats(RAnalEsil *esil, int enable);
/* pin */
R_API void r_anal_pin_init(RAnal *a);
R_API void r_anal_pin_fini(RAnal *a);
R_API void r_anal_pin (RAnal *a, ut64 addr, const char *name);
R_API void r_anal_pin_unset (RAnal *a, ut64 addr);
R_API int r_anal_pin_call(RAnal *a, ut64 addr);
R_API void r_anal_pin_list(RAnal *a);
/* fcn.c */
R_API RAnalFunction *r_anal_fcn_new(void);
R_API int r_anal_fcn_is_in_offset (RAnalFunction *fcn, ut64 addr);