2013-02-15 03:08:42 +08:00
|
|
|
/* radare - LGPL - Copyright 2009-2013 - pancake */
|
2010-05-29 09:30:36 +08:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2012-06-01 20:50:24 +08:00
|
|
|
#include <getopt.c>
|
2010-05-29 09:30:36 +08:00
|
|
|
|
|
|
|
#include <r_types.h>
|
|
|
|
#include <r_print.h>
|
|
|
|
#include <r_search.h>
|
|
|
|
#include <r_util.h>
|
|
|
|
#include <r_cons.h>
|
|
|
|
#include <r_lib.h>
|
|
|
|
#include <r_io.h>
|
|
|
|
|
|
|
|
static struct r_io_t *io;
|
2011-01-23 20:12:16 +08:00
|
|
|
static RIODesc *fd = NULL;
|
2013-02-15 03:08:42 +08:00
|
|
|
static int showstr = 0;
|
2010-05-29 09:30:36 +08:00
|
|
|
static int rad = 0;
|
|
|
|
struct r_search_t *rs;
|
|
|
|
static ut64 from = 0LL, to = -1;
|
|
|
|
static char *mask = "";
|
|
|
|
static int nonstop = 0;
|
|
|
|
static int mode = R_SEARCH_STRING;
|
|
|
|
static ut64 cur = 0;
|
2013-05-22 10:22:49 +08:00
|
|
|
static ut8 *buf = NULL;
|
2010-05-29 09:30:36 +08:00
|
|
|
static char *curfile = NULL;
|
|
|
|
static ut64 bsize = 4096;
|
|
|
|
static int hexstr = 0;
|
2015-02-04 10:03:44 +08:00
|
|
|
static int widestr = 0;
|
2010-05-29 09:30:36 +08:00
|
|
|
static struct r_print_t *pr = NULL;
|
2012-11-02 10:35:50 +08:00
|
|
|
static RList *keywords;
|
2010-05-29 09:30:36 +08:00
|
|
|
|
|
|
|
static int hit(RSearchKeyword *kw, void *user, ut64 addr) {
|
|
|
|
int delta = addr-cur;
|
|
|
|
if (rad) {
|
2011-06-22 06:28:03 +08:00
|
|
|
printf ("f hit%d_%d 0x%08"PFMT64x" ; %s\n", 0, kw->count, addr, curfile);
|
2010-05-29 09:30:36 +08:00
|
|
|
} else {
|
2013-02-15 03:08:42 +08:00
|
|
|
if (showstr) {
|
2013-05-22 10:22:49 +08:00
|
|
|
printf ("0x%"PFMT64x" %s\n", addr, buf+delta);
|
2013-02-15 03:08:42 +08:00
|
|
|
} else {
|
|
|
|
printf ("0x%"PFMT64x"\n", addr);
|
|
|
|
if (pr) {
|
2013-05-22 10:22:49 +08:00
|
|
|
r_print_hexdump (pr, addr, (ut8*)buf+delta, 78, 16, R_TRUE);
|
2013-02-15 03:08:42 +08:00
|
|
|
r_cons_flush ();
|
|
|
|
}
|
2010-05-29 09:30:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int show_help(char *argv0, int line) {
|
2015-02-04 10:03:44 +08:00
|
|
|
printf ("Usage: %s [-Xnzhv] [-b sz] [-f/t from/to] [-[m|s|S|e] str] [-x hex] file ..\n", argv0);
|
2010-05-29 09:30:36 +08:00
|
|
|
if (line) return 0;
|
2011-06-22 06:28:03 +08:00
|
|
|
printf (
|
2013-02-15 20:24:09 +08:00
|
|
|
" -h show this help\n"
|
|
|
|
" -v print version and exit\n"
|
|
|
|
" -b [size] set block size\n"
|
|
|
|
|
2011-06-22 06:28:03 +08:00
|
|
|
" -f [from] start searching from address 'from'\n"
|
|
|
|
" -t [to] stop search at address 'to'\n"
|
|
|
|
" -n do not stop on read errors\n"
|
2013-02-15 20:24:09 +08:00
|
|
|
|
|
|
|
" -s [str] search for a specific string (can be used multiple times)\n"
|
2015-02-04 10:03:44 +08:00
|
|
|
" -S [str] search for a specific wide string (can be used multiple times)\n"
|
2013-02-15 20:24:09 +08:00
|
|
|
" -x [hex] search for hexpair string (909090) (can be used multiple times)\n"
|
|
|
|
" -e [regex] search for regular expression string matches\n"
|
|
|
|
" -m [str] set a binary mask to be applied on keywords\n"
|
|
|
|
" -z search for zero-terminated strings\n"
|
|
|
|
|
2011-06-22 06:28:03 +08:00
|
|
|
" -r print using radare commands\n"
|
2013-02-15 20:24:09 +08:00
|
|
|
" -X show hexdump of search results\n"
|
|
|
|
" -Z show zero-terminated strings of search results\n"
|
2010-05-29 09:30:36 +08:00
|
|
|
);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int rafind_open(char *file) {
|
2012-11-02 10:35:50 +08:00
|
|
|
const char *kw;
|
|
|
|
RListIter *iter;
|
2010-05-29 09:30:36 +08:00
|
|
|
int ret, last = 0;
|
2010-09-15 16:50:43 +08:00
|
|
|
|
2011-01-23 20:12:16 +08:00
|
|
|
io = r_io_new ();
|
2014-09-07 05:05:59 +08:00
|
|
|
fd = r_io_open_nomap (io, file, R_IO_READ, 0);
|
2011-01-23 20:12:16 +08:00
|
|
|
if (fd == NULL) {
|
2010-09-15 16:50:43 +08:00
|
|
|
eprintf ("Cannot open file '%s'\n", file);
|
2010-05-29 09:30:36 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-06-22 06:28:03 +08:00
|
|
|
r_cons_new ();
|
2010-09-15 16:50:43 +08:00
|
|
|
rs = r_search_new (mode);
|
2013-05-22 10:22:49 +08:00
|
|
|
buf = malloc (bsize);
|
|
|
|
if (buf==NULL) {
|
2010-09-15 16:50:43 +08:00
|
|
|
eprintf ("Cannot allocate %"PFMT64d" bytes\n", bsize);
|
|
|
|
return 1;
|
2010-05-29 09:30:36 +08:00
|
|
|
}
|
2013-05-22 10:22:49 +08:00
|
|
|
r_search_set_callback (rs, &hit, buf);
|
2010-09-15 16:50:43 +08:00
|
|
|
if (to == -1)
|
2011-01-21 17:21:04 +08:00
|
|
|
to = r_io_size(io);
|
2011-12-01 17:53:02 +08:00
|
|
|
if (mode == R_SEARCH_STRING) {
|
|
|
|
eprintf ("TODO: searchin stringz\n");
|
|
|
|
}
|
2010-05-29 09:30:36 +08:00
|
|
|
if (mode == R_SEARCH_KEYWORD) {
|
2012-11-02 10:35:50 +08:00
|
|
|
r_list_foreach (keywords, iter, kw) {
|
2015-02-04 10:03:44 +08:00
|
|
|
if (hexstr)
|
|
|
|
r_search_kw_add (rs, r_search_keyword_new_hex (kw, mask, NULL));
|
|
|
|
else if (widestr)
|
|
|
|
r_search_kw_add (rs, r_search_keyword_new_wide (kw, mask, NULL, 0));
|
|
|
|
else
|
|
|
|
r_search_kw_add (rs, r_search_keyword_new_str (kw, mask, NULL, 0));
|
2010-05-29 09:30:36 +08:00
|
|
|
}
|
2011-12-02 07:18:35 +08:00
|
|
|
} else if (mode == R_SEARCH_STRING) {
|
|
|
|
r_search_kw_add (rs,
|
|
|
|
r_search_keyword_new_hexmask ("00", NULL)); //XXX
|
2010-05-29 09:30:36 +08:00
|
|
|
}
|
2011-12-02 07:18:35 +08:00
|
|
|
|
2010-05-29 09:30:36 +08:00
|
|
|
curfile = file;
|
2010-09-15 16:50:43 +08:00
|
|
|
r_search_begin (rs);
|
|
|
|
r_io_seek (io, from, R_IO_SEEK_SET);
|
2010-05-29 09:30:36 +08:00
|
|
|
//printf("; %s 0x%08"PFMT64x"-0x%08"PFMT64x"\n", file, from, to);
|
2011-12-02 07:18:35 +08:00
|
|
|
for (cur = from; !last && cur < to; cur += bsize) {
|
2010-05-29 09:30:36 +08:00
|
|
|
if ((cur+bsize)>to) {
|
|
|
|
bsize = to-cur;
|
|
|
|
last=1;
|
|
|
|
}
|
2014-09-07 05:39:43 +08:00
|
|
|
ret = r_io_pread (io, cur, buf, bsize);
|
2010-05-29 09:30:36 +08:00
|
|
|
if (ret == 0) {
|
|
|
|
if (nonstop) continue;
|
|
|
|
// fprintf(stderr, "Error reading at 0x%08"PFMT64x"\n", cur);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (ret != bsize)
|
|
|
|
bsize = ret;
|
2011-12-02 07:18:35 +08:00
|
|
|
|
2013-05-22 10:22:49 +08:00
|
|
|
if (r_search_update (rs, &cur, buf, ret) == -1) {
|
2011-12-02 07:18:35 +08:00
|
|
|
eprintf ("search: update read error at 0x%08"PFMT64x"\n", cur);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-05-29 09:30:36 +08:00
|
|
|
}
|
2010-09-15 16:50:43 +08:00
|
|
|
rs = r_search_free (rs);
|
2013-05-22 10:22:49 +08:00
|
|
|
free (buf);
|
2010-05-29 09:30:36 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
|
|
int c;
|
|
|
|
|
2012-11-02 10:35:50 +08:00
|
|
|
keywords = r_list_new ();
|
2015-02-04 10:03:44 +08:00
|
|
|
while ((c = getopt(argc, argv, "e:b:m:s:S:x:Xzf:t:rnhvZ")) != -1) {
|
2011-06-22 06:28:03 +08:00
|
|
|
switch (c) {
|
2010-05-29 09:30:36 +08:00
|
|
|
case 'r':
|
|
|
|
rad = 1;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
nonstop = 1;
|
|
|
|
break;
|
2011-06-22 06:28:03 +08:00
|
|
|
case 'e':
|
|
|
|
mode = R_SEARCH_REGEXP;
|
|
|
|
hexstr = 0;
|
2012-11-02 10:35:50 +08:00
|
|
|
r_list_append (keywords, optarg);
|
2011-06-22 06:28:03 +08:00
|
|
|
break;
|
2010-05-29 09:30:36 +08:00
|
|
|
case 's':
|
|
|
|
mode = R_SEARCH_KEYWORD;
|
|
|
|
hexstr = 0;
|
2015-02-04 10:03:44 +08:00
|
|
|
widestr = 0;
|
2012-11-02 10:35:50 +08:00
|
|
|
r_list_append (keywords, optarg);
|
2010-05-29 09:30:36 +08:00
|
|
|
break;
|
2015-02-04 10:03:44 +08:00
|
|
|
case 'S':
|
|
|
|
mode = R_SEARCH_KEYWORD;
|
|
|
|
hexstr = 0;
|
|
|
|
widestr = 1;
|
|
|
|
r_list_append(keywords, optarg);
|
|
|
|
break;
|
2010-05-29 09:30:36 +08:00
|
|
|
case 'b':
|
2011-06-22 06:28:03 +08:00
|
|
|
bsize = r_num_math (NULL, optarg);
|
2010-05-29 09:30:36 +08:00
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
mode = R_SEARCH_KEYWORD;
|
|
|
|
hexstr = 1;
|
2015-02-04 10:03:44 +08:00
|
|
|
widestr = 0;
|
2012-11-02 10:35:50 +08:00
|
|
|
r_list_append (keywords, optarg);
|
2010-05-29 09:30:36 +08:00
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
// XXX should be from hexbin
|
|
|
|
mask = optarg;
|
|
|
|
break;
|
|
|
|
case 'f':
|
2010-07-15 19:34:53 +08:00
|
|
|
from = r_num_math (NULL, optarg);
|
2010-05-29 09:30:36 +08:00
|
|
|
break;
|
|
|
|
case 't':
|
2010-07-15 19:34:53 +08:00
|
|
|
to = r_num_math (NULL, optarg);
|
2010-05-29 09:30:36 +08:00
|
|
|
break;
|
|
|
|
case 'X':
|
2010-07-15 19:34:53 +08:00
|
|
|
pr = r_print_new ();
|
2010-05-29 09:30:36 +08:00
|
|
|
break;
|
2011-12-02 10:43:08 +08:00
|
|
|
case 'v':
|
2010-07-15 19:34:53 +08:00
|
|
|
printf ("rafind2 v"R2_VERSION"\n");
|
2010-05-29 09:30:36 +08:00
|
|
|
return 0;
|
|
|
|
case 'h':
|
|
|
|
return show_help(argv[0], 0);
|
2013-02-15 03:08:42 +08:00
|
|
|
case 'z':
|
|
|
|
mode = R_SEARCH_STRING;
|
|
|
|
break;
|
|
|
|
case 'Z':
|
|
|
|
showstr = 1;
|
|
|
|
break;
|
2010-05-29 09:30:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (optind == argc)
|
2010-09-15 16:50:43 +08:00
|
|
|
return show_help (argv[0], 1);
|
2010-05-29 09:30:36 +08:00
|
|
|
|
|
|
|
for (;optind < argc;optind++)
|
2010-09-15 16:50:43 +08:00
|
|
|
rafind_open (argv[optind]);
|
2010-05-29 09:30:36 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|