Bring back code|data xrefs to life. Use 'ar' command

'ax' and 'ar' are in conflict. must resolve
Uses sdb to store code and references
Ugly code that needs a huge cleanup
Update to latest sdb
This commit is contained in:
pancake 2013-07-19 03:35:45 +02:00
parent 19314bc27f
commit a597b0e414
13 changed files with 191 additions and 81 deletions

View File

@ -187,6 +187,12 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut8 *buf, ut64
free (varname);
break;
}
if (op.ptr && op.ptr != UT64_MAX) {
if (!r_anal_fcn_xref_add (anal, fcn, op.ptr, op.addr, 'd')) {
r_anal_op_fini (&op);
return R_ANAL_RET_ERROR;
}
}
switch (op.type) {
case R_ANAL_OP_TYPE_JMP:
if (!r_anal_fcn_xref_add (anal, fcn, op.addr, op.jump,

View File

@ -24,28 +24,56 @@ R_API void r_anal_ref_free(void *ref) {
free (ref);
}
#define USE_NEW_REFS 1
// TODO: use sdb or hashmap for fucks sake
R_API int r_anal_ref_add(RAnal *anal, ut64 addr, ut64 at, int type) {
#if USE_NEW_REFS
const char *types = type=='c'?"jmp":
type=='C'?"call": "data";
r_anal_xrefs_set (anal, types, at, addr);
#else
RAnalRef *ref = NULL, *refi;
RListIter *iter;
int append = 0;
r_list_foreach (anal->refs, iter, refi)
RListIter *iter, *iter2;
RAnalFunction *fcni;
// search in funrefs
r_list_foreach (anal->fcns, iter, fcni) {
r_list_foreach (fcni->refs, iter2, refi) {
if (at == refi->at) {
if (addr == refi->addr) {
return R_FALSE;
}
ref = refi;
break;
}
}
}
if (!ref)
r_list_foreach (anal->refs, iter, refi) {
if (at == refi->at) {
if (addr == refi->addr) {
return R_FALSE;
}
ref = refi;
break;
}
}
if (ref == NULL) {
if (!(ref = r_anal_ref_new ()))
return R_FALSE;
append = 1;
r_list_append (anal->refs, ref);
}
ref->addr = addr;
ref->at = at;
ref->type = type;
if (append) r_list_append (anal->refs, ref);
return R_TRUE;
#endif
}
R_API int r_anal_ref_del(RAnal *anal, ut64 at) {
R_API int r_anal_ref_del(RAnal *anal, ut64 at, ut64 addr) {
#if USE_NEW_REFS
r_anal_xrefs_deln (anal, "code", at, addr);
r_anal_xrefs_deln (anal, "data", at, addr);
#else
RAnalRef *refi;
RListIter *iter, *iter_tmp;
if (at == 0) {
@ -58,20 +86,21 @@ R_API int r_anal_ref_del(RAnal *anal, ut64 at) {
r_list_delete (anal->refs, iter);
}
}
#endif
return R_TRUE;
}
R_API RList *r_anal_xrefs_get (RAnal *anal, ut64 addr);
// XXX: MAJOR SLOWDOWN PLZ FIX
R_API RList *r_anal_xref_get(RAnal *anal, ut64 addr) {
return r_anal_xrefs_get (anal, addr);
}
#if 0
RAnalFunction *fcni;
RAnalRef *refi, *ref, *refr;
RListIter *iter, *iter2, *iter3;
RList *ret;
return r_anal_xrefs_get (anal, addr);
return NULL; // fuck yeah optimization!
#if 0
for (list = sdb_list_begin (DB); list; list = sdb_list_next (list)) {
char *str = astring();
@ -160,3 +189,4 @@ while (list) {
}
return ret;
}
#endif

View File

@ -39,28 +39,38 @@ R_API RList *r_anal_xrefs_deln (RAnal *anal, const char *type, ut64 from, ut64 t
}
R_API int r_anal_xrefs_from (RAnal *anal, RList *list, const char *kind, const char *type, ut64 addr) {
const char *str;
char key[256];
char *s, *str, *ptr, key[256];
RAnalRef *ref = NULL;
int hasnext = 1;
snprintf (key, sizeof (key), "%s.%s.%"PFMT64x, kind, type, addr);
str = sdb_getc (DB, key, 0);
//eprintf ("-->add %s %s\n", kind, type);
//r_list_append ();
return R_FALSE;
str = sdb_get (DB, key, 0);
if (!str) return R_FALSE;
for (ptr=str; hasnext; ptr = (char *)sdb_anext (s)) {
s = sdb_astring (ptr, &hasnext);
if (!(ref = r_anal_ref_new ()))
return R_FALSE;
ref->addr = addr;
ref->at = r_num_get (NULL, s);
ref->type = (!strcmp (type, "code"))?'C':'d'; // XXX
r_list_append (list, ref);
}
free (str);
return R_TRUE;
}
// (in,out)[code,data]
R_API RList *r_anal_xrefs_get (RAnal *anal, ut64 addr) {
RList *list = r_list_new ();
list->free = NULL; // XXX
r_anal_xrefs_from (anal, list, "xref", "code", addr);
r_anal_xrefs_from (anal, list, "xref", "data", addr);
// XXX: not all!
//r_anal_xrefs_from (anal, list, "xref", "code", addr);
//r_anal_xrefs_from (anal, list, "xref", "data", addr);
r_anal_xrefs_from (anal, list, "ref", "code", addr);
r_anal_xrefs_from (anal, list, "ref", "data", addr);
if (r_list_length (list)<1) {
r_list_free (list);
list = NULL;
}
return list;
}
@ -73,3 +83,18 @@ R_API void r_anal_xrefs_init (RAnal *anal) {
r_anal_xrefs_get (anal, "code", 0);
#endif
}
R_API void r_anal_xrefs_list(RAnal *anal) {
// TODO: make it better!
sdb_list (DB);
#if 0
char *k, *v;
sdb_dump_begin (DB);
while (sdb_dump_dupnext (DB, &k, &v)) {
printf ("%s=%s\n", k, v);
free (k);
free (v);
}
#endif
}

View File

@ -296,7 +296,9 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
ut8 *buf;
#define ANALBS 256
if (at>>63 == 1 || at == UT64_MAX || depth < 0)
if (from != UT64_MAX && at == 0)
return R_FALSE;
if ((at>>63) == 1 || at == UT64_MAX || depth < 0)
return R_FALSE;
#warning This must be optimized to use the fcnstore api
r_list_foreach (core->anal->fcns, iter, fcni) {
@ -304,7 +306,16 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
break;
if (at == fcni->addr) { /* Function already analyzed */
if (from != -1) {
r_list_foreach (fcni->xrefs, iter2, refi) /* If the xref is new, add it */
#define USE_NEW_REFS 1
#if USE_NEW_REFS
r_list_foreach (fcni->xrefs, iter2, refi) {
const char *types = "code";
if (refi->type == 'd') types = "data";
r_anal_xrefs_set (core->anal, types, refi->addr, refi->at);
}
#else
/* If the xref is new, add it */
r_list_foreach (fcni->xrefs, iter2, refi)
if (from == refi->addr)
return R_TRUE;
if (!(ref = r_anal_ref_new ())) {
@ -316,6 +327,7 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
ref->type = reftype;
if (reftype == 'd') // XXX HACK TO AVOID INVALID REFS
r_list_append (fcni->xrefs, ref);
#endif
}
return R_TRUE;
}
@ -881,28 +893,30 @@ R_API int r_core_anal_search(RCore *core, ut64 from, ut64 to, ut64 ref) {
}
R_API int r_core_anal_ref_list(RCore *core, int rad) {
r_anal_xrefs_list (core->anal);
return 0;
#if 0
RAnalFunction *fcni;
struct r_anal_ref_t *refi;
RListIter *iter, *iter2;
r_list_foreach (core->anal->fcns, iter, fcni)
r_list_foreach (fcni->refs, iter2, refi) {
if (rad)
r_cons_printf ("ar%s 0x%08"PFMT64x" 0x%08"PFMT64x"\n",
refi->type==R_ANAL_REF_TYPE_DATA?"d":"",
refi->at, refi->addr);
if (rad) r_cons_printf ("ar%s 0x%08"PFMT64x" 0x%08"PFMT64x"\n",
refi->type==R_ANAL_REF_TYPE_DATA?"d":"",
refi->addr, refi->at);
else r_cons_printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" (%c)\n",
refi->at, refi->addr, refi->type);
refi->addr, refi->at, refi->type);
}
r_list_foreach (core->anal->refs, iter2, refi) {
if (rad) r_cons_printf ("ar%s 0x%08"PFMT64x" 0x%08"PFMT64x"\n",
refi->type==R_ANAL_REF_TYPE_DATA?"d":"",
refi->at, refi->addr);
refi->type==R_ANAL_REF_TYPE_DATA?"d":"",
refi->addr, refi->at);
else r_cons_printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" (%c)\n",
refi->at, refi->addr, refi->type);
refi->addr, refi->at, refi->type);
}
r_cons_flush ();
return R_TRUE;
#endif
}
R_API int r_core_anal_all(RCore *core) {

View File

@ -372,6 +372,7 @@ static int cmd_anal(void *data, const char *input) {
break;
default:
case '?':
eprintf ("XXX: This command conflicts with 'ar'\n");
r_cons_printf (
"Usage: ax[-cCd?] [src] [dst]\n"
" axc sym.main+0x38 sym.printf ; add code ref\n"
@ -539,7 +540,7 @@ static int cmd_anal(void *data, const char *input) {
fcn = r_anal_fcn_find (core->anal, off,
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_LOC);
if (fcn) {
eprintf ("fr %s %s@ 0x%"PFMT64x"\n",
r_cons_printf ("fr %s %s@ 0x%"PFMT64x"\n",
fcn->name, name, off);
r_core_cmdf (core, "fr %s %s@ 0x%"PFMT64x,
fcn->name, name, off);
@ -798,31 +799,23 @@ static int cmd_anal(void *data, const char *input) {
}
break;
case 'r':
switch(input[1]) {
case '?':
r_cons_printf (
"Usage: ar[?d-l*]\n"
" ar addr [at] ; Add code ref\n"
" ard addr [at] ; Add data ref\n"
" ar- [at] ; Clean all refs (or refs from addr)\n"
" arl ; List refs\n"
" ar* ; Output radare commands\n");
break;
switch (input[1]) {
case '-':
r_anal_ref_del (core->anal, r_num_math (core->num, input+2));
r_anal_ref_del (core->anal, r_num_math (core->num, input+2), core->offset);
break;
case 'l':
case '\0':
r_core_anal_ref_list (core, R_FALSE);
break;
case '*':
r_core_anal_ref_list (core, R_TRUE);
break;
default:
case 'd':
case ' ':
{
char *ptr = strdup (r_str_trim_head ((char*)input+2));
int n = r_str_word_set0 (ptr);
ut64 at = core->offset;
ut64 addr = -1LL;
ut64 addr = UT64_MAX;
switch (n) {
case 2: // get at
at = r_num_math (core->num, r_str_word_get0 (ptr, 1));
@ -833,9 +826,22 @@ static int cmd_anal(void *data, const char *input) {
return R_FALSE;
}
r_anal_ref_add (core->anal, addr, at,
input[1]=='d'?R_ANAL_REF_TYPE_DATA:R_ANAL_REF_TYPE_CODE);
input[1]=='d'? R_ANAL_REF_TYPE_DATA:
R_ANAL_REF_TYPE_CODE);
free (ptr);
}
break;
default:
case '?':
eprintf ("XXX: This command conflicts with 'ax'\n");
r_cons_printf (
"Usage: ar[?d-l*]\n"
" ar addr [at] ; Add code ref pointing to addr (at is curseek)\n"
" ard addr [at] ; Add data ref\n"
" ar- [at] ; Clean all refs (or refs from addr)\n"
" ar ; List refs\n"
" ar* ; Output radare commands\n");
break;
}
break;
case 'a':

View File

@ -104,9 +104,7 @@ static int cmd_meta(void *data, const char *input) {
r_meta_del (core->anal->meta,
R_META_TYPE_COMMENT,
addr, 1, NULL);
} else {
eprintf ("Usage: CCa-[address]\n");
}
} else eprintf ("Usage: CCa-[address]\n");
free (s);
return R_TRUE;
}
@ -116,9 +114,7 @@ static int cmd_meta(void *data, const char *input) {
r_meta_add (core->anal->meta,
R_META_TYPE_COMMENT,
addr, addr+1, p);
} else {
eprintf ("Usage: CCa [address] [comment]\n");
}
} else eprintf ("Usage: CCa [address] [comment]\n");
free (s);
return R_TRUE;
}
@ -266,7 +262,7 @@ static int cmd_meta(void *data, const char *input) {
break;
case '\0':
case '?':
eprintf (
r_cons_strcat (
"Usage: C[-LCvsdfm?] [...]\n"
" C* # List meta info in r2 commands\n"
" C- [len] [@][ addr] # delete metadata at given address range\n"

View File

@ -333,29 +333,39 @@ toro:
RList *xrefs;
RAnalRef *refi;
RListIter *iter;
/* show reverse refs */
/* show xrefs */
if ((xrefs = r_anal_xref_get (core->anal, at))) {
r_list_foreach (xrefs, iter, refi) {
#if 0
r_list_foreach (core->anal->refs, iter, refi)
#endif
if (refi->addr == at) {
RAnalFunction *fun = r_anal_fcn_find (
core->anal, refi->addr,
R_ANAL_FCN_TYPE_NULL);
core->anal, refi->at,
R_ANAL_FCN_TYPE_FCN|
R_ANAL_FCN_TYPE_ROOT);
if (show_color) {
r_cons_printf ("%s%c "Color_RESET"%s%s"Color_RESET, color_fline,
((f&&f->type==R_ANAL_FCN_TYPE_FCN)&&f->addr==at)
?' ':'|',color_flow, refline);
} else {
r_cons_printf ("%c %s", ((f&&f->type==R_ANAL_FCN_TYPE_FCN)
&&f->addr==at)?' ':'|',refline);
&& f->addr==at)?' ':'|',refline);
}
if (show_color)
r_cons_printf ("%s; %s XREF 0x%08"PFMT64x" (%s)"Color_RESET"\n",
r_cons_printf ("%s; %s XREF from 0x%08"PFMT64x" (%s)"Color_RESET"\n",
pal_comment, refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
refi->type=='C'?"CODE (CALL)":"DATA", refi->at,
fun?fun->name:"unk");
else r_cons_printf ("; %s XREF 0x%08"PFMT64x" (%s)\n",
refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
else r_cons_printf ("; %s XREF from 0x%08"PFMT64x" (%s)\n",
refi->type=='c'?"CODE (JMP)":
refi->type=='C'?"CODE (CALL)":"DATA", refi->at,
fun?fun->name: "unk");
}
}
r_list_free (xrefs);
}
}
@ -443,6 +453,12 @@ toro:
oplen = (hint && hint->length)?
hint->length: r_asm_op_get_size (&asmop);
}
if (pseudo) {
r_parse_parse (core->parser, opstr?
opstr:asmop.buf_asm, str);
free (opstr);
opstr = strdup (str);
}
if (acase)
r_str_case (asmop.buf_asm, 1);
if (show_color && colorop)
@ -585,19 +601,19 @@ toro:
}
} else {
const char *fmt = show_color?
"%s/ "Color_RESET"%s%s: %s"Color_RESET" %d\n":
"/ %s: %s %d\n| ";
"%s/ "Color_RESET"%s(%s) %s"Color_RESET" %d\n":
"/ (%s) %s %d\n| ";
if (show_color) {
r_cons_printf (fmt, color_fline, color_fname,
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"function":
(f->type==R_ANAL_FCN_TYPE_IMP)?"import":"loc",
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"fcn":
(f->type==R_ANAL_FCN_TYPE_IMP)?"imp":"loc",
f->name, f->size);
r_cons_strcat (color_fline);
r_cons_strcat ("| "Color_RESET);
} else
r_cons_printf (fmt,
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"function":
(f->type==R_ANAL_FCN_TYPE_IMP)?"import":"loc",
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"fcn":
(f->type==R_ANAL_FCN_TYPE_IMP)?"imp":"loc",
f->name, f->size);
}
if (sign) r_cons_printf ("// %s\n", sign);
@ -739,6 +755,7 @@ toro:
strcpy (extra, " ");
flag = NULL; // HACK
if (!flag) {
str = strdup (asmop.buf_hex);
if (r_str_ansi_len (str) > nb) {
char *p = (char *)r_str_ansi_chrn (str, nb);
@ -845,6 +862,7 @@ toro:
case R_ANAL_OP_TYPE_NULL:
case R_ANAL_OP_TYPE_UNK:
r_cons_strcat (color_invalid);
break;
}
}
opstr = NULL;
@ -883,12 +901,6 @@ toro:
if (!opstr)
opstr = strdup (asmop.buf_asm);
}
if (pseudo) {
r_parse_parse (core->parser, opstr?
opstr:asmop.buf_asm, str);
free (opstr);
opstr = strdup (str);
}
if (varsub) {
RAnalFunction *f = r_anal_fcn_find (core->anal,
at, R_ANAL_FCN_TYPE_NULL);

View File

@ -1296,10 +1296,22 @@ R_API void r_core_visual_define (RCore *core) {
r_anal_fcn_del (core->anal, off);
break;
case 'f':
r_cons_break(NULL,NULL);
r_core_anal_fcn (core, off, -1, R_ANAL_REF_TYPE_NULL,
r_config_get_i (core->config, "anal.depth"));
r_cons_break_end();
{
int funsize = 0;
int depth = r_config_get_i (core->config, "anal.depth");
if (core->print->cur_enabled) {
funsize = 1+ R_ABS (core->print->cur - core->print->ocur);
depth = 0;
}
r_cons_break (NULL,NULL);
r_core_anal_fcn (core, off, UT64_MAX,
R_ANAL_REF_TYPE_NULL, depth);
r_cons_break_end ();
if (funsize) {
RAnalFunction *f = r_anal_fcn_find (core->anal, off, -1);
if (f) f->size = funsize;
}
}
break;
case 'q':
default:

View File

@ -542,7 +542,7 @@ typedef struct r_anal_value_t {
typedef struct r_anal_op_t {
char *mnemonic; /* mnemonic */
ut64 addr; /* address */
ut64 type; /* type of opcode */
ut64 type; /* type of opcode */
int stackop; /* operation on stack? */
int cond; /* condition type */
int length; /* length in bytes of opcode */
@ -769,7 +769,7 @@ R_API RAnalRef *r_anal_ref_new();
R_API RList *r_anal_ref_list_new();
R_API void r_anal_ref_free(void *ref);
R_API int r_anal_ref_add(RAnal *anal, ut64 addr, ut64 at, int type);
R_API int r_anal_ref_del(RAnal *anal, ut64 at);
R_API int r_anal_ref_del(RAnal *anal, ut64 at, ut64 addr);
R_API RList *r_anal_xref_get(RAnal *anal, ut64 addr);
R_API RList *r_anal_ref_get(RAnal *anal, ut64 addr);

View File

@ -36,7 +36,8 @@ sdb-sync sync-sdb:
cp -f sdb/src/*.h $I/sdb
echo '#include <sdb/sdb.h>' > $I/sdb.h
mkdir -p sdb/test sdb/memcache
sed -e 's,HAVE_VALA=,HAVE_VALA=#,' -i sdb/config.mk
sed -e 's,HAVE_VALA=,HAVE_VALA=#,' sdb/config.mk > .t
mv .t sdb/config.mk
echo all clean mrproper: | tee sdb/test/Makefile > sdb/memcache/Makefile
git add $I/sdb*
git add sdb

View File

@ -85,7 +85,6 @@ static int sdb_dump (const char *db) {
free (v);
}
sdb_free (s);
s = NULL;
return 0;
}

View File

@ -0,0 +1 @@
#define SDB_VERSION "0.6.4"

View File

@ -238,6 +238,14 @@ SDB_VISIBLE int sdb_set (Sdb* s, const char *key, const char *val, ut32 cas) {
return kv->cas;
}
SDB_VISIBLE void sdb_list (Sdb *s) {
SdbKv *kv;
SdbListIter *iter;
ls_foreach (s->ht->list, iter, kv) {
printf ("%s=%s\n", kv->key, kv->value);
}
}
SDB_VISIBLE int sdb_sync (Sdb* s) {
SdbKv *kv;
SdbListIter it, *iter;