Initial implementation of bin.strfilter and bin.strpurge

This commit is contained in:
pancake 2015-10-13 03:50:14 +02:00
parent 3a5612190b
commit 1dba5a687d
5 changed files with 143 additions and 10 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -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