Add aad command to analyze data refs as code (LEA)

This commit is contained in:
pancake 2016-08-04 22:52:33 +02:00
parent f47a328e32
commit f840836af8
4 changed files with 87 additions and 36 deletions

View File

@ -1769,6 +1769,7 @@ static void anop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh
op->type = R_ANAL_OP_TYPE_LEA;
switch (INSOP(1).type) {
case X86_OP_MEM:
// op->type = R_ANAL_OP_TYPE_ULEA;
op->ptr = INSOP(1).mem.disp;
op->refptr = INSOP(1).size;
switch (INSOP(1).mem.base) {
@ -1786,8 +1787,9 @@ static void anop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh
}
break;
case X86_OP_IMM:
if (INSOP(1).imm > 10)
if (INSOP(1).imm > 10) {
op->ptr = INSOP(1).imm;
}
break;
default:
break;

View File

@ -1,30 +1,30 @@
/* radare - LGPL - Copyright 2009-2014 - pancake, nibble */
/* radare - LGPL - Copyright 2009-2016 - pancake, nibble */
#include <r_anal.h>
#include <sdb.h>
#define DB anal->sdb_xrefs
static void XREFKEY(char * const key, const size_t key_len,
char const * const kind, const RAnalRefType type, const ut64 addr) {
char const * _sdb_type = "unk";
static const char *analref_toString(RAnalRefType type) {
switch (type) {
case R_ANAL_REF_TYPE_NULL:
_sdb_type = "unk";
/* do nothing */
break;
case R_ANAL_REF_TYPE_CODE:
_sdb_type = "code.jmp";
break;
return "code.jmp";
case R_ANAL_REF_TYPE_CALL:
_sdb_type = "code.call";
break;
return "code.call";
case R_ANAL_REF_TYPE_DATA:
_sdb_type = "data.mem";
break;
return "data.mem";
case R_ANAL_REF_TYPE_STRING:
_sdb_type = "data.string";
break;
return "data.string";
}
return "unk";
}
static void XREFKEY(char * const key, const size_t key_len,
char const * const kind, const RAnalRefType type, const ut64 addr) {
char const * _sdb_type = analref_toString (type);
snprintf (key, key_len, "%s.%s.0x%"PFMT64x, kind, _sdb_type, addr);
}
@ -33,8 +33,7 @@ R_API bool r_anal_xrefs_save(RAnal *anal, const char *prjfile) {
return sdb_sync (anal->sdb_xrefs);
}
R_API int r_anal_xrefs_set (RAnal *anal, const RAnalRefType type,
ut64 from, ut64 to) {
R_API int r_anal_xrefs_set (RAnal *anal, const RAnalRefType type, ut64 from, ut64 to) {
char key[32];
if (!anal || !DB)
return false;
@ -51,8 +50,9 @@ R_API int r_anal_xrefs_set (RAnal *anal, const RAnalRefType type,
R_API int r_anal_xrefs_deln (RAnal *anal, const RAnalRefType type, ut64 from, ut64 to) {
char key[32];
if (!anal || !DB)
if (!anal || !DB) {
return false;
}
XREFKEY (key, sizeof (key), "ref", type, from);
sdb_array_remove_num (DB, key, to, 0);
XREFKEY (key, sizeof (key), "xref", type, to);
@ -60,22 +60,49 @@ R_API int r_anal_xrefs_deln (RAnal *anal, const RAnalRefType type, ut64 from, ut
return true;
}
static int _type = -1;
static RList *_list = NULL;
static char *_kpfx = NULL;
static int xrefs_list_cb_any(RAnal *anal, const char *k, const char *v) {
//ut64 dst, src = r_num_get (NULL, v);
if (!strncmp (_kpfx, k, strlen (_kpfx))) {
RAnalRef *ref = r_anal_ref_new ();
if (ref) {
ref->addr = r_num_get (NULL, k + strlen (_kpfx) + 1);
ref->at = r_num_get (NULL, v); // XXX
ref->type = _type;
r_list_append (_list, ref);
}
}
return true;
}
R_API int r_anal_xrefs_from (RAnal *anal, RList *list, const char *kind, const RAnalRefType type, ut64 addr) {
char *next, *s, *str, *ptr, key[256];
RAnalRef *ref = NULL;
if (addr == UT64_MAX) {
_type = type;
_list = list;
_kpfx = r_str_newf ("xref.%s", analref_toString (type));
sdb_foreach (DB, (SdbForeachCallback)xrefs_list_cb_any, anal);
free (_kpfx);
return true;
}
XREFKEY(key, sizeof (key), kind, type, addr);
str = sdb_get (DB, key, 0);
if (!str) return false;
for (ptr=str; ; ptr = next) {
if (!str) {
return false;
}
for (next = ptr = str; next; ptr = next) {
s = sdb_anext (ptr, &next);
if (!(ref = r_anal_ref_new ()))
if (!(ref = r_anal_ref_new ())) {
return false;
}
ref->addr = r_num_get (NULL, s);
ref->at = addr;
ref->type = type;
r_list_append (list, ref);
if (!next)
break;
}
free (str);
return true;
@ -83,7 +110,9 @@ R_API int r_anal_xrefs_from (RAnal *anal, RList *list, const char *kind, const R
R_API RList *r_anal_xrefs_get (RAnal *anal, ut64 to) {
RList *list = r_list_new ();
if (!list) return NULL;
if (!list) {
return NULL;
}
list->free = NULL; // XXX
r_anal_xrefs_from (anal, list, "xref", R_ANAL_REF_TYPE_NULL, to);
r_anal_xrefs_from (anal, list, "xref", R_ANAL_REF_TYPE_CODE, to);
@ -127,7 +156,7 @@ static int xrefs_list_cb_rad(RAnal *anal, const char *k, const char *v) {
if (!strncmp (k, "ref.", 4)) {
const char *p = r_str_rchr (k, NULL, '.');
if (p) {
dst = r_num_get (NULL, p+1);
dst = r_num_get (NULL, p + 1);
anal->cb_printf ("ax 0x%"PFMT64x" 0x%"PFMT64x"\n", src, dst);
}
}
@ -136,11 +165,11 @@ static int xrefs_list_cb_rad(RAnal *anal, const char *k, const char *v) {
static int xrefs_list_cb_json(RAnal *anal, const char *k, const char *v) {
ut64 dst, src = r_num_get (NULL, v);
if (!strncmp (k, "ref.", 4) && (strlen (k)>8)) {
if (!strncmp (k, "ref.", 4) && (strlen (k) > 8)) {
const char *p = r_str_rchr (k, NULL, '.');
if (p) {
dst = r_num_get (NULL, p+1);
sscanf (p+1, "0x%"PFMT64x, &dst);
dst = r_num_get (NULL, p + 1);
sscanf (p + 1, "0x%"PFMT64x, &dst);
anal->cb_printf ("%"PFMT64d":%"PFMT64d",", src, dst);
}
}

View File

@ -2,18 +2,21 @@
#include "r_util.h"
#include "r_core.h"
static int cc_print(void *p, const char *k, const char *v) {
if (!strcmp (v, "cc")) {
r_cons_println (k);
}
return 1;
}
static void find_refs(RCore *core, const char *glob) {
char cmd[128];
ut64 curseek = core->offset;
while (*glob == ' ') glob++;
if (!*glob)
if (!*glob) {
glob = "str.";
}
if (*glob == '?') {
eprintf ("Usage: arf [flag-str-filter]\n");
return;
@ -1499,7 +1502,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
}
r_list_foreach (fcn->refs, iter, ref) {
if (ref->addr == UT64_MAX || ref->addr < text_addr) {
eprintf ("Warning: ignore 0x%08"PFMT64x" call 0x%08"PFMT64x"\n", ref->at, ref->addr);
//eprintf ("Warning: ignore 0x%08"PFMT64x" call 0x%08"PFMT64x"\n", ref->at, ref->addr);
continue;
}
r_core_anal_fcn (core, ref->addr, fcn->addr, R_ANAL_REF_TYPE_CALL, depth);
@ -4118,7 +4121,7 @@ static void r_core_anal_info (RCore *core, const char *input) {
int covr = compute_coverage (core);
int call = compute_calls (core);
int xrfs = r_anal_xrefs_count (core->anal);
int cvpc = (code>0)? (covr * 100 / code): 0;
int cvpc = (code > 0)? (covr * 100 / code): 0;
if (*input == 'j') {
r_cons_printf ("{\"fcns\":%d", fcns);
r_cons_printf (",\"xrefs\":%d", xrfs);
@ -4144,6 +4147,17 @@ static void r_core_anal_info (RCore *core, const char *input) {
extern int cmd_search_value_in_range(RCore *core, ut64 from, ut64 to, ut64 vmin, ut64 vmax, int vsize);
static void cmd_anal_aad(RCore *core, const char *input) {
RListIter *iter;
RAnalRef *ref;
RList *list = r_list_newf (NULL);
r_anal_xrefs_from (core->anal, list, "xref", R_ANAL_REF_TYPE_DATA, UT64_MAX);
r_list_foreach (list, iter, ref) {
r_core_cmdf (core, "af @ 0x%"PFMT64x, ref->addr);
}
r_list_free (list);
}
static void cmd_anal_aav(RCore *core, const char *input) {
#define set(x,y) r_config_set(core->config, x, y);
#define seti(x,y) r_config_set_i(core->config, x, y);
@ -4213,6 +4227,7 @@ static int cmd_anal_all(RCore *core, const char *input) {
"aa*", "", "analyze all flags starting with sym. (af @@ sym.*)",
"aaa", "", "autoname functions after aa (see afna)",
"aac", " [len]", "analyze function calls (af @@ `pi len~call[1]`)",
"aad", " [len]", "analyze data references to code",
"aae", " [len] ([addr])", "analyze references with ESIL (optionally to address)",
"aai", "[j]", "show info of all analysis parameters",
"aar", " [len]", "analyze len bytes of instructions for references",
@ -4232,6 +4247,9 @@ static int cmd_anal_all(RCore *core, const char *input) {
r_core_cmd0 (core, "af @@ sym.*");
r_core_cmd0 (core, "af @ entry0");
break;
case 'd': // "aad"
cmd_anal_aad (core, input);
break;
case 'v': // "aav"
cmd_anal_aav (core, input);
break;
@ -4286,10 +4304,12 @@ static int cmd_anal_all(RCore *core, const char *input) {
goto jacuzzi;
rowlog (core, "Analyze function calls (aac)");
r_core_seek (core, curseek, 1);
(void)cmd_anal_calls (core, ""); // "aac"
rowlog_done(core);
if (core->cons->breaked)
(void) cmd_anal_calls (core, ""); // "aac"
(void) cmd_anal_aad (core, NULL);
rowlog_done (core);
if (core->cons->breaked) {
goto jacuzzi;
}
if (input[1] == 'a') { // "aaaa"
rowlog (core, "Emulate code to find computed references (aae)");
r_core_cmd0 (core, "aae $SS @ $S");

View File

@ -180,8 +180,8 @@ enum {
/*--------------------Function Convnetions-----------*/
//XXX dont use then in the future
#define R_ANAL_CC_TYPE_STDCALL 0
#define R_ANAL_CC_TYPE_PASCAL 1
#define R_ANAL_CC_TYPE_STDCALL 0
#define R_ANAL_CC_TYPE_PASCAL 1
#define R_ANAL_CC_TYPE_FASTCALL 'A' // syscall
#define R_ANAL_CC_TYPE_SYSV 8
@ -398,7 +398,7 @@ typedef enum {
R_ANAL_OP_TYPE_NOT = 30,
R_ANAL_OP_TYPE_STORE = 31, /* store from register to memory */
R_ANAL_OP_TYPE_LOAD = 32, /* load from memory to register */
R_ANAL_OP_TYPE_LEA = 33,
R_ANAL_OP_TYPE_LEA = 33, /* TODO add ulea */
R_ANAL_OP_TYPE_LEAVE = 34,
R_ANAL_OP_TYPE_ROR = 35,
R_ANAL_OP_TYPE_ROL = 36,