* Show detailed info for diffing in afl output

* Create struct RAnalDiff and move diff related fields inside
* Move {RAnalFcn, RAnalBlock}.diff from int to RAnalDiff*
* Add r_anal_diff API
This commit is contained in:
Nibble 2010-12-05 08:46:56 +01:00
parent b3e34d3270
commit a0ae2c2286
9 changed files with 121 additions and 44 deletions

View File

@ -11,7 +11,7 @@ foo: pre libr_anal.${EXT_SO} libr_anal.${EXT_AR} plugins
include ${STATIC_ANAL_PLUGINS}
#STATIC_OBJS=$(subst ..,p/..,$(subst anal_,p/anal_,$(STATIC_OBJ)))
STATIC_OBJS=$(subst ../ar,p/../ar,$(subst anal_,p/anal_,$(STATIC_OBJ)))
OBJLIBS=ctx.o meta.o reflines.o ref.o aop.o fcn.o bb.o var.o anal.o cond.o value.o call.o
OBJLIBS=ctx.o meta.o reflines.o ref.o aop.o fcn.o bb.o var.o anal.o cond.o value.o call.o diff.o
OBJ=${STATIC_OBJS} ${OBJLIBS}
pre:

View File

@ -14,10 +14,10 @@ R_API RAnalBlock *r_anal_bb_new() {
bb->jump = -1;
bb->fail = -1;
bb->type = R_ANAL_BB_TYPE_NULL;
bb->diff = R_ANAL_DIFF_NULL;
bb->aops = r_anal_aop_list_new();
bb->cond = NULL;
bb->fingerprint = NULL;
bb->diff = r_anal_diff_new ();
}
return bb;
}
@ -49,6 +49,8 @@ R_API void r_anal_bb_free(void *_bb) {
r_list_free (bb->aops);
if (bb->fingerprint)
free (bb->fingerprint);
if (bb->diff)
r_anal_diff_free (bb->diff);
free (bb);
}
}
@ -172,7 +174,7 @@ R_API int r_anal_bb_overlap(RAnal *anal, RAnalBlock *bb, RList *bbs) {
return R_ANAL_RET_NEW;
}
R_API int r_anal_bb_add(RAnal *anal, ut64 addr, ut64 size, ut64 jump, ut64 fail, int type, int diff) {
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;
@ -197,7 +199,13 @@ R_API int r_anal_bb_add(RAnal *anal, ut64 addr, ut64 size, ut64 jump, ut64 fail,
bb->jump = jump;
bb->fail = fail;
bb->type = type;
bb->diff = diff;
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;
}

24
libr/anal/diff.c Normal file
View File

@ -0,0 +1,24 @@
/* radare - LGPL - Copyright 2010 - nibble<.ds@gmail.com> */
#include <r_anal.h>
#include <r_util.h>
R_API RAnalDiff *r_anal_diff_new() {
RAnalDiff *diff = R_NEW (RAnalDiff);
if (diff) {
diff->type = R_ANAL_DIFF_TYPE_NULL;
diff->addr = -1;
diff->name = NULL;
}
return diff;
}
R_API void* r_anal_diff_free(RAnalDiff *diff) {
if (diff) {
if (diff->name)
free (diff->name);
}
free (diff);
return NULL;
}

View File

@ -15,8 +15,8 @@ R_API RAnalFcn *r_anal_fcn_new() {
fcn->vars = r_anal_var_list_new ();
fcn->refs = r_anal_ref_list_new ();
fcn->xrefs = r_anal_ref_list_new ();
fcn->diff = R_ANAL_DIFF_NULL;
fcn->fingerprint = NULL;
fcn->diff = r_anal_diff_new ();
}
return fcn;
}
@ -40,6 +40,8 @@ R_API void r_anal_fcn_free(void *_fcn) {
r_list_free (fcn->vars);
if (fcn->fingerprint)
free (fcn->fingerprint);
if (fcn->diff)
r_anal_diff_free (fcn->diff);
}
free (fcn);
}
@ -117,7 +119,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
return fcn->size;
}
R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size, const char *name, int type, int diff) {
R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size, const char *name, int type, RAnalDiff *diff) {
RAnalFcn *fcn = NULL, *fcni;
RListIter *iter;
int append = 0;
@ -136,7 +138,13 @@ R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size, const char *name, in
free (fcn->name);
fcn->name = strdup (name);
fcn->type = type;
fcn->diff = diff;
if (diff) {
fcn->diff->type = diff->type;
fcn->diff->addr = diff->addr;
R_FREE (fcn->diff->name);
if (diff->name)
fcn->diff->name = strdup (diff->name);
}
if (append) r_list_append (anal->fcns, fcn);
return R_TRUE;
}

View File

