mirror of
https://github.com/radareorg/radare2.git
synced 2025-03-03 19:59:09 +00:00
Add byte signature diff zd
##diff ##signatures (#18620)
This commit is contained in:
parent
9a14c294fc
commit
f550986e8e
@ -12,6 +12,7 @@ static const char *help_msg_z[] = {
|
||||
"z", "", "show zignatures",
|
||||
"z.", "", "find matching zignatures in current offset",
|
||||
"zb", "[?][n=5]", "search for best match",
|
||||
"zd", "zignature", "diff current function and signature",
|
||||
"z*", "", "show zignatures in radare format",
|
||||
"zq", "", "show zignatures in quiet mode",
|
||||
"zj", "", "show zignatures in json format",
|
||||
@ -1096,9 +1097,198 @@ static bool bestmatch(void *data, const char *input) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool _sig_bytediff_cb(RLevBuf *va, RLevBuf *vb, ut32 ia, ut32 ib) {
|
||||
RSignBytes *a = (RSignBytes *)va->buf;
|
||||
RSignBytes *b = (RSignBytes *)vb->buf;
|
||||
|
||||
if ((a->bytes[ia] & a->mask[ia]) == (b->bytes[ib] & b->mask[ib])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define lines_addbytesmask(l, sig, index, add, col) \
|
||||
if (col) { \
|
||||
l.bytes = r_str_appendf (l.bytes, " %s%s%02x\x1b[0m", col, add, sig->bytes[index]); \
|
||||
l.mask = r_str_appendf (l.mask, " %s%s%02x\x1b[0m", col, add, sig->mask[index]); \
|
||||
l.land = r_str_appendf (l.land, " %s%s%02x\x1b[0m", col, add, sig->bytes[index] & sig->mask[index]); \
|
||||
} else { \
|
||||
l.bytes = r_str_appendf (l.bytes, " %s%02x", add, sig->bytes[index]); \
|
||||
l.mask = r_str_appendf (l.mask, " %s%02x", add, sig->mask[index]); \
|
||||
l.land = r_str_appendf (l.land, " %s%02x", add, sig->bytes[index] & sig->mask[index]); \
|
||||
} \
|
||||
index++;
|
||||
|
||||
#define lines_addblnk(l) \
|
||||
l.bytes = r_str_append (l.bytes, " "); \
|
||||
l.mask = r_str_append (l.mask, " "); \
|
||||
l.land = r_str_append (l.land, " ");
|
||||
|
||||
#define freelines(x) \
|
||||
free (x.bytes); \
|
||||
free (x.mask); \
|
||||
free (x.land); \
|
||||
memset (&x, 0, sizeof (x));
|
||||
|
||||
static void print_zig_diff(RCore *c, RSignBytes *ab, RSignBytes *bb, RLevOp *ops) {
|
||||
struct lines {
|
||||
char *mask, *bytes, *land;
|
||||
} al, bl;
|
||||
memset (&al, 0, sizeof (al));
|
||||
memset (&bl, 0, sizeof (bl));
|
||||
|
||||
char *colsub, *coladd, *coldel;
|
||||
colsub = coladd = coldel = NULL;
|
||||
if (r_config_get_b (c->config, "scr.color")) {
|
||||
coldel = "\x1b[1;31m";
|
||||
coladd = "\x1b[1;32m";
|
||||
colsub = "\x1b[1;33m";
|
||||
}
|
||||
|
||||
int i, ia, ib, iastart, ibstart;
|
||||
ia = ib = iastart = ibstart = 0;
|
||||
bool printb = false;
|
||||
for (i = 0; ops[i] != LEVEND; i++) {
|
||||
switch (ops[i]) {
|
||||
case LEVNOP:
|
||||
// lines_addbytesmask macro does ia++ so test must before
|
||||
if (!printb && (ab->bytes[ia] != bb->bytes[ib] || ab->mask[ia] != bb->mask[ib])) {
|
||||
printb = true;
|
||||
}
|
||||
lines_addbytesmask (al, ab, ia, " ", (char *)NULL);
|
||||
lines_addbytesmask (bl, bb, ib, " ", (char *)NULL);
|
||||
break;
|
||||
case LEVSUB:
|
||||
lines_addbytesmask (al, ab, ia, " ", colsub);
|
||||
lines_addbytesmask (bl, bb, ib, "^", colsub);
|
||||
printb = true;
|
||||
break;
|
||||
case LEVADD:
|
||||
lines_addblnk (al);
|
||||
lines_addbytesmask (bl, bb, ib, "+", coladd);
|
||||
printb = true;
|
||||
break;
|
||||
case LEVDEL:
|
||||
lines_addbytesmask (al, ab, ia, "-", coldel);
|
||||
lines_addblnk (bl);
|
||||
printb = true;
|
||||
break;
|
||||
default:
|
||||
r_warn_if_reached ();
|
||||
freelines (al);
|
||||
freelines (bl);
|
||||
return;
|
||||
}
|
||||
// when alloc fails
|
||||
if (!(al.bytes && al.mask && al.land && bl.bytes && bl.mask && bl.land)) {
|
||||
freelines (al);
|
||||
freelines (bl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (i % 16 == 15 || ops[i + 1] == LEVEND) {
|
||||
if (i > 16) {
|
||||
r_cons_printf ("\n");
|
||||
}
|
||||
r_cons_printf ("Fnc cmp 0x%04x %s\n", iastart, al.land);
|
||||
if (printb) {
|
||||
r_cons_printf ("Sig cmp 0x%04x %s\n", ibstart, bl.land);
|
||||
}
|
||||
r_cons_printf ("Fnc Mask 0x%04x %s\n", iastart, al.mask);
|
||||
if (printb) {
|
||||
r_cons_printf ("Sig Mask 0x%04x %s\n", ibstart, bl.mask);
|
||||
}
|
||||
r_cons_printf ("Fnc Bytes 0x%04x %s\n", iastart, al.bytes);
|
||||
if (printb) {
|
||||
r_cons_printf ("Sig Bytes 0x%04x %s\n", ibstart, bl.bytes);
|
||||
} else {
|
||||
r_cons_printf ("== Signature was same ==\n");
|
||||
}
|
||||
freelines (al);
|
||||
freelines (bl);
|
||||
iastart = ia;
|
||||
ibstart = ib;
|
||||
printb = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef lines_addbytesmask
|
||||
#undef lines_addblnk
|
||||
#undef freelines
|
||||
|
||||
static bool diff_zig(void *data, const char *input) {
|
||||
r_return_val_if_fail (data && input, false);
|
||||
RCore *core = (RCore *)data;
|
||||
|
||||
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
|
||||
if (!fcn) {
|
||||
eprintf ("No function at 0x%08" PFMT64x "\n", core->offset);
|
||||
return false;
|
||||
}
|
||||
|
||||
char *argv = r_str_new (input);
|
||||
if (!argv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char *zigname = strtok (argv, " ");
|
||||
if (!zigname) {
|
||||
eprintf ("Need a signature\n");
|
||||
free (argv);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strtok (NULL, " ")) {
|
||||
eprintf ("too many arguments");
|
||||
free (argv);
|
||||
return false;
|
||||
}
|
||||
|
||||
RSignItem *it = item_frm_signame (core->anal, zigname);
|
||||
if (!it) {
|
||||
eprintf ("Couldn't get signature for %s\n", zigname);
|
||||
free (argv);
|
||||
return false;
|
||||
}
|
||||
free (argv);
|
||||
|
||||
if (!it->bytes) {
|
||||
eprintf ("Signature %s missing bytes\n", it->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
RLevBuf b;
|
||||
b.buf = it->bytes;
|
||||
b.len = it->bytes->size;
|
||||
|
||||
RSignItem *fit = r_sign_item_new ();
|
||||
if (!fit) {
|
||||
r_sign_item_free (it);
|
||||
return false;
|
||||
}
|
||||
r_sign_addto_item (core->anal, fit, fcn, R_SIGN_BYTES);
|
||||
|
||||
RLevBuf a;
|
||||
a.buf = fit->bytes;
|
||||
a.len = fit->bytes->size;
|
||||
|
||||
RLevOp *ops = NULL;
|
||||
|
||||
if (r_diff_levenshtein_path (&a, &b, UT32_MAX, _sig_bytediff_cb, &ops) < 0) {
|
||||
eprintf ("Diff failed\n");
|
||||
} else {
|
||||
print_zig_diff (core, fit->bytes, it->bytes, ops);
|
||||
}
|
||||
|
||||
free (ops);
|
||||
r_sign_item_free (fit);
|
||||
r_sign_item_free (it);
|
||||
return false;
|
||||
}
|
||||
|
||||
static int cmdCompare(void *data, const char *input) {
|
||||
int result = true;
|
||||
RCore *core = (RCore *) data;
|
||||
RCore *core = (RCore *)data;
|
||||
const char *raw_bytes_thresh = r_config_get (core->config, "zign.diff.bthresh");
|
||||
const char *raw_graph_thresh = r_config_get (core->config, "zign.diff.gthresh");
|
||||
RSignOptions *options = r_sign_options_new (raw_bytes_thresh, raw_graph_thresh);
|
||||
@ -1279,6 +1469,8 @@ static int cmd_zign(void *data, const char *input) {
|
||||
return cmdCheck (data, arg);
|
||||
case 'b': // "zb"
|
||||
return bestmatch (data, arg);
|
||||
case 'd': // "zb"
|
||||
return diff_zig (data, arg);
|
||||
case 'o': // "zo"
|
||||
return cmdOpen (data, arg);
|
||||
case 'g': // "zg"
|
||||
|
@ -1784,3 +1784,34 @@ int sym.new_function_name (int NEWARGC, char **NEWARGV);
|
||||
sym.new_function_name
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=zd basic
|
||||
FILE=bins/elf/static-glibc-2.27
|
||||
CMDS=<<EOF
|
||||
s 0x00410210
|
||||
e zign.maxsz = 32
|
||||
af
|
||||
za sym.test b ff41554154498afc555383ec08e89e02ffff488b2d77952a004889c38b450045:ffffffffffffffffffffffffffff00000000ff000000000000ffffffffffffff
|
||||
zd sym.test
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
Fnc cmp 0x0000 41 55 41 54 49 89 fc 55 53 -48 83 ec 08 e8 00
|
||||
Sig cmp 0x0000 +ff 41 55 41 54 49 ^8a fc 55 53 83 ec 08 e8 00
|
||||
Fnc Mask 0x0000 ff ff ff ff ff ff ff ff ff -ff ff ff ff ff 00
|
||||
Sig Mask 0x0000 +ff ff ff ff ff ff ^ff ff ff ff ff ff ff ff 00
|
||||
Fnc Bytes 0x0000 41 55 41 54 49 89 fc 55 53 -48 83 ec 08 e8 9e
|
||||
Sig Bytes 0x0000 +ff 41 55 41 54 49 ^8a fc 55 53 83 ec 08 e8 9e
|
||||
|
||||
Fnc cmp 0x000f 00 00 00 48 00 00 00 00 00 00 48 89 c3 8b 45 00
|
||||
Fnc Mask 0x000f 00 00 00 ff 00 00 00 00 00 00 ff ff ff ff ff ff
|
||||
Fnc Bytes 0x000f 02 ff ff 48 8b 2d 77 95 2a 00 48 89 c3 8b 45 00
|
||||
== Signature was same ==
|
||||
|
||||
Fnc cmp 0x001f 48
|
||||
Sig cmp 0x001f ^45
|
||||
Fnc Mask 0x001f ff
|
||||
Sig Mask 0x001f ^ff
|
||||
Fnc Bytes 0x001f 48
|
||||
Sig Bytes 0x001f ^45
|
||||
EOF
|
||||
RUN
|
||||
|
Loading…
x
Reference in New Issue
Block a user