Skip to content

Commit

Permalink
Use system diff in graphdiff nodes if possible and improve graphviz s…
Browse files Browse the repository at this point in the history
…tyle (radareorg#9988)

$ radiff2 -g sym._call -A  b c | dot -Tpng > a.png

- we need disasmdiff native in r2, as well as more inter-core commands
  • Loading branch information
radare authored Apr 30, 2018
1 parent dd4761f commit 000e725
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 20 deletions.
10 changes: 7 additions & 3 deletions binr/radiff2/radiff2.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static int cb(RDiff *d, void *user, RDiffOp *op) {
for (i = 0; i < len; i++) {
printf ("%02x", op->a_buf[i]);
}
char *p = r_str_escape((const char*)op->a_buf);
char *p = r_str_escape ((const char*)op->a_buf);
printf (" \"%s\"\n", p);
free (p);
if (!quiet) {
Expand Down Expand Up @@ -791,7 +791,9 @@ int main(int argc, char **argv) {
if (!c || !c2) {
eprintf ("Cannot open '%s'\n", r_str_get (file2));
return 1;
}
}
c->c2 = c2;
c2->c2 = c;
if (arch) {
r_config_set (c->config, "asm.arch", arch);
r_config_set (c2->config, "asm.arch", arch);
Expand Down Expand Up @@ -914,7 +916,9 @@ int main(int argc, char **argv) {
write (1, "\x04", 1);
}
if (diffmode == 'U') {
r_diff_buffers_unified (d, bufa, sza, bufb, szb);
char * res = r_diff_buffers_unified (d, bufa, sza, bufb, szb);
printf ("%s", res);
free (res);
} else if (diffmode == 'B') {
r_diff_set_callback (d, &bcb, 0);
r_diff_buffers (d, bufa, sza, bufb, szb);
Expand Down
55 changes: 52 additions & 3 deletions libr/core/canal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1223,9 +1223,58 @@ static int core_anal_graph_nodes(RCore *core, RAnalFunction *fcn, int opts) {
//r_cons_printf (" \"0x%08"PFMT64x"_0x%08"PFMT64x"\" [color=\"%s\","
// " label=\"%s\", URL=\"%s/0x%08"PFMT64x"\"]\n",
// fcn->addr, bbi->addr, difftype, str, fcn->name, bbi->addr);
r_cons_printf (" \"0x%08"PFMT64x"\" [fillcolor=\"%s\","
" label=\"%s\", URL=\"%s/0x%08"PFMT64x"\"]\n",
bbi->addr, difftype, str, fcn->name, bbi->addr);
RConfigHold *hc = r_config_hold_new (core->config);
r_config_save_num (hc, "scr.color", "scr.utf8", "asm.offset", "asm.lines",
"asm.cmt.right", "asm.fcnlines", "asm.bytes", NULL);
RDiff *d = r_diff_new ();
r_config_set_i (core->config, "scr.color", 0);
r_config_set_i (core->config, "scr.utf8", 0);
r_config_set_i (core->config, "asm.offset", 0);
r_config_set_i (core->config, "asm.lines", 0);
r_config_set_i (core->config, "asm.cmt.right", 0);
r_config_set_i (core->config, "asm.fcnlines", 0);
r_config_set_i (core->config, "asm.bytes", 0);

if (bbi->diff && bbi->diff->type != R_ANAL_DIFF_TYPE_MATCH && core->c2) {
RCore *c = core->c2;
RConfig *oc = c->config;
char *str = r_core_cmd_strf (core, "pdb @ 0x%08"PFMT64x, bbi->addr);
c->config = core->config;
// XXX. the bbi->addr doesnt needs to be in the same address in core2
char *str2 = r_core_cmd_strf (c, "pdb @ 0x%08"PFMT64x, bbi->diff->addr);
char *diffstr = r_diff_buffers_to_string (d,
(const ut8*)str, strlen (str),
(const ut8*)str2, strlen(str2));
if (diffstr) {
char *nl = strchr (diffstr, '\n');
if (nl) {
nl = strchr (nl + 1, '\n');
if (nl) {
nl = strchr (nl + 1, '\n');
if (nl) {
r_str_cpy (diffstr, nl + 1);
}
}
}
}
diffstr = r_str_replace (diffstr, "\n", "\\l", 1);
diffstr = r_str_replace (diffstr, "\"", "'", 1);
// eprintf ("%s\n", diffstr? diffstr: "");
r_cons_printf (" \"0x%08"PFMT64x"\" [fillcolor=\"%s\","
"color=\"black\", fontname=\"Courier\","
" label=\"%s\", URL=\"%s/0x%08"PFMT64x"\"]\n",
bbi->addr, difftype, diffstr, fcn->name, bbi->addr);
free (diffstr);
c->config = oc;
} else {
r_cons_printf (" \"0x%08"PFMT64x"\" [fillcolor=\"%s\","
"color=\"black\", fontname=\"Courier\","
" label=\"%s\", URL=\"%s/0x%08"PFMT64x"\"]\n",
bbi->addr, difftype, str, fcn->name, bbi->addr);
}
r_diff_free (d);
r_config_set_i (core->config, "scr.color", 1);
r_config_hold_free (hc);
}
} else {
if (is_html) {
Expand Down
3 changes: 1 addition & 2 deletions libr/core/gdiff.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2016 - nibble, pancake */
/* radare - LGPL - Copyright 2010-2018 - nibble, pancake */

#include <stdio.h>
#include <string.h>
Expand Down Expand Up @@ -91,7 +91,6 @@ R_API void r_core_diff_show(RCore *c, RCore *c2) {
int digits = 1;
int len;


r_list_foreach (fcns, iter, f) {
if (f->name && (len = strlen (f->name)) > maxnamelen) {
maxnamelen = len;
Expand Down
1 change: 1 addition & 0 deletions libr/include/r_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ typedef struct r_core_t {
RList *undos;
bool fixedbits;
bool fixedarch;
struct r_core_t *c2;
} RCore;

R_API int r_core_bind(RCore *core, RCoreBind *bnd);
Expand Down
3 changes: 2 additions & 1 deletion libr/include/r_diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, in
R_API int r_diff_buffers_radiff(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb);
R_API int r_diff_buffers_delta(RDiff *diff, const ut8 *sa, int la, const ut8 *sb, int lb);
R_API int r_diff_buffers(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb);
R_API char *r_diff_buffers_to_string(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb);
R_API int r_diff_set_callback(RDiff *d, RDiffCallback callback, void *user);
R_API bool r_diff_buffers_distance(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb, ut32 *distance, double *similarity);
R_API bool r_diff_buffers_distance_myers(RDiff *diff, const ut8 *a, ut32 la, const ut8 *b, ut32 lb, ut32 *distance, double *similarity);
R_API bool r_diff_buffers_distance_levenstein(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb, ut32 *distance, double *similarity);
R_API int r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb);
R_API char *r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb);
/* static method !??! */
R_API int r_diff_lines(const char *file1, const char *sa, int la, const char *file2, const char *sb, int lb);
R_API int r_diff_set_delta(RDiff *d, int delta);
Expand Down
73 changes: 68 additions & 5 deletions libr/util/diff.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2017 - pancake, nikolai */
/* radare - LGPL - Copyright 2009-2018 - pancake, nikolai */

#include <r_diff.h>

Expand Down Expand Up @@ -33,13 +33,68 @@ R_API int r_diff_set_delta(RDiff *d, int delta) {
return 1;
}

typedef struct {
RDiff *d;
char *str;
} RDiffUser;

// XXX buffers_static doesnt constructs the correct string in this callback
static int tostring(RDiff *d, void *user, RDiffOp *op) {
RDiffUser *u = (RDiffUser*)user;
if (op->a_len > 0) {
char *a_str = r_str_ndup ((const char *)op->a_buf + op->a_off, op->a_len);
u->str = r_str_appendf (u->str, "+(%s)", a_str);
#if 0
char *bufasm = r_str_prefix_all (a_str, "- ");
u->str = r_str_appendf (u->str, "-(%s)", bufasm);
free (bufasm);
#endif
free (a_str);
}
if (op->b_len > 0) {
char *b_str = r_str_ndup ((const char *)op->b_buf + op->b_off, op->b_len);
u->str = r_str_appendf (u->str, "+(%s)", b_str);
#if 0
char *bufasm = r_str_prefix_all (b_str, "+ ");
u->str = r_str_appendf (u->str, "+(%s)", bufasm);
free (bufasm);
#endif
free (b_str);
}
if (op->a_len == op->b_len) {
char *b_str = r_str_ndup ((const char *)op->a_buf + op->a_off, op->a_len);
// char *bufasm = r_str_prefix_all (b_str, " ");
u->str = r_str_appendf (u->str, "%s", b_str);
// free (bufasm);
free (b_str);
}
return 1;
}

R_API char *r_diff_buffers_to_string(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
#if 1
return r_diff_buffers_unified (d, a, la, b, lb);
#else
// XXX buffers_static doesnt constructs the correct string in this callback
void *c = d->callback;
void *u = d->user;
RDiffUser du = {d, strdup ("")};
d->callback = &tostring;
d->user = &du;
r_diff_buffers_static (d, a, la, b, lb);
d->callback = c;
d->user = u;
return du.str;
#endif
}

R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
int i, len;
int hit = 0;
la = R_ABS (la);
lb = R_ABS (lb);
if (la != lb) {
len = R_MIN(la, lb);
len = R_MIN (la, lb);
eprintf ("Buffer truncated to %d byte(s) (%d not compared)\n", len, R_ABS(lb-la));
} else {
len = la;
Expand Down Expand Up @@ -74,18 +129,26 @@ R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, in
}

// XXX: temporary files are
R_API int r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
R_API char *r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) {
r_file_dump (".a", a, la, 0);
r_file_dump (".b", b, lb, 0);
#if 0
if (r_mem_is_printable (a, R_MIN (5, la))) {
r_file_dump (".a", a, la, 0);
r_file_dump (".b", b, lb, 0);
} else {
r_file_hexdump (".a", a, la, 0);
r_file_hexdump (".b", b, lb, 0);
}
r_sys_cmd ("diff -ru .a .b");
#endif
char* err = NULL;
char* out = NULL;
int out_len;
int rc = r_sys_cmd_str_full ("/usr/bin/diff -u .a .b", NULL, &out, &out_len, &err);
r_file_rm (".a");
r_file_rm (".b");
return 0;
free (err);
return out;
}

R_API int r_diff_buffers(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb) {
Expand Down
17 changes: 11 additions & 6 deletions libr/util/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,10 @@ R_API int r_sys_chdir(const char *s) {

#if __UNIX__ || __CYGWIN__ && !defined(MINGW32)
R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output, int *len, char **sterr) {
char *mysterr = NULL;
if (!sterr) {
sterr = &mysterr;
}
char buffer[1024], *outputptr = NULL;
char *inputptr = (char *)input;
int pid, bytes = 0, status;
Expand Down Expand Up @@ -528,7 +532,7 @@ R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output,
if (!(bytes = read (sh_out[0], buffer, sizeof (buffer)-1))) {
break;
}
buffer[sizeof(buffer) - 1] = '\0';
buffer[sizeof (buffer) - 1] = '\0';
if (len) {
*len += bytes;
}
Expand All @@ -537,7 +541,7 @@ R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output,
if (!read (sh_err[0], buffer, sizeof (buffer)-1)) {
break;
}
buffer[sizeof(buffer) - 1] = '\0';
buffer[sizeof (buffer) - 1] = '\0';
*sterr = r_str_append (*sterr, buffer);
} else if (FD_ISSET (sh_in[1], &wfds) && inputptr && *inputptr) {
int inputptr_len = strlen (inputptr);
Expand All @@ -564,10 +568,11 @@ R_API int r_sys_cmd_str_full(const char *cmd, const char *input, char **output,
waitpid (pid, &status, 0);
bool ret = true;
if (status) {
char *escmd = r_str_escape (cmd);
eprintf ("error code %d\n", WEXITSTATUS(status));
//eprintf ("%s: failed command '%s'\n", __func__, escmd);
free (escmd);
// char *escmd = r_str_escape (cmd);
// eprintf ("error code %d (%s): %s\n", WEXITSTATUS (status), escmd, *sterr);
// eprintf ("(%s)\n", output);
// eprintf ("%s: failed command '%s'\n", __func__, escmd);
// free (escmd);
ret = false;
}

Expand Down

0 comments on commit 000e725

Please sign in to comment.