Fix slow ELF loading and add anal hints support to projects

Fix slow ELF loading when shstr section was huge
Added 'ahj' command to list anal hints in json
Add 'ah*' and use it from r_core_project
Fix 'i*' command
This commit is contained in:
pancake 2013-01-22 18:08:33 +01:00
parent fc9301b14b
commit 2365918652
13 changed files with 128 additions and 90 deletions

View File

@ -122,3 +122,4 @@ use rarun2 to launch your programs with a predefined environment
You are probably using an old version of r2, go checkout the git!
Run your own r2 scripts in awk using the r2awk program
I love gradients
Use -e bin.strings=false to disable search for strings when loading the binary

0
doc/idc2rdb.pl Executable file → Normal file
View File

View File

@ -13,26 +13,6 @@ R_API void r_anal_hint_del (RAnal *a, ut64 addr) {
if (hint) r_list_delete_data (a->hints, hint);
}
R_API void r_anal_hint_list (RAnal *a, int mode) {
RAnalHint *hint;
RListIter *iter;
// TODO: move into r_Core, show rad output mode too
r_list_foreach (a->hints, iter, hint) {
eprintf (" 0x%08"PFMT64x" - 0x%08"PFMT64x, hint->from, hint->to);
if (hint->arch)
eprintf (" arch='%s'", hint->arch);
if (hint->bits)
eprintf (" bits=%d", hint->bits);
if (hint->length)
eprintf (" length=%d", hint->length);
if (hint->opcode)
eprintf (" opcode='%s'", hint->opcode);
if (hint->analstr)
eprintf (" analstr='%s'", hint->analstr);
eprintf ("\n");
}
}
R_API void r_anal_hint_set_arch (RAnal *a, ut64 addr, int size, const char *arch) {
RAnalHint *hint = r_anal_hint_add (a, addr, size);
free (hint->arch);

View File

@ -556,9 +556,12 @@ int Elf_(r_bin_elf_get_bits)(struct Elf_(r_bin_elf_obj_t) *bin) {
}
static inline int needle(struct Elf_(r_bin_elf_obj_t) *bin, const char *s) {
if (bin->shstrtab)
return r_mem_mem ((const ut8*)bin->shstrtab, bin->shstrtab_size,
if (bin->shstrtab) {
int len = bin->shstrtab_size;
if (len > 4096) len = 4096; // avoid slow loading .. can be buggy?
return r_mem_mem ((const ut8*)bin->shstrtab, len,
(const ut8*)s, strlen (s)) != NULL;
}
return 0;
}

View File

@ -1,10 +1,49 @@
/* radare - LGPL - Copyright 2009-2012 - pancake, nibble */
/* radare - LGPL - Copyright 2009-2013 - pancake, nibble */
#include <r_types.h>
#include <r_list.h>
#include <r_flags.h>
#include <r_core.h>
R_API void r_core_anal_hint_list (RAnal *a, int mode) {
int count = 0;
RAnalHint *hint;
RListIter *iter;
if (mode == 'j') r_cons_printf ("[");
// TODO: support ranged hints!
r_list_foreach (a->hints, iter, hint) {
switch (mode) {
case '*':
if (hint->arch) r_cons_printf ("aha %s @ 0x%"PFMT64x"\n", hint->arch, hint->from);
if (hint->bits) r_cons_printf ("ahb %d @ 0x%"PFMT64x"\n", hint->bits, hint->from);
if (hint->length) r_cons_printf ("ahl %d @ 0x%"PFMT64x"\n", hint->length, hint->from);
if (hint->opcode) r_cons_printf ("aho %s @ 0x%"PFMT64x"\n", hint->opcode, hint->from);
if (hint->analstr) r_cons_printf ("ahA %s @ 0x%"PFMT64x"\n", hint->analstr, hint->from);
break;
case 'j':
r_cons_printf ("%s{\"from\":%"PFMT64d",\"to\":%"PFMT64d,
count>0?",":"", hint->from, hint->to);
if (hint->arch) r_cons_printf (",\"arch\":\"%s\"", hint->arch); // XXX: arch must not contain strange chars
if (hint->bits) r_cons_printf (",\"bits\":%d", hint->bits);
if (hint->length) r_cons_printf (",\"length\":%d", hint->length);
if (hint->opcode) r_cons_printf (",\"opcode\":\"%s\"", hint->opcode);
if (hint->analstr) r_cons_printf (",\"analstr\":\"%s\"", hint->analstr);
r_cons_printf ("}");
break;
default:
r_cons_printf (" 0x%08"PFMT64x" - 0x%08"PFMT64x, hint->from, hint->to);
if (hint->arch) r_cons_printf (" arch='%s'", hint->arch);
if (hint->bits) r_cons_printf (" bits=%d", hint->bits);
if (hint->length) r_cons_printf (" length=%d", hint->length);
if (hint->opcode) r_cons_printf (" opcode='%s'", hint->opcode);
if (hint->analstr) r_cons_printf (" analstr='%s'", hint->analstr);
r_cons_printf ("\n");
}
count++;
}
if (mode == 'j') r_cons_printf ("]\n");
}
static char *r_core_anal_graph_label(RCore *core, RAnalBlock *bb, int opts) {
int is_html = r_cons_singleton ()->is_html;
char cmd[1024], file[1024], *cmdstr = NULL, *filestr = NULL, *str = NULL;

View File

@ -238,15 +238,15 @@ static int cmd_anal(void *data, const char *input) {
#if 1
switch (input[0]) {
case 'o':
if (input[0] && input[1]) {
l = (int) r_num_get (core->num, input+2);
if (l>0) len = l;
if (l>tbs) {
r_core_block_size (core, l);
len = l;
}
} else len = l = core->blocksize;
case 'o':
if (input[0] && input[1]) {
l = (int) r_num_get (core->num, input+2);
if (l>0) len = l;
if (l>tbs) {
r_core_block_size (core, l);
len = l;
}
} else len = l = core->blocksize;
}
#endif
r_cons_break (NULL, NULL);
@ -861,7 +861,10 @@ case 'o':
} else
r_cons_printf (
"Usage: ah[lba-]\n"
" ah? # show this help\n"
" ah? offset # show hint of given offset\n"
" ah # list hints in human-readable format\n"
" ah* offset # list hints in radare commands format\n"
" aha ppc 51 # set arch for a range of N bytes\n"
" ahb 16 @ $$ # force 16bit for current instruction\n"
" ahl 4 32 # set opcode size=4 for range of 32 bytes\n"
@ -916,8 +919,9 @@ R_API int r_core_hint(RCore *core, ut64 addr) {
break;
#endif
case '*':
case 'j':
case '\0':
r_anal_hint_list (core->anal, input[1]);
r_core_anal_hint_list (core->anal, input[1]);
break;
case '-':
if (input[2]) {

View File

@ -6,6 +6,8 @@ static void r_core_file_info (RCore *core, int mode) {
RBinInfo *info = r_bin_get_info (core->bin);
if (mode == R_CORE_BIN_JSON)
r_cons_printf ("{");
if (mode == R_CORE_BIN_RADARE)
return;
if (info) {
fn = info->file;
switch (mode) {

View File

@ -210,38 +210,8 @@ static int cmd_print(void *data, const char *input) {
} else eprintf ("ERROR: Cannot malloc %d bytes\n", size);
}
break;
case 'i': {
RAsmOp asmop;
int j, ret, err = 0;
const ut8 *buf = core->block;
int bs = core->blocksize;
RAnalOp analop = {0};
int decode = r_config_get_i (core->config, "asm.decode");
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);
ret = r_asm_disassemble (core->assembler,
&asmop, buf+i, core->blocksize-i);
//r_cons_printf ("0x%08"PFMT64x" ", core->offset+i);
if (ret<1) {
ret = err = 1;
r_cons_printf ("???\n");
} else {
if (decode) {
char *tmpopstr, *opstr;
r_anal_op (core->anal, &analop, core->offset+i,
buf+i, core->blocksize-i);
tmpopstr = r_anal_op_to_string (core->anal, &analop);
opstr = (tmpopstr)? tmpopstr: strdup (asmop.buf_asm);
r_cons_printf ("%s\n", opstr);
free (opstr);
} else r_cons_printf ("%s\n", asmop.buf_asm);
}
}
}
case 'i':
r_core_print_disasm_instructions (core, len, l);
break;
case 'D':
case 'd':
@ -576,7 +546,7 @@ static int cmd_print(void *data, const char *input) {
int idx = ((int)(size_t)i)-1;
const char *key = r_strpool_get (sht->sp, idx);
const char *val = r_strht_get (core->print->formats, key);
r_cons_printf ("%s %s\n", key, val);
r_cons_printf ("pf$%s %s\n", key, val);
}
} else
if (input[2]=='-') {

View File

@ -402,6 +402,11 @@ static const char *r_core_print_offname(void *p, ut64 addr) {
R_API int r_core_init(RCore *core) {
static int singleton = R_TRUE;
core->print = r_print_new ();
core->print->user = core;
core->print->offname = r_core_print_offname;
core->print->printf = (void *)r_cons_printf;
core->print->write = (void *)r_cons_memcat;
core->rtr_n = 0;
core->blocksize_max = R_CORE_BLOCKSIZE_MAX;
core->watchers = r_list_new ();
@ -449,11 +454,6 @@ R_API int r_core_init(RCore *core) {
/* XXX memory leak */
return R_FALSE;
}
core->print = r_print_new ();
core->print->user = core;
core->print->offname = r_core_print_offname;
core->print->printf = (void *)r_cons_printf;
core->print->write = (void *)r_cons_memcat;
core->lang = r_lang_new ();
r_lang_define (core->lang, "RCore", "core", core);
r_lang_set_user_ptr (core->lang, core);

View File

@ -342,31 +342,31 @@ toro:
r_anal_op_fini (&analop);
if (!lastfail)
r_anal_op (core->anal, &analop, at, buf+idx, (int)(len-idx));
if (hint && hint->length)
analop.length = hint->length;
if (hint && hint->length)
analop.length = hint->length;
{
RAnalValue *src;
switch (analop.type) {
case R_ANAL_OP_TYPE_MOV:
src = analop.src[0];
if (src && src->memref>0 && src->reg) {
if (core->anal->reg && core->anal->reg->name) {
const char *pc = core->anal->reg->name[R_REG_NAME_PC];
RAnalValue *dst = analop.dst;
if (dst && dst->reg && dst->reg->name)
if (!strcmp (src->reg->name, pc)) {
RFlagItem *item;
ut8 b[8];
ut64 ptr = idx+addr+src->delta+analop.length;
ut64 off = 0LL;
r_core_read_at (core, ptr, b, src->memref);
off = r_mem_get_num (b, src->memref, 1);
item = r_flag_get_i (core->flags, off);
r_cons_printf ("; MOV %s = [0x%"PFMT64x"] = 0x%"PFMT64x" %s\n",
dst->reg->name, ptr, off, item?item->name: "");
if (core->anal->reg && core->anal->reg->name) {
const char *pc = core->anal->reg->name[R_REG_NAME_PC];
RAnalValue *dst = analop.dst;
if (dst && dst->reg && dst->reg->name)
if (!strcmp (src->reg->name, pc)) {
RFlagItem *item;
ut8 b[8];
ut64 ptr = idx+addr+src->delta+analop.length;
ut64 off = 0LL;
r_core_read_at (core, ptr, b, src->memref);
off = r_mem_get_num (b, src->memref, 1);
item = r_flag_get_i (core->flags, off);
r_cons_printf ("; MOV %s = [0x%"PFMT64x"] = 0x%"PFMT64x" %s\n",
dst->reg->name, ptr, off, item?item->name: "");
}
}
}
}
break;
#if 1
// TODO: get from meta anal?
@ -836,6 +836,7 @@ R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int len) {
RAnalOp analop;
int i, oplen, ret;
r_cons_printf ("[");
// TODO: add support for anal hints
for (i=0; i<len;) {
ut64 at = addr +i;
r_asm_set_pc (core->assembler, at);
@ -868,3 +869,37 @@ R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int len) {
r_cons_printf ("]");
return R_TRUE;
}
R_API int r_core_print_disasm_instructions (RCore *core, int len, int l) {
RAsmOp asmop;
int i, j, ret, err = 0;
const ut8 *buf = core->block;
int bs = core->blocksize;
RAnalOp analop = {0};
int decode = r_config_get_i (core->config, "asm.decode");
// 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);
ret = r_asm_disassemble (core->assembler,
&asmop, buf+i, core->blocksize-i);
//r_cons_printf ("0x%08"PFMT64x" ", core->offset+i);
if (ret<1) {
ret = err = 1;
r_cons_printf ("???\n");
} else {
if (decode) {
char *tmpopstr, *opstr;
r_anal_op (core->anal, &analop, core->offset+i,
buf+i, core->blocksize-i);
tmpopstr = r_anal_op_to_string (core->anal, &analop);
opstr = (tmpopstr)? tmpopstr: strdup (asmop.buf_asm);
r_cons_printf ("%s\n", opstr);
free (opstr);
} else r_cons_printf ("%s\n", asmop.buf_asm);
}
}
}

View File

@ -104,6 +104,8 @@ R_API int r_core_project_save(RCore *core, const char *file) {
r_cons_flush ();
r_core_cmd (core, "af*", 0);
r_cons_flush ();
r_core_cmd (core, "ah*", 0);
r_cons_flush ();
r_str_write (fd, "# seek\n");
r_str_writef (fd, "s 0x%08"PFMT64x, core->offset);
r_cons_flush ();

View File

@ -843,7 +843,7 @@ R_API int r_anal_fcn_xref_add (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 ad
R_API int r_anal_fcn_xref_del (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 addr, int type);
/* hints */
R_API void r_anal_hint_list (RAnal *anal, int mode);
//R_API void r_anal_hint_list (RAnal *anal, int mode);
R_API void r_anal_hint_del (RAnal *anal, ut64 addr);
R_API RAnalHint *r_anal_hint_at (RAnal *a, ut64 from, int size);
R_API RAnalHint *r_anal_hint_add (RAnal *a, ut64 from, int size);

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2012 - pancake */
/* radare - LGPL - Copyright 2009-2013 - pancake */
#ifndef _INCLUDE_R_CORE_H_
#define _INCLUDE_R_CORE_H_
@ -210,6 +210,7 @@ R_API char *r_core_disassemble_instr(RCore *core, ut64 addr, int l);
R_API char *r_core_disassemble_bytes(RCore *core, ut64 addr, int b);
/* anal.c */
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_data (RCore *core, ut64 addr, int count, int depth);
R_API void r_core_anal_refs(RCore *core, ut64 addr, int gv);
@ -238,6 +239,7 @@ R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut6
R_API RList *r_core_asm_bwdisassemble (RCore *core, ut64 addr, int n, int len);
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int lines, int invbreak, int nbytes);
R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int len);
R_API int r_core_print_disasm_instructions (RCore *core, int len, int l);
R_API int r_core_bin_load(RCore *core, const char *file);
R_API int r_core_hash_load(RCore *core, const char *file);