mirror of
https://github.com/radareorg/radare2.git
synced 2024-12-05 03:56:46 +00:00
Initial support for ESIL pins to emulate entire functions
This commit is contained in:
parent
d6cb2ae553
commit
693ba387a0
@ -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}
|
||||
|
||||
|
@ -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
81
libr/anal/pin.c
Normal 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);
|
||||
}
|
@ -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':
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user