@ -82,8 +82,9 @@ static void r_core_anal_graph_nodes(RCore *core, RList *pbb, ut64 addr, int opts
memcpy (bbc, bbi, sizeof (RAnalBlock));
/* We don't want to free this refs when the temporary list is destroyed */
bbc->aops = NULL;
bbc->fingerprint = NULL;
bbc->cond = NULL;
bbc->diff = NULL;
bbc->fingerprint = NULL;
r_list_append (pbb, bbc);
}
}
@ -103,8 +104,8 @@ static void r_core_anal_graph_nodes(RCore *core, RList *pbb, ut64 addr, int opts
if ((str = r_core_anal_graph_label (core, bbi, opts))) {
if (opts & R_CORE_ANAL_GRAPHDIFF) {
r_cons_printf (" \"0x%08"PFMT64x"\" [color=\"%s\", label=\"%s\"]\n", bbi->addr,
bbi->diff==R_ANAL_DIFF_MATCH?"green":
bbi->diff==R_ANAL_DIFF_UNMATCH?"red":"lightgray",str);
bbi->diff->type==R_ANAL_DIFF_TYPE_MATCH?"lightgray":
bbi->diff->type==R_ANAL_DIFF_TYPE_UNMATCH?"yellow":"red",str);
} else {
r_cons_printf (" \"0x%08"PFMT64x"\" [color=\"%s\", label=\"%s\"]\n", bbi->addr,
bbi->traced?"yellow":"lightgray",str);
@ -138,8 +139,9 @@ static int fcn_cc(RCore *core, RList *pbb, ut64 addr) {
memcpy (bbc, bbi, sizeof (RAnalBlock));
/* We don't want to free this refs when the temporary list is destroyed */
bbc->aops = NULL;
bbc->fingerprint = 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);
@ -226,9 +228,9 @@ R_API int r_core_anal_bb_list(RCore *core, int rad) {
r_cons_printf ("l");
} else r_cons_printf ("n");
if ((bbi->diff == R_ANAL_DIFF_MATCH))
if ((bbi->diff->type == R_ANAL_DIFF_TYPE_MATCH))
r_cons_printf (" m");
else if ((bbi->diff == R_ANAL_DIFF_UNMATCH))
else if ((bbi->diff->type == R_ANAL_DIFF_TYPE_UNMATCH))
r_cons_printf (" u");
else r_cons_printf (" n");
r_cons_printf ("\n");
@ -252,9 +254,9 @@ R_API int r_core_anal_bb_list(RCore *core, int rad) {
} else r_cons_printf ("null ");
r_cons_printf ("diff=");
if ((bbi->diff == R_ANAL_DIFF_MATCH))
if ((bbi->diff->type == R_ANAL_DIFF_TYPE_MATCH))
r_cons_printf ("match");
else if ((bbi->diff == R_ANAL_DIFF_UNMATCH))
else if ((bbi->diff->type == R_ANAL_DIFF_TYPE_UNMATCH))
r_cons_printf ("unmatch");
else r_cons_printf ("new");
@ -407,8 +409,9 @@ R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad) {
fcni->addr, fcni->size, fcni->name);
r_cons_printf (" type=%s",
fcni->type==R_ANAL_FCN_TYPE_LOC?"loc":"fcn");
r_cons_printf (" diff=%s",
fcni->diff=='m'?"match":fcni->diff=='u'?"unmatch":"new");
r_cons_printf (" [%s]",
fcni->diff->type==R_ANAL_DIFF_TYPE_MATCH?"MATCH":
fcni->diff->type==R_ANAL_DIFF_TYPE_UNMATCH?"UNMATCH":"NEW");
r_cons_printf ("\n CODE refs: ");
r_list_foreach (fcni->refs, iter2, refi)
@ -434,15 +437,23 @@ R_API int r_core_anal_fcn_list(RCore *core, const char *input, int rad) {
if (refi->type == R_ANAL_REF_TYPE_DATA)
r_cons_printf ("0x%08"PFMT64x" ", refi->addr);
r_cons_printf ("\n vars:\n");
r_cons_printf ("\n vars:");
r_list_foreach (fcni->vars, iter2, vari)
r_cons_printf (" %-10s delta=0x%02x type=%s\n", vari->name,
r_cons_printf ("\n %-10s delta=0x%02x type=%s", vari->name,
vari->delta, r_anal_var_type_to_str (core->anal, vari->type));
r_cons_printf ("\n diff: type=%s",
fcni->diff->type==R_ANAL_DIFF_TYPE_MATCH?"match":
fcni->diff->type==R_ANAL_DIFF_TYPE_UNMATCH?"unmatch":"new");
if (fcni->diff->addr != -1)
r_cons_printf (" addr=0x%"PFMT64x, fcni->diff->addr);
if (fcni->diff->name != NULL)
r_cons_printf (" function=%s",
fcni->diff->name);
r_cons_newline ();
} 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':'f',
fcni->diff==R_ANAL_DIFF_MATCH?'m':'n');
fcni->diff->type==R_ANAL_DIFF_TYPE_MATCH?'m':'n');
}
r_cons_flush ();
return R_TRUE;

