* Import Vv command to visually analyze functions from r1

This commit is contained in:
pancake 2010-08-22 19:07:03 +02:00
parent 3c8ddce624
commit 19f072f3f5
3 changed files with 192 additions and 172 deletions

2
TODO
View File

@ -69,7 +69,7 @@ TODO pancake
| r_asm > r_vm |
| r_debug > r_reg |
`-----------------'
* Implement visual function editor .. its done hacky in anal.c
* Implement visual function editor .. its done hacky in core/cmd.c .. maybe move to visual.c
* Implement remote:// socket:// and listen://
{
* Implement RAnalCall (analyze function arguments, return values, propagate types..)

View File

@ -1667,177 +1667,6 @@ static int var_cmd(RCore *core, const char *str) {
#endif
////// VISUAL /////////
#if 0
void var_index_show(ut64 addr, int idx)
{
int i = 0;
struct list_head *pos, *pos2;
struct var_t *v;
struct var_xs_t *x;
int window = 15;
int wdelta = (idx>5)?idx-5:0;
list_for_each(pos, &vars) {
v = (struct var_t *)list_entry(pos, struct var_t, list);
if (addr == 0 || (addr >= v->addr && addr <= v->eaddr)) {
if (i>=wdelta) {
if (i> window+wdelta) {
cons_printf("...\n");
break;
}
if (idx == i) printf(" * ");
else printf(" ");
cons_printf("0x%08llx - 0x%08llx type=%s type=%s name=%s delta=%d array=%d\n",
v->addr, v->eaddr, var_type_str(v->type),
v->vartype, v->name, v->delta, v->arraysize);
list_for_each_prev(pos2, &v->access) {
x = (struct var_xs_t *)list_entry(pos2, struct var_xs_t, list);
cons_printf(" 0x%08llx %s\n", x->addr, x->set?"set":"get");
}
}
i++;
}
//}
}
}
/* Like emenu but for real */
void var_visual_menu()
{
struct list_head *pos;
const char *ptr;
char *fs = NULL;
char *fs2 = NULL;
int option = 0;
int _option = 0;
int delta = 9;
int menu = 0;
int i,j, ch;
int hit;
int level = 0;
int show;
char old[1024];
char cmd[1024];
ut64 size, addr = config.seek;
old[0]='\0';
while(1) {
cons_gotoxy(0,0);
cons_clear();
cons_printf("Visual code analysis manipulation\n");
switch(level) {
case 0:
cons_printf("-[ functions ]------------------- \n");
cons_printf("(a) add (x)xrefs (q)quit\n");
cons_printf("(m) modify (c)calls (g)go\n");
cons_printf("(d) delete (v)variables\n");
addr = var_functions_show(option);
break;
case 1:
cons_printf("-[ variables ]------------------- 0x%08llx\n", addr);
cons_printf("(a) add (x)xrefs (q)quit\n");
cons_printf("(m) modify (c)calls (g)go\n");
cons_printf("(d) delete (v)variables\n");
var_index_show(addr, option);
break;
case 2:
cons_printf("-[ calls ]----------------------- 0x%08llx\n", addr);
sprintf(old, "aCf@0x%08llx", addr);
cons_flush();
radare_cmd(old, 0);
//cons_printf("\n");
break;
case 3:
cons_printf("-[ xrefs ]----------------------- 0x%08llx\n", addr);
sprintf(old, "Cx~0x%08llx", addr);
radare_cmd(old, 0);
//cons_printf("\n");
break;
}
cons_flushit();
// show indexable vars
ch = cons_readchar();
ch = cons_get_arrow(ch); // get ESC+char, return 'hjkl' char
switch(ch) {
case 'a':
switch(level) {
case 0:
cons_set_raw(0);
printf("Address: ");
fflush(stdout);
if (!fgets(old, sizeof(old), stdin)) break;
old[strlen(old)-1] = 0;
if (!old[0]) break;
addr = get_math(old);
printf("Size: ");
fflush(stdout);
if (!fgets(old, sizeof(old), stdin)) break;
old[strlen(old)-1] = 0;
if (!old[0]) break;
size = get_math(old);
printf("Name: ");
fflush(stdout);
if (!fgets(old, sizeof(old), stdin)) break;
old[strlen(old)-1] = 0;
flag_set(old, addr, 0);
sprintf(cmd, "CF %lld @ 0x%08llx", size, addr);
radare_cmd(cmd, 0);
cons_set_raw(1);
break;
case 1:
break;
}
break;
case 'd':
switch(level) {
case 0:
data_del(addr, DATA_FUN, 0);
// XXX correcly remove all the data contained inside the size of the function
flag_remove_at(addr);
break;
}
break;
case 'x':
level = 3;
break;
case 'c':
level = 2;
break;
case 'v':
level = 1;
break;
case 'j':
option++;
break;
case 'k':
if (--option<0)
option = 0;
break;
case 'g': // go!
radare_seek(addr, SEEK_SET);
return;
case ' ':
case 'l':
level = 1;
_option = option;
break;
case 'h':
case 'b': // back
level = 0;
option = _option;
break;
case 'q':
if (level==0)
return;
level = 0;
break;
}
}
}
#endif
static int cmd_anal(void *data, const char *input) {
const char *ptr;
RCore *core = (RCore *)data;

View File

@ -468,6 +468,194 @@ R_API void r_core_visual_config(RCore *core) {
}
}
#if 1
static void var_index_show(RAnal *anal, RAnalFcn *fcn, ut64 addr, int idx) {
int i = 0;
RAnalVar *v;
RAnalVarAccess *x;
RListIter *iter, *iter2;
int window = 15;
int wdelta = (idx>5)?idx-5:0;
if (!fcn)
return;
r_list_foreach(fcn->vars, iter, v) {
if (addr == 0 || (addr >= v->addr && addr <= v->eaddr)) {
if (i>=wdelta) {
if (i> window+wdelta) {
r_cons_printf("...\n");
break;
}
if (idx == i) r_cons_printf(" * ");
else r_cons_printf(" ");
r_cons_printf("0x%08llx - 0x%08llx type=%s type=%s name=%s delta=%d array=%d\n",
v->addr, v->eaddr, r_anal_var_type_to_str (anal, v->type),
v->vartype, v->name, v->delta, v->array);
r_list_foreach(v->accesses, iter2, x) {
r_cons_printf(" 0x%08llx %s\n", x->addr, x->set?"set":"get");
}
}
i++;
}
}
}
// helper
static ut64 var_functions_show(RCore *core, int idx) {
const char *mark = "";//nullstr;
int i = 0;
ut64 seek = core->offset;
ut64 addr = core->offset;
int window = 15;
int wdelta = (idx>5)?idx-5:0;
RListIter *iter;
RAnalFcn *fcn;
r_list_foreach (core->anal->fcns, iter, fcn) {
if (i>=wdelta) {
if (i> window+wdelta) {
r_cons_printf("...\n");
break;
}
if (seek > fcn->addr && seek < fcn->addr+fcn->size)
mark = "<SEEK IS HERE>";
else mark = "";
if (idx == i)
addr = fcn->addr;
r_cons_printf (" %c 0x%08llx (%s) %s\n", (idx==i)?'*':' ',
fcn->addr, fcn->name, mark);
}
i++;
}
return addr;
}
/* Like emenu but for real */
R_API void r_core_visual_anal(RCore *core) {
int option = 0;
int _option = 0;
int ch, level = 0;
char old[1024];
ut64 size, addr = core->offset;
old[0]='\0';
RAnalFcn *fcn = r_anal_fcn_find (core->anal, core->offset);
for(;;) {
r_cons_gotoxy(0,0);
r_cons_clear();
r_cons_printf("Visual code analysis manipulation\n");
switch(level) {
case 0:
r_cons_printf("-[ functions ]------------------- \n"
"(a) add (x)xrefs (q)quit\n"
"(m) modify (c)calls (g)go\n"
"(d) delete (v)variables\n");
addr = var_functions_show(core, option);
break;
case 1:
r_cons_printf("-[ variables ]------------------- 0x%08llx\n"
"(a) add (x)xrefs (q)quit\n"
"(m) modify (c)calls (g)go\n"
"(d) delete (v)variables\n", addr);
var_index_show(core->anal, fcn, addr, option);
break;
case 2:
r_cons_printf("-[ calls ]----------------------- 0x%08llx (TODO)\n", addr);
#if 0
sprintf(old, "aCf@0x%08llx", addr);
cons_flush();
radare_cmd(old, 0);
#endif
break;
case 3:
r_cons_printf("-[ xrefs ]----------------------- 0x%08llx\n", addr);
sprintf(old, "Cx~0x%08llx", addr);
r_core_cmd0 (core, old);
//cons_printf("\n");
break;
}
r_cons_flush();
// show indexable vars
ch = r_cons_readchar();
ch = r_cons_arrow_to_hjkl(ch); // get ESC+char, return 'hjkl' char
switch(ch) {
case 'a':
switch(level) {
case 0:
r_cons_set_raw(0);
printf("Address: ");
fflush(stdout);
if (!fgets(old, sizeof(old), stdin)) break;
old[strlen(old)-1] = 0;
if (!old[0]) break;
addr = r_num_math(core->num, old);
printf("Size: ");
fflush(stdout);
if (!fgets(old, sizeof(old), stdin)) break;
old[strlen(old)-1] = 0;
if (!old[0]) break;
size = r_num_math(core->num, old);
printf("Name: ");
fflush(stdout);
if (!fgets(old, sizeof(old), stdin)) break;
old[strlen(old)-1] = 0;
r_flag_set(core->flags, old, addr, 0, 0);
//XXX sprintf(cmd, "CF %lld @ 0x%08llx", size, addr);
// XXX r_core_cmd0(core, cmd);
r_cons_set_raw(1);
break;
case 1:
break;
}
break;
case 'd':
switch(level) {
case 0:
eprintf ("TODO\n");
//data_del(addr, DATA_FUN, 0);
// XXX correcly remove all the data contained inside the size of the function
//flag_remove_at(addr);
break;
}
break;
case 'x':
level = 3;
break;
case 'c':
level = 2;
break;
case 'v':
level = 1;
break;
case 'j':
option++;
break;
case 'k':
if (--option<0)
option = 0;
break;
case 'g': // go!
r_core_seek (core, addr, SEEK_SET);
return;
case ' ':
case 'l':
level = 1;
_option = option;
break;
case 'h':
case 'b': // back
level = 0;
option = _option;
break;
case 'q':
if (level==0)
return;
level = 0;
break;
}
}
}
#endif
R_API void r_core_visual_define (RCore *core) {
int ch;
ut64 off = core->offset;
@ -590,6 +778,9 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
case 't':
r_core_visual_trackflags (core);
break;
case 'v':
r_core_visual_anal (core);
break;
case 'J':
if (curset) {
if (ocursor==-1) ocursor = cursor;