Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support every output format for the bb graph (agf) #10030

Merged
merged 3 commits into from May 7, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
124 changes: 124 additions & 0 deletions libr/core/canal.c
Expand Up @@ -1579,6 +1579,130 @@ 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, strlen(body));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space before = and before (. if you use -1 in the length argument, the bsae64 api will do the strlen for you

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if any of those variables are null, following lines will make it crash

body_b64 = r_str_prefix (body_b64, "base64:");

r_cons_printf ("agn \"%s\" \"%s\"\n", title, body_b64);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quotes dont work like this in r2land


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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quotes dont work like this in r2land, remove them

}
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\t1\n" "label\t\"\"\n" "directed\t1\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use spaces intead of tabs here? or graphviz will not work? it is better to not print tabs to stdout in r2 commands to avoid problems in visual and such, even if its not suposed to be printed


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
68 changes: 65 additions & 3 deletions libr/core/cmd_anal.c
Expand Up @@ -5776,14 +5776,76 @@ 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);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else goes here , in the same line of the }

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"
if (input[2] == 'f') {
//TODO
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uh

}
RAnalFunction *fcn = NULL;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ternary operator instead of assigning to null and such. also the only thing that changes is the off_fcn, so you dont need to copy the r_anal-get_fcn_in call twice

if (*(input + 2)) {
ut64 off_fcn = r_num_math (core->num, input + 2);
fcn = r_anal_get_fcn_in (core->anal, off_fcn, 0);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as before (else in this line, use ternary operator and avoid dupped call when only 1 arg changes)

else {
fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
}
r_core_print_bb_gml (core, fcn);
break;
case 'k':// "agfk"
r_core_cmd0 (core, "ag-; .agf*; aggk");
break;
case '*':{// "agf*"
RAnalFunction *fcn = NULL;
if (*(input + 2)) {
ut64 off_fcn = r_num_math (core->num, input + 2);
fcn = r_anal_get_fcn_in (core->anal, off_fcn, 0);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

else {
fcn = r_anal_get_fcn_in (core->anal, core->offset, 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