Add visual search and enhace search output

- e search.show = true # by default
- add keyword type (string, binary)
- visual search only works in cursor mode
This commit is contained in:
pancake 2012-08-02 01:50:39 +02:00
parent e43a1f921d
commit afbda180d5
11 changed files with 140 additions and 11 deletions

View File

@ -22,6 +22,10 @@ plugins.cfg:
gitpush:
sh mk/gitpush.sh
.PHONY: todo
todo:
grep -re TODO:0.9.2 libr binr
libr:
cd libr && ${MAKE} all

19
TODO
View File

@ -5,13 +5,30 @@
------8<-------------------8<--------------------8<-----------------8<----------
* add 'mov al, cl' for x86.nz
* fix ragg2
====[[ 0.9.1 ]]====
* Analysis
- assume there's a function at the end of each function
* Allow to seek to branch N like in visual, but from cmdline
* Colorize multiple ranges of chars in hexdump
* List functions
- calculate and show ciclomatic complexity
* Searching for asm opcodes does not increase the hit count?
* insert assembly in visual should be more userfriendly (keep unwritten bytes)
* Search in io.va=true must be fixed
- search.infile=true (ignore va and offset)
* Source debugging or gtfo
- integration with rabin2 -d
* get cparse ftw
* show analized functions in 'aa' -> discuss
* show search hits.. if string, if hexdump...
if (search.view) {
if (is_string) pf z
}
* timeout for code analysis (check timestamp)
* io_next must work properly
- r_io must read in 512 or 4096 aligned blocks (get next section?)
Discuss
Add $EDITOR alias for file open(read/write) -

View File

