* Added initial aop_to_string() method for RAnal
- accessible via asm.decode * Add more 'Vd' keys (data, code, string, ..)
This commit is contained in:
parent
00214c95ef
commit
255504b79c
40
TODO
40
TODO
|
@ -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)
|
||||
- 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) )
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue