* Added initial aop_to_string() method for RAnal

- accessible via asm.decode
* Add more 'Vd' keys (data, code, string, ..)
This commit is contained in:
pancake 2010-06-21 11:55:48 +02:00
parent 00214c95ef
commit 255504b79c
8 changed files with 125 additions and 32 deletions

38
TODO
View File

@ -9,23 +9,29 @@
0.5 RELEASE
===========
Build fixes:
------------
* Store version information in libraries ? debian claims for it
Bugs:
-----
* nibble: trace counts after step..thats not correct!
Features:
---------
* references: data (read, write), code (call, jmp)
* Handle metadata from disassembler (structs, hexdump, ...)
- r_meta_print (RMeta, RMetaItem, RPrint);
* pancake: FileDescriptors: dd -- copy from !fd in r1
* Write manpages for r2rc, r2rc-tool, rasign2
* pancake: we need an api to define function signatures
- arg/var set name/get value/ ..
- integrated with function signatures
- offset -> formatstring (offset is the key to function signature)
* pancake: implement RAnalCall (analyze function arguments, return values, propagate types..)
- define number of arguments for given function
- warn if signature and analysis differs in number of args or so..
* gerardo?: implement GMP in util/big.c
* Implement C command as in r1 (same for visual..define strings, hexdumps, etc..)
* nibble: diff code analysis
- diff two programs
1st level:
@ -35,6 +41,16 @@ Features:
- check all strings
2nd level:
- basic block level diffing (output in graph mode)
* code analysis with r_parse // isnt this already done? nibble?
- generate by just parsing the opcode
RAnalAopArg {
int size;
int delta;
int type;
}
r_anal_aop_arg_set ();
r_anal_aop_arg_get ();
r_anal_aop_arg_binmask ();
---8<------------8<------------------8<---------------------8<------------- -- - -
@ -47,16 +63,6 @@ Analysis
Bindings
========
* code analysis with r_parse // isnt this already done? nibble?
- generate by just parsing the opcode
RAnalAopArg {
int size;
int delta;
int type;
}
r_anal_aop_arg_set ();
r_anal_aop_arg_get ();
r_anal_aop_arg_binmask ();
* generate accessors automatically from valaswig
* Script plugins
- We should enable r_lib to implement plugins in any
@ -66,29 +72,29 @@ Bindings
Build system
============
* Store version information in libraries ? debian claims for it
* install.sh (to track installed files ..)
changes and per-opcode execution count (RRange)
Refactoring
===========
* Move disasm loop into r_print (r_print should depend on r_asm)
- thats hard :)
* Move 'r_syscall_t' stuff into r_debug (sync r_core)
* merge r_asm and r_anal?
* Implement r_bind api to link multiple pointers
core->asm = r_bind_set (core->asm->bind, r_asm_new ());
* what do we have to do with r_th, r_parse and r_vm ?
* Is RCore->block and blocksize a RBuf ? refactor!11
* Find a better name for r_buf_fread (really?)
* typedef all function pointers, like in r_bp
* Review r_io API
* rasm2 should be configurable at startup time to choose default arch (use environment?)
* correct result (R_TRUFAE), but with warnings (implement r_errno and r_errstr in r_util?)
* rasm2 should be configurable at startup time to choose default arch (use env?)
* semi-ok state (R_TRUFAE), implement r_errno and r_errstr in r_util?
* Finish and import the spp's getopt owns implementation in r_util (like in p9)
* Rename __UNIX__ as __POSIX__
Design
======
* Implement 'av' command we need it (really?) how about to eval with ?
* references: data (read, write), code (call, jmp)
* filter search results..
cc 8080 @@ hit* .. check for values that has changed.
- maybe we should 'cache' some memory regions

View File

