mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-31 18:43:28 +00:00
Implement basic zign matching
This commit is contained in:
parent
86c8fa1a01
commit
0427524f97
269
libr/anal/sign.c
269
libr/anal/sign.c
@ -4,9 +4,76 @@
|
||||
#include <r_sign.h>
|
||||
#include <r_search.h>
|
||||
#include <r_util.h>
|
||||
#include <r_core.h>
|
||||
|
||||
R_LIB_VERSION (r_sign);
|
||||
|
||||
const char *getRealRef(RCore *core, ut64 off) {
|
||||
RFlagItem *item = NULL;
|
||||
RListIter *iter = NULL;
|
||||
RList *list = NULL;
|
||||
|
||||
list = ht_find (core->flags->ht_off, sdb_fmt (2, "flg.%"PFMT64x, off), NULL);
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r_list_foreach (list, iter, item) {
|
||||
if (!item->name) {
|
||||
continue;
|
||||
}
|
||||
if (strncmp (item->name, "sym.", 4)) {
|
||||
continue;
|
||||
}
|
||||
return item->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API char **r_sign_fcn_refs(RAnal *a, RAnalFunction *fcn) {
|
||||
RListIter *iter = NULL;
|
||||
RAnalRef *refi = NULL;
|
||||
const char *flag = NULL;
|
||||
char **refs = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (!a || !fcn || !a->coreb.core) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
refs = malloc (R_SIGN_MAXREFS * sizeof (char*));
|
||||
|
||||
r_list_foreach (fcn->refs, iter, refi) {
|
||||
if (i >= R_SIGN_MAXREFS - 1) {
|
||||
break;
|
||||
}
|
||||
if (refi->type == R_ANAL_REF_TYPE_CODE || refi->type == R_ANAL_REF_TYPE_CALL) {
|
||||
flag = getRealRef (a->coreb.core, refi->addr);
|
||||
if (flag) {
|
||||
refs[i] = r_str_newf (flag);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
refs[i] = NULL;
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
R_API void r_sign_fcn_refs_free(char **refs) {
|
||||
int i;
|
||||
|
||||
if (!refs) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; refs[i] && i < R_SIGN_MAXREFS; i++) {
|
||||
free (refs[i]);
|
||||
}
|
||||
free (refs);
|
||||
}
|
||||
|
||||
static bool deserialize(RAnal *a, RSignItem *it, const char *k, const char *v) {
|
||||
char *k2 = NULL, *v2 = NULL, *refs = NULL;
|
||||
const char *token = NULL;
|
||||
@ -182,7 +249,7 @@ static void mergeItem(RSignItem *dst, RSignItem *src) {
|
||||
|
||||
static bool addItem(RAnal *a, RSignItem *it) {
|
||||
char key[R_SIGN_KEY_MAXSZ], val[R_SIGN_VAL_MAXSZ];
|
||||
const char *curval;
|
||||
const char *curval = NULL;
|
||||
bool retval = true;
|
||||
RSignItem *curit = r_sign_item_new ();
|
||||
|
||||
@ -206,15 +273,16 @@ exit_function:
|
||||
}
|
||||
|
||||
static bool addBytes(RAnal *a, const char *name, ut64 size, const ut8 *bytes, const ut8 *mask) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
RSignItem *it = NULL;
|
||||
bool retval = true;
|
||||
|
||||
if (r_mem_is_zero (mask, size)) {
|
||||
eprintf ("error: zero mask\n");
|
||||
retval = false;
|
||||
goto exit_function;
|
||||
return false;
|
||||
}
|
||||
|
||||
it = r_sign_item_new ();
|
||||
|
||||
it->name = r_str_new (name);
|
||||
it->space = a->zign_spaces.space_idx;
|
||||
it->bytes = R_NEW0 (RSignBytes);
|
||||
@ -226,13 +294,16 @@ static bool addBytes(RAnal *a, const char *name, ut64 size, const ut8 *bytes, co
|
||||
|
||||
retval = addItem (a, it);
|
||||
|
||||
exit_function:
|
||||
r_sign_item_free (it);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
R_API bool r_sign_add_bytes(RAnal *a, const char *name, ut64 size, const ut8 *bytes, const ut8 *mask) {
|
||||
if (!a || !name || size <= 0 || !bytes || !mask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return addBytes (a, name, size, bytes, mask);
|
||||
}
|
||||
|
||||
@ -240,7 +311,15 @@ R_API bool r_sign_add_anal(RAnal *a, const char *name, ut64 size, const ut8 *byt
|
||||
ut8 *mask = NULL;
|
||||
bool retval = true;
|
||||
|
||||
if (!a || !name || size <= 0 || !bytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mask = r_anal_mask (a, size, bytes, at);
|
||||
if (!mask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
retval = addBytes (a, name, size, bytes, mask);
|
||||
|
||||
free (mask);
|
||||
@ -248,9 +327,14 @@ R_API bool r_sign_add_anal(RAnal *a, const char *name, ut64 size, const ut8 *byt
|
||||
}
|
||||
|
||||
R_API bool r_sign_add_graph(RAnal *a, const char *name, RSignGraph graph) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
RSignItem *it = NULL;
|
||||
bool retval = true;
|
||||
|
||||
if (!a || !name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
it = r_sign_item_new ();
|
||||
it->name = r_str_new (name);
|
||||
it->space = a->zign_spaces.space_idx;
|
||||
it->graph = R_NEW0 (RSignGraph);
|
||||
@ -264,9 +348,15 @@ R_API bool r_sign_add_graph(RAnal *a, const char *name, RSignGraph graph) {
|
||||
}
|
||||
|
||||
R_API bool r_sign_add_offset(RAnal *a, const char *name, ut64 offset) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
RSignItem *it = NULL;
|
||||
bool retval = true;
|
||||
|
||||
if (!a || !name || offset == UT64_MAX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
it = r_sign_item_new ();
|
||||
|
||||
it->name = r_str_new (name);
|
||||
it->space = a->zign_spaces.space_idx;
|
||||
it->offset = offset;
|
||||
@ -278,15 +368,21 @@ R_API bool r_sign_add_offset(RAnal *a, const char *name, ut64 offset) {
|
||||
return retval;
|
||||
}
|
||||
|
||||
R_API bool r_sign_add_refs(RAnal *a, const char *name, const char *refs[]) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
int i;
|
||||
R_API bool r_sign_add_refs(RAnal *a, const char *name, char **refs) {
|
||||
RSignItem *it = NULL;
|
||||
int i = 0;
|
||||
bool retval = true;
|
||||
|
||||
if (!a || !name || !refs) {
|
||||
return false;
|
||||
}
|
||||
|
||||
it = r_sign_item_new ();
|
||||
|
||||
it->name = r_str_new (name);
|
||||
it->space = a->zign_spaces.space_idx;
|
||||
|
||||
for (i = 0; i < R_SIGN_MAXREFS - 1 && refs[i]; i++) {
|
||||
for (i = 0; refs[i] && i < R_SIGN_MAXREFS - 1; i++) {
|
||||
it->refs[i] = r_str_new (refs[i]);
|
||||
}
|
||||
it->refs[i] = NULL;
|
||||
@ -317,6 +413,10 @@ R_API bool r_sign_delete(RAnal *a, const char *name) {
|
||||
struct ctxDeleteCB ctx;
|
||||
char k[R_SIGN_KEY_MAXSZ];
|
||||
|
||||
if (!a || !name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove all zigns
|
||||
if (name[0] == '*') {
|
||||
if (a->zign_spaces.space_idx == -1) {
|
||||
@ -344,7 +444,7 @@ struct ctxListCB {
|
||||
static void listBytes(RAnal *a, RSignItem *it, int format) {
|
||||
RSignBytes *bytes = it->bytes;
|
||||
char *strbytes = NULL;
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < bytes->size; i++) {
|
||||
if (bytes->mask[i] & 0xf0) {
|
||||
@ -396,7 +496,7 @@ static void listOffset(RAnal *a, RSignItem *it, int format) {
|
||||
}
|
||||
|
||||
static void listRefs(RAnal *a, RSignItem *it, int format) {
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
if (format == '*') {
|
||||
a->cb_printf ("za %s r ", it->name);
|
||||
@ -515,6 +615,10 @@ exit_function:
|
||||
R_API void r_sign_list(RAnal *a, int format) {
|
||||
struct ctxListCB ctx = { a, 0, format };
|
||||
|
||||
if (!a) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (format == 'j') {
|
||||
a->cb_printf ("[");
|
||||
}
|
||||
@ -555,6 +659,10 @@ exit_function:
|
||||
R_API int r_sign_space_count_for(RAnal *a, int idx) {
|
||||
struct ctxCountForCB ctx = { a, idx, 0 };
|
||||
|
||||
if (!a) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sdb_foreach (a->sdb_zigns, countForCB, &ctx);
|
||||
|
||||
return ctx.count;
|
||||
@ -597,6 +705,10 @@ exit_function:
|
||||
R_API void r_sign_space_unset_for(RAnal *a, int idx) {
|
||||
struct ctxUnsetForCB ctx = { a, idx };
|
||||
|
||||
if (!a) {
|
||||
return;
|
||||
}
|
||||
|
||||
sdb_foreach (a->sdb_zigns, unsetForCB, &ctx);
|
||||
}
|
||||
|
||||
@ -609,7 +721,7 @@ struct ctxRenameForCB {
|
||||
static int renameForCB(void *user, const char *k, const char *v) {
|
||||
struct ctxRenameForCB *ctx = (struct ctxRenameForCB *) user;
|
||||
char nk[R_SIGN_KEY_MAXSZ], nv[R_SIGN_VAL_MAXSZ];
|
||||
const char *zigname;
|
||||
const char *zigname = NULL;
|
||||
Sdb *db = ctx->anal->sdb_zigns;
|
||||
|
||||
if (!strncmp (k, ctx->oprefix, strlen (ctx->oprefix))) {
|
||||
@ -626,6 +738,10 @@ static int renameForCB(void *user, const char *k, const char *v) {
|
||||
R_API void r_sign_space_rename_for(RAnal *a, int idx, const char *oname, const char *nname) {
|
||||
struct ctxRenameForCB ctx;
|
||||
|
||||
if (!a || !oname || !nname) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.anal = a;
|
||||
serializeKeySpaceStr (a, oname, "", ctx.oprefix);
|
||||
serializeKeySpaceStr (a, nname, "", ctx.nprefix);
|
||||
@ -667,6 +783,10 @@ exit_function:
|
||||
R_API bool r_sign_foreach(RAnal *a, RSignForeachCallback cb, void *user) {
|
||||
struct ctxForeachCB ctx = { a, cb, user };
|
||||
|
||||
if (!a || !cb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sdb_foreach (a->sdb_zigns, foreachCB, &ctx);
|
||||
}
|
||||
|
||||
@ -693,7 +813,7 @@ static int searchHitCB(RSearchKeyword *kw, void *user, ut64 addr) {
|
||||
RSignSearch *ss = (RSignSearch *) user;
|
||||
|
||||
if (ss->cb) {
|
||||
return ss->cb (kw, (RSignItem *) kw->data, addr, ss->user);
|
||||
return ss->cb ((RSignItem *) kw->data, kw, addr, ss->user);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -701,8 +821,8 @@ static int searchHitCB(RSearchKeyword *kw, void *user, ut64 addr) {
|
||||
|
||||
static int searchCB(RSignItem *it, void *user) {
|
||||
RSignSearch *ss = (RSignSearch *) user;
|
||||
RSearchKeyword *kw;
|
||||
RSignItem *it2;
|
||||
RSearchKeyword *kw = NULL;
|
||||
RSignItem *it2 = NULL;
|
||||
RSignBytes *bytes = it->bytes;
|
||||
|
||||
if (!bytes) {
|
||||
@ -720,6 +840,10 @@ static int searchCB(RSignItem *it, void *user) {
|
||||
}
|
||||
|
||||
R_API void r_sign_search_init(RAnal *a, RSignSearch *ss, RSignSearchCallback cb, void *user) {
|
||||
if (!a || !ss || !cb) {
|
||||
return;
|
||||
}
|
||||
|
||||
ss->cb = cb;
|
||||
ss->user = user;
|
||||
|
||||
@ -732,6 +856,10 @@ R_API void r_sign_search_init(RAnal *a, RSignSearch *ss, RSignSearchCallback cb,
|
||||
}
|
||||
|
||||
R_API int r_sign_search_update(RAnal *a, RSignSearch *ss, ut64 *at, const ut8 *buf, int len) {
|
||||
if (!a || !ss || !buf || len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return r_search_update (ss->search, at, buf, len);
|
||||
}
|
||||
|
||||
@ -755,7 +883,7 @@ static bool fcnMetricsCmp(RSignItem *it, RAnalFunction *fcn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct ctxMetricMatchCB {
|
||||
struct ctxFcnMatchCB {
|
||||
RAnal *anal;
|
||||
RAnalFunction *fcn;
|
||||
RSignGraphMatchCallback cb;
|
||||
@ -763,7 +891,7 @@ struct ctxMetricMatchCB {
|
||||
};
|
||||
|
||||
static int graphMatchCB(RSignItem *it, void *user) {
|
||||
struct ctxMetricMatchCB *ctx = (struct ctxMetricMatchCB *) user;
|
||||
struct ctxFcnMatchCB *ctx = (struct ctxFcnMatchCB *) user;
|
||||
|
||||
if (!it->graph) {
|
||||
return 1;
|
||||
@ -780,14 +908,90 @@ static int graphMatchCB(RSignItem *it, void *user) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API int r_sign_match_graph(RAnal *a, RAnalFunction *fcn, RSignGraphMatchCallback cb, void *user) {
|
||||
struct ctxMetricMatchCB ctx = { a, fcn, cb, user };
|
||||
R_API bool r_sign_match_graph(RAnal *a, RAnalFunction *fcn, RSignGraphMatchCallback cb, void *user) {
|
||||
struct ctxFcnMatchCB ctx = { a, fcn, cb, user };
|
||||
|
||||
r_sign_foreach (a, graphMatchCB, &ctx);
|
||||
if (!a || !fcn || !cb) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return r_sign_foreach (a, graphMatchCB, &ctx);
|
||||
}
|
||||
|
||||
static int offsetMatchCB(RSignItem *it, void *user) {
|
||||
struct ctxFcnMatchCB *ctx = (struct ctxFcnMatchCB *) user;
|
||||
|
||||
if (it->offset == UT64_MAX) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (it->offset != ctx->fcn->addr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ctx->cb) {
|
||||
return ctx->cb (it, ctx->fcn, ctx->user);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API bool r_sign_match_offset(RAnal *a, RAnalFunction *fcn, RSignOffsetMatchCallback cb, void *user) {
|
||||
struct ctxFcnMatchCB ctx = { a, fcn, cb, user };
|
||||
|
||||
if (!a || !fcn || !cb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return r_sign_foreach (a, offsetMatchCB, &ctx);
|
||||
}
|
||||
|
||||
static int refsMatchCB(RSignItem *it, void *user) {
|
||||
struct ctxFcnMatchCB *ctx = (struct ctxFcnMatchCB *) user;
|
||||
char **refs = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (!it->refs[0]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO(nibble): slow operation, add cache
|
||||
refs = r_sign_fcn_refs (ctx->anal, ctx->fcn);
|
||||
if (!refs) {
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; ; i++) {
|
||||
if (!refs[i] || !it->refs[i]) {
|
||||
if (refs[i] != it->refs[i]) {
|
||||
goto exit_function;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (strcmp (refs[i], it->refs[i])) {
|
||||
goto exit_function;
|
||||
}
|
||||
}
|
||||
if (ctx->cb) {
|
||||
return ctx->cb (it, ctx->fcn, ctx->user);
|
||||
}
|
||||
|
||||
exit_function:
|
||||
r_sign_fcn_refs_free (refs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API bool r_sign_match_refs(RAnal *a, RAnalFunction *fcn, RSignRefsMatchCallback cb, void *user) {
|
||||
struct ctxFcnMatchCB ctx = { a, fcn, cb, user };
|
||||
|
||||
if (!a || !fcn || !cb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return r_sign_foreach (a, refsMatchCB, &ctx);
|
||||
}
|
||||
|
||||
|
||||
R_API RSignItem *r_sign_item_new() {
|
||||
RSignItem *ret = R_NEW0 (RSignItem);
|
||||
|
||||
@ -798,9 +1002,14 @@ R_API RSignItem *r_sign_item_new() {
|
||||
}
|
||||
|
||||
R_API RSignItem *r_sign_item_dup(RSignItem *it) {
|
||||
RSignItem *ret = r_sign_item_new ();
|
||||
int i;
|
||||
RSignItem *ret = NULL;
|
||||
int i = 0;
|
||||
|
||||
if (!it) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = r_sign_item_new ();
|
||||
ret->name = r_str_new (it->name);
|
||||
ret->space = it->space;
|
||||
|
||||
@ -826,7 +1035,7 @@ R_API RSignItem *r_sign_item_dup(RSignItem *it) {
|
||||
}
|
||||
|
||||
R_API void r_sign_item_free(RSignItem *item) {
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
if (!item) {
|
||||
return;
|
||||
@ -871,6 +1080,10 @@ exit_function:
|
||||
}
|
||||
|
||||
R_API bool r_sign_load(RAnal *a, const char *file) {
|
||||
if (!a || !file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!r_file_exists (file)) {
|
||||
eprintf ("error: file %s does not exist\n", file);
|
||||
return false;
|
||||
@ -887,6 +1100,10 @@ R_API bool r_sign_load(RAnal *a, const char *file) {
|
||||
R_API bool r_sign_save(RAnal *a, const char *file) {
|
||||
bool retval = true;
|
||||
|
||||
if (!a || !file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Sdb *db = sdb_new (NULL, file, 0);
|
||||
sdb_merge (db, a->sdb_zigns);
|
||||
retval = sdb_sync (db);
|
||||
|
@ -1964,6 +1964,8 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETPREF("zign.prefix", "sign", "Default prefix for zignatures matches");
|
||||
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");
|
||||
|
||||
/* diff */
|
||||
SETCB("diff.sort", "addr", &cb_diff_sort, "Specify function diff sorting column see (e diff.sort=?)");
|
||||
|
@ -7,42 +7,6 @@
|
||||
#include <r_cons.h>
|
||||
#include <r_util.h>
|
||||
|
||||
const char *getRealRef(RCore *core, ut64 off) {
|
||||
RFlagItem *item;
|
||||
RListIter *iter;
|
||||
RList *list;
|
||||
|
||||
list = ht_find (core->flags->ht_off, sdb_fmt (2, "flg.%"PFMT64x, off), NULL);
|
||||
if (!list) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r_list_foreach (list, iter, item) {
|
||||
if (!item->name) {
|
||||
continue;
|
||||
}
|
||||
/* catch sym. first */
|
||||
if (!strncmp (item->name, "loc.", 4)) {
|
||||
continue;
|
||||
}
|
||||
if (!strncmp (item->name, "fcn.", 4)) {
|
||||
continue;
|
||||
}
|
||||
if (!strncmp (item->name, "section.", 8)) {
|
||||
continue;
|
||||
}
|
||||
if (!strncmp (item->name, "section_end.", 12)) {
|
||||
continue;
|
||||
}
|
||||
if (!strncmp (item->name, "sub.", 4)) {
|
||||
continue;
|
||||
}
|
||||
return item->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool addFcnBytes(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
ut8 *buf = NULL;
|
||||
int fcnlen = 0, len = 0;
|
||||
@ -88,32 +52,17 @@ static bool addFcnGraph(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
}
|
||||
|
||||
static bool addFcnRefs(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
RListIter *iter;
|
||||
RAnalRef *refi;
|
||||
const char *flag;
|
||||
char *refs[R_SIGN_MAXREFS];
|
||||
int i = 0, n = 0;
|
||||
char **refs;
|
||||
bool retval = true;
|
||||
|
||||
r_list_foreach (fcn->refs, iter, refi) {
|
||||
if (n >= R_SIGN_MAXREFS - 1) {
|
||||
break;
|
||||
}
|
||||
if (refi->type == R_ANAL_REF_TYPE_CODE || refi->type == R_ANAL_REF_TYPE_CALL) {
|
||||
flag = getRealRef (core, refi->addr);
|
||||
if (flag) {
|
||||
refs[n] = r_str_newf (flag);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
refs = r_sign_fcn_refs (core->anal, fcn);
|
||||
if (!refs) {
|
||||
return false;
|
||||
}
|
||||
refs[n] = NULL;
|
||||
|
||||
retval = r_sign_add_refs (core->anal, name, refs);
|
||||
|
||||
retval = r_sign_add_refs (core->anal, name, (const char **)refs);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
free (refs[i]);
|
||||
}
|
||||
r_sign_fcn_refs_free (refs);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -235,20 +184,27 @@ static bool addOffsetZign(RCore *core, const char *name, const char *args0, int
|
||||
}
|
||||
|
||||
static bool addRefsZign(RCore *core, const char *name, const char *args0, int nargs) {
|
||||
const char *refs[R_SIGN_MAXREFS];
|
||||
char *refs[R_SIGN_MAXREFS];
|
||||
int i;
|
||||
bool retval = true;
|
||||
|
||||
if (nargs < 1) {
|
||||
eprintf ("error: invalid syntax\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < R_SIGN_MAXREFS - 1 && i < nargs; i++) {
|
||||
refs[i] = r_str_word_get0 (args0, i);
|
||||
for (i = 0; i < nargs && i < R_SIGN_MAXREFS - 1; i++) {
|
||||
refs[i] = r_str_new (r_str_word_get0 (args0, i));
|
||||
}
|
||||
refs[i] = NULL;
|
||||
|
||||
return r_sign_add_refs (core->anal, name, refs);
|
||||
retval = r_sign_add_refs (core->anal, name, refs);
|
||||
|
||||
for (i = 0; refs[i] && i < R_SIGN_MAXREFS - 1; i++) {
|
||||
free (refs[i]);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static bool addZign(RCore *core, const char *name, int type, const char *args0, int nargs) {
|
||||
@ -632,6 +588,7 @@ struct ctxSearchCB {
|
||||
RCore *core;
|
||||
bool rad;
|
||||
int count;
|
||||
const char *prefix;
|
||||
};
|
||||
|
||||
static void addFlag(RCore *core, RSignItem *it, ut64 addr, int size, int count, const char* prefix, bool rad) {
|
||||
@ -649,20 +606,20 @@ static void addFlag(RCore *core, RSignItem *it, ut64 addr, int size, int count,
|
||||
free(name);
|
||||
}
|
||||
|
||||
static int graphMatchCB(RSignItem *it, RAnalFunction *fcn, void *user) {
|
||||
static int searchHitCB(RSignItem *it, RSearchKeyword *kw, ut64 addr, void *user) {
|
||||
struct ctxSearchCB *ctx = (struct ctxSearchCB *) user;
|
||||
|
||||
// TODO(nibble): use one counter per metric zign instead of ctx->count
|
||||
addFlag (ctx->core, it, fcn->addr, r_anal_fcn_realsize (fcn), ctx->count, "graph", ctx->rad);
|
||||
addFlag (ctx->core, it, addr, kw->keyword_length, kw->count, ctx->prefix, ctx->rad);
|
||||
ctx->count++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int searchHitCB(RSearchKeyword *kw, RSignItem *it, ut64 addr, void *user) {
|
||||
static int fcnMatchCB(RSignItem *it, RAnalFunction *fcn, void *user) {
|
||||
struct ctxSearchCB *ctx = (struct ctxSearchCB *) user;
|
||||
|
||||
addFlag (ctx->core, it, addr, kw->keyword_length, kw->count, "bytes", ctx->rad);
|
||||
// TODO(nibble): use one counter per metric zign instead of ctx->count
|
||||
addFlag (ctx->core, it, fcn->addr, r_anal_fcn_realsize (fcn), ctx->count, ctx->prefix, ctx->rad);
|
||||
ctx->count++;
|
||||
|
||||
return 1;
|
||||
@ -705,8 +662,6 @@ static bool searchRange(RCore *core, ut64 from, ut64 to, bool rad, struct ctxSea
|
||||
}
|
||||
|
||||
static bool search(RCore *core, bool rad) {
|
||||
struct ctxSearchCB graph_match_ctx = { core, rad, 0 };
|
||||
struct ctxSearchCB bytes_search_ctx = { core, rad, 0 };
|
||||
RList *list;
|
||||
RListIter *iter;
|
||||
RAnalFunction *fcni = NULL;
|
||||
@ -715,10 +670,17 @@ static bool search(RCore *core, bool rad) {
|
||||
ut64 sin_from = UT64_MAX, sin_to = UT64_MAX;
|
||||
int hits = 0;
|
||||
|
||||
struct ctxSearchCB bytes_search_ctx = { core, rad, 0, "bytes" };
|
||||
struct ctxSearchCB graph_match_ctx = { core, rad, 0, "graph" };
|
||||
struct ctxSearchCB offset_match_ctx = { core, rad, 0, "offset" };
|
||||
struct ctxSearchCB refs_match_ctx = { core, rad, 0, "refs" };
|
||||
|
||||
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");
|
||||
|
||||
if (rad) {
|
||||
r_cons_printf ("fs+%s\n", zign_prefix);
|
||||
@ -744,15 +706,23 @@ static bool search(RCore *core, bool rad) {
|
||||
}
|
||||
}
|
||||
|
||||
// Graph search
|
||||
if (useGraph) {
|
||||
// Function search
|
||||
if (useGraph || useOffset || useRefs) {
|
||||
eprintf ("[+] searching function metrics\n");
|
||||
r_cons_break_push (NULL, NULL);
|
||||
r_list_foreach (core->anal->fcns, iter, fcni) {
|
||||
if (r_cons_is_breaked ()) {
|
||||
break;
|
||||
}
|
||||
r_sign_match_graph (core->anal, fcni, graphMatchCB, &graph_match_ctx);
|
||||
if (useGraph) {
|
||||
r_sign_match_graph (core->anal, fcni, fcnMatchCB, &graph_match_ctx);
|
||||
}
|
||||
if (useOffset) {
|
||||
r_sign_match_offset (core->anal, fcni, fcnMatchCB, &offset_match_ctx);
|
||||
}
|
||||
if (useRefs){
|
||||
r_sign_match_refs (core->anal, fcni, fcnMatchCB, &refs_match_ctx);
|
||||
}
|
||||
}
|
||||
r_cons_break_pop ();
|
||||
}
|
||||
@ -766,7 +736,8 @@ static bool search(RCore *core, bool rad) {
|
||||
}
|
||||
}
|
||||
|
||||
hits = bytes_search_ctx.count + graph_match_ctx.count;
|
||||
hits = bytes_search_ctx.count + graph_match_ctx.count +
|
||||
offset_match_ctx.count + refs_match_ctx.count;
|
||||
eprintf ("hits: %d\n", hits);
|
||||
|
||||
return retval;
|
||||
@ -805,13 +776,18 @@ static int cmdCheck(void *data, const char *input) {
|
||||
ut64 at = core->offset;
|
||||
bool retval = true;
|
||||
bool rad = input[0] == '*';
|
||||
struct ctxSearchCB bytes_search_ctx = { core, rad, 0 };
|
||||
struct ctxSearchCB graph_match_ctx = { core, rad, 0 };
|
||||
int hits = 0;
|
||||
|
||||
struct ctxSearchCB bytes_search_ctx = { core, rad, 0, "bytes" };
|
||||
struct ctxSearchCB graph_match_ctx = { core, rad, 0, "graph" };
|
||||
struct ctxSearchCB offset_match_ctx = { core, rad, 0, "offset" };
|
||||
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");
|
||||
|
||||
if (rad) {
|
||||
r_cons_printf ("fs+%s\n", zign_prefix);
|
||||
@ -834,8 +810,8 @@ static int cmdCheck(void *data, const char *input) {
|
||||
r_sign_search_free (ss);
|
||||
}
|
||||
|
||||
// Graph search
|
||||
if (useGraph) {
|
||||
// Function search
|
||||
if (useGraph || useOffset || useRefs) {
|
||||
eprintf ("[+] searching function metrics\n");
|
||||
r_cons_break_push (NULL, NULL);
|
||||
r_list_foreach (core->anal->fcns, iter, fcni) {
|
||||
@ -843,7 +819,15 @@ static int cmdCheck(void *data, const char *input) {
|
||||
break;
|
||||
}
|
||||
if (fcni->addr == core->offset) {
|
||||
r_sign_match_graph (core->anal, fcni, graphMatchCB, &graph_match_ctx);
|
||||
if (useGraph) {
|
||||
r_sign_match_graph (core->anal, fcni, fcnMatchCB, &graph_match_ctx);
|
||||
}
|
||||
if (useOffset) {
|
||||
r_sign_match_offset (core->anal, fcni, fcnMatchCB, &offset_match_ctx);
|
||||
}
|
||||
if (useRefs){
|
||||
r_sign_match_refs (core->anal, fcni, fcnMatchCB, &refs_match_ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -859,7 +843,8 @@ static int cmdCheck(void *data, const char *input) {
|
||||
}
|
||||
}
|
||||
|
||||
hits = bytes_search_ctx.count + graph_match_ctx.count;
|
||||
hits = bytes_search_ctx.count + graph_match_ctx.count +
|
||||
offset_match_ctx.count + refs_match_ctx.count;
|
||||
eprintf ("hits: %d\n", hits);
|
||||
|
||||
return retval;
|
||||
|
@ -20,7 +20,7 @@ enum {
|
||||
R_SIGN_ANAL = 'a', // bytes pattern (anal mask)
|
||||
R_SIGN_GRAPH = 'g', // graph metrics
|
||||
R_SIGN_OFFSET = 'o', // offset
|
||||
R_SIGN_REFS = 'r', // refs
|
||||
R_SIGN_REFS = 'r', // references
|
||||
};
|
||||
|
||||
typedef struct r_sign_graph_t {
|
||||
@ -47,8 +47,10 @@ typedef struct r_sign_item_t {
|
||||
} RSignItem;
|
||||
|
||||
typedef int (*RSignForeachCallback)(RSignItem *it, void *user);
|
||||
typedef int (*RSignSearchCallback)(RSearchKeyword *kw, RSignItem *it, ut64 addr, void *user);
|
||||
typedef int (*RSignSearchCallback)(RSignItem *it, RSearchKeyword *kw, ut64 addr, void *user);
|
||||
typedef int (*RSignGraphMatchCallback)(RSignItem *it, RAnalFunction *fcn, void *user);
|
||||
typedef int (*RSignOffsetMatchCallback)(RSignItem *it, RAnalFunction *fcn, void *user);
|
||||
typedef int (*RSignRefsMatchCallback)(RSignItem *it, RAnalFunction *fcn, void *user);
|
||||
|
||||
typedef struct r_sign_search_t {
|
||||
RSearch *search;
|
||||
@ -62,7 +64,7 @@ R_API bool r_sign_add_bytes(RAnal *a, const char *name, ut64 size, const ut8 *by
|
||||
R_API bool r_sign_add_anal(RAnal *a, const char *name, ut64 size, const ut8 *bytes, ut64 at);
|
||||
R_API bool r_sign_add_graph(RAnal *a, const char *name, RSignGraph graph);
|
||||
R_API bool r_sign_add_offset(RAnal *a, const char *name, ut64 offset);
|
||||
R_API bool r_sign_add_refs(RAnal *a, const char *name, const char *refs[]);
|
||||
R_API bool r_sign_add_refs(RAnal *a, const char *name, char **refs);
|
||||
R_API bool r_sign_delete(RAnal *a, const char *name);
|
||||
R_API void r_sign_list(RAnal *a, int format);
|
||||
|
||||
@ -72,7 +74,9 @@ R_API RSignSearch *r_sign_search_new();
|
||||
R_API void r_sign_search_free(RSignSearch *ss);
|
||||
R_API void r_sign_search_init(RAnal *a, RSignSearch *ss, RSignSearchCallback cb, void *user);
|
||||
R_API int r_sign_search_update(RAnal *a, RSignSearch *ss, ut64 *at, const ut8 *buf, int len);
|
||||
R_API int r_sign_match_graph(RAnal *a, RAnalFunction *fcn, RSignGraphMatchCallback cb, void *user);
|
||||
R_API bool r_sign_match_graph(RAnal *a, RAnalFunction *fcn, RSignGraphMatchCallback cb, void *user);
|
||||
R_API bool r_sign_match_offset(RAnal *a, RAnalFunction *fcn, RSignOffsetMatchCallback cb, void *user);
|
||||
R_API bool r_sign_match_refs(RAnal *a, RAnalFunction *fcn, RSignRefsMatchCallback cb, void *user);
|
||||
|
||||
R_API bool r_sign_load(RAnal *a, const char *file);
|
||||
R_API bool r_sign_save(RAnal *a, const char *file);
|
||||
@ -81,6 +85,9 @@ R_API RSignItem *r_sign_item_new();
|
||||
R_API RSignItem *r_sign_item_dup(RSignItem *it);
|
||||
R_API void r_sign_item_free(RSignItem *item);
|
||||
|
||||
R_API char **r_sign_fcn_refs(RAnal *a, RAnalFunction *fcn);
|
||||
R_API void r_sign_fcn_refs_free(char **refs);
|
||||
|
||||
// TODO
|
||||
R_API int r_sign_is_flirt(RBuffer *buf);
|
||||
R_API void r_sign_flirt_dump(const RAnal *anal, const char *flirt_file);
|
||||
|
Loading…
x
Reference in New Issue
Block a user