diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index aebb7a9cb8..b8b362477e 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -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;