mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-02 03:32:04 +00:00
Initial implementation of bin.strfilter and bin.strpurge
This commit is contained in:
parent
3a5612190b
commit
1dba5a687d
@ -98,6 +98,12 @@ static int rabin_show_help(int v) {
|
||||
" -zzz dump raw strings to stdout (for huge files)\n"
|
||||
" -Z guess size of binary program\n"
|
||||
);
|
||||
if (v) {
|
||||
printf ("Environment:\n"
|
||||
" RABIN2_MAXSTRBUF: e bin.maxstrbuf # specify maximum buffer size\n"
|
||||
" RABIN2_STRFILTER: e bin.strfilter # r2 -qe bin.strfilter=? -c '' --\n"
|
||||
" RABIN2_STRPURGE: e bin.strpurge # try to purge false positives\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -377,6 +383,7 @@ int main(int argc, char **argv) {
|
||||
const char *op = NULL;
|
||||
const char *chksum = NULL;
|
||||
const char *forcebin = NULL;
|
||||
char *tmp;
|
||||
RCoreBinFilter filter;
|
||||
RCore core;
|
||||
RCoreFile *cf = NULL;
|
||||
@ -397,10 +404,17 @@ int main(int argc, char **argv) {
|
||||
r_lib_opendir (l, homeplugindir);
|
||||
r_lib_opendir (l, R2_LIBDIR"/radare2/"R2_VERSION);
|
||||
|
||||
char *maxstrbuf = r_sys_getenv ("RABIN2_MAXSTRBUF");
|
||||
if (maxstrbuf) {
|
||||
r_config_set (core.config, "bin.maxstrbuf", maxstrbuf);
|
||||
free(maxstrbuf);
|
||||
if ((tmp = r_sys_getenv ("RABIN2_MAXSTRBUF"))) {
|
||||
r_config_set (core.config, "bin.maxstrbuf", tmp);
|
||||
free (tmp);
|
||||
}
|
||||
if ((tmp = r_sys_getenv ("RABIN2_STRFILTER"))) {
|
||||
r_config_set (core.config, "bin.strfilter", tmp);
|
||||
free (tmp);
|
||||
}
|
||||
if ((tmp = r_sys_getenv ("RABIN2_STRPURGE"))) {
|
||||
r_config_set (core.config, "bin.strpurge", tmp);
|
||||
free (tmp);
|
||||
}
|
||||
|
||||
#define is_active(x) (action&x)
|
||||
|
@ -130,6 +130,89 @@ R_API RBinFile * r_core_bin_cur(RCore *core) {
|
||||
return binfile;
|
||||
}
|
||||
|
||||
static bool string_filter(RCore *core, const char *str) {
|
||||
int i;
|
||||
/* pointer/rawdata detection */
|
||||
if (core->bin->strpurge) {
|
||||
ut8 bo[0x100];
|
||||
int up = 0;
|
||||
int lo = 0;
|
||||
int ot = 0;
|
||||
int di = 0;
|
||||
int ln = 0;
|
||||
int sp = 0;
|
||||
int nm = 0;
|
||||
for (i = 0; i<0x100; i++) {
|
||||
bo[i] = 0;
|
||||
}
|
||||
for (i = 0; str[i]; i++) {
|
||||
if (str[i]>='0' && str[i]<='9')
|
||||
nm++;
|
||||
else if (str[i]>='a' && str[i]<='z')
|
||||
lo++;
|
||||
else if (str[i]>='A' && str[i]<='Z')
|
||||
up++;
|
||||
else ot++;
|
||||
if (str[i]=='\\') ot++;
|
||||
if (str[i]==' ') sp++;
|
||||
bo[(ut8)str[i]] = 1;
|
||||
ln++;
|
||||
}
|
||||
for (i = 0; i<0x100; i++) {
|
||||
if (bo[i])
|
||||
di++;
|
||||
}
|
||||
if (ln>2 && str[0] != '_') {
|
||||
if (ln<10) return false;
|
||||
if (ot >= (nm+up+lo))
|
||||
return false;
|
||||
if (lo <3)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (core->bin->strfilter) {
|
||||
case 'a': // only alphanumeric - plain ascii
|
||||
for (i = 0; str[i]; i++) {
|
||||
char ch = str[i];
|
||||
if (ch<0 || !IS_PRINTABLE (ch))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'e': // emails
|
||||
if (str && *str) {
|
||||
if (!strstr (str+1, "@"))
|
||||
return false;
|
||||
if (!strstr (str+1, "."))
|
||||
return false;
|
||||
} else return false;
|
||||
break;
|
||||
case 'f': // format-string
|
||||
if (str && *str) {
|
||||
if (!strstr (str+1, "%"))
|
||||
return false;
|
||||
} else return false;
|
||||
break;
|
||||
case 'u': // URLs
|
||||
if (!strstr (str, "://"))
|
||||
return false;
|
||||
break;
|
||||
case 'p': // path
|
||||
if (str[0] != '/')
|
||||
return false;
|
||||
break;
|
||||
case '8': // utf8
|
||||
for (i = 0; str[i]; i++) {
|
||||
char ch = str[i];
|
||||
if (ch<0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int bin_strings(RCore *r, int mode, int va) {
|
||||
char *q, str[R_FLAG_NAME_SIZE];
|
||||
RBinSection *section;
|
||||
@ -171,9 +254,12 @@ static int bin_strings(RCore *r, int mode, int va) {
|
||||
}
|
||||
r_list_foreach (list, iter, string) {
|
||||
const char *section_name, *type_string;
|
||||
ut64 paddr = string->paddr;
|
||||
ut64 vaddr = r_bin_get_vaddr (bin, paddr, string->vaddr);
|
||||
ut64 addr = va ? vaddr : paddr;
|
||||
ut64 paddr, vaddr, addr;
|
||||
if (!string_filter (r, string->string))
|
||||
continue;
|
||||
paddr = string->paddr;
|
||||
vaddr = r_bin_get_vaddr (bin, paddr, string->vaddr);
|
||||
addr = va ? vaddr : paddr;
|
||||
|
||||
if (string->length < minstr) continue;
|
||||
if (maxstr && string->length > maxstr) continue;
|
||||
|
@ -392,6 +392,31 @@ static int cb_binfilter(void *user, void *data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cb_strpurge(void *user, void *data) {
|
||||
RCore *core = (RCore*) user;
|
||||
RConfigNode *node = (RConfigNode*) data;
|
||||
core->bin->strpurge = node->i_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cb_strfilter(void *user, void *data) {
|
||||
RCore *core = (RCore*) user;
|
||||
RConfigNode *node = (RConfigNode*) data;
|
||||
if (node->value[0] == '?') {
|
||||
eprintf ("Valid values for bin.strfilter:\n");
|
||||
eprintf ("a only alphanumeric printable\n");
|
||||
eprintf ("8 only strings with utf8 chars\n");
|
||||
eprintf ("p file/directory paths\n");
|
||||
eprintf ("e email-like addresses\n");
|
||||
eprintf ("u urls\n");
|
||||
eprintf ("f format-strings\n");
|
||||
return false;
|
||||
} else {
|
||||
core->bin->strfilter = node->value[0];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cb_binforce(void *user, void *data) {
|
||||
RCore *core = (RCore*) user;
|
||||
RConfigNode *node = (RConfigNode*) data;
|
||||
@ -1255,6 +1280,8 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETPREF("asm.demangle", "true", "Show demangled symbols in disasm");
|
||||
SETPREF("asm.describe", "false", "Show opcode description");
|
||||
SETPREF("asm.marks", "true", "Show marks before the disassembly");
|
||||
SETCB("bin.strpurge", "false", &cb_strpurge, "Try to purge false positive strings");
|
||||
SETCB("bin.strfilter", "", &cb_strfilter, "Filter strings (?:help, a:scii, e:mail, p:ath, u:rl, 8:utf8)");
|
||||
SETCB("bin.filter", "true", &cb_binfilter, "Filter symbol names to fix dupped names");
|
||||
SETCB("bin.force", "", &cb_binforce, "Force that rbin plugin");
|
||||
SETPREF("bin.lang", "", "Language for bin.demangle");
|
||||
@ -1266,7 +1293,7 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETPREF("bin.dwarf", "true", "Load dwarf information on startup if available");
|
||||
SETICB("bin.minstr", 0, &cb_binminstr, "Minimum string length for r_bin");
|
||||
SETICB("bin.maxstr", 0, &cb_binmaxstr, "Maximum string length for r_bin");
|
||||
SETICB("bin.maxstrbuf", 1024*1024*2, & cb_binmaxstrbuf, "Maximum size of range to load strings from");
|
||||
SETICB("bin.maxstrbuf", 1024*1024*10, & cb_binmaxstrbuf, "Maximum size of range to load strings from");
|
||||
SETCB("bin.rawstr", "false", &cb_rawstr, "Load strings from raw binaries");
|
||||
SETPREF("bin.strings", "true", "Load strings from rbin on startup");
|
||||
SETPREF("bin.classes", "true", "Load classes from rbin on startup");
|
||||
|
@ -188,7 +188,9 @@ typedef struct r_bin_t {
|
||||
RIOBind iob;
|
||||
char *force;
|
||||
int is_debugger;
|
||||
int filter;
|
||||
int filter; // symbol filtering
|
||||
char strfilter; // string filtering
|
||||
int strpurge; // purge false positive strings
|
||||
} RBin;
|
||||
|
||||
typedef int (*FREE_XTR)(void *xtr_obj);
|
||||
|
@ -1,4 +1,4 @@
|
||||
.Dd Jan 10, 2015
|
||||
.Dd Oct 13, 2015
|
||||
.Dt RABIN2 1
|
||||
.Sh NAME
|
||||
.Nm RABIN2
|
||||
@ -103,6 +103,10 @@ Shows strings from raw bins
|
||||
.Sh ENVIRONMENT
|
||||
.Pp
|
||||
RABIN2_MAXSTRBUF same as r2 -e bin.maxstrbuf for rabin2
|
||||
.Pp
|
||||
RABIN2_STRFILTER same as r2 -e bin.strfilter for rabin2
|
||||
.Pp
|
||||
RABIN2_STRPURGE same as r2 -e bin.strpurge for rabin2
|
||||
.Sh EXAMPLES
|
||||
.Pp
|
||||
List symbols of a program
|
||||
|
Loading…
x
Reference in New Issue
Block a user