Fix #20439 - rafind2 -V search for values like in /v ##tools

This commit is contained in:
pancake 2022-07-31 19:33:20 +02:00 committed by pancake
parent a2007867bb
commit fec0a64b41
4 changed files with 61 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2021 - pancake */ /* radare - LGPL - Copyright 2009-2022 - pancake */
#include <r_main.h> #include <r_main.h>

View File

@ -34,6 +34,7 @@ typedef struct {
RPrint *pr; RPrint *pr;
RList *keywords; RList *keywords;
const char *mask; const char *mask;
const char *valstr;
const char *curfile; const char *curfile;
PJ *pj; PJ *pj;
} RafindOptions; } RafindOptions;
@ -188,6 +189,7 @@ static int show_help(const char *argv0, int line) {
" -t [to] stop search at address 'to'\n" " -t [to] stop search at address 'to'\n"
" -q quiet: fewer output do not show headings or filenames.\n" " -q quiet: fewer output do not show headings or filenames.\n"
" -v print version and exit\n" " -v print version and exit\n"
" -V [s:num] search for given value (-V 4:123) // assume local endian\n"
" -x [hex] search for hexpair string (909090) (can be used multiple times)\n" " -x [hex] search for hexpair string (909090) (can be used multiple times)\n"
" -X show hexdump of search results\n" " -X show hexdump of search results\n"
" -z search for zero-terminated strings\n" " -z search for zero-terminated strings\n"
@ -389,7 +391,7 @@ R_API int r_main_rafind2(int argc, const char **argv) {
return show_help (argv[0], 0); return show_help (argv[0], 0);
} }
RGetopt opt; RGetopt opt;
r_getopt_init (&opt, argc, argv, "a:ie:b:cjmM:s:S:x:Xzf:F:t:E:rqnhvZL"); r_getopt_init (&opt, argc, argv, "a:ie:b:cjmM:s:S:x:Xzf:F:t:E:rqnhvZLV:");
while ((c = r_getopt_next (&opt)) != -1) { while ((c = r_getopt_next (&opt)) != -1) {
switch (c) { switch (c) {
case 'a': case 'a':
@ -487,6 +489,50 @@ R_API int r_main_rafind2(int argc, const char **argv) {
case 'q': case 'q':
ro.quiet = true; ro.quiet = true;
break; break;
case 'V':
{
char *arg = strdup (opt.arg);
char *colon = strchr (arg, ':');
ut8 buf[8] = {0};
int size = (R_SYS_BITS & R_SYS_BITS_64)? 8: 4;
ut64 value = 0;
// TODO: const int endian = R_SYS_ENDIAN;
if (colon) {
*colon++ = 0;
size = atoi (arg);
size = R_MIN (8, size);
size = R_MAX (1, size);
value = r_num_math (NULL, colon);
} else {
value = r_num_math (NULL, arg);
}
switch (size) {
case 1:
buf[0] = value;
break;
case 2:
r_write_le16 (buf, value);
break;
case 4:
r_write_le32 (buf, value);
break;
case 8:
r_write_le64 (buf, value);
break;
default:
R_LOG_ERROR ("Invalid value size. Must be 1, 2, 4 or 8");
return 1;
}
char *hexdata = r_hex_bin2strdup ((ut8*)buf, size);
if (hexdata) {
ro.align = size;
ro.mode = R_SEARCH_KEYWORD;
ro.hexstr = true;
ro.widestr = false;
r_list_append (ro.keywords, (void*)hexdata);
}
}
break;
case 'v': case 'v':
return r_main_version_print ("rafind2"); return r_main_version_print ("rafind2");
case 'h': case 'h':

View File

@ -1,9 +1,8 @@
/* radare - LGPL - Copyright 2008-2016 pancake */ /* radare - LGPL - Copyright 2008-2022 pancake */
#define R_LOG_ORIGIN "search"
#include <r_search.h> #include <r_search.h>
#include <r_list.h>
#include <ctype.h>
#include <r_util/r_assert.h>
#include "search.h" #include "search.h"
// Experimental search engine (fails, because stops at first hit of every block read // Experimental search engine (fails, because stops at first hit of every block read
@ -119,14 +118,14 @@ R_API int r_search_begin(RSearch *s) {
// use when the size of the hit does not match the size of the keyword (ie: /a{30}/) // use when the size of the hit does not match the size of the keyword (ie: /a{30}/)
R_IPI int r_search_hit_sz(RSearch *s, RSearchKeyword *kw, ut64 addr, ut32 sz) { R_IPI int r_search_hit_sz(RSearch *s, RSearchKeyword *kw, ut64 addr, ut32 sz) {
if (s->align && (addr%s->align)) { if (s->align && (addr%s->align)) {
eprintf ("0x%08"PFMT64x" unaligned\n", addr); // eprintf ("0x%08"PFMT64x" unaligned\n", addr);
return 1; return 1;
} }
if (!s->contiguous) { if (!s->contiguous) {
if (kw->last && addr == kw->last) { if (kw->last && addr == kw->last) {
kw->count--; kw->count--;
kw->last = s->bckwrds? addr: addr + sz; kw->last = s->bckwrds? addr: addr + sz;
eprintf ("0x%08"PFMT64x" Sequential hit ignored.\n", addr); R_LOG_WARN ("0x%08"PFMT64x" Sequential hit ignored", addr);
return 1; return 1;
} }
} }
@ -409,7 +408,7 @@ R_IPI int search_kw_update(RSearch *s, ut64 from, const ut8 *buf, int len) {
left->len = 0; left->len = 0;
} }
} else { } else {
left = malloc (sizeof(RSearchLeftover) + (size_t)2 * (longest - 1)); left = malloc (sizeof (RSearchLeftover) + (size_t)2 * (longest - 1));
if (!left) { if (!left) {
return -1; return -1;
} }
@ -483,8 +482,8 @@ R_IPI int search_kw_update(RSearch *s, ut64 from, const ut8 *buf, int len) {
} }
R_API void r_search_set_distance(RSearch *s, int dist) { R_API void r_search_set_distance(RSearch *s, int dist) {
if (dist>=R_SEARCH_DISTANCE_MAX) { if (dist >= R_SEARCH_DISTANCE_MAX) {
eprintf ("Invalid distance\n"); R_LOG_ERROR ("Invalid distance");
s->distance = 0; s->distance = 0;
} else { } else {
s->distance = (dist>0)?dist:0; s->distance = (dist>0)?dist:0;
@ -518,7 +517,7 @@ R_API int r_search_update(RSearch *s, ut64 from, const ut8 *buf, long len) {
} }
ret = s->update (s, from, buf, len); ret = s->update (s, from, buf, len);
} else { } else {
eprintf ("r_search_update: No search method defined\n"); R_LOG_ERROR ("Missing r_search_update callback");
} }
return ret; return ret;
} }
@ -534,7 +533,7 @@ R_API int r_search_update_read(RSearch *s, ut64 from, ut64 to) {
case R_SEARCH_RABIN_KARP: case R_SEARCH_RABIN_KARP:
return search_rk (s, from, to); return search_rk (s, from, to);
default: default:
eprintf ("Unsupported mode\n"); R_LOG_WARN ("Unsupported search mode");
return -1; return -1;
} }
} }

View File

@ -11,6 +11,7 @@
.Op Fl F Ar file .Op Fl F Ar file
.Op Fl t Ar to .Op Fl t Ar to
.Op Fl [m|s|e] Ar str .Op Fl [m|s|e] Ar str
.Op Fl V Ar s:val
.Op Fl x Ar hex .Op Fl x Ar hex
.Ar file|dir .Ar file|dir
.Sh DESCRIPTION .Sh DESCRIPTION
@ -30,6 +31,8 @@ Only accept aligned hits
Search for a specific string Search for a specific string
.It Fl S Ar str .It Fl S Ar str
Search for a specific wide string Search for a specific wide string
.It Fl V Ar size:value
Search for a little-endian value of given size. For example -V 4:123
.It Fl e Ar regex .It Fl e Ar regex
Search for a regular expression string matches Search for a regular expression string matches
.It Fl x Ar hex .It Fl x Ar hex