Skip to content

Commit

Permalink
Support every output format for the bb graph (agf) (#10030)
Browse files Browse the repository at this point in the history
  • Loading branch information
cyanpencil authored and radare committed May 7, 2018
1 parent e216f08 commit 94807b4
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 3 deletions.
128 changes: 128 additions & 0 deletions libr/core/canal.c
Expand Up @@ -1579,6 +1579,134 @@ R_API int r_core_anal_fcn_clean(RCore *core, ut64 addr) {
return true;
}

static char *get_title(ut64 addr) {
return r_str_newf ("0x%"PFMT64x, addr);
}

R_API int r_core_print_bb_custom(RCore *core, RAnalFunction *fcn) {
RAnalBlock *bb;
RListIter *iter;
if (!fcn) {
return false;
}

RConfigHold *hc = r_config_hold_new (core->config);
r_config_save_num (hc, "scr.color", "scr.utf8", "asm.marks", "asm.offset", "asm.lines",
"asm.cmt.right", "asm.cmt.col", "asm.fcnlines", "asm.bytes", NULL);
/*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.marks", 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.cmt.col", 0);
r_config_set_i (core->config, "asm.fcnlines", 0);
r_config_set_i (core->config, "asm.bytes", 0);

r_list_foreach (fcn->bbs, iter, bb) {
if (bb->addr == UT64_MAX) {
continue;
}

char *title = get_title (bb->addr);
char *body = r_core_cmd_strf (core, "pdb @ 0x%08"PFMT64x, bb->addr);
char *body_b64 = r_base64_encode_dyn (body, -1);

if (!title || !body || !body_b64) {
return false;
}

body_b64 = r_str_prefix (body_b64, "base64:");
r_cons_printf ("agn %s %s\n", title, body_b64);

free (body);
free (body_b64);
free (title);
}

r_config_restore (hc);
r_config_hold_free (hc);

r_list_foreach (fcn->bbs, iter, bb) {
if (bb->addr == UT64_MAX) {
continue;
}

char *u = get_title (bb->addr), *v = NULL;
if (bb->jump != UT64_MAX) {
v = get_title (bb->jump);
r_cons_printf ("age %s %s\n", u, v);
}
if (bb->fail != UT64_MAX) {
v = get_title (bb->fail);
r_cons_printf ("age %s %s\n", u, v);
}
if (bb->switch_op) {
RListIter *it;
RAnalCaseOp *cop;
r_list_foreach (bb->switch_op->cases, it, cop) {
v = get_title (cop->addr);
r_cons_printf ("age %s %s\n", u, v);
}
}
free (u);
free (v);
}
return true;
}

R_API int r_core_print_bb_gml(RCore *core, RAnalFunction *fcn) {
RAnalBlock *bb;
RListIter *iter;
if (!fcn) {
return false;
}

r_cons_printf ("graph\n[\n" "hierarchic 1\n" "label \"\"\n" "directed 1\n");

r_list_foreach (fcn->bbs, iter, bb) {
RFlagItem *flag = r_flag_get_i (core->flags, bb->addr);
char *msg = flag? strdup (flag->name): r_str_newf ("0x%08"PFMT64x, bb->addr);
r_cons_printf ("\tnode [\n"
"\t\tid\t%"PFMT64d"\n"
"\t\tlabel\t\"%s\"\n"
"\t]\n", bb->addr, msg);
}

r_list_foreach (fcn->bbs, iter, bb) {
if (bb->addr == UT64_MAX) {
continue;
}

if (bb->jump != UT64_MAX) {
r_cons_printf ("\tedge [\n"
"\t\tsource %"PFMT64d"\n"
"\t\ttarget %"PFMT64d"\n"
"\t]\n", bb->addr, bb->jump
);
}
if (bb->fail != UT64_MAX) {
r_cons_printf ("\tedge [\n"
"\t\tsource %"PFMT64d"\n"
"\t\ttarget %"PFMT64d"\n"
"\t]\n", bb->addr, bb->fail
);
}
if (bb->switch_op) {
RListIter *it;
RAnalCaseOp *cop;
r_list_foreach (bb->switch_op->cases, it, cop) {
r_cons_printf ("\tedge [\n"
"\t\tsource %"PFMT64d"\n"
"\t\ttarget %"PFMT64d"\n"
"\t]\n", bb->addr, cop->addr
);
}
}
}
return true;
}

R_API void r_core_anal_codexrefs(RCore *core, ut64 addr, int fmt) {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, addr, -1);
if (fcn) {
Expand Down
53 changes: 50 additions & 3 deletions libr/core/cmd_anal.c
Expand Up @@ -5776,14 +5776,61 @@ static void cmd_anal_graph(RCore *core, const char *input) {
switch (input[0]) {
case 'f': // "agf"
switch (input[1]) {
case 0:// "agf"
r_core_visual_graph (core, NULL, NULL, false);
break;
case 'v':// "agfv"
eprintf ("\rRendering graph...");
r_core_visual_graph (core, NULL, NULL, 1);
r_cons_show_cursor (true);
break;
case 't':// "agft" - tiny graph
r_core_visual_graph (core, NULL, NULL, 2);
break;
case 0:
r_core_visual_graph (core, NULL, NULL, false);
case 'd':// "agfd"
if (input[2] == 'm') {
r_core_anal_graph (core, r_num_math (core->num, input + 2),
R_CORE_ANAL_GRAPHLINES);
} else {
r_core_anal_graph (core, r_num_math (core->num, input + 1),
R_CORE_ANAL_GRAPHBODY);
}
break;
case 'j':// "agfj"
r_core_anal_graph (core, r_num_math (core->num, input + 1), R_CORE_ANAL_JSON);
break;
case 'J':// "agfJ"
r_core_anal_graph (core, r_num_math (core->num, input + 1),
R_CORE_ANAL_JSON | R_CORE_ANAL_JSON_FORMAT_DISASM);
case 'g':{// "agfg"
ut64 off_fcn = (*(input + 2)) ? r_num_math (core->num, input + 2) : core->offset;
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, off_fcn, 0);
r_core_print_bb_gml (core, fcn);
break;
}
case 'k':// "agfk"
r_core_cmd0 (core, "ag-; .agf*; aggk");
break;
case '*':{// "agf*"
ut64 off_fcn = (*(input + 2)) ? r_num_math (core->num, input + 2) : core->offset;
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, off_fcn, 0);
r_core_print_bb_custom (core, fcn);
break;
}
case 'w':// "agfw"
if (r_config_get_i (core->config, "graph.web")) {
r_core_cmd0 (core, "=H /graph/");
} else {
const char *cmd = r_config_get (core->config, "cmd.graph");
if (cmd && *cmd) {
r_core_cmd0 (core, cmd);
} else {
eprintf ("Command cmd.graph not valid\n");
}
}
break;
default:
eprintf ("Usage: agf or agft (for tiny)\n");
eprintf ("Usage: see ag?");
break;
}
break;
Expand Down
2 changes: 2 additions & 0 deletions libr/include/r_core.h
Expand Up @@ -417,6 +417,8 @@ R_API int r_core_anal_fcn_list(RCore *core, const char *input, const char *rad);
R_API int r_core_anal_fcn_list_size(RCore *core);
R_API void r_core_anal_fcn_labels(RCore *core, RAnalFunction *fcn, int rad);
R_API int r_core_anal_fcn_clean(RCore *core, ut64 addr);
R_API int r_core_print_bb_custom(RCore *core, RAnalFunction *fcn);
R_API int r_core_print_bb_gml(RCore *core, RAnalFunction *fcn);
R_API int r_core_anal_graph(RCore *core, ut64 addr, int opts);
R_API int r_core_anal_graph_fcn(RCore *core, char *input, int opts);
R_API RList* r_core_anal_graph_to(RCore *core, ut64 addr, int n);
Expand Down

0 comments on commit 94807b4

Please sign in to comment.