Reverse walk all xrefs as a tmp fix the broken analysis (SLOW)

This commit is contained in:
pancake 2013-02-13 17:54:20 +01:00
parent 1daa05e125
commit 770f556e9d
4 changed files with 52 additions and 21 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2012 - nibble, pancake */
/* radare - LGPL - Copyright 2010-2013 - nibble, pancake */
#include <r_anal.h>
#include <r_util.h>
@ -60,8 +60,8 @@ R_API int r_anal_fcn_xref_add (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 ad
RAnalRef *ref;
if (!fcn || !anal || !(ref = r_anal_ref_new ()))
return R_FALSE;
ref->at = at;
ref->addr = addr;
ref->at = at; // from
ref->addr = addr; // to
ref->type = type;
// TODO: ensure we are not dupping xrefs
r_list_append (fcn->refs, ref);

View File

@ -64,27 +64,58 @@ R_API int r_anal_ref_del(RAnal *anal, ut64 at) {
R_API RList *r_anal_xref_get(RAnal *anal, ut64 addr) {
RAnalFunction *fcni;
RAnalRef *refi, *ref;
RListIter *iter, *iter2;
RAnalRef *refi, *ref, *refr;
RListIter *iter, *iter2, *iter3;
RList *ret;
if (!(ret = r_anal_ref_list_new ()))
return NULL;
// XXX: this is just a hack that makes analysis/disasm much slower but
// work as expected. We need to redesign the whole analysis engine :)
// - find real reverse xrefs by deep walk
// - addr = our target destination
r_list_foreach (anal->fcns, iter, fcni) {
if (addr >= fcni->addr && addr < fcni->addr+fcni->size)
r_list_foreach (fcni->xrefs, iter2, refi) {
if (refi->at == addr) {
r_list_foreach (fcni->refs, iter2, refi) {
if (refi->addr == addr) {
int gonext = 0;
r_list_foreach (ret, iter3, refr) {
if (refr->addr == refi->at) // same sauce, so we can skip
gonext = 1;
}
if (gonext) continue;
// wtf copying xrefs for new lists .. tahts insanely slow
if (!(ref = r_anal_ref_new ())) {
r_list_destroy (ret);
return NULL;
}
ref->addr = refi->addr;
ref->at = refi->at;
ref->type= refi->type;
// NOTE: swapped hacky valuez
ref->addr = refi->at;
ref->at = refi->addr;
ref->type = refi->type;
r_list_append (ret, ref);
}
}
}
if (r_list_length (ret)>0)
return ret;
r_list_foreach (anal->fcns, iter, fcni) {
if (addr >= fcni->addr && addr < fcni->addr+fcni->size) {
r_list_foreach (fcni->xrefs, iter2, refi) {
if (refi->at == addr) {
if (!(ref = r_anal_ref_new ())) {
r_list_destroy (ret);
return NULL;
}
ref->addr = refi->addr;
ref->at = refi->at;
ref->type= refi->type;
r_list_append (ret, ref);
}
}
break; // may break on corner cases
}
}
r_list_foreach (anal->refs, iter2, refi)
if (refi->addr == addr) {
if (!(ref = r_anal_ref_new ())) {

View File

@ -362,12 +362,12 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
r_flag_set (core->flags, fcn->name, at, fcn->size, 0);
}
/* TODO: Dupped analysis, needs more optimization */
fcn->depth = 256;
fcn->depth = 256;
r_core_anal_bb (core, fcn, fcn->addr, R_TRUE);
// hack
if (fcn->depth == 0) {
eprintf ("Analysis depth reached at 0x%08"PFMT64x"\n", fcn->addr);
} else fcn->depth = 256-fcn->depth;
if (fcn->depth == 0) {
eprintf ("Analysis depth reached at 0x%08"PFMT64x"\n", fcn->addr);
} else fcn->depth = 256-fcn->depth;
r_list_sort (fcn->bbs, &cmpaddr);
/* New function: Add initial xref */
@ -541,10 +541,9 @@ else
} else if (fmt==2) {
if (fr) {
if (!hideempty || (hideempty && r_list_length (fr->refs)>0)) {
if (usenames)
r_cons_printf ("%s\"%s\"", first2?",":"", fr->name);
else
r_cons_printf ("%s\"0x%08"PFMT64x"\"", first2?",":"", fr->addr);
if (usenames)
r_cons_printf ("%s\"%s\"", first2?",":"", fr->name);
else r_cons_printf ("%s\"0x%08"PFMT64x"\"", first2?",":"", fr->addr);
first2 = 1;
}
}
@ -794,9 +793,8 @@ static int r_core_anal_followptr(RCore *core, ut64 at, ut64 ptr, ut64 ref, int c
return R_FALSE;
endian = (core->bin->cur.o->info->big_endian)? !LIL_ENDIAN: LIL_ENDIAN;
wordsize = (int)(core->anal->bits/8);
if ((dataptr = r_io_read_i (core->io, ptr, wordsize, endian)) == -1) {
if ((dataptr = r_io_read_i (core->io, ptr, wordsize, endian)) == -1)
return R_FALSE;
}
return r_core_anal_followptr (core, at, dataptr, ref, code, depth-1);
}
@ -820,6 +818,7 @@ R_API int r_core_anal_search(RCore *core, ut64 from, ut64 to, ut64 ref) {
for (at = from; at < to; at += core->blocksize - OPSZ) {
if (r_cons_singleton ()->breaked)
break;
// TODO: this can be probably enhaced
ret = r_io_read_at (core->io, at, buf, core->blocksize);
if (ret != core->blocksize)
break;

View File

@ -742,6 +742,7 @@ 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 RList *r_anal_xref_get(RAnal *anal, ut64 addr);
R_API RList *r_anal_ref_get(RAnal *anal, ut64 addr);
/* var.c */
R_API RAnalVar *r_anal_var_new();