Implement RAnal.fcn_del_locs() to fix Vdu and af-

New commands: fx and fxd to show contents of flags
Fix pZ-pz help message and stuff
fF in visual is now nN
nN in visual has been deprecated
sfF also renamed to snN
sn renamed to so
e scr.fkey is now scr.nkey
Beautify the disasm loc functions
Toggle breakpoints with 'b' in visual
This commit is contained in:
pancake 2012-09-28 02:20:52 +02:00
parent 4ffdaeb04f
commit 7e9af106bb
13 changed files with 144 additions and 53 deletions

View File

@ -44,6 +44,7 @@ R_API RList *r_anal_fcn_list_new() {
R_API void r_anal_fcn_free(void *_fcn) {
RAnalFunction *fcn = _fcn;
if (!_fcn) return;
fcn->size = 0;
free (fcn->name);
free (fcn->attr);
r_list_free (fcn->refs);
@ -205,6 +206,25 @@ R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size, const char *name, in
return append? r_anal_fcn_insert (anal, fcn): R_TRUE;
}
R_API int r_anal_fcn_del_locs(RAnal *anal, ut64 addr) {
RListIter *iter, *iter2;
RAnalFunction *fcn, *f = r_anal_fcn_find (anal, addr, R_ANAL_FCN_TYPE_ROOT);
#if USE_NEW_FCN_STORE
#warning TODO: r_anal_fcn_del_locs not implemented for newstore
#endif
if (f) {
r_list_foreach_safe (anal->fcns, iter, iter2, fcn) {
if (fcn->type != R_ANAL_FCN_TYPE_LOC)
continue;
if (fcn->addr >= f->addr && fcn->addr < (f->addr+f->size)) {
r_list_delete (anal->fcns, iter);
}
}
}
r_anal_fcn_del (anal, addr);
return R_TRUE;
}
R_API int r_anal_fcn_del(RAnal *anal, ut64 addr) {
if (addr == 0) {
#if USE_NEW_FCN_STORE

View File

@ -311,7 +311,11 @@ case 'o':
case 'f':
switch (input[1]) {
case '-':
r_anal_fcn_del (core->anal, r_num_math (core->num, input+2));
{
ut64 addr = r_num_math (core->num, input+2);
r_anal_fcn_del_locs (core->anal, addr);
r_anal_fcn_del (core->anal, addr);
}
break;
case '+':
{

View File

@ -41,6 +41,34 @@ static int cmd_flag(void *data, const char *input) {
r_cons_printf ("0x%08"PFMT64x"\n", item->offset);
} else eprintf ("Missing arguments\n");
break;
#if 0
case 'd':
if (input[1] == ' ') {
char cmd[128];
RFlagItem *item = r_flag_get_i (core->flags,
r_num_math (core->num, input+2));
if (item) {
r_cons_printf ("0x%08"PFMT64x"\n", item->offset);
snprintf (cmd, sizeof (cmd), "pD@%"PFMT64d":%"PFMT64d,
item->offset, item->size);
r_core_cmd0 (core, cmd);
}
} else eprintf ("Missing arguments\n");
break;
#endif
case 'x':
if (input[1] == ' ') {
char cmd[128];
RFlagItem *item = r_flag_get_i (core->flags,
r_num_math (core->num, input+2));
if (item) {
r_cons_printf ("0x%08"PFMT64x"\n", item->offset);
snprintf (cmd, sizeof (cmd), "px@%"PFMT64d":%"PFMT64d,
item->offset, item->size);
r_core_cmd0 (core, cmd);
}
} else eprintf ("Missing arguments\n");
break;
case 'S':
r_flag_sort (core->flags, (input[1]=='n'));
break;
@ -134,6 +162,7 @@ static int cmd_flag(void *data, const char *input) {
" fs ; display flagspaces\n"
" fl [flagname] ; show flag length (size)\n"
" fS[on] ; sort flags by offset or name\n"
" fx[d] ; show hexdump (or disasm) of flag:flagsize\n"
" fo ; show fortunes\n");
break;
}

View File

@ -541,7 +541,7 @@ static int cmd_print(void *data, const char *input) {
case 'z':
if (input[1]=='?') {
r_cons_printf (
"Usage: pZ [len]\n"
"Usage: pz [len]\n"
" print N bytes where each byte represents a block of filesize/N\n"
"Configuration:\n"
" zoom.maxsz : max size of block\n"

View File

@ -122,13 +122,13 @@ static int cmd_seek(void *data, const char *input) {
r_core_seek (core, off, 0);
}
break;
case 'f':
case 'n':
r_io_sundo_push (core->io, core->offset);
r_core_seek_next (core, r_config_get (core->config, "scr.fkey"));
r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
break;
case 'F':
case 'N':
r_io_sundo_push (core->io, core->offset);
r_core_seek_previous (core, r_config_get (core->config, "scr.fkey"));
r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
break;
case 'a':
off = core->blocksize;
@ -153,7 +153,7 @@ static int cmd_seek(void *data, const char *input) {
r_io_sundo_push (core->io, core->offset);
r_core_anal_bb_seek (core, off);
break;
case 'n':
case 'o':
{
RAnalOp op;
int ret = r_anal_op (core->anal, &op,
@ -173,12 +173,12 @@ static int cmd_seek(void *data, const char *input) {
" s+ 512 ; seek 512 bytes forward\n"
" s- 512 ; seek 512 bytes backward\n"
" sa [[+-]a] [asz] ; seek asz (or bsize) aligned to addr\n"
" sf|sF ; seek next/prev scr.fkey\n"
" sn|sN ; seek next/prev scr.nkey\n"
" s/ DATA ; search for next occurrence of 'DATA'\n"
" s/x 9091 ; search for next occurrence of \\x90\\x91\n"
" sb ; seek aligned to bb start\n"
//" sp [page] ; seek page N (page = block)\n"
" sn ; seek to next opcode\n"
" so ; seek to next opcode\n"
" sC str ; seek to comment matching given string\n"
" sr pc ; seek to register\n");
break;

View File

@ -2,10 +2,10 @@
#include <r_core.h>
static int config_scrfkey_callback(void *user, void *data) {
static int config_scrnkey_callback(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (!strcmp (node->value, "help") || *node->value == '?') {
r_cons_printf ("scr.fkey = fun, hit, flag\n");
r_cons_printf ("scr.nkey = fun, hit, flag\n");
return R_FALSE;
}
return R_TRUE;
@ -81,7 +81,7 @@ static int config_zoombyte_callback(void *user, void *data) {
core->print->zoom->mode = *node->value;
break;
default:
eprintf ("Invalid zoom.byte value. See pZ? for help\n");
eprintf ("Invalid zoom.byte value. See pz? for help\n");
return R_FALSE;
}
return R_TRUE;
@ -640,9 +640,9 @@ R_API int r_core_config_init(RCore *core) {
r_config_desc (cfg, "scr.color", "Enable/Disable colors");
r_config_set_cb (cfg, "scr.pager", "", &config_pager_callback);
r_config_desc (cfg, "scr.pager", "Select pager program (used if output doesn't fit on window)");
//r_config_set_cb (cfg, "scr.fkey", "function", &config_scrfkey_callback);
r_config_set_cb (cfg, "scr.fkey", "hit", &config_scrfkey_callback);
r_config_desc (cfg, "scr.fkey", "Select the seek mode in visual");
//r_config_set_cb (cfg, "scr.nkey", "function", &config_scrnkey_callback);
r_config_set_cb (cfg, "scr.nkey", "hit", &config_scrnkey_callback);
r_config_desc (cfg, "scr.nkey", "Select the seek mode in visual");
r_config_set (cfg, "scr.seek", "");
r_config_set_i_cb (cfg, "scr.cols", 16, &config_scrcols_callback);
r_config_desc (cfg, "scr.cols", "Configure the number of columns to print");
@ -697,7 +697,7 @@ R_API int r_core_config_init(RCore *core) {
r_config_desc (cfg, "magic.depth", "Recursivity depth in magic description strings");
r_config_set (cfg, "rap.loop", "true");
r_config_desc (cfg, "rap.loop", "run rap as a forever-listening daemon");
/* fkeys */
/* nkeys */
for (i=1; i<13; i++) {
snprintf (buf, sizeof (buf), "key.f%d", i);
snprintf (buf+10, sizeof (buf)-10,
@ -720,7 +720,7 @@ R_API int r_core_config_init(RCore *core) {
r_config_set_i (cfg, "zoom.to", 0);
r_config_desc (cfg, "zoom.to", "Zoom end address");
r_config_set_cb (cfg, "zoom.byte", "h", &config_zoombyte_callback);
r_config_desc (cfg, "zoom.byte", "Zoom callback to calculate each byte (See pZ? for help)");
r_config_desc (cfg, "zoom.byte", "Zoom callback to calculate each byte (See pz? for help)");
/* TODO cmd */
#if 0
config_set("asm.section", "true");

View File

@ -319,6 +319,9 @@ toro:
pre = " ";
if (f->addr == at) {
char *sign = r_anal_fcn_to_string (core->anal, f);
if (f->type == R_ANAL_FCN_TYPE_LOC) {
r_cons_printf ("|- %s (%d)\n| ", f->name, f->size);
} else
r_cons_printf ("/ %s: %s (%d)\n| ",
(f->type==R_ANAL_FCN_TYPE_FCN||f->type==R_ANAL_FCN_TYPE_SYM)?"function":
(f->type==R_ANAL_FCN_TYPE_IMP)?"import":"loc",
@ -409,11 +412,11 @@ toro:
continue;
}
/* show cursor */
if (core->print->cur_enabled && cursor >= idx && cursor < (idx+oplen))
r_cons_printf ("* ");
else {
{
int q = core->print->cur_enabled && cursor >= idx && cursor < (idx+oplen);
void *p = r_bp_get (core->dbg->bp, at);
r_cons_printf (p? "b ": " ");
r_cons_printf (p&&q?"b*":p? "b ":q?"* ":" ");
}
if (show_bytes) {
char *str = NULL, pad[64];

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2012 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2009-2012 - pancake */
#include <r_core.h>

View File

@ -6,8 +6,8 @@
static int blocksize = 0;
static const char *printfmt[] = {
"x", "pd",
"f tmp;sr sp;pw 64;dr=;s-;s tmp;f-tmp;pd",
"pw", "pc"
"f tmp;sr sp;pxw 64;dr=;s-;s tmp;f-tmp;pd",
"pxw", "pc"
};
static int autoblocksize = 1;
static int obs = 0;
@ -94,7 +94,7 @@ R_API void r_core_visual_prompt (RCore *core) {
if (curset) r_core_seek (core, oseek, 1);
}
static int visual_fkey(RCore *core, int ch) {
static int visual_nkey(RCore *core, int ch) {
const char *cmd;
switch (ch) {
case R_CONS_KEY_F1:
@ -206,7 +206,7 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
char buf[4096];
int i, cols = core->print->cols;
ch = r_cons_arrow_to_hjkl (ch);
ch = visual_fkey (core, ch);
ch = visual_nkey (core, ch);
if (ch<2) return 1;
// do we need hotkeys for data references? not only calls?
@ -247,10 +247,25 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
r_print_set_flags (core->print, flags);
break;
case 'f':
r_core_seek_next (core, r_config_get (core->config, "scr.fkey"));
{
char name[256], *n;
r_line_set_prompt ("flag name: ");
if (r_cons_fgets (name, sizeof (name), 0, NULL) >=0 && *name) {
int range = curset? (R_ABS (cursor-ocursor)+1): 1;
if (range<1) range=1;
n = r_str_chop (name);
if (*n) r_flag_set (core->flags, n, core->offset + cursor, range, 1);
}
}
break;
case 'F':
r_core_seek_previous (core, r_config_get (core->config, "scr.fkey"));
r_flag_unset_i (core->flags, core->offset + cursor, NULL);
break;
case 'n':
r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
break;
case 'N':
r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
break;
case 'a':
if (core->file && !(core->file->rwx & 2)) {
@ -635,12 +650,10 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
case '.':
r_core_cmd (core, "sr pc", 0);
break;
case 'n':
r_core_seek_delta (core, core->blocksize);
break;
case 'N':
r_core_seek_delta (core, 0-(int)core->blocksize);
break;
#if 0
case 'n': r_core_seek_delta (core, core->blocksize); break;
case 'N': r_core_seek_delta (core, 0-(int)core->blocksize); break;
#endif
case ':':
r_core_visual_prompt (core);
break;
@ -678,6 +691,17 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
r_cons_set_raw (R_TRUE);
r_cons_show_cursor (R_FALSE);
break;
case 'b':
{
ut64 addr = curset? core->offset + cursor : core->offset;
RBreakpointItem *bp = r_bp_get (core->dbg->bp, addr);
if (bp) {
r_bp_del (core->dbg->bp, addr);
} else {
r_bp_add_sw (core->dbg->bp, addr, 1, R_BP_PROT_EXEC);
}
}
break;
case 'B':
autoblocksize = !autoblocksize;
if (autoblocksize)
@ -713,8 +737,7 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
r_cons_printf (
"Visual mode help:\n"
" >||< seek aligned to block size\n"
" hjkl move around\n"
" HJKL move around faster\n"
" hjkl move around (or HJKL)\n"
" pP rotate print modes\n"
" /*+-[] change block size, [] = resize scr.cols\n"
" cC toggle cursor and colors\n"
@ -723,14 +746,15 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
" D enter visual diff mode (set diff.from/to)\n"
" x show xrefs to seek between them\n"
" sS step / step over\n"
" n/N seek next/previous block\n"
//" n/N seek next/previous block\n"
" e edit eval configuration variables\n"
" t track flags (browse symbols, functions..)\n"
" T browse anal info and comments\n"
" v visual code analysis menu\n"
" V view graph using cmd.graph (agv?)\n"
" fF seek next/prev function/flag/hit (scr.fkey)\n"
" B toggle automatic block size\n"
" f/F set/unset flag\n"
" n/N seek next/prev function/flag/hit (scr.nkey)\n"
" b/B toggle breakpoint / automatic block size\n"
" uU undo/redo seek\n"
" yY copy and paste selection\n"
" mK/'K mark/go to Key (any key)\n"
@ -834,7 +858,7 @@ static void r_core_visual_refresh (RCore *core) {
r_core_cmd (core, vi, 0);
r_cons_column (80);
}
if (zoom) r_core_cmd (core, "pZ", 0);
if (zoom) r_core_cmd (core, "pz", 0);
else r_core_cmd (core, printfmt[PIDX], 0);
blocksize = core->num->value? core->num->value : core->blocksize;
r_cons_visual_flush ();

View File

@ -1,12 +1,13 @@
/* radare - LGPL - Copyright 2009-2012 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2009-2012 - pancake */
#include "r_core.h"
#define MAX_FORMAT 2
R_API int r_core_visual_trackflags(RCore *core) {
char cmd[1024];
RListIter *iter;
RFlagItem *flag;
#define MAX_FORMAT 2
int format = 0;
const char *fs = NULL;
char *fs2 = NULL;
@ -338,6 +339,7 @@ R_API int r_core_visual_comments (RCore *core) {
if (mode == 0) {
if (p) r_meta_del (core->anal->meta, R_META_TYPE_ANY, from, size, p);
} else {
r_anal_fcn_del_locs (core->anal, from);
r_anal_fcn_del (core->anal, from);
}
break;
@ -441,7 +443,6 @@ R_API void r_core_visual_config(RCore *core) {
RListIter *iter;
RConfigNode *bt;
char cmd[1024];
#define MAX_FORMAT 2
char *fs = NULL;
char *fs2 = NULL;
int option, _option = 0;
@ -1203,8 +1204,7 @@ R_API void r_core_visual_define (RCore *core) {
" S - set strings in current block\n"
" f - analyze function\n"
" u - undefine metadata here\n"
" q - quit/cancel operation\n"
"TODO: add support for data, string, code ..\n");
" q - quit/cancel operation\n");
r_cons_flush ();
// get ESC+char, return 'hjkl' char
@ -1245,9 +1245,14 @@ R_API void r_core_visual_define (RCore *core) {
r_meta_add (core->anal->meta, R_META_TYPE_CODE, off, off+core->blocksize, "");
break;
case 'u':
r_meta_del (core->anal->meta, R_META_TYPE_ANY, off, 1, "");
r_flag_unset_i (core->flags, off, NULL);
r_anal_fcn_del (core->anal, off);
{
// rm bbs
RAnalFunction *f = r_anal_fcn_find (core->anal, off, 0);
r_anal_fcn_del_locs (core->anal, off);
if (f) r_meta_del (core->anal->meta, R_META_TYPE_ANY, off, f->size, "");
r_anal_fcn_del (core->anal, off);
}
break;
case 'f':
r_cons_break(NULL,NULL);

View File

@ -154,6 +154,11 @@ R_API int r_flag_unset_i(RFlag *f, ut64 addr, RFlagItem *p) {
RFlagItem *item;
RListIter *iter;
#if USE_BTREE
/* XXX */
btree_del (f->tree, item, cmp, NULL);
btree_del (f->ntree, item, ncmp, NULL);
#endif
/* No _safe loop necessary because we return immediately after the delete. */
r_list_foreach (f->flags, iter, item) {
if (item->offset == addr) {

View File

@ -205,9 +205,9 @@ R_API int r_flag_rename(RFlag *f, RFlagItem *item, const char *name) {
}
R_API int r_flag_unset_i(RFlag *f, ut64 off, RFlagItem *p) {
RFlagItem *item = r_flag_get_i (f, off);
eprintf ("TODO: r_flag_unset_i\n");
if (item) {
RFlagItem *flag = r_flag_get_i (f, off);
if (flag) {
r_flag_unset (f, flag->name, NULL); //, flag);
return R_TRUE;
}
return R_FALSE;

View File

@ -95,7 +95,7 @@ enum {
/* type = (R_ANAL_VAR_TYPE_BYTE & R_ANAL_VAR_TYPE_SIZE_MASK) |
* ( RANAL_VAR_TYPE_SIGNED & RANAL_VAR_TYPE_SIGN_MASK) |
* ( RANAL_VAR_TYPE_CONST & RANAL_VAR_TYPE_MODIFIER_MASK)
*/
*/
typedef struct r_anal_type_var_t {
char *name;
ut16 type; // contain (type || signedness || modifier)
@ -113,7 +113,7 @@ typedef struct r_anal_type_ptr_t {
ut16 type; // contain (type || signedness || modifier)
ut8 size;
union {
ut8 v8;
ut8 v8;
ut16 v16;
ut32 v32;
ut64 v64;
@ -287,7 +287,7 @@ typedef struct r_anal_fcn_store_t {
typedef struct r_anal_type_function_t {
char* name;
char* dsc; // For producing nice listings
ut64 size; // Size of function
int size; // Size of function XXX. use int, or ut32. no need for ut64
short type;
/*item_list *rets; // Type of return value */
short rets;
@ -681,6 +681,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr,
R_API int r_anal_fcn_add(RAnal *anal, ut64 addr, ut64 size,
const char *name, int type, RAnalDiff *diff);
R_API int r_anal_fcn_del(RAnal *anal, ut64 addr);
R_API int r_anal_fcn_del_locs(RAnal *anal, ut64 addr);
R_API int r_anal_fcn_add_bb(RAnalFunction *fcn, ut64 addr, ut64 size,
ut64 jump, ut64 fail, int type, RAnalDiff *diff);
R_API int r_anal_fcn_cc(RAnalFunction *fcn);