Use zign limits on matching

This commit is contained in:
Roi Martin 2017-04-05 19:15:57 +00:00
parent b99eb501c5
commit af896c500c
3 changed files with 56 additions and 45 deletions

View File

@ -34,11 +34,12 @@ const char *getRealRef(RCore *core, ut64 off) {
R_API char **r_sign_fcn_refs(RAnal *a, RAnalFunction *fcn) {
RListIter *iter = NULL;
RAnalRef *refi = NULL;
RCore *core = a->coreb.core;
const char *flag = NULL;
char **refs = NULL;
int i = 0;
if (!a || !fcn || !a->coreb.core) {
if (!a || !fcn || !core) {
return NULL;
}
@ -49,7 +50,7 @@ R_API char **r_sign_fcn_refs(RAnal *a, RAnalFunction *fcn) {
break;
}
if (refi->type == R_ANAL_REF_TYPE_CODE || refi->type == R_ANAL_REF_TYPE_CALL) {
flag = getRealRef (a->coreb.core, refi->addr);
flag = getRealRef (core, refi->addr);
if (flag) {
refs[i] = r_str_newf (flag);
i++;
@ -819,16 +820,26 @@ static int searchHitCB(RSearchKeyword *kw, void *user, ut64 addr) {
return 1;
}
static int searchCB(RSignItem *it, void *user) {
RSignSearch *ss = (RSignSearch *) user;
struct ctxAddSearchKwCB {
RSignSearch *ss;
int minsz;
};
static int addSearchKwCB(RSignItem *it, void *user) {
struct ctxAddSearchKwCB *ctx = (struct ctxAddSearchKwCB *) user;
RSignSearch *ss = ctx->ss;
RSignBytes *bytes = it->bytes;
RSearchKeyword *kw = NULL;
RSignItem *it2 = NULL;
RSignBytes *bytes = it->bytes;
if (!bytes) {
return 1;
}
if (bytes->size < ctx->minsz) {
return 1;
}
it2 = r_sign_item_dup (it);
r_list_append(ss->items, it2);
@ -840,17 +851,24 @@ static int searchCB(RSignItem *it, void *user) {
}
R_API void r_sign_search_init(RAnal *a, RSignSearch *ss, RSignSearchCallback cb, void *user) {
RCore *core = a->coreb.core;
struct ctxAddSearchKwCB ctx = { ss, 0 };
if (!a || !ss || !cb) {
return;
}
if (core) {
ctx.minsz = r_config_get_i (core->config, "zign.minsz");
}
ss->cb = cb;
ss->user = user;
r_list_purge (ss->items);
r_search_reset (ss->search, R_SEARCH_KEYWORD);
r_sign_foreach (a, searchCB, ss);
r_sign_foreach (a, addSearchKwCB, &ctx);
r_search_begin (ss->search);
r_search_set_callback (ss->search, searchHitCB, ss);
}
@ -888,12 +906,18 @@ struct ctxFcnMatchCB {
RAnalFunction *fcn;
RSignGraphMatchCallback cb;
void *user;
int mincc;
};
static int graphMatchCB(RSignItem *it, void *user) {
struct ctxFcnMatchCB *ctx = (struct ctxFcnMatchCB *) user;
RSignGraph *graph = it->graph;
if (!it->graph) {
if (!graph) {
return 1;
}
if (graph->cc < ctx->mincc) {
return 1;
}
@ -909,12 +933,17 @@ static int graphMatchCB(RSignItem *it, void *user) {
}
R_API bool r_sign_match_graph(RAnal *a, RAnalFunction *fcn, RSignGraphMatchCallback cb, void *user) {
struct ctxFcnMatchCB ctx = { a, fcn, cb, user };
RCore *core = a->coreb.core;
struct ctxFcnMatchCB ctx = { a, fcn, cb, user, 0 };
if (!a || !fcn || !cb) {
return false;
}
if (core) {
ctx.mincc = r_config_get_i (core->config, "zign.mincc");
}
return r_sign_foreach (a, graphMatchCB, &ctx);
}
@ -937,7 +966,7 @@ static int offsetMatchCB(RSignItem *it, void *user) {
}
R_API bool r_sign_match_offset(RAnal *a, RAnalFunction *fcn, RSignOffsetMatchCallback cb, void *user) {
struct ctxFcnMatchCB ctx = { a, fcn, cb, user };
struct ctxFcnMatchCB ctx = { a, fcn, cb, user, 0 };
if (!a || !fcn || !cb) {
return false;
@ -985,7 +1014,7 @@ exit_function:
}
R_API bool r_sign_match_refs(RAnal *a, RAnalFunction *fcn, RSignRefsMatchCallback cb, void *user) {
struct ctxFcnMatchCB ctx = { a, fcn, cb, user };
struct ctxFcnMatchCB ctx = { a, fcn, cb, user, 0 };
if (!a || !fcn || !cb) {
return false;

View File

@ -1960,13 +1960,13 @@ R_API int r_core_config_init(RCore *core) {
// zign
SETPREF("zign.prefix", "sign", "Default prefix for zignatures matches");
SETI("zign.minsz", 16, "Minimum zignature length");
SETI("zign.maxsz", 500, "Maximum zignature length");
SETI("zign.mincc", 10, "Minimum cyclomatic complexity");
SETPREF("zign.match.graph", "true", "Use graph metrics for matching");
SETPREF("zign.match.bytes", "true", "Use bytes patterns for matching");
SETPREF("zign.match.offset", "true", "Use original offset for matching");
SETPREF("zign.match.refs", "true", "Use references for matching");
SETI("zign.minsz", 16, "Minimum zignature length for matching");
SETI("zign.mincc", 10, "Minimum cyclomatic complexity for matching");
SETPREF("zign.graph", "true", "Use graph metrics for matching");
SETPREF("zign.bytes", "true", "Use bytes patterns for matching");
SETPREF("zign.offset", "true", "Use original offset for matching");
SETPREF("zign.refs", "true", "Use references for matching");
/* diff */
SETCB("diff.sort", "addr", &cb_diff_sort, "Specify function diff sorting column see (e diff.sort=?)");

View File

@ -10,20 +10,11 @@
static bool addFcnBytes(RCore *core, RAnalFunction *fcn, const char *name) {
ut8 *buf = NULL;
int fcnlen = 0, len = 0;
int minzlen = r_config_get_i (core->config, "zign.minsz");
int maxzlen = r_config_get_i (core->config, "zign.maxsz");
bool retval = true;
int maxsz = r_config_get_i (core->config, "zign.maxsz");
fcnlen = r_anal_fcn_realsize (fcn);
if (fcnlen < minzlen) {
eprintf ("warn: omitting %s bytes zignature (length is %d, check zign.minsz)\n",
fcn->name, fcnlen);
retval = false;
goto exit_function;
}
len = R_MIN (fcnlen, maxzlen);
len = R_MIN (fcnlen, maxsz);
buf = malloc (len);
@ -43,17 +34,8 @@ exit_function:
static bool addFcnGraph(RCore *core, RAnalFunction *fcn, const char *name) {
RSignGraph graph;
int cc = -1;
int mincc = r_config_get_i (core->config, "zign.mincc");
cc = r_anal_fcn_cc (fcn);
if (cc < mincc) {
eprintf ("warn: omitting %s graph zignature (CC is %d, check zign.mincc)\n",
fcn->name, cc);
return false;
}
graph.cc = cc;
graph.cc = r_anal_fcn_cc (fcn);
graph.nbbs = r_list_length (fcn->bbs);
graph.edges = r_anal_fcn_count_edges (fcn, &graph.ebbs);
@ -685,10 +667,10 @@ static bool search(RCore *core, bool rad) {
const char *zign_prefix = r_config_get (core->config, "zign.prefix");
const char *mode = r_config_get (core->config, "search.in");
bool useBytes = r_config_get_i (core->config, "zign.match.bytes");
bool useGraph = r_config_get_i (core->config, "zign.match.graph");
bool useOffset = r_config_get_i (core->config, "zign.match.offset");
bool useRefs = r_config_get_i (core->config, "zign.match.refs");
bool useBytes = r_config_get_i (core->config, "zign.bytes");
bool useGraph = r_config_get_i (core->config, "zign.graph");
bool useOffset = r_config_get_i (core->config, "zign.offset");
bool useRefs = r_config_get_i (core->config, "zign.refs");
if (rad) {
r_cons_printf ("fs+%s\n", zign_prefix);
@ -792,10 +774,10 @@ static int cmdCheck(void *data, const char *input) {
struct ctxSearchCB refs_match_ctx = { core, rad, 0, "refs" };
const char *zign_prefix = r_config_get (core->config, "zign.prefix");
bool useBytes = r_config_get_i (core->config, "zign.match.bytes");
bool useGraph = r_config_get_i (core->config, "zign.match.graph");
bool useOffset = r_config_get_i (core->config, "zign.match.offset");
bool useRefs = r_config_get_i (core->config, "zign.match.refs");
bool useBytes = r_config_get_i (core->config, "zign.bytes");
bool useGraph = r_config_get_i (core->config, "zign.graph");
bool useOffset = r_config_get_i (core->config, "zign.offset");
bool useRefs = r_config_get_i (core->config, "zign.refs");
if (rad) {
r_cons_printf ("fs+%s\n", zign_prefix);