Skip to content

Commit

Permalink
Better webui, fix segfault in ag, add agj for json graphs
Browse files Browse the repository at this point in the history
More work on the webui
New 'agj' command to get function graphs in json
Fix segfault in 'ag' command
'agv' now launches the internal http server
Initial refactoring for RAnalHint integration into RCore
Add basic mime-type support in the http server
Enhace the graph view style
  • Loading branch information
radare committed Jan 24, 2013
1 parent 150c43d commit 1c93e8a
Show file tree
Hide file tree
Showing 33 changed files with 425 additions and 211 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Broken stuff to fixe before release

0.9.4
=====
* foldable stuff .. was in r1..redo?
* cmp rip+xx -> not resolved wtf
* search for CALL instructions in text segment.
- analyze the destination address of each call destination
Expand Down
71 changes: 62 additions & 9 deletions libr/core/anal.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ R_API void r_core_anal_hint_list (RAnal *a, int mode) {

static char *r_core_anal_graph_label(RCore *core, RAnalBlock *bb, int opts) {
int is_html = r_cons_singleton ()->is_html;
int is_json = opts & R_CORE_ANAL_JSON;
char cmd[1024], file[1024], *cmdstr = NULL, *filestr = NULL, *str = NULL;
int i, j, line = 0, oline = 0, idx = 0;
ut64 at;
Expand All @@ -67,14 +68,21 @@ static char *r_core_anal_graph_label(RCore *core, RAnalBlock *bb, int opts) {
cmdstr[idx] = 0;
// TODO: optimize all this strcat stuff
strcat (cmdstr, filestr);
strcat (cmdstr, "\\l");
if (is_json)
strcat (cmdstr, "\\n");
else
if (is_html)
strcat (cmdstr, "<br />");
else
strcat (cmdstr, "\\l");
idx += strlen (filestr);
free (filestr);
}
}
oline = line;
}
} else if (opts & R_CORE_ANAL_GRAPHBODY) {
r_cons_flush ();
snprintf (cmd, sizeof (cmd), "pD %"PFMT64d" @ 0x%08"PFMT64x"", bb->size, bb->addr);
cmdstr = r_core_cmd_str (core, cmd);
}
Expand All @@ -96,7 +104,7 @@ static char *r_core_anal_graph_label(RCore *core, RAnalBlock *bb, int opts) {
str[j] = cmdstr[i];
} else {
str[j] = '\\';
str[++j] = cmdstr[i]=='"'? '"': 'l';
str[++j] = cmdstr[i]=='"'? '"': ((is_json)?'n':'l');
}
break;
default:
Expand All @@ -111,13 +119,45 @@ static char *r_core_anal_graph_label(RCore *core, RAnalBlock *bb, int opts) {

static void r_core_anal_graph_nodes(RCore *core, RAnalFunction *fcn, int opts) {
int is_html = r_cons_singleton ()->is_html;
int is_json = opts & R_CORE_ANAL_JSON;
struct r_anal_bb_t *bbi;
RListIter *iter;
char *str;
int top = 0;
int left = 300;
int count = 0;

if (is_json) {
// TODO: show vars, refs and xrefs
r_cons_printf ("{\"name\":\"%s\"", fcn->name);
r_cons_printf (",\"offset\":%"PFMT64d, fcn->addr);
r_cons_printf (",\"ninstr\":%"PFMT64d, fcn->ninstr);
r_cons_printf (",\"nargs\":%"PFMT64d, fcn->nargs);
r_cons_printf (",\"size\":%d", fcn->size);
r_cons_printf (",\"stack\":%d", fcn->stack);
r_cons_printf (",\"type\":%d", fcn->type); // TODO: output string
//r_cons_printf (",\"cc\":%d", fcn->call); // TODO: calling convention
if (fcn->dsc) r_cons_printf (",\"signature\":\"%s\"", fcn->dsc);
r_cons_printf (",\"blocks\":[");
}
r_list_foreach (fcn->bbs, iter, bbi) {
count ++;
if (is_json) {
if (count>1)
r_cons_printf (",");
r_cons_printf ("{\"offset\":%"PFMT64d",\"size\":%"PFMT64d, bbi->addr, bbi->size);
if (bbi->jump != -1)
r_cons_printf (",\"jump\":%"PFMT64d, bbi->jump);
if (bbi->fail != -1)
r_cons_printf (",\"fail\":%"PFMT64d, bbi->fail);
if ((str = r_core_anal_graph_label (core, bbi, opts))) {
str = r_str_replace (str, "\\ ", "\\\\ ", 1);
r_cons_printf (",\"code\":\"%s\"", str);
free (str);
}
r_cons_printf ("}");
continue;
}
if (bbi->jump != -1) {
if (is_html) {
r_cons_printf ("<div class=\"connector _0x%08"PFMT64x" _0x%08"PFMT64x"\">\n"
Expand All @@ -131,7 +171,7 @@ static void r_core_anal_graph_nodes(RCore *core, RAnalFunction *fcn, int opts) {
if (bbi->fail != -1) {
if (is_html) {
r_cons_printf ("<div class=\"connector _0x%08"PFMT64x" _0x%08"PFMT64x"\">\n"
" <img class=\"connector-end\" src=\"img/arrow.gif\" /></div>\n",
" <img class=\"connector-end\" src=\"img/arrow.gif\"/></div>\n",
bbi->addr, bbi->fail);
} else r_cons_printf ("\t\"0x%08"PFMT64x"_0x%08"PFMT64x"\" -> \"0x%08"PFMT64x"_0x%08"PFMT64x"\" "
"[color=\"red\"];\n", fcn->addr, bbi->addr, fcn->addr, bbi->fail);
Expand All @@ -147,7 +187,7 @@ static void r_core_anal_graph_nodes(RCore *core, RAnalFunction *fcn, int opts) {
fcn->name, bbi->addr);
} else {
if (is_html) {
r_cons_printf ("<p class=\"block draggable\" style=\"top: %dpx; left: %dpx; width: 500px;\" id=\"_0x%08"PFMT64x"\">\n"
r_cons_printf ("<p class=\"block draggable\" style=\"top: %dpx; left: %dpx; width: 400px;\" id=\"_0x%08"PFMT64x"\">\n"
"%s</p>\n", top, left, bbi->addr, str);
left = left? 0: 600;
if (!left) top += 250;
Expand All @@ -162,6 +202,8 @@ static void r_core_anal_graph_nodes(RCore *core, RAnalFunction *fcn, int opts) {
free (str);
}
}
if (is_json)
r_cons_printf ("]}");
}

R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head) {
Expand Down Expand Up @@ -704,11 +746,14 @@ R_API RList* r_core_anal_graph_to(RCore *core, ut64 addr, int n) {

R_API int r_core_anal_graph(RCore *core, ut64 addr, int opts) {
const char *font = r_config_get (core->config, "graph.font");
int count = 0;
int is_html = r_cons_singleton ()->is_html;
int is_json = opts & R_CORE_ANAL_JSON;
int reflines, bytes, dwarf;
RAnalFunction *fcni;
RListIter *iter;

opts|=R_CORE_ANAL_GRAPHBODY;
if (r_list_empty (core->anal->fcns))
return R_FALSE;

Expand All @@ -718,17 +763,25 @@ R_API int r_core_anal_graph(RCore *core, ut64 addr, int opts) {
r_config_set_i (core->config, "asm.lines", 0);
r_config_set_i (core->config, "asm.bytes", 0);
r_config_set_i (core->config, "asm.dwarf", 0);
if (!is_html)
if (!is_html && !is_json)
r_cons_printf ("digraph code {\n"
"\tgraph [bgcolor=white];\n"
"\tnode [color=lightgray, style=filled shape=box"
" fontname=\"%s\" fontsize=\"8\"];\n", font);
if (is_json) {
r_cons_printf ("[");
}
r_cons_flush ();
r_list_foreach (core->anal->fcns, iter, fcni)
if (fcni->type & (R_ANAL_FCN_TYPE_SYM | R_ANAL_FCN_TYPE_FCN) &&
(addr == 0 || addr == fcni->addr))
r_list_foreach (core->anal->fcns, iter, fcni) {
if (fcni->type & (R_ANAL_FCN_TYPE_SYM | R_ANAL_FCN_TYPE_FCN)
&& (addr == 0 || addr == fcni->addr)) {
if (is_json && count++>0) r_cons_printf (",");
r_core_anal_graph_nodes (core, fcni, opts);
if (!is_html) r_cons_printf ("}\n");
}
}
if (!is_html && !is_json) r_cons_printf ("}\n");
if (is_json)
r_cons_printf ("]\n");
r_cons_flush ();
r_config_set_i (core->config, "asm.lines", reflines);
r_config_set_i (core->config, "asm.bytes", bytes);
Expand Down
6 changes: 4 additions & 2 deletions libr/core/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,10 @@ static int cmd_rap(void *data, const char *input) {
RCore *core = (RCore *)data;
switch (*input) {
case '\0': r_core_rtr_list (core); break;
case 'h': r_core_rtr_http (core, 0); break;
case 'H': r_core_rtr_http (core, 1); break;
case 'h': r_core_rtr_http (core, 0, NULL); break;
case 'H':
while (input[1]==' ') input++;
r_core_rtr_http (core, 1, input+1); break;
case '?': r_core_rtr_help (core); break;
case '+': r_core_rtr_add (core, input+1); break;
case '-': r_core_rtr_remove (core, input+1); break;
Expand Down
6 changes: 6 additions & 0 deletions libr/core/cmd_anal.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,9 @@ static int cmd_anal(void *data, const char *input) {
case 'c':
r_core_anal_refs (core, r_num_math (core->num, input+2), input[2]=='j'? 2: 1);
break;
case 'j':
r_core_anal_graph (core, r_num_math (core->num, input+2), R_CORE_ANAL_JSON);
break;
case 'l':
r_core_anal_graph (core, r_num_math (core->num, input+2), R_CORE_ANAL_GRAPHLINES);
break;
Expand All @@ -601,6 +604,8 @@ static int cmd_anal(void *data, const char *input) {
R_CORE_ANAL_GRAPHBODY|R_CORE_ANAL_GRAPHDIFF);
break;
case 'v':
r_core_cmd0 (core, "=H /graph/");
#if 0
{
int is_html = (r_config_get_i (core->config, "scr.html"));
const char *cmd = r_config_get (core->config, "cmd.graph");
Expand All @@ -622,6 +627,7 @@ static int cmd_anal(void *data, const char *input) {
r_core_cmdf (core, "%s", cmd);
free (tmp);
}
#endif
break;
case '?':
r_cons_printf (
Expand Down
81 changes: 49 additions & 32 deletions libr/core/disasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,40 @@

#include "r_core.h"

R_API RAnalHint *r_core_hint_begin (RCore *core, RAnalHint* hint, ut64 at) {
// XXX not here
static char *hint_arch = NULL;
static int hint_bits = 0;
if (hint) {
r_anal_hint_free (hint);
hint = NULL;
}
hint = r_anal_hint_get (core->anal, at);
if (hint_arch) {
r_config_set (core->config, "asm.arch", hint_arch);
hint_arch = NULL;
}
if (hint_bits) {
r_config_set_i (core->config, "asm.bits", hint_bits);
hint_bits = 0;
}
if (hint) {
/* arch */
if (hint->arch) {
if (!hint_arch) hint_arch = strdup (
r_config_get (core->config, "asm.arch"));
r_config_set (core->config, "asm.arch", hint->arch);
}
/* bits */
if (hint->bits) {
if (!hint_bits) hint_bits =
r_config_get_i (core->config, "asm.bits");
r_config_set_i (core->config, "asm.bits", hint->bits);
}
}
return hint;
}

static char *filter_refline(const char *str) {
char *p, *s = strdup (str);
p = strstr (s, "->");
Expand Down Expand Up @@ -36,8 +70,6 @@ static void printoffset(ut64 off, int show_color, int invert, int opt) {
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int l, int invbreak, int cbytes) {
/* hints */
RAnalHint *hint = NULL;
char *hint_arch = NULL;
int hint_bits = 0;
/* other */
int ret, idx = 0, i, j, k, lines, ostackptr = 0, stackptr = 0;
char *line = NULL, *comment = NULL, *opstr, *osl = NULL; // old source line
Expand Down Expand Up @@ -175,35 +207,10 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
oplen = 1;
for (i=idx=ret=0; idx < len && lines < l; idx+=oplen,i++, lines++) {
ut64 at = addr + idx;
if (hint) {
r_anal_hint_free (hint);
hint = NULL;
}
hint = r_anal_hint_get (core->anal, at);

hint = r_core_hint_begin (core, hint, at);
if (cbytes && idx>=l)
break;
if (hint_arch) {
r_config_set (core->config, "asm.arch", hint_arch);
hint_arch = NULL;
}
if (hint_bits) {
r_config_set_i (core->config, "asm.bits", hint_bits);
hint_bits = 0;
}
if (hint) {
/* arch */
if (hint->arch) {
if (!hint_arch) hint_arch = strdup (
r_config_get (core->config, "asm.arch"));
r_config_set (core->config, "asm.arch", hint->arch);
}
/* bits */
if (hint->bits) {
if (!hint_bits) hint_bits =
r_config_get_i (core->config, "asm.bits");
r_config_set_i (core->config, "asm.bits", hint->bits);
}
}
r_asm_set_pc (core->assembler, at);
if (show_lines) {
line = r_anal_reflines_str (core->anal,
Expand Down Expand Up @@ -700,7 +707,7 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
RFlagItem *flag = r_flag_get_at (core->flags, cc.jump);
if (show_color)
r_cons_printf ("\n%s%s "Color_TURQOISE"; %s (%s+%d)"Color_RESET,
f?pre:"", refline, ccstr, flag? flag->name: "", f? cc.jump-flag->offset: 0);
f?pre:"", refline, ccstr, flag? flag->name: "", (f&&flag)? cc.jump-flag->offset: 0);
else r_cons_printf ("\n%s%s ; %s (%s+%d)",
pre, refline, ccstr,
flag?flag->name:"", flag? cc.jump-flag->offset: 0);
Expand Down Expand Up @@ -876,14 +883,22 @@ R_API int r_core_print_disasm_instructions (RCore *core, int len, int l) {
const ut8 *buf = core->block;
int bs = core->blocksize;
RAnalOp analop = {0};
RAnalHint *hint = NULL;
int decode = r_config_get_i (core->config, "asm.decode");
ut64 at;

// TODO: add support for anal hints
if (len>core->blocksize)
r_core_block_size (core, len);
if (l==0) l = len;
for (i=j=0; i<bs && i<len && j<len; i+=ret, j++) {
r_asm_set_pc (core->assembler, core->offset+i);
at = core->offset +i;
if (hint) {
r_anal_hint_free (hint);
hint = NULL;
}
hint = r_core_hint_begin (core, hint, at);
r_asm_set_pc (core->assembler, at);
ret = r_asm_disassemble (core->assembler,
&asmop, buf+i, core->blocksize-i);
//r_cons_printf ("0x%08"PFMT64x" ", core->offset+i);
Expand All @@ -893,7 +908,7 @@ R_API int r_core_print_disasm_instructions (RCore *core, int len, int l) {
} else {
if (decode) {
char *tmpopstr, *opstr;
r_anal_op (core->anal, &analop, core->offset+i,
r_anal_op (core->anal, &analop, at,
buf+i, core->blocksize-i);
tmpopstr = r_anal_op_to_string (core->anal, &analop);
opstr = (tmpopstr)? tmpopstr: strdup (asmop.buf_asm);
Expand All @@ -902,4 +917,6 @@ R_API int r_core_print_disasm_instructions (RCore *core, int len, int l) {
} else r_cons_printf ("%s\n", asmop.buf_asm);
}
}
if (hint) r_anal_hint_free (hint);
return 0;
}
12 changes: 8 additions & 4 deletions libr/core/rtr.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ SECURITY IMPLICATIONS
- follow symlinks
#endif

R_API int r_core_rtr_http(RCore *core, int launch) {
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) {
RSocketHTTPRequest *rs;
int oldsandbox = -1;
int timeout = r_config_get_i (core->config, "http.timeout");
Expand All @@ -58,8 +58,8 @@ R_API int r_core_rtr_http(RCore *core, int launch) {
if (launch) {
char cmd[128];
const char *browser = r_config_get (core->config, "http.browser");
snprintf (cmd, sizeof (cmd), "%s http://localhost:%d/",
browser, atoi (port));
snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s",
browser, atoi (port), path?path:"");
r_sys_cmd (cmd);
}
r_config_set (core->config, "asm.cmtright", "false");
Expand Down Expand Up @@ -162,7 +162,11 @@ R_API int r_core_rtr_http(RCore *core, int launch) {
int sz = 0;
char *f = r_file_slurp (path, &sz);
if (f) {
r_socket_http_response (rs, 200, f, sz, NULL);
const char *contenttype = NULL;
if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n";
if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n";
if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n";
r_socket_http_response (rs, 200, f, sz, contenttype);
free (f);
} else {
r_socket_http_response (rs, 403, "Permission denied", 0, NULL);
Expand Down
3 changes: 2 additions & 1 deletion libr/include/r_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define R_CORE_ANAL_GRAPHLINES 0x1
#define R_CORE_ANAL_GRAPHBODY 0x2
#define R_CORE_ANAL_GRAPHDIFF 0x4
#define R_CORE_ANAL_JSON 0x8

/* rtr */
#define RTR_PROT_RAP 0
Expand Down Expand Up @@ -293,7 +294,7 @@ R_API void r_core_rtr_add(RCore *core, const char *input);
R_API void r_core_rtr_remove(RCore *core, const char *input);
R_API void r_core_rtr_session(RCore *core, const char *input);
R_API void r_core_rtr_cmd(RCore *core, const char *input);
R_API int r_core_rtr_http(RCore *core, int launch);
R_API int r_core_rtr_http(RCore *core, int launch, const char *path);

R_API void r_core_visual_define (RCore *core);
R_API void r_core_visual_config (RCore *core);
Expand Down
Loading

0 comments on commit 1c93e8a

Please sign in to comment.