diff --git a/libr/anal/Makefile b/libr/anal/Makefile index f77b7fb801..cacdf6435f 100644 --- a/libr/anal/Makefile +++ b/libr/anal/Makefile @@ -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: diff --git a/libr/anal/bb.c b/libr/anal/bb.c index 3e35180284..8b9ea03c66 100644 --- a/libr/anal/bb.c +++ b/libr/anal/bb.c @@ -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; } diff --git a/libr/anal/diff.c b/libr/anal/diff.c new file mode 100644 index 0000000000..66aaa021ef --- /dev/null +++ b/libr/anal/diff.c @@ -0,0 +1,24 @@ +/* radare - LGPL - Copyright 2010 - nibble<.ds@gmail.com> */ + +#include +#include + +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; +} diff --git a/libr/anal/fcn.c b/libr/anal/fcn.c index 17652a362c..695c3a7721 100644 --- a/libr/anal/fcn.c +++ b/libr/anal/fcn.c @@ -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; } diff --git a/libr/core/anal.c b/libr/core/anal.c index 7a73b63da6..de79ec29fa 100644 --- a/libr/core/anal.c +++ b/libr/core/anal.c @@ -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; diff --git a/libr/core/cmd.c b/libr/core/cmd.c index 8968ad879d..249de18af9 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -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; diff --git a/libr/core/file.c b/libr/core/file.c index 5a6b903b54..cc97e417a2 100644 --- a/libr/core/file.c +++ b/libr/core/file.c @@ -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, diff --git a/libr/core/gdiff.c b/libr/core/gdiff.c index e2befe991f..02a35d3415 100644 --- a/libr/core/gdiff.c +++ b/libr/core/gdiff.c @@ -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); } } diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 488e871154..9fb33d33ab 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -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);