Implement axgj

* Added axgj option in the ax help menu
* Added an opts field for anal_axg in order to allow json output
* Added an if case for axg (allows json output)
* Added some checks for the json output from axg in order to have a correct json object
This commit is contained in:
redmed666 2018-03-01 10:50:56 +01:00 committed by radare
parent 6b36d7773b
commit 2b9c554724

View File

@ -554,6 +554,7 @@ static const char *help_msg_ax[] = {
"axc", " addr [at]", "add code jmp ref // unused?",
"axC", " addr [at]", "add code call ref",
"axg", " [addr]", "show xrefs graph to reach current function",
"axgj", " [addr]", "show xrefs graph to reach current function in json format",
"axd", " addr [at]", "add data ref",
"axq", "", "list refs in quiet/human-readable format",
"axj", "", "list refs in json format",
@ -4897,12 +4898,13 @@ static void cmd_anal_syscall(RCore *core, const char *input) {
}
}
static void anal_axg (RCore *core, const char *input, int level, Sdb *db) {
static void anal_axg (RCore *core, const char *input, int level, Sdb *db, int opts) {
char arg[32], pre[128];
RList *xrefs;
RListIter *iter;
RAnalRef *ref;
ut64 addr = core->offset;
int is_json = opts & R_CORE_ANAL_JSON;
if (input && *input) {
addr = r_num_math (core->num, input);
}
@ -4917,31 +4919,78 @@ static void anal_axg (RCore *core, const char *input, int level, Sdb *db) {
if (!r_list_empty (xrefs)) {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, addr, -1);
if (fcn) {
//if (sdb_add (db, fcn->name, "1", 0)) {
if (is_json) {
r_cons_printf ("{\"%"PFMT64d"\":{\"type\":\"fcn\","
"\"fcn_addr\":%"PFMT64d",\"name\":\"%s\",\"refs\":[",
addr, fcn->addr, fcn->name);
} else {
//if (sdb_add (db, fcn->name, "1", 0)) {
r_cons_printf ("%s0x%08"PFMT64x" fcn 0x%08"PFMT64x" %s\n",
pre + 2, addr, fcn->addr, fcn->name);
//}
//}
}
} else {
if (is_json) {
r_cons_printf ("{\"%"PFMT64d"\":{\"refs\":[", addr);
} else {
//snprintf (arg, sizeof (arg), "0x%08"PFMT64x, addr);
//if (sdb_add (db, arg, "1", 0)) {
r_cons_printf ("%s0x%08"PFMT64x"\n", pre+2, addr);
//}
}
}
}
r_list_foreach (xrefs, iter, ref) {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, ref->addr, -1);
if (fcn) {
r_cons_printf ("%s0x%08"PFMT64x" fcn 0x%08"PFMT64x" %s\n", pre, ref->addr, fcn->addr, fcn->name);
if (is_json) {
if (level == 0) {
r_cons_printf ("{\"%"PFMT64d"\":{\"type\":\"fcn\",\"fcn_addr\": %"PFMT64d",\"name\":\"%s\",\"refs\":[", ref->addr, fcn->addr, fcn->name);
} else {
r_cons_printf ("]}},{\"%"PFMT64d"\":{\"type\":\"fcn\",\"fcn_addr\": %"PFMT64d",\"name\":\"%s\",\"refs\":[", ref->addr, fcn->addr, fcn->name);
}
} else {
r_cons_printf ("%s0x%08"PFMT64x" fcn 0x%08"PFMT64x" %s\n", pre, ref->addr, fcn->addr, fcn->name);
}
if (sdb_add (db, fcn->name, "1", 0)) {
snprintf (arg, sizeof (arg), "0x%08"PFMT64x, fcn->addr);
anal_axg (core, arg, level+1, db);
anal_axg (core, arg, level+1, db, opts);
} else {
if (is_json) {
r_cons_printf("]}}");
}
}
if (is_json) {
if (iter->n) {
r_cons_printf (",");
}
}
} else {
r_cons_printf ("%s0x%08"PFMT64x" ???\n", pre, ref->addr);
if (is_json) {
r_cons_printf ("{\"%"PFMT64d"\":{\"type\":\"???\",\"refs\":[", ref->addr);
} else {
r_cons_printf ("%s0x%08"PFMT64x" ???\n", pre, ref->addr);
}
snprintf (arg, sizeof (arg), "0x%08"PFMT64x, ref->addr);
if (sdb_add (db, arg, "1", 0)) {
anal_axg (core, arg, level +1, db);
anal_axg (core, arg, level +1, db, opts);
} else {
if (is_json) {
r_cons_printf("]}}");
}
}
if (is_json) {
if (iter->n) {
r_cons_printf (",");
}
}
}
}
if (is_json) {
r_cons_printf("]}}");
if (level == 0) {
r_cons_printf("\n");
}
}
r_list_free (xrefs);
@ -4999,7 +5048,11 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
case 'g': // "axg"
{
Sdb *db = sdb_new0 ();
anal_axg (core, input[1] ? input + 2 : NULL, 0, db);
if(input[1] == '\0') {
anal_axg (core, input[1] ? input + 2 : NULL, 0, db, 0);
} else if(input[1] == 'j') {
anal_axg (core, input[1] ? input + 2 : NULL, 0, db, R_CORE_ANAL_JSON);
}
sdb_free (db);
}
break;