* Huge refactoring of r_anal code and API

This commit is contained in:
Nibble 2011-02-11 11:22:43 +01:00
parent dc34c9f41a
commit f3f094117a
12 changed files with 269 additions and 390 deletions

View File

@ -30,7 +30,6 @@ R_API RAnal *r_anal_new() {
r_io_bind_init (anal->iob);
anal->reg = NULL;
anal->lineswidth = 0;
anal->bbs = r_anal_bb_list_new ();
anal->fcns = r_anal_fcn_list_new ();
anal->refs = r_anal_ref_list_new ();
anal->vartypes = r_anal_var_type_list_new ();
@ -51,8 +50,6 @@ R_API RAnal *r_anal_new() {
R_API RAnal *r_anal_free(RAnal *anal) {
if (anal) {
/* TODO: Free a->anals here */
if (anal->bbs)
r_list_free (anal->bbs);
if (anal->fcns)
r_list_free (anal->fcns);
if (anal->vartypes)
@ -147,8 +144,29 @@ R_API char *r_anal_strmask (RAnal *anal, const char *data) {
return ret;
}
R_API RList *r_anal_get_fcns (RAnal *anal) {
if (anal)
return anal->fcns;
R_API RList *r_anal_get_fcns(RAnal *anal) {
return anal->fcns;
}
R_API RAnalFcn *r_anal_get_fcn_at(RAnal *anal, ut64 addr) {
RAnalFcn *fcni;
RListIter *iter;
r_list_foreach (anal->fcns, iter, fcni)
if (fcni->addr == addr)
return fcni;
return NULL;
}
R_API void r_anal_trace_bb(RAnal *anal, ut64 addr) {
RAnalBlock *bbi;
RAnalFcn *fcni;
RListIter *iter, *iter2;
VERBOSE_ANAL eprintf("bbtraced\n"); // XXX Debug msg
r_list_foreach (anal->fcns, iter, fcni)
r_list_foreach (fcni->bbs, iter2, bbi) {
if (addr>=bbi->addr && addr<(bbi->addr+bbi->size)) {
bbi->traced = R_TRUE;
break;
}
}
}

View File

@ -14,6 +14,8 @@ R_API RAnalOp *r_anal_aop_new() {
aop->addr = -1;
aop->jump = -1;
aop->fail = -1;
aop->ref = -1;
aop->value = -1;
}
return aop;
}

View File

@ -6,8 +6,6 @@
#include <r_util.h>
#include <r_list.h>
#define VERBOSE if(0)
R_API RAnalBlock *r_anal_bb_new() {
RAnalBlock *bb = R_NEW (RAnalBlock);
if (bb) {
@ -24,18 +22,6 @@ R_API RAnalBlock *r_anal_bb_new() {
return bb;
}
R_API void r_anal_bb_trace(RAnal *anal, ut64 addr) {
RAnalBlock *bbi;
RListIter *iter;
VERBOSE eprintf("bbtraced\n"); // XXX Debug msg
r_list_foreach (anal->bbs, iter, bbi) {
if (addr>=bbi->addr && addr<(bbi->addr+bbi->size)) {
bbi->traced = R_TRUE;
break;
}
}
}
R_API RList *r_anal_bb_list_new() {
RList *list = r_list_new ();
list->free = &r_anal_bb_free;
@ -71,7 +57,7 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
if ((oplen = r_anal_aop (anal, aop, addr+idx, buf+idx, len-idx)) == 0) {
r_anal_aop_free (aop);
if (idx == 0) {
VERBOSE eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx);
VERBOSE_ANAL eprintf ("Unknown opcode at 0x%08"PFMT64x"\n", addr+idx);
return R_ANAL_RET_END;
} else break;
}
@ -81,10 +67,6 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
r_list_append (bb->aops, aop);
if (head) bb->type = R_ANAL_BB_TYPE_HEAD;
switch (aop->type) {
case R_ANAL_OP_TYPE_CALL:
case R_ANAL_OP_TYPE_UCALL:
bb->ncalls++;
break;
case R_ANAL_OP_TYPE_CMP:
bb->cond = r_anal_cond_new_from_aop (aop);
break;
@ -92,8 +74,8 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
if (bb->cond) {
// TODO: get values from anal backend
bb->cond->type = R_ANAL_COND_EQ;
} else VERBOSE
eprintf ("Unknown conditional for block 0x%"PFMT64x"\n", bb->addr);
} else
VERBOSE_ANAL eprintf ("Unknown conditional for block 0x%"PFMT64x"\n", bb->addr);
bb->conditional = 1;
bb->fail = aop->fail;
bb->jump = aop->jump;
@ -108,132 +90,8 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
return R_ANAL_RET_END;
case R_ANAL_OP_TYPE_RET:
bb->type |= R_ANAL_BB_TYPE_LAST;
bb->ncalls++;
return R_ANAL_RET_END;
}
}
return bb->size;
}
R_API int r_anal_bb_split(RAnal *anal, RAnalBlock *bb, RList *bbs, ut64 addr) {
RAnalBlock *bbi;
RAnalOp *aopi;
RListIter *iter;
r_list_foreach (bbs, iter, bbi)
if (addr == bbi->addr)
return R_ANAL_RET_DUP;
else if (addr > bbi->addr && addr < bbi->addr + bbi->size) {
r_list_append (bbs, bb);
bb->addr = addr;
bb->size = bbi->addr + bbi->size - addr;
bb->jump = bbi->jump;
bb->fail = bbi->fail;
bbi->size = addr - bbi->addr;
bbi->jump = addr;
bbi->fail = -1;
if (bbi->type&R_ANAL_BB_TYPE_HEAD) {
bb->type = bbi->type^R_ANAL_BB_TYPE_HEAD;
bbi->type = R_ANAL_BB_TYPE_HEAD;
} else {
bb->type = bbi->type;
bbi->type = R_ANAL_BB_TYPE_BODY;
}
iter = r_list_iterator (bbi->aops);
while (r_list_iter_next (iter)) {
aopi = r_list_iter_get (iter);
if (aopi->addr >= addr) {
r_list_split (bbi->aops, aopi);
bbi->ninstr--;
r_list_append (bb->aops, aopi);
bb->ninstr++;
}
}
return R_ANAL_RET_END;
}
return R_ANAL_RET_NEW;
}
R_API int r_anal_bb_overlap(RAnal *anal, RAnalBlock *bb, RList *bbs) {
RAnalBlock *bbi;
RAnalOp *aopi;
RListIter *iter;
r_list_foreach (bbs, iter, bbi)
if (bb->addr+bb->size > bbi->addr && bb->addr+bb->size <= bbi->addr+bbi->size) {
bb->size = bbi->addr - bb->addr;
bb->jump = bbi->addr;
bb->fail = -1;
if (bbi->type&R_ANAL_BB_TYPE_HEAD) {
bb->type = R_ANAL_BB_TYPE_HEAD;
bbi->type = bbi->type^R_ANAL_BB_TYPE_HEAD;
} else bb->type = R_ANAL_BB_TYPE_BODY;
r_list_foreach (bb->aops, iter, aopi)
if (aopi->addr >= bbi->addr)
r_list_unlink (bb->aops, aopi);
r_list_append (bbs, bb);
return R_ANAL_RET_END;
}
return R_ANAL_RET_NEW;
}
R_API int r_anal_bb_add(RAnal *anal, ut64 addr, ut64 size, ut64 jump, ut64 fail, int type, RAnalDiff *diff) {
RAnalBlock *bb = NULL, *bbi;
RListIter *iter;
int append = 0, mid = 0;
r_list_foreach (anal->bbs, iter, bbi) {
if (addr == bbi->addr) {
bb = bbi;
mid = 0;
break;
} else if (addr > bbi->addr && addr < bbi->addr+bbi->size)
mid = 1;
}
if (mid)
return R_FALSE;
if (bb == NULL) {
if (!(bb = r_anal_bb_new ()))
return R_FALSE;
append = 1;
}
bb->addr = addr;
bb->size = size;
bb->jump = jump;
bb->fail = fail;
bb->type = type;
if (diff) {
bb->diff->type = diff->type;
bb->diff->addr = diff->addr;
R_FREE (bb->diff->name);
if (diff->name)
bb->diff->name = strdup (diff->name);
}
if (append) r_list_append (anal->bbs, bb);
return R_TRUE;
}
R_API int r_anal_bb_del(RAnal *anal, ut64 addr) {
RAnalBlock *bbi;
RListIter *iter;
ut64 jump, fail;
if (addr == 0) {
r_list_free (anal->bbs);
if (!(anal->bbs = r_anal_bb_list_new ()))
return R_FALSE;
} else {
r_list_foreach (anal->bbs, iter, bbi) {
if (addr >= bbi->addr && addr < bbi->addr+bbi->size) {
jump = bbi->jump;
fail = bbi->fail;
r_list_unlink (anal->bbs, bbi);
if (fail != -1)
r_anal_bb_del (anal, fail);
if (jump != -1)
r_anal_bb_del (anal, jump);
}
}
}
return R_TRUE;
}

View File

@ -167,17 +167,6 @@ R_API int r_anal_fcn_del(RAnal *anal, ut64 addr) {
return R_TRUE;
}
R_API RList *r_anal_fcn_bb_list(RAnal *anal, RAnalFcn *fcn) {
RAnalBlock *bbi;
RListIter *iter;
RList *list = r_list_new ();
r_list_foreach (anal->bbs, iter, bbi) {
if (bbi->addr>=fcn->addr && bbi->addr<(fcn->addr+fcn->size))
r_list_append (list, bbi);
}
return list;
}
R_API RAnalFcn *r_anal_fcn_find(RAnal *anal, ut64 addr, int type) {
RAnalFcn *fcn, *ret = NULL;
RListIter *iter;
@ -190,6 +179,121 @@ R_API RAnalFcn *r_anal_fcn_find(RAnal *anal, ut64 addr, int type) {
return ret;
}
R_API int r_anal_fcn_add_bb(RAnalFcn *fcn, ut64 addr, ut64 size, ut64 jump, ut64 fail, int type, RAnalDiff *diff) {
RAnalBlock *bb = NULL, *bbi;
RListIter *iter;
int append = 0, mid = 0;
r_list_foreach (fcn->bbs, iter, bbi) {
if (addr == bbi->addr) {
bb = bbi;
mid = 0;
break;
} else if (addr > bbi->addr && addr < bbi->addr+bbi->size)
mid = 1;
}
if (mid)
return R_FALSE;
if (bb == NULL) {
if (!(bb = r_anal_bb_new ()))
return R_FALSE;
append = 1;
}
bb->addr = addr;
bb->size = size;
bb->jump = jump;
bb->fail = fail;
bb->type = type;
if (diff) {
bb->diff->type = diff->type;
bb->diff->addr = diff->addr;
R_FREE (bb->diff->name);
if (diff->name)
bb->diff->name = strdup (diff->name);
}
if (append) r_list_append (fcn->bbs, bb);
return R_TRUE;
}
R_API int r_anal_fcn_split_bb(RAnalFcn *fcn, RAnalBlock *bb, ut64 addr) {
RAnalBlock *bbi;
RAnalOp *aopi;
RListIter *iter;
r_list_foreach (fcn->bbs, iter, bbi)
if (addr == bbi->addr)
return R_ANAL_RET_DUP;
else if (addr > bbi->addr && addr < bbi->addr + bbi->size) {
r_list_append (fcn->bbs, bb);
bb->addr = addr;
bb->size = bbi->addr + bbi->size - addr;
bb->jump = bbi->jump;
bb->fail = bbi->fail;
bb->conditional = bbi->conditional;
bbi->size = addr - bbi->addr;
bbi->jump = addr;
bbi->fail = -1;
bbi->conditional = R_FALSE;
if (bbi->type&R_ANAL_BB_TYPE_HEAD) {
bb->type = bbi->type^R_ANAL_BB_TYPE_HEAD;
bbi->type = R_ANAL_BB_TYPE_HEAD;
} else {
bb->type = bbi->type;
bbi->type = R_ANAL_BB_TYPE_BODY;
}
iter = r_list_iterator (bbi->aops);
while (r_list_iter_next (iter)) {
aopi = r_list_iter_get (iter);
if (aopi->addr >= addr) {
r_list_split (bbi->aops, aopi);
bbi->ninstr--;
r_list_append (bb->aops, aopi);
bb->ninstr++;
}
}
return R_ANAL_RET_END;
}
return R_ANAL_RET_NEW;
}
R_API int r_anal_fcn_overlap_bb(RAnalFcn *fcn, RAnalBlock *bb) {
RAnalBlock *bbi;
RAnalOp *aopi;
RListIter *iter;
r_list_foreach (fcn->bbs, iter, bbi)
if (bb->addr+bb->size > bbi->addr && bb->addr+bb->size <= bbi->addr+bbi->size) {
bb->size = bbi->addr - bb->addr;
bb->jump = bbi->addr;
bb->fail = -1;
bb->conditional = R_FALSE;
if (bbi->type&R_ANAL_BB_TYPE_HEAD) {
bb->type = R_ANAL_BB_TYPE_HEAD;
bbi->type = bbi->type^R_ANAL_BB_TYPE_HEAD;
} else bb->type = R_ANAL_BB_TYPE_BODY;
r_list_foreach (bb->aops, iter, aopi)
if (aopi->addr >= bbi->addr)
r_list_unlink (bb->aops, aopi);
r_list_append (fcn->bbs, bb);
return R_ANAL_RET_END;
}
return R_ANAL_RET_NEW;
}
R_API int r_anal_fcn_cc(RAnalFcn *fcn) {
struct r_anal_bb_t *bbi;
RListIter *iter;
int ret = 0, retbb;
r_list_foreach (fcn->bbs, iter, bbi) {
if ((bbi->type & R_ANAL_BB_TYPE_LAST))
retbb = 1;
else retbb = 0;
ret += bbi->conditional + retbb;
}
return ret;
}
R_API RAnalVar *r_anal_fcn_get_var(RAnalFcn *fs, int num, int type) {
RAnalVar *var;
RListIter *iter;

View File

@ -270,7 +270,8 @@ static void anal_mov(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
break;
case X86IM_IO_ID_MOV_RG_IM: /* mov reg, 0x1 */
case X86IM_IO_ID_MOV_AC_IM:
/* io.imm = 0x1 & io.rop[0] = reg */
aop->dst = anal_fill_ai_rg (anal, io, 0);
aop->src[0] = anal_fill_im (anal, io);
break;
case X86IM_IO_ID_MOV_CR0_RG: /* mov cr0, reg */
case X86IM_IO_ID_MOV_CR2_RG: /* mov cr2, reg */

View File

@ -110,49 +110,7 @@ static void r_core_anal_graph_nodes(RCore *core, RAnalFcn *fcn, RList *pbb, int
}
}
static int fcn_cc(RCore *core, RList *pbb, ut64 addr) {
struct r_anal_bb_t *bbi, *bbc;
RListIter *iter;
int ret = -1, jcalls = 0, fcalls = 0;
if (!pbb)
return -1;
/* Test if the bb has been analyzed before */
r_list_foreach (pbb, iter, bbi)
if (addr == bbi->addr)
return 0;
r_list_foreach (core->anal->bbs, iter, bbi)
if (addr == bbi->addr) {
/* Copy BB and append to the list of printed bbs */
bbc = R_NEW (RAnalBlock);
if (!bbc)
return -1;
memcpy (bbc, bbi, sizeof (RAnalBlock));
/* We don't want to free this refs when the temporary list is destroyed */
bbc->aops = NULL;
bbc->cond = NULL;
bbc->diff = NULL;
bbc->fingerprint = NULL;
r_list_append (pbb, bbc);
if (bbi->jump != -1) {
jcalls = fcn_cc (core, pbb, bbi->jump);
if (jcalls == -1)
return -1;
}
if (bbi->fail != -1) {
fcalls = fcn_cc (core, pbb, bbi->fail);
if (fcalls == -1)
return -1;
}
ret = bbi->conditional + bbi->ncalls + jcalls + fcalls;
break;
}
return ret;
}
R_API int r_core_anal_bb(RCore *core, RList *bbs, ut64 at, int depth, int head) {
R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int depth, int head) {
struct r_anal_bb_t *bb, *bbi;
RListIter *iter;
ut64 jump, fail;
@ -164,8 +122,8 @@ R_API int r_core_anal_bb(RCore *core, RList *bbs, ut64 at, int depth, int head)
return R_FALSE;
if (!(bb = r_anal_bb_new()))
return R_FALSE;
if (split) ret = r_anal_bb_split (core->anal, bb, bbs, at);
else r_list_foreach (bbs, iter, bbi)
if (split) ret = r_anal_fcn_split_bb (fcn, bb, at);
else r_list_foreach (fcn->bbs, iter, bbi)
if (at == bbi->addr)
ret = R_ANAL_RET_DUP;
if (ret == R_ANAL_RET_DUP) { /* Dupped bb */
@ -184,15 +142,15 @@ R_API int r_core_anal_bb(RCore *core, RList *bbs, ut64 at, int depth, int head)
return R_FALSE;
} else if (bblen == R_ANAL_RET_END) { /* bb analysis complete */
if (split)
ret = r_anal_bb_overlap (core->anal, bb, bbs);
ret = r_anal_fcn_overlap_bb (fcn, bb);
if (ret == R_ANAL_RET_NEW) {
r_list_append (bbs, bb);
r_list_append (fcn->bbs, bb);
fail = bb->fail;
jump = bb->jump;
if (fail != -1)
r_core_anal_bb (core, bbs, fail, depth-1, R_FALSE);
r_core_anal_bb (core, fcn, fail, depth-1, R_FALSE);
if (jump != -1)
r_core_anal_bb (core, bbs, jump, depth-1, R_FALSE);
r_core_anal_bb (core, fcn, jump, depth-1, R_FALSE);
}
}
} while (bblen != R_ANAL_RET_END);
@ -201,77 +159,14 @@ R_API int r_core_anal_bb(RCore *core, RList *bbs, ut64 at, int depth, int head)
return R_TRUE;
}
R_API int r_core_anal_bb_list(RCore *core, int rad) {
struct r_anal_bb_t *bbi;
RListIter *iter;
r_list_foreach (core->anal->bbs, iter, bbi) {
if (rad) {
r_cons_printf ("ab+ 0x%08"PFMT64x" %04"PFMT64d" ", bbi->addr, bbi->size);
r_cons_printf ("0x%08"PFMT64x" ", bbi->jump);
r_cons_printf ("0x%08"PFMT64x" ", bbi->fail);
if (bbi->type != R_ANAL_BB_TYPE_NULL) {
if ((bbi->type & R_ANAL_BB_TYPE_BODY))
r_cons_printf ("b");
if ((bbi->type & R_ANAL_BB_TYPE_FOOT))
r_cons_printf ("f");
if ((bbi->type & R_ANAL_BB_TYPE_HEAD))
r_cons_printf ("h");
if ((bbi->type & R_ANAL_BB_TYPE_LAST))
r_cons_printf ("l");
} else r_cons_printf ("n");
if ((bbi->diff->type == R_ANAL_DIFF_TYPE_MATCH))
r_cons_printf (" m");
else if ((bbi->diff->type == R_ANAL_DIFF_TYPE_UNMATCH))
r_cons_printf (" u");
else r_cons_printf (" n");
r_cons_printf ("\n");
} else {
r_cons_printf ("[0x%08"PFMT64x"] size=%04"PFMT64d, bbi->addr, bbi->size);
if (bbi->jump != -1)
r_cons_printf (" jump=0x%08"PFMT64x, bbi->jump);
if (bbi->fail != -1)
r_cons_printf (" fail=0x%08"PFMT64x, bbi->fail);
r_cons_printf (" type=");
if (bbi->type != R_ANAL_BB_TYPE_NULL) {
if ((bbi->type & R_ANAL_BB_TYPE_BODY))
r_cons_printf ("body,");
if ((bbi->type & R_ANAL_BB_TYPE_FOOT))
r_cons_printf ("foot,");
if ((bbi->type & R_ANAL_BB_TYPE_HEAD))
r_cons_printf ("head,");
if ((bbi->type & R_ANAL_BB_TYPE_LAST))
r_cons_printf ("last ");
} else r_cons_printf ("null ");
r_cons_printf ("diff=");
if ((bbi->diff->type == R_ANAL_DIFF_TYPE_MATCH))
r_cons_printf ("match");
else if ((bbi->diff->type == R_ANAL_DIFF_TYPE_UNMATCH))
r_cons_printf ("unmatch");
else r_cons_printf ("new");
r_cons_printf (" traced=%d", bbi->traced);
if (bbi->cond)
r_cons_printf (" cond=\"%s\" match=%d\n",
r_anal_cond_to_string (bbi->cond),
r_anal_cond_eval (core->anal, bbi->cond));
else r_cons_newline ();
}
}
r_cons_flush ();
return R_TRUE;
}
R_API int r_core_anal_bb_seek(RCore *core, ut64 addr) {
struct r_anal_bb_t *bbi;
RListIter *iter;
r_list_foreach (core->anal->bbs, iter, bbi)
if (addr >= bbi->addr && addr < bbi->addr+bbi->size)
return r_core_seek (core, bbi->addr, R_FALSE);
RAnalBlock *bbi;
RAnalFcn *fcni;
RListIter *iter, *iter2;
r_list_foreach (core->anal->fcns, iter, fcni)
r_list_foreach (fcni->bbs, iter2, bbi)
if (addr >= bbi->addr && addr < bbi->addr+bbi->size)
return r_core_seek (core, bbi->addr, R_FALSE);
return r_core_seek (core, addr, R_FALSE);
}
@ -338,7 +233,7 @@ 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 */
r_core_anal_bb (core, fcn->bbs, fcn->addr, depth, R_TRUE);
r_core_anal_bb (core, fcn, fcn->addr, depth, R_TRUE);
r_list_sort (fcn->bbs, &cmpaddr);
/* New function: Add initial xref */
if (from != -1) {
@ -402,6 +297,36 @@ R_API void r_core_anal_refs(RCore *core, ut64 addr, int gv) {
r_cons_printf ("}\n");
}
static void fcn_list_bbs(RAnalFcn *fcn) {
RAnalBlock *bbi;
RListIter *iter;
r_list_foreach (fcn->bbs, iter, bbi) {
r_cons_printf ("afb 0x%08"PFMT64x" 0x%08"PFMT64x" %04"PFMT64d" ",
fcn->addr, bbi->addr, bbi->size);
r_cons_printf ("0x%08"PFMT64x" ", bbi->jump);
r_cons_printf ("0x%08"PFMT64x" ", bbi->fail);
if (bbi->type != R_ANAL_BB_TYPE_NULL) {
if ((bbi->type & R_ANAL_BB_TYPE_BODY))
r_cons_printf ("b");
if ((bbi->type & R_ANAL_BB_TYPE_FOOT))
r_cons_printf ("f");
if ((bbi->type & R_ANAL_BB_TYPE_HEAD))
r_cons_printf ("h");
if ((bbi->type & R_ANAL_BB_TYPE_LAST))
r_cons_printf ("l");
} else r_cons_printf ("n");
if ((bbi->diff->type == R_ANAL_DIFF_TYPE_MATCH))
r_cons_printf (" m");
else if ((bbi->diff->type == R_ANAL_DIFF_TYPE_UNMATCH))
r_cons_printf (" u");
else r_cons_printf (" n");
r_cons_printf ("\n");
}
r_cons_flush ();
}
R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad) {
RAnalFcn *fcni;
struct r_anal_ref_t *refi;
@ -461,13 +386,16 @@ R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad) {
fcni->diff->name);
}
r_cons_newline ();
} else r_cons_printf ("af+ 0x%08"PFMT64x" %"PFMT64d" %s %c %c\n",
} else {
r_cons_printf ("af+ 0x%08"PFMT64x" %"PFMT64d" %s %c %c\n",
fcni->addr, fcni->size, fcni->name,
fcni->type==R_ANAL_FCN_TYPE_LOC?'l':
fcni->type==R_ANAL_FCN_TYPE_SYM?'s':
fcni->type==R_ANAL_FCN_TYPE_IMP?'i':'f',
fcni->diff->type==R_ANAL_DIFF_TYPE_MATCH?'m':
fcni->diff->type==R_ANAL_DIFF_TYPE_UNMATCH?'u':'n');
fcn_list_bbs (fcni);
}
}
r_cons_flush ();
return R_TRUE;
@ -606,18 +534,6 @@ R_API int r_core_anal_ref_list(RCore *core, int rad) {
return R_TRUE;
}
R_API int r_core_anal_fcn_cc(RCore *core, ut64 addr) {
RList *pbb;
int ret;
pbb = r_anal_bb_list_new ();
if (!pbb)
return -1;
ret = fcn_cc (core, pbb, addr);
r_list_free (pbb);
return ret;
}
R_API int r_core_anal_all(RCore *core) {
RList *list;
RListIter *iter;

View File

@ -2046,78 +2046,6 @@ static int cmd_anal(void *data, const char *input) {
}
}
break;
case 'b':
switch (input[1]) {
case '-':
r_anal_bb_del (core->anal, r_num_math (core->num, input+2));
break;
case '+':
{
char *ptr = strdup(input+3), *ptr2 = NULL;
ut64 addr = -1LL;
ut64 size = 0LL;
ut64 jump = -1LL;
ut64 fail = -1LL;
int type = R_ANAL_BB_TYPE_NULL;
RAnalDiff *diff = NULL;
switch(r_str_word_set0 (ptr)) {
case 6:
ptr2 = r_str_word_get0 (ptr, 5);
if (!(diff = r_anal_diff_new ())) {
eprintf ("error: Cannot init RAnalDiff\n");
free (ptr);
return R_FALSE;
}
if (ptr2[0] == 'm')
diff->type = R_ANAL_DIFF_TYPE_MATCH;
else if (ptr2[0] == 'u')
diff->type = R_ANAL_DIFF_TYPE_UNMATCH;
case 5:
ptr2 = r_str_word_get0 (ptr, 4);
if (strchr (ptr2, 'h'))
type |= R_ANAL_BB_TYPE_HEAD;
if (strchr (ptr2, 'b'))
type |= R_ANAL_BB_TYPE_BODY;
if (strchr (ptr2, 'l'))
type |= R_ANAL_BB_TYPE_LAST;
if (strchr (ptr2, 'f'))
type |= R_ANAL_BB_TYPE_FOOT;
case 4: // get fail
fail = r_num_math (core->num, r_str_word_get0 (ptr, 3));
case 3: // get jump
jump = r_num_math (core->num, r_str_word_get0 (ptr, 2));
case 2: // get size
size = r_num_math (core->num, r_str_word_get0 (ptr, 1));
case 1: // get addr
addr = r_num_math (core->num, r_str_word_get0 (ptr, 0));
}
if (!r_anal_bb_add (core->anal, addr, size, jump, fail, type, diff))
eprintf ("Cannot add bb (duplicated or overlaped)\n");
r_anal_diff_free (diff);
free (ptr);
}
break;
case 'l':
r_core_anal_bb_list (core, R_FALSE);
break;
case '*':
r_core_anal_bb_list (core, R_TRUE);
break;
case '?':
r_cons_printf (
"Usage: ab[?+-l*]\n"
" ab @ [addr] ; Analyze basic blocks (start at addr)\n"
" ab+ addr size [jump] [fail] [type] [diff] ; Add basic block\n"
" ab- [addr] ; Clean all basic block data (or bb at addr and childs)\n"
" abl ; List basic blocks\n"
" ab* ; Output radare commands\n");
break;
default:
r_core_anal_bb (core, core->anal->bbs, core->offset,
r_config_get_i (core->config, "anal.depth"), R_TRUE);
}
break;
case 'f':
switch (input[1]) {
case '-':
@ -2201,8 +2129,63 @@ static int cmd_anal(void *data, const char *input) {
break;
case 'c':
{
int cc = r_core_anal_fcn_cc (core, core->offset);
r_cons_printf ("Cyclomatic Complexity at 0x%08"PFMT64x" = %i\n", core->offset, cc);
RAnalFcn *fcn;
int cc;
if ((fcn = r_anal_get_fcn_at (core->anal, core->offset)) != NULL) {
cc = r_anal_fcn_cc (fcn);
r_cons_printf ("Cyclomatic Complexity at 0x%08"PFMT64x" = %i\n", core->offset, cc);
} else r_cons_printf ("Error: function not found\n");
}
break;
case 'b':
{
char *ptr = strdup(input+3), *ptr2 = NULL;
ut64 fcnaddr = -1LL, addr = -1LL;
ut64 size = 0LL;
ut64 jump = -1LL;
ut64 fail = -1LL;
int type = R_ANAL_BB_TYPE_NULL;
RAnalFcn *fcn = NULL;
RAnalDiff *diff = NULL;
switch(r_str_word_set0 (ptr)) {
case 7:
ptr2 = r_str_word_get0 (ptr, 6);
if (!(diff = r_anal_diff_new ())) {
eprintf ("error: Cannot init RAnalDiff\n");
free (ptr);
return R_FALSE;
}
if (ptr2[0] == 'm')
diff->type = R_ANAL_DIFF_TYPE_MATCH;
else if (ptr2[0] == 'u')
diff->type = R_ANAL_DIFF_TYPE_UNMATCH;
case 6:
ptr2 = r_str_word_get0 (ptr, 5);
if (strchr (ptr2, 'h'))
type |= R_ANAL_BB_TYPE_HEAD;
if (strchr (ptr2, 'b'))
type |= R_ANAL_BB_TYPE_BODY;
if (strchr (ptr2, 'l'))
type |= R_ANAL_BB_TYPE_LAST;
if (strchr (ptr2, 'f'))
type |= R_ANAL_BB_TYPE_FOOT;
case 5: // get fail
fail = r_num_math (core->num, r_str_word_get0 (ptr, 4));
case 4: // get jump
jump = r_num_math (core->num, r_str_word_get0 (ptr, 3));
case 3: // get size
size = r_num_math (core->num, r_str_word_get0 (ptr, 2));
case 2: // get addr
addr = r_num_math (core->num, r_str_word_get0 (ptr, 1));
case 1: // get fcnaddr
fcnaddr = r_num_math (core->num, r_str_word_get0 (ptr, 0));
}
if ((fcn = r_anal_get_fcn_at (core->anal, fcnaddr)) == NULL ||
!r_anal_fcn_add_bb (fcn, addr, size, jump, fail, type, diff))
eprintf ("Error: Cannot add bb\n");
r_anal_diff_free (diff);
free (ptr);
}
break;
case '?':
@ -2210,6 +2193,7 @@ static int cmd_anal(void *data, const char *input) {
"Usage: af[?+-l*]\n"
" af @ [addr] ; Analyze functions (start at addr)\n"
" af+ addr size name [type] [diff] ; Add function\n"
" afb fcnaddr addr size name [type] [diff] ; Add bb to function @ fcnaddr\n"
" af- [addr] ; Clean all function analysis data (or function at addr)\n"
" afl [fcn name] ; List functions\n"
" afs [addr] [fcnsign] ; Get/set function signature at current address\n"
@ -2296,7 +2280,7 @@ static int cmd_anal(void *data, const char *input) {
//trace_set_times(addr, atoi(ptr+1));
RDebugTracepoint *tp = r_debug_trace_add (core->dbg, addr, aop->length);
tp->count = atoi (ptr+1);
r_anal_bb_trace (core->anal, addr);
r_anal_trace_bb (core->anal, addr);
r_anal_aop_free (aop);
} else eprintf ("Cannot analyze opcode at 0x%"PFMT64x"\n", addr);
}

View File

@ -100,7 +100,7 @@ R_API RDebugTracepoint *r_debug_trace_add (RDebug *dbg, ut64 addr, int size) {
int tag = dbg->trace->tag;
if (!r_debug_trace_is_traceable (dbg, addr))
return NULL;
r_anal_bb_trace (dbg->anal, addr);
r_anal_trace_bb (dbg->anal, addr);
tp = r_debug_trace_get (dbg, addr);
if (!tp) {
tp = R_NEW (RDebugTracepoint);

View File

@ -11,6 +11,8 @@
#include <r_util.h>
#include <r_syscall.h>
#define VERBOSE_ANAL if(0)
enum {
R_ANAL_OP_FAMILY_UNKNOWN = 0,
R_ANAL_OP_FAMILY_CPU, /* normal cpu insturction */
@ -123,7 +125,6 @@ typedef struct r_anal_t {
int big_endian;
int split;
void *user;
RList *bbs;
RList *fcns;
RList *refs;
RList *vartypes;
@ -195,7 +196,7 @@ typedef struct r_anal_bb_t {
ut64 fail;
int type;
int ninstr;
int ncalls;
int returnbb;
int conditional;
int traced;
ut8 *fingerprint;
@ -326,29 +327,24 @@ R_API int r_anal_use(RAnal *anal, const char *name);
R_API int r_anal_set_bits(RAnal *anal, int bits);
R_API int r_anal_set_big_endian(RAnal *anal, int boolean);
R_API char *r_anal_strmask (RAnal *anal, const char *data);
R_API RList *r_anal_get_fcns (RAnal *anal);
R_API void r_anal_trace_bb(RAnal *anal, ut64 addr);
R_API RAnalFcn *r_anal_get_fcn_at(RAnal *anal, ut64 addr);
R_API RList *r_anal_get_fcns(RAnal *anal);
/* bb.c */
R_API RAnalBlock *r_anal_bb_new();
R_API RList *r_anal_bb_list_new();
R_API void r_anal_bb_free(void *bb);
R_API void r_anal_bb_trace(RAnal *anal, ut64 addr);
R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb,
ut64 addr, ut8 *buf, ut64 len, int head);
R_API int r_anal_bb_split(RAnal *anal, RAnalBlock *bb,
RList *bbs, ut64 addr);
R_API int r_anal_bb_overlap(RAnal *anal, RAnalBlock *bb, RList *bbs);
R_API int r_anal_bb_add(RAnal *anal, ut64 addr,
ut64 size, ut64 jump, ut64 fail, int type, RAnalDiff *diff);
R_API int r_anal_bb_del(RAnal *anal, ut64 addr);
/* aop.c */
R_API RAnalOp *r_anal_aop_new();
R_API char *r_anal_aop_to_string(RAnal *anal, RAnalOp *op);
R_API void r_anal_aop_free(void *aop);
R_API RList *r_anal_aop_list_new();
R_API int r_anal_aop(RAnal *anal, RAnalOp *aop, ut64 addr,
const ut8 *data, int len);
R_API char *r_anal_aop_to_string(RAnal *anal, RAnalOp *op);
/* fcn.c */
R_API RAnalFcn *r_anal_fcn_new();
@ -360,7 +356,11 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr,
R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size,
const char *name, int type, RAnalDiff *diff);
R_API int r_anal_fcn_del(RAnal *anal, ut64 addr);
R_API RList *r_anal_fcn_bb_list(RAnal *anal, RAnalFcn *fcn);
R_API int r_anal_fcn_add_bb(RAnalFcn *fcn, ut64 addr, ut64 size,
ut64 jump, ut64 fail, int type, RAnalDiff *diff);
R_API int r_anal_fcn_cc(RAnalFcn *fcn);
R_API int r_anal_fcn_split_bb(RAnalFcn *fcn, RAnalBlock *bb, ut64 addr);
R_API int r_anal_fcn_overlap_bb(RAnalFcn *fcn, RAnalBlock *bb);
R_API RAnalVar *r_anal_fcn_get_var(RAnalFcn *fs, int num, int dir);
R_API char *r_anal_fcn_to_string(RAnal *a, RAnalFcn* fs);
R_API int r_anal_fcn_from_string(RAnal *a, RAnalFcn *f, const char *_str);

View File

@ -158,12 +158,10 @@ R_API char *r_core_disassemble_bytes(RCore *core, ut64 addr, int b);
/* anal.c */
R_API int r_core_anal_search(RCore *core, ut64 from, ut64 to, ut64 ref);
R_API void r_core_anal_refs(RCore *core, ut64 addr, int gv);
R_API int r_core_anal_bb(RCore *core, RList *bbs, ut64 at, int depth, int head);
R_API int r_core_anal_bb_list(RCore *core, int rad);
R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int depth, int head);
R_API int r_core_anal_bb_seek(struct r_core_t *core, ut64 addr);
R_API int r_core_anal_fcn(struct r_core_t *core, ut64 at, ut64 from, int reftype, int depth);
R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad);
R_API int r_core_anal_fcn_cc(RCore *core, ut64 addr);
R_API int r_core_anal_graph(struct r_core_t *core, ut64 addr, int opts);
R_API int r_core_anal_graph_fcn(struct r_core_t *core, char *input, int opts);
R_API int r_core_anal_ref_list(struct r_core_t *core, int rad);

View File

@ -10,7 +10,6 @@ public class RAnal {
public int bits;
public bool big_endian;
public void *user;
public RList<RAnal.Block> bbs;
public RList<RAnal.Fcn> fcns;
public RList<RAnal.VarType> vartypes;
@ -18,7 +17,6 @@ public class RAnal {
public bool set_bits (int bits);
public bool set_big_endian (bool big);
//public bool set_pc (uint64 addr);
public RList<RAnal.Block> fcn_bb_list(Fcn fun);
public RList<RAnal.Fcn> get_fcns();
[Compact]
@ -217,6 +215,7 @@ public class RAnal {
public uint64 size;
public Diff diff;
public FcnType type;
public RList<RAnal.Block> bbs;
public RList<RAnal.Var> vars;
public RList<uint64> refs;
public RList<uint64> xrefs;

View File

@ -52,7 +52,6 @@ public class RCore {
public int anal_search (uint64 from, uint64 to, uint64 ref);
public void anal_refs(uint64 addr, int gv);
public int anal_bb(RList<RAnal.Block> bbs, uint64 at, int depth, int head);
public int anal_bb_list(bool rad);
public int anal_bb_seek(uint64 addr);
public int anal_fcn(uint64 at, uint64 from, int reftype, int depth);
public int anal_fcn_list(string input, bool rad);