View File

@ -1951,15 +1951,20 @@ static int cmd_anal(void *data, const char *input) {
ut64 jump = -1LL;
ut64 fail = -1LL;
int type = R_ANAL_BB_TYPE_NULL;
int diff = R_ANAL_DIFF_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 = R_ANAL_DIFF_MATCH;
diff->type = R_ANAL_DIFF_TYPE_MATCH;
else if (ptr2[0] == 'u')
diff = R_ANAL_DIFF_UNMATCH;
diff->type = R_ANAL_DIFF_TYPE_UNMATCH;
case 5:
ptr2 = r_str_word_get0 (ptr, 4);
if (strchr (ptr2, 'h'))
@ -1981,6 +1986,7 @@ static int cmd_anal(void *data, const char *input) {
}
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;
@ -2016,17 +2022,22 @@ static int cmd_anal(void *data, const char *input) {
const char *name = NULL;
ut64 addr = -1LL;
ut64 size = 0LL;
int diff = R_ANAL_DIFF_NULL;
RAnalDiff *diff = NULL;
int type = R_ANAL_FCN_TYPE_FCN;
if (n > 2) {
switch(n) {
case 5:
ptr2 = r_str_word_get0 (ptr, 4);
if (!(diff = r_anal_diff_new ())) {
eprintf ("error: Cannot init RAnalDiff\n");
free (ptr);
return R_FALSE;
}
if (ptr2[0] == 'm')
diff = R_ANAL_DIFF_MATCH;
diff->type = R_ANAL_DIFF_TYPE_MATCH;
else if (ptr2[0] == 'u')
diff = R_ANAL_DIFF_UNMATCH;
diff->type = R_ANAL_DIFF_TYPE_UNMATCH;
case 4:
ptr2 = r_str_word_get0 (ptr, 3);
if (strchr (ptr2, 'l'))
@ -2042,6 +2053,7 @@ static int cmd_anal(void *data, const char *input) {
if (!r_anal_fcn_add (core->anal, addr, size, name, type, diff))
eprintf ("Cannot add function (duplicated)\n");
}
r_anal_diff_free (diff);
free (ptr);
}
break;

View File

@ -145,7 +145,7 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
snprintf (str, R_FLAG_NAME_SIZE, "fcn.imp.%s", import->name);
if (import->size)
if (!r_anal_fcn_add (r->anal, va?baddr+import->rva:import->offset,
import->size, str, R_ANAL_FCN_TYPE_FCN, R_ANAL_DIFF_NULL))
import->size, str, R_ANAL_FCN_TYPE_FCN, NULL))
eprintf ("Cannot add function: %s (duplicated)\n", import->name);
r_flag_space_set (r->flags, "functions");
r_flag_set (r->flags, str, va?baddr+import->rva:import->offset,

View File

@ -43,7 +43,7 @@ static void gdiff_diff_bb(RAnalFcn *mfcn, RAnalFcn *mfcn2, RList *bbs, RList *bb
iter = r_list_iterator (bbs);
while (r_list_iter_next (iter)) {
bb = r_list_iter_get (iter);
if (bb->diff != R_ANAL_DIFF_NULL)
if (bb->diff->type != R_ANAL_DIFF_TYPE_NULL)
continue;
if (bb->addr >= mfcn->addr && bb->addr < mfcn->addr + mfcn->size) {
ot = 0;
@ -51,7 +51,7 @@ static void gdiff_diff_bb(RAnalFcn *mfcn, RAnalFcn *mfcn2, RList *bbs, RList *bb
iter2 = r_list_iterator (bbs2);
while (r_list_iter_next (iter2)) {
bb2 = r_list_iter_get (iter2);
if (bb2->diff == R_ANAL_DIFF_NULL &&
if (bb2->diff->type == R_ANAL_DIFF_TYPE_NULL &&
bb2->addr >= mfcn2->addr && bb2->addr < mfcn2->addr + mfcn2->size) {
r_diff_buffers_distance(NULL, bb->fingerprint, bb->size,
bb2->fingerprint, bb2->size, &d, &t);
@ -68,9 +68,10 @@ static void gdiff_diff_bb(RAnalFcn *mfcn, RAnalFcn *mfcn2, RList *bbs, RList *bb
}
if (mbb != NULL && mbb2 != NULL) {
if (ot == 1)
mbb->diff = mbb2->diff = R_ANAL_DIFF_MATCH;
mbb->diff->type = mbb2->diff->type = R_ANAL_DIFF_TYPE_MATCH;
else
mbb->diff = mbb2->diff = R_ANAL_DIFF_UNMATCH;
mbb->diff->type = mbb2->diff->type = R_ANAL_DIFF_TYPE_UNMATCH;
mbb->diff->addr = mbb2->addr;
R_FREE (mbb->fingerprint);
R_FREE (mbb2->fingerprint);
}
@ -94,7 +95,7 @@ static void gdiff_diff_fcn(RList *fcns, RList *fcns2, RList *bbs, RList *bbs2) {
iter2 = r_list_iterator (fcns2);
while (r_list_iter_next (iter2)) {
fcn2 = r_list_iter_get (iter2);
if (fcn2->type != R_ANAL_FCN_TYPE_FCN || fcn2->diff != R_ANAL_DIFF_NULL)
if (fcn2->type != R_ANAL_FCN_TYPE_FCN || fcn2->diff->type != R_ANAL_DIFF_TYPE_NULL)
continue;
r_diff_buffers_distance(NULL, fcn->fingerprint, fcn->size,
fcn2->fingerprint, fcn2->size, &d, &t);
@ -114,11 +115,14 @@ static void gdiff_diff_fcn(RList *fcns, RList *fcns2, RList *bbs, RList *bbs2) {
#endif
/* Set flag in matched functions */
if (ot == 1)
mfcn->diff = mfcn2->diff = R_ANAL_DIFF_MATCH;
mfcn->diff->type = mfcn2->diff->type = R_ANAL_DIFF_TYPE_MATCH;
else
mfcn->diff = mfcn2->diff = R_ANAL_DIFF_UNMATCH;
mfcn->diff->type = mfcn2->diff->type = R_ANAL_DIFF_TYPE_UNMATCH;
R_FREE (mfcn->fingerprint);
R_FREE (mfcn2->fingerprint);
mfcn->diff->addr = mfcn2->addr;
if (mfcn2->name)
mfcn->diff->name = strdup (mfcn2->name);
gdiff_diff_bb (mfcn, mfcn2, bbs, bbs2);
}
}

View File

@ -67,12 +67,6 @@ enum {
R_ANAL_COND_LT,
};
enum {
R_ANAL_DIFF_NULL = 0,
R_ANAL_DIFF_MATCH = 'm',
R_ANAL_DIFF_UNMATCH = 'u'
};
enum {
R_ANAL_VAR_TYPE_NULL = 0,
R_ANAL_VAR_TYPE_GLOBAL = 0x01,
@ -182,18 +176,30 @@ typedef struct r_anal_cond_t {
RAnalValue *arg[2]; // filled by CMP opcode
} RAnalCond;
enum {
R_ANAL_DIFF_TYPE_NULL = 0,
R_ANAL_DIFF_TYPE_MATCH = 'm',
R_ANAL_DIFF_TYPE_UNMATCH = 'u'
};
typedef struct r_anal_diff_t {
int type;
ut64 addr;
char *name;
} RAnalDiff;
typedef struct r_anal_bb_t {
ut64 addr;
ut64 size;
ut64 jump;
ut64 fail;
int type;
int diff;
int ninstr;
int ncalls;
int conditional;
int traced;
ut8 *fingerprint;
RAnalDiff *diff;
RList *aops;
RAnalCond *cond;
} RAnalBlock;
@ -224,10 +230,10 @@ typedef struct r_anal_fcn_t {
int type;
int fastcall; /* non-zero if following fastcall convention */
int stack;
int diff;
int ninstr;
int nargs;
ut8 *fingerprint;
RAnalDiff *diff;
RList *vars;
RList *refs;
RList *xrefs;
@ -311,7 +317,7 @@ 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, int diff);
ut64 size, ut64 jump, ut64 fail, int type, RAnalDiff *diff);
R_API int r_anal_bb_del(RAnal *anal, ut64 addr);
/* aop.c */
@ -330,7 +336,7 @@ R_API void r_anal_fcn_free(void *fcn);
R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr,
ut8 *buf, ut64 len, int reftype);
R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size,
const char *name, int type, int diff);
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 RAnalVar *r_anal_fcn_get_var(RAnalFcn *fs, int num, int dir);
@ -367,6 +373,10 @@ R_API int r_anal_var_access_add(RAnal *anal, RAnalVar *var, ut64 from, int set);
R_API int r_anal_var_access_del(RAnal *anal, RAnalVar *var, ut64 from);
R_API RAnalVarAccess *r_anal_var_access_get(RAnal *anal, RAnalVar *var, ut64 from);
/* diff.c */
R_API RAnalDiff *r_anal_diff_new();
R_API void* r_anal_diff_free(RAnalDiff *diff);
R_API RAnalValue *r_anal_value_new();
R_API RAnalValue *r_anal_value_new_from_string(const char *str);
R_API st64 r_anal_value_eval(RAnalValue *value);