@ -2,14 +2,18 @@ http://www.pivotaltracker.com/
Objectives
==========
- name local variables argments and global vars
- locate variable types
- find switchcases
- Name local variables argments and global vars
- Cv ...
- Detect and propagate variable types
- Identify switch statements
- Symbol Recognising
- Loop Detection (for/while/do)
- Oh, Enum detection would be Awesome.. As in the Defaults of the glib. IDA doesnt
do this. As its hard (I guess)
ANd ofc lowerlevel.. like Block Detection (but Radare does this already)
enum? or switch?
We can do this if it can read header files of the symbols I guess
As most of those enums are Macros and thus are Pre-Compilation Parsed
- Loop detection (for/while/do)
- enum detection/support (load from .h ?) #define /enum parse only
- Detect sign of variables (depending on the conditionals used)
- change operations to ease reading ('\n' instead of 0xa.. sub<->add)
UI
==
- Walk along the decompiled program code
- go xrefs
- change variable names

View File

@ -41,3 +41,56 @@ R_API int r_anal_aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int
return anal->cur->aop (anal, aop, addr, data, len);
return 0;
}
R_API char *r_anal_aop_to_string(RAnal *anal, RAnalOp *op) {
int retsz = 128;
char *cstr, *ret = malloc (128);
char *r0 = r_anal_value_to_string (op->dst);
char *a0 = r_anal_value_to_string (op->src[0]);
char *a1 = r_anal_value_to_string (op->src[1]);
switch (op->type) {
case R_ANAL_OP_TYPE_MOV:
snprintf (ret, retsz, "%s = %s", r0, a0);
break;
case R_ANAL_OP_TYPE_ADD:
if (a1 == NULL || !strcmp (a0, a1))
snprintf (ret, retsz, "%s += %s", r0, a0);
else snprintf (ret, retsz, "%s = %s + %s", r0, a0, a1);
break;
case R_ANAL_OP_TYPE_MUL:
if (a1 == NULL || !strcmp (a0, a1))
snprintf (ret, retsz, "%s *= %s", r0, a0);
else snprintf (ret, retsz, "%s = %s * %s", r0, a0, a1);
break;
case R_ANAL_OP_TYPE_DIV:
if (a1 == NULL || !strcmp (a0, a1))
snprintf (ret, retsz, "%s /= %s", r0, a0);
else snprintf (ret, retsz, "%s = %s / %s", r0, a0, a1);
break;
case R_ANAL_OP_TYPE_CJMP:
cstr = r_anal_cond_to_string (op->cond);
snprintf (ret, retsz, "if (%s) goto 0x%08llx", cstr, op->jump);
//free (cstr);
break;
case R_ANAL_OP_TYPE_JMP:
snprintf (ret, retsz, "goto 0x%08llx", op->jump);
break;
case R_ANAL_OP_TYPE_CALL:
// XXX: resolve flag name
snprintf (ret, retsz, "0x%08llx()", op->jump);
break;
case R_ANAL_OP_TYPE_SUB:
if (a1 == NULL || !strcmp (a0, a1))
snprintf (ret, retsz, "%s -= %s", r0, a0);
else snprintf (ret, retsz, "%s = %s - %s", r0, a0, a1);
break;
default:
sprintf (ret, "// ?");
break;
}
free (r0);
free (a0);
free (a1);
return ret;
}

View File

@ -19,8 +19,10 @@ R_API RAnalCond *r_anal_cond_clone(RAnalCond *cond) {
static inline const char *condstring(RAnalCond *cond) {
const char *condstr_single[] = { "!", "", "0<", "0<=", "0>", "0>=" };
const char *condstr[] = { "==", "!=", ">=", ">", "<=", "<" };
if (cond)
return (cond->arg[1])?condstr [cond->type%sizeof (condstr)]:
condstr_single [cond->type%sizeof (condstr_single)];
return "";
}
R_API int r_anal_cond_eval(RAnal *anal, RAnalCond *cond) {
@ -61,10 +63,13 @@ R_API int r_anal_cond_eval(RAnal *anal, RAnalCond *cond) {
}
R_API char *r_anal_cond_to_string(RAnalCond *cond) {
char *out = NULL;
const char *cnd = condstring (cond);
char *val0 = r_anal_value_to_string (cond->arg[0]);
char *val1 = r_anal_value_to_string (cond->arg[1]);
char *val0, *val1, *out = NULL;
const char *cnd;
if (cond == NULL)
return "?=";
cnd = condstring (cond);
val0 = r_anal_value_to_string (cond->arg[0]);
val1 = r_anal_value_to_string (cond->arg[1]);
if (val0) {
if (R_ANAL_COND_SINGLE(cond)) {
if ( (out = malloc (strlen (val0) + 10)) )

View File

@ -32,6 +32,7 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
// TODO: All those options must be print flags
int show_color = r_config_get_i (core->config, "scr.color");
int decode = r_config_get_i (core->config, "asm.decode");
int pseudo = r_config_get_i (core->config, "asm.pseudo");
int filter = r_config_get_i (core->config, "asm.filter");
int show_lines = r_config_get_i (core->config, "asm.lines");
@ -239,6 +240,11 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
break;
}
}
if (decode) {
// TODO: Use data from code analysis..not raw analop here
// if we want to get more information
opstr = r_anal_aop_to_string (core->anal, &analop);
} else
if (pseudo) {
r_parse_parse (core->parser, asmop.buf_asm, str);
opstr = str;
@ -247,6 +253,8 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
opstr = str;
} else opstr = asmop.buf_asm;
r_cons_strcat (opstr);
if (decode)
free (opstr);
if (show_color)
r_cons_strcat (Color_RESET);
if (show_dwarf) {

View File

@ -165,6 +165,7 @@ R_API int r_core_config_init(RCore *core) {
r_config_set (cfg, "asm.pseudo", "false"); // DEPRECATED ???
r_config_set (cfg, "asm.filter", "true");
r_config_set (cfg, "asm.trace", "true");
r_config_set (cfg, "asm.decode", "false");
r_config_set (cfg, "asm.bytes", "true");
r_config_set (cfg, "asm.offset", "true");
r_config_set (cfg, "asm.lines", "true");

View File

@ -455,8 +455,11 @@ R_API void r_core_visual_define (RCore *core) {
if (core->print->cur_enabled)
off += core->print->cur;
r_cons_printf ("Define current block as:\n"
" u - undefine metadata here\n"
" d - set as data\n"
" c - set as code\n"
" s - set string\n"
" f - analyze function\n"
" u - undefine metadata here\n"
" q - quit/cancel operation\n"
"TODO: add support for data, string, code ..\n");
r_cons_flush ();
@ -465,6 +468,18 @@ R_API void r_core_visual_define (RCore *core) {
ch = r_cons_arrow_to_hjkl (ch); // get ESC+char, return 'hjkl' char
switch(ch) {
case 's':
// detect type of string
// find EOS
// capture string value
r_meta_add (core->meta, R_META_STRING, off, core->blocksize, "");
break;
case 'd': // TODO: check
r_meta_add (core->meta, R_META_DATA, off, core->blocksize, "");
break;
case 'c': // TODO: check
r_meta_add (core->meta, R_META_CODE, off, core->blocksize, "");
break;
case 'u':
r_meta_del (core->meta, R_META_ANY, off, 1, "");
r_flag_unset_i (core->flags, off);

View File

@ -284,6 +284,7 @@ R_API int r_anal_bb_del(RAnal *anal, ut64 addr);
/* aop.c */
R_API RAnalOp *r_anal_aop_new();
R_API char *r_anal_aop_to_string(RAnal *anal, RAnalOp *op);
R_API void r_anal_aop_free(void *aop);
R_API RList *r_anal_aop_list_new();
R_API int r_anal_aop(RAnal *anal, RAnalOp *aop, ut64 addr,