Add aar command to search xrefs in code

- Ignore references to sections with vaddr=0
- Skip overlapping instructions in xref search
- Improve debugger mode support of `axa`
- Remove unused cmd variable
This commit is contained in:
deffi420 2015-07-11 07:53:58 +03:00 committed by pancake
parent 8ff870be8e
commit 9d92712cea
4 changed files with 206 additions and 1 deletions

View File

@ -1568,6 +1568,144 @@ R_API int r_core_anal_search(RCore *core, ut64 from, ut64 to, ut64 ref) {
return count;
}
R_API int r_core_anal_search_xrefs(RCore *core, ut64 from, ut64 to, int rad) {
ut8 *buf;
ut64 at;
int count = 0;
RAnalOp op = {0};
if (from >= to) {
eprintf ("Invalid range (from >= to)\n");
return -1;
}
if (core->blocksize <= OPSZ) {
eprintf ("Error: block size too small\n");
return -1;
}
buf = (ut8 *)malloc (core->blocksize);
if (!buf) {
eprintf ("Error: cannot allocate a block\n");
return -1;
}
if (rad == 'j')
r_cons_printf ("{");
r_io_use_desc (core->io, core->file->desc);
r_cons_break (NULL, NULL);
at = from;
while (at < to && !r_cons_singleton ()->breaked) {
int i, ret;
ret = r_io_read_at (core->io, at, buf, core->blocksize);
if (ret != core->blocksize && at+ret-OPSZ < to)
break;
i = 0;
while (at+i < to && i < ret-OPSZ) {
RAnalRefType type;
ut64 xref_from, xref_to;
xref_from = at+i;
r_anal_op_fini (&op);
ret = r_anal_op (core->anal, &op, at+i, buf+i, core->blocksize-i);
i += (ret > 0) ? ret : 1;
if (ret <= 0 || at+i > to)
continue;
// Get reference type and target address
type = R_ANAL_REF_TYPE_NULL;
switch (op.type) {
case R_ANAL_OP_TYPE_JMP:
case R_ANAL_OP_TYPE_CJMP:
type = R_ANAL_REF_TYPE_CODE;
xref_to = op.jump;
break;
case R_ANAL_OP_TYPE_CALL:
case R_ANAL_OP_TYPE_CCALL:
type = R_ANAL_REF_TYPE_CALL;
xref_to = op.jump;
break;
case R_ANAL_OP_TYPE_UJMP:
case R_ANAL_OP_TYPE_UCJMP:
type = R_ANAL_REF_TYPE_CODE;
xref_to = op.ptr;
break;
case R_ANAL_OP_TYPE_UCALL:
case R_ANAL_OP_TYPE_UCCALL:
type = R_ANAL_REF_TYPE_CALL;
xref_to = op.ptr;
break;
default:
if (op.ptr != -1) {
type = R_ANAL_REF_TYPE_DATA;
xref_to = op.ptr;
}
break;
}
// Validate the reference. If virtual addressing is enabled, we
// allow only references to virtual addresses in order to reduce
// the number of false positives. In debugger mode, the reference
// must point to a mapped memory region.
if (type == R_ANAL_REF_TYPE_NULL)
continue;
if (!r_core_is_valid_offset (core, xref_to))
continue;
if (r_config_get_i (core->config, "cfg.debug")) {
if (!r_debug_map_get (core->dbg, xref_to))
continue;
} else if (core->io->va) {
RListIter *iter;
RIOSection *s;
r_list_foreach (core->io->sections, iter, s) {
if (xref_to >= s->vaddr && xref_to < s->vaddr + s->vsize) {
if (s->vaddr != 0)
break;
}
}
if (!iter)
continue;
}
if (!rad) {
// Add to SDB
r_anal_xrefs_set (core->anal, type, xref_from, xref_to);
} else if (rad == 'j') {
// Output JSON
if (count > 0) r_cons_printf (",");
r_cons_printf ("%"PFMT64d":%"PFMT64d, xref_to, xref_from);
} else {
// Display in radare commands format
char *cmd;
switch (type) {
case R_ANAL_REF_TYPE_CODE: cmd = "axc"; break;
case R_ANAL_REF_TYPE_CALL: cmd = "axC"; break;
case R_ANAL_REF_TYPE_DATA: cmd = "axd"; break;
default: cmd = "ax"; break;
}
r_cons_printf ("%s 0x%08"PFMT64x" 0x%08"PFMT64x"\n",
cmd, xref_to, xref_from);
}
count++;
}
at += i;
}
r_cons_break_end ();
free (buf);
r_anal_op_fini (&op);
if (rad == 'j')
r_cons_printf ("}\n");
return count;
}
R_API int r_core_anal_ref_list(RCore *core, int rad) {
r_anal_xrefs_list (core->anal, rad);
return 0;

View File

@ -2610,6 +2610,7 @@ static int cmd_anal(void *data, const char *input) {
"aa*", "", "analyze all flags starting with sym. (af @@ sym.*)",
"aaa", "", "autoname functions after aa (see afna)",
"aac", " [len]", "analyze function calls (af @@ `pi len~call[1]`)",
"aar", " [len]", "analyze len bytes of instructions for references",
"aas", " [len]", "analyze symbols (af @@= `isq~[0]`)",
"aap", "", "find and analyze function preludes",
NULL};
@ -2706,6 +2707,71 @@ static int cmd_anal(void *data, const char *input) {
if (input[1] == 'a') // "aaa"
r_core_cmd0 (core, ".afna @@ fcn.*"); break; // "aaa"
break;
case 'r':
{
ut64 from, to;
char *ptr;
int rad, n;
const char* help_msg_aar[] = {
"Usage:", "aar", "[j*] [sz] # search and analyze xrefs",
"aar", " [sz]", "analyze xrefs in current section or sz bytes of code",
"aarj", " [sz]", "list found xrefs in JSON format",
"aar*", " [sz]", "list found xrefs in radare commands format",
NULL};
if (input[2] == '?') {
r_core_cmd_help (core, help_msg_aar);
break;
}
if (input[2] == 'j' || input[2] == '*') {
rad = input[2];
input++;
} else rad = 0;
from = to = 0;
ptr = strdup (r_str_trim_head ((char*)input+2));
n = r_str_word_set0 (ptr);
if (n == 0) {
int rwx = R_IO_EXEC;
// get boundaries of current memory map, section or io map
if (r_config_get_i (core->config, "cfg.debug")) {
RDebugMap *map = r_debug_map_get (core->dbg, core->offset);
if (map) {
from = map->addr;
to = map->addr_end;
rwx = map->perm;
}
} else if (core->io->va) {
RIOSection *section = r_io_section_vget (core->io, core->offset);
if (section) {
from = section->vaddr;
to = section->vaddr + section->vsize;
rwx = section->rwx;
}
} else {
RIOMap *map = r_io_map_get (core->io, core->offset);
from = core->offset;
to = r_io_size (core->io) + (map? map->to:0);
}
if (from == 0 && to == 0)
eprintf ("Cannot determine xref search boundaries\n");
else if (!(rwx & R_IO_EXEC))
eprintf ("Warning: Searching xrefs in non-executable region\n");
} else if (n == 1) {
from = core->offset;
to = core->offset + r_num_math (core->num, r_str_word_get0 (ptr, 0));
} else {
eprintf ("Invalid number of arguments\n");
}
free (ptr);
if (from == 0 && to == 0)
return R_FALSE;
r_core_anal_search_xrefs (core, from, to, rad);
}
break;
default: r_core_cmd_help (core, help_msg_aa); break;
}
break;

View File

@ -1936,7 +1936,7 @@ static void agraph_init(RAGraph *g) {
g->graph = r_graph_new ();
g->nodes = sdb_new0 ();
g->zoom = ZOOM_DEFAULT;
g->movspeed = r_config_get_i (g->core->config, "graph.scroll");
g->movspeed = DEFAULT_SPEED; //r_config_get_i (g->core->config, "graph.scroll");
}
R_API void r_agraph_print (RAGraph *g) {

View File

@ -295,6 +295,7 @@ R_API ut64 r_core_anal_address (RCore *core, ut64 addr);
R_API void r_core_anal_undefine (RCore *core, ut64 off);
R_API void r_core_anal_hint_list (RAnal *a, int mode);
R_API int r_core_anal_search(RCore *core, ut64 from, ut64 to, ut64 ref);
R_API int r_core_anal_search_xrefs(RCore *core, ut64 from, ut64 to, int rad);
R_API int r_core_anal_data (RCore *core, ut64 addr, int count, int depth);
R_API void r_core_anal_refs(RCore *core, ut64 addr, int gv);
R_API int r_core_anal_bb(RCore *core, RAnalFunction *fcn, ut64 at, int head);