mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-08 06:12:13 +00:00
Implement the zc command ##signatures
Also add zcn, zcn! to compare only signatures with the same name.
This commit is contained in:
parent
b4015791be
commit
0b880ed0b0
225
libr/anal/sign.c
225
libr/anal/sign.c
@ -162,7 +162,7 @@ R_API bool r_sign_deserialize(RAnal *a, RSignItem *it, const char *k, const char
|
||||
token = word + 2;
|
||||
if (!strcmp (word, "*")) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (strlen (word) < 3 || word[1] != ':') {
|
||||
eprintf ("Corrupted zignatures database (%s)\n", word);
|
||||
break;
|
||||
@ -837,6 +837,229 @@ R_API bool r_sign_delete(RAnal *a, const char *name) {
|
||||
return sdb_remove (a->sdb_zigns, k, 0);
|
||||
}
|
||||
|
||||
static bool matchBytes(RSignItem *a, RSignItem *b) {
|
||||
if (a->bytes && b->bytes) {
|
||||
if (a->bytes->size == b->bytes->size) {
|
||||
return !memcmp (a->bytes->bytes, b->bytes->bytes, b->bytes->size);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool matchGraph(RSignItem *a, RSignItem *b) {
|
||||
if (a->graph && b->graph) {
|
||||
if (a->graph->cc != b->graph->cc) {
|
||||
return false;
|
||||
}
|
||||
if (a->graph->nbbs != b->graph->nbbs) {
|
||||
return false;
|
||||
}
|
||||
if (a->graph->ebbs != b->graph->ebbs) {
|
||||
return false;
|
||||
}
|
||||
if (a->graph->edges != b->graph->edges) {
|
||||
return false;
|
||||
}
|
||||
if (a->graph->bbsum!= b->graph->bbsum) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API bool r_sign_diff(RAnal *a, const char *other_space_name) {
|
||||
char k[R_SIGN_KEY_MAXSZ];
|
||||
|
||||
r_return_val_if_fail (a && other_space_name, false);
|
||||
|
||||
RSpace *current_space = r_spaces_current (&a->zign_spaces);
|
||||
if (!current_space) {
|
||||
return false;
|
||||
}
|
||||
RSpace *other_space = r_spaces_get (&a->zign_spaces, other_space_name);
|
||||
if (!other_space) {
|
||||
return false;
|
||||
}
|
||||
|
||||
serializeKey (a, current_space, "", k);
|
||||
SdbList *current_zigns = sdb_foreach_match (a->sdb_zigns, k, false);
|
||||
|
||||
serializeKey (a, other_space, "", k);
|
||||
SdbList *other_zigns = sdb_foreach_match (a->sdb_zigns, k, false);
|
||||
|
||||
eprintf ("Diff %d %d\n", (int)ls_length (current_zigns), (int)ls_length (other_zigns));
|
||||
|
||||
SdbListIter *iter;
|
||||
SdbKv *kv;
|
||||
RList *lb = NULL;
|
||||
RList *la = r_list_new ();
|
||||
if (!la) {
|
||||
goto beach;
|
||||
}
|
||||
ls_foreach (current_zigns, iter, kv) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
if (!it) {
|
||||
goto beach;
|
||||
}
|
||||
if (r_sign_deserialize (a, it, kv->base.key, kv->base.value)) {
|
||||
r_list_append (la, it);
|
||||
} else {
|
||||
r_sign_item_free (it);
|
||||
}
|
||||
}
|
||||
lb = r_list_new ();
|
||||
if (!lb) {
|
||||
goto beach;
|
||||
}
|
||||
ls_foreach (other_zigns, iter, kv) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
if (!it) {
|
||||
goto beach;
|
||||
}
|
||||
if (r_sign_deserialize (a, it, kv->base.key, kv->base.value)) {
|
||||
r_list_append (lb, it);
|
||||
} else {
|
||||
r_sign_item_free (it);
|
||||
}
|
||||
}
|
||||
|
||||
ls_free (current_zigns);
|
||||
ls_free (other_zigns);
|
||||
|
||||
RListIter *itr;
|
||||
RListIter *itr2;
|
||||
RSignItem *si;
|
||||
RSignItem *si2;
|
||||
|
||||
// do the sign diff here
|
||||
r_list_foreach (la, itr, si) {
|
||||
if (strstr (si->name, "imp.")) {
|
||||
continue;
|
||||
}
|
||||
r_list_foreach (lb, itr2, si2) {
|
||||
if (strstr (si2->name, "imp.")) {
|
||||
continue;
|
||||
}
|
||||
if (matchBytes (si, si2)) {
|
||||
a->cb_printf ("0x%08"PFMT64x" 0x%08"PFMT64x" B %s\n", si->addr, si2->addr, si->name);
|
||||
}
|
||||
if (matchGraph (si, si2)) {
|
||||
a->cb_printf ("0x%08"PFMT64x" 0x%08"PFMT64x" G %s\n", si->addr, si2->addr, si->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r_list_free (la);
|
||||
r_list_free (lb);
|
||||
|
||||
return true;
|
||||
beach:
|
||||
ls_free (current_zigns);
|
||||
ls_free (other_zigns);
|
||||
r_list_free (la);
|
||||
r_list_free (lb);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API bool r_sign_diff_by_name(RAnal *a, const char *other_space_name, bool not_matching) {
|
||||
char k[R_SIGN_KEY_MAXSZ];
|
||||
|
||||
r_return_val_if_fail (a && other_space_name, false);
|
||||
|
||||
RSpace *current_space = r_spaces_current (&a->zign_spaces);
|
||||
if (!current_space) {
|
||||
return false;
|
||||
}
|
||||
RSpace *other_space = r_spaces_get (&a->zign_spaces, other_space_name);
|
||||
if (!other_space) {
|
||||
return false;
|
||||
}
|
||||
|
||||
serializeKey (a, current_space, "", k);
|
||||
SdbList *current_zigns = sdb_foreach_match (a->sdb_zigns, k, false);
|
||||
|
||||
serializeKey (a, other_space, "", k);
|
||||
SdbList *other_zigns = sdb_foreach_match (a->sdb_zigns, k, false);
|
||||
|
||||
eprintf ("Diff by name %d %d (%s)\n", (int)ls_length (current_zigns), (int)ls_length (other_zigns), not_matching ? "not maching" : "matching");
|
||||
|
||||
SdbListIter *iter;
|
||||
SdbKv *kv;
|
||||
RList *lb = NULL;
|
||||
RList *la = r_list_new ();
|
||||
if (!la) {
|
||||
goto beach;
|
||||
}
|
||||
ls_foreach (current_zigns, iter, kv) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
if (!it) {
|
||||
goto beach;
|
||||
}
|
||||
if (r_sign_deserialize (a, it, kv->base.key, kv->base.value)) {
|
||||
r_list_append (la, it);
|
||||
} else {
|
||||
r_sign_item_free (it);
|
||||
}
|
||||
}
|
||||
lb = r_list_new ();
|
||||
if (!la) {
|
||||
goto beach;
|
||||
}
|
||||
ls_foreach (other_zigns, iter, kv) {
|
||||
RSignItem *it = r_sign_item_new ();
|
||||
if (!it) {
|
||||
goto beach;
|
||||
}
|
||||
if (r_sign_deserialize (a, it, kv->base.key, kv->base.value)) {
|
||||
r_list_append (lb, it);
|
||||
} else {
|
||||
r_sign_item_free (it);
|
||||
}
|
||||
}
|
||||
|
||||
ls_free (current_zigns);
|
||||
ls_free (other_zigns);
|
||||
|
||||
RListIter *itr;
|
||||
RListIter *itr2;
|
||||
RSignItem *si;
|
||||
RSignItem *si2;
|
||||
size_t current_space_name_len = strlen (current_space->name);
|
||||
size_t other_space_name_len = strlen (other_space->name);
|
||||
|
||||
r_list_foreach (la, itr, si) {
|
||||
if (strstr (si->name, "imp.")) {
|
||||
continue;
|
||||
}
|
||||
r_list_foreach (lb, itr2, si2) {
|
||||
if (strcmp (si->name + current_space_name_len + 1, si2->name + other_space_name_len + 1)) {
|
||||
continue;
|
||||
}
|
||||
bool bytesMatch = matchBytes (si, si2);
|
||||
bool graphMatch = matchGraph (si, si2);
|
||||
if ((bytesMatch && !not_matching) || (!bytesMatch && not_matching)) {
|
||||
a->cb_printf ("0x%08"PFMT64x" 0x%08"PFMT64x" B %s\n", si->addr, si2->addr, si->name);
|
||||
}
|
||||
if ((graphMatch && !not_matching) || (!graphMatch && not_matching)) {
|
||||
a->cb_printf ("0x%08"PFMT64x" 0x%08"PFMT64x" G %s\n", si->addr, si2->addr, si->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r_list_free (la);
|
||||
r_list_free (lb);
|
||||
|
||||
return true;
|
||||
beach:
|
||||
ls_free (current_zigns);
|
||||
ls_free (other_zigns);
|
||||
r_list_free (la);
|
||||
r_list_free (lb);
|
||||
|
||||
return false;
|
||||
}
|
||||
struct ctxListCB {
|
||||
RAnal *anal;
|
||||
int idx;
|
||||
|
@ -22,7 +22,7 @@ static const char *help_msg_z[] = {
|
||||
"zo", "[?]", "manage zignature files",
|
||||
"zf", "[?]", "manage FLIRT signatures",
|
||||
"z/", "[?]", "search zignatures",
|
||||
"zc", " [zspace]", "compare current zignspace zignatures with others",
|
||||
"zc", "[?]", "compare current zignspace zignatures with another one",
|
||||
"zs", "[?]", "manage zignspaces",
|
||||
"zi", "", "show zignatures matching information",
|
||||
NULL
|
||||
@ -74,6 +74,14 @@ static const char *help_msg_zs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_zc[] = {
|
||||
"Usage:", "zc[n!] other_space ", "# Compare zignspaces",
|
||||
"zc", " other_space", "compare all current space with other_space",
|
||||
"zcn", " other_space", "compare current space with zigns with same name on other_space",
|
||||
"zcn!", " other_space", "same as above but show the ones not matching",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void cmd_zign_init(RCore *core) {
|
||||
DEFINE_CMD_DESCRIPTOR (core, z);
|
||||
DEFINE_CMD_DESCRIPTOR_SPECIAL (core, z/, z_slash);
|
||||
@ -81,6 +89,7 @@ static void cmd_zign_init(RCore *core) {
|
||||
DEFINE_CMD_DESCRIPTOR (core, zf);
|
||||
DEFINE_CMD_DESCRIPTOR (core, zo);
|
||||
DEFINE_CMD_DESCRIPTOR (core, zs);
|
||||
DEFINE_CMD_DESCRIPTOR (core, zc);
|
||||
}
|
||||
|
||||
static bool addFcnHash(RCore *core, RAnalFunction *fcn, const char *name) {
|
||||
@ -158,7 +167,7 @@ static char *getFcnComments(RCore *core, RAnalFunction *fcn) {
|
||||
if (r && *r) {
|
||||
return r;
|
||||
}
|
||||
//
|
||||
//
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
@ -820,8 +829,46 @@ TODO: add useXRefs, useName
|
||||
}
|
||||
|
||||
static int cmdCompare(void *data, const char *input) {
|
||||
eprintf ("TODO\n");
|
||||
return 0;
|
||||
RCore *core = (RCore *) data;
|
||||
|
||||
switch (*input) {
|
||||
case ' ':
|
||||
if (!input[1]) {
|
||||
eprintf ("usage: zc other_space\n");
|
||||
return false;
|
||||
}
|
||||
return r_sign_diff (core->anal, input + 1);
|
||||
break;
|
||||
case 'n':
|
||||
switch (input[1]) {
|
||||
case ' ':
|
||||
if (!input[2]) {
|
||||
eprintf ("usage: zcn other_space\n");
|
||||
return false;
|
||||
}
|
||||
return r_sign_diff_by_name (core->anal, input + 2, false);
|
||||
break;
|
||||
case '!':
|
||||
if (input[2] != ' ' || !input[3]) {
|
||||
eprintf ("usage: zcn! other_space\n");
|
||||
return false;
|
||||
}
|
||||
return r_sign_diff_by_name (core->anal, input + 3, true);
|
||||
break;
|
||||
default:
|
||||
eprintf ("usage: zcn! other_space\n");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
r_core_cmd_help (core, help_msg_zc);
|
||||
break;
|
||||
default:
|
||||
eprintf ("usage: zc[?n!] other_space\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cmdCheck(void *data, const char *input) {
|
||||
|
@ -126,6 +126,9 @@ R_API RList *r_sign_fcn_vars(RAnal *a, RAnalFunction *fcn);
|
||||
R_API int r_sign_is_flirt(RBuffer *buf);
|
||||
R_API void r_sign_flirt_dump(const RAnal *anal, const char *flirt_file);
|
||||
R_API void r_sign_flirt_scan(RAnal *anal, const char *flirt_file);
|
||||
|
||||
R_API bool r_sign_diff(RAnal *a, const char *other_space_name);
|
||||
R_API bool r_sign_diff_by_name(RAnal *a, const char *other_space_name, bool not_matching);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
Reference in New Issue
Block a user