* Implement 'Ct' command to manage anal_var_types

* Minor todo cleanup
* Use more PFMT64
This commit is contained in:
pancake 2010-07-13 10:56:56 +02:00
parent 28f3d983e6
commit a2ab58dbe6
5 changed files with 69 additions and 44 deletions

20
TODO
View File

@ -19,6 +19,10 @@ Build system:
Questions:
----------
* We need a command to retrieve r2 version '?V'
* How to search for an opcode like CALL+REG? or MOV+CONST, ...
- r_anal_match(anal, aop CALL | REG) ?
- Implememnted in a command like /a..
* imports from PE doesnt works with /a because there's an indirect call
* Load symbol information from libraries (only the ones imported by rabin2?)
- only in runtime when eip is in library code?
@ -28,12 +32,7 @@ Questions:
- 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 ();
Bugs:
-----
* Cx/CX are not displayed in disasm as they should.. (C! must die)
* nibble: check if we use objcopy --stripsymbols on a library..the stripped symbols are not
listed by nm or rabin..but objcopy is able to see them O_O
TODO nibble
-----------
@ -52,15 +51,10 @@ TODO nibble
TODO pancake
------------
#### * implement callback for conditional breakpoints
### * must check from core if stopped address is a breakpoint and run it
* FileDescriptors: dd -- copy from !fd in r1
* we need an api to define function signatures
- Ct to manage types
- CF<addr> void name(int foo, char* var)
- arg/var set name/get value/ ..
- CF* must be used to define function shit
- integrated with function signatures
- offset -> formatstring (offset is the key to function signature)
* 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..
@ -69,8 +63,8 @@ TODO gerardo
------------
* implement GMP in util/big.c
unassigned
----------
unassigned TODO pointz
----------------------
* Implement a r_list_get_n() to get Nth element in linked list
* Test r_lib^w32/osx support
* port r_sign to RList

View File

