Add experimental bin.str.nofp config for less false positives ##bin

This commit is contained in:
pancake 2022-11-11 11:26:44 +01:00 committed by GitHub
parent e1fb455345
commit d29d7b1a26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 17 deletions

View File

@ -107,9 +107,9 @@ static void print_string(RBinFile *bf, RBinString *string, int raw, PJ *pj) {
}
}
static int string_scan_range(RList *list, RBinFile *bf, int min,
const ut64 from, const ut64 to, int type, int raw, RBinSection *section) {
static int string_scan_range(RList *list, RBinFile *bf, int min, const ut64 from, const ut64 to, int type, int raw, RBinSection *section) {
RBin *bin = bf->rbin;
const bool strings_nofp = bin->strings_nofp;
ut8 tmp[R_STRING_SCAN_BUFFER_SIZE];
ut64 str_start, needle = from;
int count = 0, i, rc, runes;
@ -268,20 +268,34 @@ static int string_scan_range(RList *list, RBinFile *bf, int min,
}
rc = r_utf8_encode (tmp + i, r);
runes++;
/* Print the escape code */
} else if (r && r < 0x100 && strchr ("\b\v\f\n\r\t\a\033\\", (char)r)) {
if ((i + 32) < sizeof (tmp) && r < 93) {
tmp[i + 0] = '\\';
tmp[i + 1] = " abtnvfr e "
" "
" "
" \\"[r];
/* Print the escape code */
if (strings_nofp) {
rc = 2;
if (r && r < 0x100 && strchr ("\n\r\t\033\\", (char)r)) {
// eprintf ("is special\n");
runes++;
// accept it as it is
rc = 1;
} else {
rc = 1;
r = 0;
break;
}
} else {
// string too long
break;
if ((i + 32) < sizeof (tmp) && r < 93) {
tmp[i + 0] = '\\';
tmp[i + 1] = " abtnvfr e "
" "
" "
" \\"[r];
} else {
// string too long
break;
}
rc = 2;
runes++;
}
rc = 2;
runes++;
} else {
/* \0 marks the end of C-strings */
break;
@ -385,7 +399,10 @@ static int string_scan_range(RList *list, RBinFile *bf, int min,
ut64 baddr = bf->loadaddr && bf->o? bf->o->baddr: bf->loadaddr;
bs->paddr = str_start + baddr;
bs->vaddr = str_start - pdelta + vdelta + baddr;
bs->string = r_str_ndup ((const char *)tmp, i);
bs->string = r_str_ndup ((const char *)tmp, i); // Use stringviews to save memory
if (strings_nofp) {
r_str_trim (bs->string); // trim spaces to ease readability
}
if (list) {
r_list_append (list, bs);
if (bf->o) {
@ -424,7 +441,7 @@ static bool __isDataSection(RBinFile *a, RBinSection *s) {
return strstr (s->name, "_const");
}
static void get_strings_range(RBinFile *bf, RList *list, int min, int raw, ut64 from, ut64 to, RBinSection *section) {
static void get_strings_range(RBinFile *bf, RList *list, int min, int raw, bool nofp, ut64 from, ut64 to, RBinSection *section) {
r_return_if_fail (bf && bf->buf);
RBinPlugin *plugin = r_bin_file_cur_plugin (bf);
@ -842,6 +859,7 @@ R_API RBinPlugin *r_bin_file_cur_plugin(RBinFile *bf) {
// TODO: searchStrings() instead
R_IPI RList *r_bin_file_get_strings(RBinFile *bf, int min, int dump, int raw) {
const bool nofp = bf->rbin->strings_nofp;
r_return_val_if_fail (bf, NULL);
RListIter *iter;
RBinSection *section;
@ -851,7 +869,7 @@ R_IPI RList *r_bin_file_get_strings(RBinFile *bf, int min, int dump, int raw) {
RBinObject *o = bf->o;
r_list_foreach (o->sections, iter, section) {
if (__isDataSection (bf, section)) {
get_strings_range (bf, ret, min, raw, section->paddr,
get_strings_range (bf, ret, min, raw, nofp, section->paddr,
section->paddr + section->size, section);
}
}
@ -867,6 +885,9 @@ R_IPI RList *r_bin_file_get_strings(RBinFile *bf, int min, int dump, int raw) {
if (section->size > bf->size) {
continue;
}
if (section->size < 1) {
continue;
}
ut8 *sbuf = malloc (section->size);
if (!sbuf) {
continue;
@ -900,7 +921,7 @@ R_IPI RList *r_bin_file_get_strings(RBinFile *bf, int min, int dump, int raw) {
}
}
} else {
get_strings_range (bf, ret, min, raw, 0, bf->size, NULL);
get_strings_range (bf, ret, min, raw, nofp, 0, bf->size, NULL);
}
return ret;
}

View File

@ -1296,6 +1296,13 @@ static bool cb_useldr(void *user, void *data) {
return true;
}
static bool cb_nofp(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->bin->strings_nofp = node->i_value;
return true;
}
static bool cb_binat(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
@ -3774,6 +3781,7 @@ R_API int r_core_config_init(RCore *core) {
SETCB ("bin.str.purge", "", &cb_strpurge, "purge strings (e bin.str.purge=? provides more detail)");
SETPREF ("bin.str.real", "false", "set the realname in rbin.strings for better disasm (EXPERIMENTAL)");
SETBPREF ("bin.b64str", "false", "try to debase64 the strings");
SETCB ("bin.str.nofp", "false", &cb_nofp, "set to true to reduce the false positive strings (EXPERIMENTAL)");
SETCB ("bin.at", "false", &cb_binat, "RBin.cur depends on RCore.offset");
SETBPREF ("bin.libs", "false", "try to load libraries after loading main binary");
n = NODECB ("bin.str.filter", "", &cb_strfilter);

View File

@ -335,6 +335,7 @@ struct r_bin_t {
int maxsymlen;
ut64 maxstrbuf;
int rawstr;
bool strings_nofp; // move to options struct passed instead of min, dump raw on every getstrings call
Sdb *sdb;
RIDStorage *ids;
RList/*<RBinPlugin>*/ *plugins;