@ -26,7 +26,7 @@ RAsmPlugin r_asm_plugin_dcpu16 = {
.name = "dcpu16",
.arch = "dpcu",
.bits = (int[]){ 16, 0 },
.desc = "DCPU16 disassembly plugin",
.desc = "DCPU16 assembler/disassembler",
.init = NULL,
.fini = NULL,
.disassemble = &disassemble,

View File

@ -73,7 +73,7 @@ static int cmd_print(void *data, const char *input) {
return R_FALSE;
}
if (input[0] && input[1] == 'f') {
if (input[0] && input[0]!='Z' && input[1] == 'f') {
RAnalFunction *f = r_anal_fcn_find (core->anal, core->offset,
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
if (f) len = f->size;
@ -431,7 +431,11 @@ return 0;
break;
}
break;
case 'z':
eprintf ("TODO:0.9.2: pz (ascii and zero-terminated string)\n");
break;
case 'Z':
// TODO:0.9.2 zoom.byte changes does not take any effect
if (input[1]=='?') {
r_cons_printf (
"Usage: pZ [len]\n"
@ -460,7 +464,7 @@ return 0;
to = r_io_size (core->io);
from = r_config_get_i (core->config, "zoom.from");
to = r_config_get_i (core->config, "zoom.to");
if (input[1] != '\0' && input[1] != ' ') {
if (input[1] && input[1] != ' ') {
oldzoom = strdup (r_config_get (core->config, "zoom.byte"));
if (!r_config_set (core->config, "zoom.byte", input+1)) {
eprintf ("Invalid zoom.byte mode (%s)\n", input+1);
@ -501,6 +505,7 @@ return 0;
" pu [len] print N url encoded bytes\n"
" pU [len] print N wide url encoded bytes\n"
" px [len] hexdump of N bytes\n"
" pz [len] print zero terminated ascii string\n"
" pZ [len] print zoom view (see pZ? for help)\n");
break;
}

View File

@ -2,6 +2,7 @@
static int preludecnt = 0;
static int searchflags = 0;
static int searchshow = 0;
static const char *cmdhit = NULL;
static const char *searchprefix = NULL;
static unsigned int searchcount = 0;
@ -80,12 +81,51 @@ static int __cb_hit(RSearchKeyword *kw, void *user, ut64 addr) {
return R_FALSE;
}
}
if (searchshow) {
int len, i;
ut8 buf[64];
char str[128], *p;
switch (kw->type) {
case R_SEARCH_KEYWORD_TYPE_STRING:
len = sizeof (str);
r_io_read_at (core->io, addr, str+1, len-2);
*str = '"';
r_str_filter_zeroline (str, len);
strcpy (str+strlen (str), "\"");
break;
default:
len = kw->keyword_length + 8; // 8 byte context
if (len>=sizeof (str)) len = sizeof (str)-1;
r_io_read_at (core->io, addr, buf, sizeof (buf));
for (i=0, p=str; i<len; i++) {
sprintf (p, "%02x", buf[i]);
p += 2;
if (i == kw->keyword_length)
*p++ = ' ';
}
*p = 0;
break;
}
r_cons_printf ("0x%08"PFMT64x" %s%d_%d %s\n",
addr, searchprefix, kw->kwidx, kw->count, str);
} else {
if (searchflags) {
r_cons_printf ("%s%d_%d\n", searchprefix, kw->kwidx, kw->count);
} else {
r_cons_printf ("f %s%d_%d %d 0x%08"PFMT64x"\n", searchprefix,
kw->kwidx, kw->count, kw->keyword_length, addr);
}
}
if (searchflags) {
r_cons_printf ("%s%d_%d\n", searchprefix, kw->kwidx, kw->count);
char flag[64];
snprintf (flag, sizeof (flag), "%s%d_%d", searchprefix, kw->kwidx, kw->count);
r_flag_set (core->flags, flag, addr, kw->keyword_length, 1);
#if 0
// TODO: use r_flag_set ()
r_core_cmdf (core, "f %s%d_%d %d 0x%08"PFMT64x"\n", searchprefix,
kw->kwidx, kw->count, kw->keyword_length, addr);
} else r_cons_printf ("f %s%d_%d %d 0x%08"PFMT64x"\n", searchprefix,
kw->kwidx, kw->count, kw->keyword_length, addr);
#endif
}
if (!strnull (cmdhit)) {
ut64 here = core->offset;
r_core_seek (core, addr, R_FALSE);
@ -118,6 +158,7 @@ static int cmd_search(void *data, const char *input) {
ut16 n16;
ut8 *buf;
searchshow = r_config_get_i (core->config, "search.show");
mode = r_config_get (core->config, "search.in");
if (!strcmp (mode, "block")) {
from = core->offset;
@ -319,6 +360,7 @@ static int cmd_search(void *data, const char *input) {
RSearchKeyword *skw;
skw = r_search_keyword_new ((const ut8*)inp, len, NULL, 0, NULL);
skw->icase = ignorecase;
skw->type = R_SEARCH_KEYWORD_TYPE_STRING;
r_search_kw_add (core->search, skw);
}
r_search_begin (core->search);

View File

@ -584,6 +584,8 @@ R_API int r_core_config_init(RCore *core) {
r_config_desc (cfg, "search.in", "Specify search boundaries (raw, block, file, section)");
r_config_set_i (cfg, "search.kwidx", 0);
r_config_desc (cfg, "search.kwidx", "Store last search index count");
r_config_set (cfg, "search.show", "true");
r_config_desc (cfg, "search.show", "Show search results while found (disable if lot of hits)");
r_config_set (cfg, "search.flags", "true");
r_config_desc (cfg, "search.flags", "If enabled all search results are flagged, else just printed r2 commands");
r_config_set_i (cfg, "search.count", 0);

View File

@ -151,6 +151,40 @@ void setcursor (RCore *core, int cur) {
core->print->col = curset? 1: 0;
}
// TODO: integrate in '/' command with search.inblock ?
static void visual_search (RCore *core) {
ut8 *p;
int len, d=cursor;
char str[128], buf[258];
r_line_set_prompt ("search byte/string in block: ");
r_cons_fgets (str, sizeof (str), 0, NULL);
len = r_hex_str2bin (str, buf);
if (*str=='"') {
char *e = strncpy (buf, str+1, sizeof (buf)-1);
if (e) { --e; if (*e=='"') *e=0; }
len = strlen (buf);
} else
if (len<1) {
strncpy (buf, str, sizeof (buf)-1);
len = strlen (str);
}
p = r_mem_mem (core->block+d, core->blocksize-d, buf, len);
if (p) {
cursor = (int)(size_t)(p-core->block);
if (len>1) {
ocursor = cursor+len-1;
} else ocursor = -1;
r_cons_show_cursor (R_TRUE);
eprintf ("FOUND IN %d\n", cursor);
r_cons_any_key ();
} else {
eprintf ("Cannot find bytes\n");
r_cons_any_key ();
r_cons_clear00 ();
}
}
R_API int r_core_visual_cmd(RCore *core, int ch) {
RAsmOp op;
char buf[4096];
@ -544,8 +578,12 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
}
break;
case '/':
if (!autoblocksize)
r_core_block_size (core, core->blocksize-cols);
if (curset) {
visual_search (core);
} else {
if (!autoblocksize)
r_core_block_size (core, core->blocksize-cols);
}
break;
case '*':
if (!autoblocksize)
@ -662,6 +700,7 @@ R_API int r_core_visual_cmd(RCore *core, int ch) {
" mK/'K mark/go to Key (any key)\n"
" M show mount points\n"
" _ enter hud mode\n"
" / in cursor mode search in current block\n"
" :cmd run radare command\n"
" ;[-]cmt add/remove comment\n"
" . seek to program counter\n"

View File

@ -19,6 +19,9 @@ enum {
#define R_SEARCH_DISTANCE_MAX 10
#define R_SEARCH_KEYWORD_TYPE_BINARY 'i'
#define R_SEARCH_KEYWORD_TYPE_STRING 's'
typedef struct r_search_keyword_t {
char keyword[128];
char binmask[128];
@ -32,7 +35,7 @@ typedef struct r_search_keyword_t {
int count;
int kwidx;
int icase; // ignore case
RList *list;
int type;
} RSearchKeyword;
typedef struct r_search_hit_t {

View File

@ -318,6 +318,7 @@ R_API int r_name_filter(char *name, int len);
R_API void r_base64_encode(ut8 *bout, const ut8 *bin, int len);
R_API int r_base64_decode(ut8 *bout, const ut8 *bin, int len);
/* strings */
R_API void r_str_filter_zeroline(char *str, int len);
R_API int r_str_write (int fd, const char *b);
R_API void r_str_ncpy(char *dst, const char *src, int n);
R_API void r_str_sanitize(char *c);

View File

@ -9,6 +9,7 @@ R_API RSearchKeyword* r_search_keyword_new(const ut8 *kw, int kwlen, const ut8 *
if (bm == NULL)
bm = (const ut8*) "";
if ((k = R_NEW (RSearchKeyword))) {
k->type = R_SEARCH_KEYWORD_TYPE_BINARY;
k->icase = 0;
memcpy (k->keyword, kw, kwlen);
k->keyword_length = kwlen;
@ -40,7 +41,10 @@ R_API RSearchKeyword* r_search_keyword_new_str(const char *kw, const char *bmhex
}
}
ks = r_search_keyword_new ((ut8 *)kw, strlen (kw), bm, bmlen, data);
if (ks) ks->icase = icase;
if (ks) {
ks->icase = icase;
ks->type = R_SEARCH_KEYWORD_TYPE_STRING;
}
free (bm);
return ks;
}

View File

@ -724,6 +724,18 @@ R_API int r_str_ansi_filter(char *str, int len) {
return j;
}
R_API void r_str_filter_zeroline(char *str, int len) {
int i;
for (i=0; str[i] && i<len; i++) {
// TODO: honor newlines?
if (str[i]=='\n' || str[i]=='\r')
break;
if (!IS_PRINTABLE (str[i]))
break;
}
str[i] = 0;
}
R_API void r_str_filter(char *str, int len) {
int i;
for (i=0; i<len; i++)