@ -23,9 +23,7 @@ R_API RAnalVarType *r_anal_var_type_new() {
}
R_API RAnalVarAccess *r_anal_var_access_new() {
RAnalVarAccess *access;
access = R_NEW (RAnalVarAccess);
RAnalVarAccess *access = R_NEW (RAnalVarAccess);
if (access)
memset (access, 0, sizeof (RAnalVarAccess));
return access;
@ -57,8 +55,8 @@ R_API void r_anal_var_free(void *var) {
free (((RAnalVar*)var)->vartype);
if (((RAnalVar*)var)->accesses)
r_list_free (((RAnalVar*)var)->accesses);
free (var);
}
free (var);
}
R_API void r_anal_var_type_free(void *vartype) {
@ -91,7 +89,6 @@ R_API int r_anal_var_type_add(RAnal *anal, const char *name, int size, const cha
R_API int r_anal_var_type_del(RAnal *anal, const char *name) {
RAnalVarType *vti;
RListIter *iter;
r_list_foreach(anal->vartypes, iter, vti)
if (!strcmp (name, vti->name)) {
r_list_unlink (anal->vartypes, vti);
@ -103,7 +100,7 @@ R_API int r_anal_var_type_del(RAnal *anal, const char *name) {
R_API RAnalVarType *r_anal_var_type_get(RAnal *anal, const char *name) {
RAnalVarType *vti;
RListIter *iter;
r_list_foreach(anal->vartypes, iter, vti)
r_list_foreach (anal->vartypes, iter, vti)
if (!strcmp (name, vti->name))
return vti;
return NULL;
@ -112,7 +109,6 @@ R_API RAnalVarType *r_anal_var_type_get(RAnal *anal, const char *name) {
R_API int r_anal_var_add(RAnal *anal, RAnalFcn *fcn, ut64 from, int delta, int type, const char *vartype, const char *name, int set) {
RAnalVar *var, *vari;
RListIter *iter;
r_list_foreach(fcn->vars, iter, vari)
if (vari->type == type && vari->delta == delta)
return r_anal_var_access_add (anal, vari, from, set);
@ -149,6 +145,7 @@ R_API RAnalVar *r_anal_var_get(RAnal *anal, RAnalFcn *fcn, int delta, int type)
return NULL;
}
// XXX: rename function type? i think this is 'scope'
R_API const char *r_anal_var_type_to_str (RAnal *anal, int type) {
switch(type) {
case R_ANAL_VAR_TYPE_GLOBAL: return "global";

View File

@ -104,7 +104,7 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
r_cons_strcat (comment);
free (comment);
}
// TODO : line analysis must respect data types! shouldnt be interpreted as code
// TODO : line analysis must respect data types! shouldnt be interpreted as code
line = r_anal_reflines_str (core->anal, core->reflines, at, linesopts);
// TODO: implement ranged meta find (if not at the begging of function..
mi = r_meta_find (core->meta, at, R_META_ANY, R_META_WHERE_HERE);
@ -125,11 +125,11 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
switch (x->type) {
case 'c':
case R_META_XREF_CODE:
r_cons_printf ("Cx # code xref from 0x%08llx\n", mi->to);
r_cons_printf ("Cx # code xref from 0x%08"PFMT64x"\n", mi->to);
break;
case 'd':
case R_META_XREF_DATA:
r_cons_printf ("CX # data xref from 0x%08llx\n", mi->to);
r_cons_printf ("CX # data xref from 0x%08"PFMT64x"\n", mi->to);
break;
}
}
@ -219,7 +219,7 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
switch (mi->type) {
case R_META_STRING:
// TODO: filter string (r_str_unscape)
r_cons_printf ("string(%lld): \"%s\"\n", mi->size, mi->str);
r_cons_printf ("string(%"PFMTd"): \"%s\"\n", mi->size, mi->str);
ret = (int)mi->size;
free (line);
continue;
@ -355,14 +355,14 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
R_META_ANY, R_META_WHERE_HERE);
if (mi2) {
char *str = r_str_unscape (mi2->str);
r_cons_printf (" (at=0x%08llx) (len=%lld) \"%s\" ", analop.ref, mi2->size, str);
r_cons_printf (" (at=0x%08"PFMT64x") (len=%"PFMT64d") \"%s\" ", analop.ref, mi2->size, str);
free (str);
} else r_cons_printf ("; => 0x%08x ", word);
} else {
if (mi2->type == R_META_STRING) {
char *str = r_str_unscape (mi2->str);
r_cons_printf (" (at=0x%08x) (len=%lld) \"%s\" ", word, mi2->size, str);
r_cons_printf (" (at=0x%08x) (len=%"PFMT64d") \"%s\" ", word, mi2->size, str);
free (str);
} else r_cons_printf ("unknown type '%c'\n", mi2->type);
}
@ -1058,8 +1058,8 @@ static int cmd_help(void *data, const char *input) {
case '$':
return cmd_help (data, " $?");
case 'z':
for (input=input+1;input[0]==' ';input=input+1);
core->num->value = strlen(input);
for (input=input+1; input[0]==' '; input=input+1);
core->num->value = strlen (input);
break;
case 't': {
struct r_prof_t prof;
@ -1184,16 +1184,15 @@ static int cmd_cmp(void *data, const char *input) {
}
buf = (ut8*)malloc (strlen (input+2));
ret = r_hex_str2bin (input+2, buf);
if (ret<1) {
eprintf ("Cannot parse hexpair\n");
} else radare_compare (core, core->block, buf, ret);
if (ret<1) eprintf ("Cannot parse hexpair\n");
else radare_compare (core, core->block, buf, ret);
free (buf);
break;
case 'X':
buf = malloc (core->blocksize);
ret = r_io_read_at (core->io, r_num_math (core->num, input+1), buf, core->blocksize);
radare_compare (core, core->block, buf, ret);
free(buf);
free (buf);
break;
case 'f':
if (input[1]!=' ') {
@ -1791,7 +1790,7 @@ static int cmd_anal(void *data, const char *input) {
RDebugTracepoint *t = r_debug_trace_get (core->dbg,
r_num_math (core->num, input+1));
if (t != NULL) {
r_cons_printf ("offset = 0x%llx\n", t->addr);
r_cons_printf ("offset = 0x%"PFMT64x"\n", t->addr);
r_cons_printf ("opsize = %d\n", t->size);
r_cons_printf ("times = %d\n", t->times);
r_cons_printf ("count = %d\n", t->count);
@ -2408,6 +2407,8 @@ static int cmd_open(void *data, const char *input) {
// XXX this command is broken. output of _list is not compatible with input
static int cmd_meta(void *data, const char *input) {
RAnalVar *var;
RListIter *iter;
RCore *core = (RCore*)data;
int i, ret, line = 0;
ut64 addr_end = 0LL;
@ -2417,6 +2418,40 @@ static int cmd_meta(void *data, const char *input) {
case '*':
r_meta_list (core->meta, R_META_ANY);
break;
case 't':
switch (input[1]) {
case '-':
r_anal_var_type_del (core->anal, input+2);
break;
case ' ':
{
int size;
const char *fmt= NULL;
const char *ptr, *name = input+2;
ptr = strchr (name, ' ');
if (ptr) {
size = atoi (ptr+1);
ptr = strchr (ptr+2, ' ');
if (ptr)
fmt = ptr+1;
}
if (fmt==NULL)
eprintf ("Usage: Ct name size format\n");
else r_anal_var_type_add (core->anal, name, size, fmt);
}
break;
case '\0':
r_list_foreach (core->anal->vars, iter, var) {
r_cons_printf ("Ct %s %d %s\n", var->name, var->size, var->fmt);
}
break;
default:
eprintf ("Usage: Ct[..]\n"
" Ct-int : remove 'int' type\n"
" Ct int 4 d : define int type\n");
break;
}
break;
case 'L': // debug information of current offset
ret = r_bin_meta_get_line (core->bin, core->offset, file, 1023, &line);
if (ret) {
@ -2595,7 +2630,6 @@ static int r_core_cmd_subst(RCore *core, char *cmd) {
if (!*cmd || cmd[0]=='\0')
return 0;
cmd = r_str_trim_head_tail (cmd);
/* quoted / raw command */
@ -2659,7 +2693,7 @@ static int r_core_cmd_subst(RCore *core, char *cmd) {
for (;;) {
char buf[1024];
int ret;
printf("> "); fflush(stdout);
printf ("> "); fflush (stdout);
fgets(buf, 1023, stdin); // XXX use r_line ??
if (feof (stdin))
break;

View File

@ -1,5 +1,7 @@
/* radare - LGPL - Copyright 2010 pancake<nopcode.org> */
// XXX: All this stuff must be linked to the code injection api
#include <r_debug.h>
R_API int r_debug_desc_open(RDebug *dbg, const char *path) {

View File

@ -127,7 +127,7 @@ typedef unsigned long mips64_regs_t [4096];
#if __APPLE__
// TODO: move into native/
task_t pid_to_task(int pid) {
static task_t old_pid = -1;
static task_t old_pid = -1;
static task_t old_task = -1;
task_t task = 0;
int err;
@ -180,7 +180,6 @@ static int r_debug_native_step(RDebug *dbg, int pid) {
r_debug_native_reg_write (dbg, R_REG_TYPE_GPR, &regs, sizeof (regs));
//single_step = pid;
r_debug_native_continue (pid, -1);
#elif __APPLE__
debug_arch_x86_trap_set (dbg, 1);
//eprintf ("stepping from pc = %08x\n", (ut32)get_offset("eip"));
@ -188,7 +187,7 @@ static int r_debug_native_step(RDebug *dbg, int pid) {
ret = ptrace (PT_STEP, pid, (caddr_t)1, SIGTRAP); //SIGINT);
if (ret != 0) {
perror ("ptrace-step");
eprintf ("mach-error: %d, %s\n", ret, MACH_ERROR_STRING(ret));
eprintf ("mach-error: %d, %s\n", ret, MACH_ERROR_STRING (ret));
/* DO NOT WAIT FOR EVENTS !!! */
ret = R_FALSE;
} else ret = R_TRUE;
@ -501,6 +500,7 @@ static const char *r_debug_native_reg_profile() {
"gpr r17 .32 68 0\n"
);
#else
#warning NO DEBUGGER REGISTERS PROFILE DEFINED
return NULL;
#endif
}
@ -679,7 +679,7 @@ static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
if (ret != 0)
return R_FALSE;
if (sizeof (regs) < size)
size = sizeof(regs);
size = sizeof (regs);
memcpy (buf, &regs, size);
return sizeof (regs);
}
@ -705,7 +705,7 @@ static int r_debug_native_reg_write(int pid, int type, const ut8* buf, int size)
size = sizeof (R_DEBUG_REG_T);
return (ret != 0) ? R_FALSE: R_TRUE;
#else
#warning r_debug_native_reg_write not implemented
#warning r_debug_native_reg_write not implemented
#endif
} else eprintf("TODO: reg_write_non-gpr (%d)\n", type);
return R_FALSE;
@ -841,9 +841,9 @@ static int r_debug_native_bp_read(int pid, ut64 addr, int hw, int rwx) {
static RList *r_debug_native_frames(RDebug *dbg) {
RRegister *reg = dbg->reg;
ut32 i, _esp, esp, ebp2;
ut8 buf[4];
RList *list = r_list_new ();
RIOBind *bio = &dbg->iob;
ut8 buf[4];
list->free = free;
_esp = r_reg_get_value (reg, r_reg_get (reg, "esp", R_REG_TYPE_GPR));
@ -901,14 +901,12 @@ static RList *r_debug_native_frames(RDebug *dbg) {
// TODO: make those two reads in a shot
bio->read_at (bio->io, _rbp, &ebp2, 4);
bio->read_at (bio->io, _rbp+4, &ptr, 4);
if (ptr == 0x0 || _rbp == 0x0)
if (!ptr || !_rbp)
break;
RDebugFrame *frame = R_NEW (RDebugFrame);
frame->addr = ptr;
frame->size = 0; // TODO ?
r_list_append (list, frame);
_rbp = ebp2;
}
return list;