Implement bin.maxstr and handle it from rabin2 -N min:max

This commit is contained in:
pancake 2014-10-21 04:39:37 +02:00
parent 5201f772f8
commit 3435dc2bb5
6 changed files with 103 additions and 14 deletions

View File

@ -42,7 +42,7 @@ static RLib *l;
static int rabin_show_help(int v) {
printf ("Usage: rabin2 [-ACdehHiIjlLMqrRsSvVxzZ] [-@ addr] [-a arch] [-b bits]\n"
" [-B addr] [-c F:C:D] [-f str] [-m addr] [-n str] [-N len]\n"
" [-B addr] [-c F:C:D] [-f str] [-m addr] [-n str] [-N m:M]\n"
" [-o str] [-O str] [-k query] file\n");
if (v) printf (
" -@ [addr] show section, symbol or import at addr\n"
@ -69,7 +69,7 @@ static int rabin_show_help(int v) {
" -m [addr] show source line at addr\n"
" -M main (show address of main symbol)\n"
" -n [str] show section, symbol or import named str\n"
" -N [minlen] force minimum number of chars per string (see -z)\n"
" -N [min:max] force min:max number of chars per string (see -z and -zz)\n"
" -o [str] output file/folder for write operations (out by default)\n"
" -O [str] write/extract operations (-O help)\n"
" -p show physical addresses\n"
@ -468,7 +468,19 @@ int main(int argc, char **argv) {
break;
case '@': at = r_num_math (NULL, optarg); break;
case 'n': name = optarg; break;
case 'N': bin->minstrlen = r_num_math (NULL, optarg); break;
case 'N':
{
char *q, *p = strdup (optarg);
q = strchr (p, ':');
if (q) {
r_config_set (core.config, "bin.minstr", p);
r_config_set (core.config, "bin.maxstr", q+1);
} else {
r_config_set (core.config, "bin.minstr", optarg);
}
free (p);
}
break;
//case 'V': return blob_version ("rabin2");
case 'h':
r_core_fini (&core);

View File

@ -107,7 +107,7 @@ R_API RBinFile * r_core_bin_cur (RCore *core) {
static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
char *p, *q, str[R_FLAG_NAME_SIZE];
RBinSection *section;
int hasstr, minstr, rawstr;
int hasstr, minstr, maxstr, rawstr;
RBinString *string;
RListIter *iter;
RList *list;
@ -117,6 +117,7 @@ static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
if (!binfile) return R_FALSE;
minstr = r_config_get_i (r->config, "bin.minstr");
maxstr = r_config_get_i (r->config, "bin.maxstr");
rawstr = r_config_get_i (r->config, "bin.rawstr");
binfile->rawstr = rawstr;
@ -137,10 +138,17 @@ static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
}
}
#if 0
if (bin->minstrlen == 0)
bin->minstrlen = plugin->minstrlen? plugin->minstrlen: 4;
if (minstr > 0 || bin->minstrlen <= 0)
bin->minstrlen = minstr;
else plugin->minstrlen? plugin->minstrlen: 4;
#endif
bin->minstrlen = minstr;
#if 0
if (bin->minstrlen <= 0)
bin->minstrlen = R_MIN (minstr, 4);
#endif
minstr = bin->minstrlen;
if ((list = r_bin_get_strings (bin)) == NULL)
return R_FALSE;
@ -152,17 +160,22 @@ static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
string->vaddr, string->paddr);
ut64 paddr = string->paddr;
q = strdup (string->string);
if (maxstr && string->length>maxstr) {
continue;
}
for (p=q; *p; p++) {
if (*p=='"') *p = '\'';
if (*p=='\\') *p = '/';
}
r_cons_printf ("%s{\"vaddr\":%"PFMT64d
if (string->length>minstr) {
r_cons_printf ("%s{\"vaddr\":%"PFMT64d
",\"paddr\":%"PFMT64d
",\"length\":%d,\"size\":%d,"
"\"type\":\"%s\",\"string\":\"%s\"}",
iter->p? ",": "", vaddr, paddr,
string->length, string->size,
string->type=='w'?"wide":"ascii", q);
}
free (q);
}
r_cons_printf ("]");
@ -171,8 +184,13 @@ static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
r_list_foreach (list, iter, string) {
ut64 addr = va? r_bin_get_vaddr (bin, baddr,
string->paddr, string->vaddr): string->paddr;
r_cons_printf ("%"PFMT64d" %d %d %s\n",
addr, string->size, string->length, string->string);
if (maxstr && string->length>maxstr) {
continue;
}
if (string->length>minstr) {
r_cons_printf ("%"PFMT64d" %d %d %s\n",
addr, string->size, string->length, string->string);
}
}
} else
if ((mode & R_CORE_BIN_SET)) {
@ -184,6 +202,11 @@ static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
ut64 addr = va? string->vaddr: string->paddr;
//r_bin_get_vaddr (bin, baddr, string->vaddr,
// string->paddr): string->paddr;
if (string->length<minstr)
continue;
if (maxstr && string->length>maxstr) {
continue;
}
if (r_cons_singleton()->breaked) break;
r_meta_add (r->anal, R_META_TYPE_STRING, addr,
addr+string->size, string->string);
@ -201,6 +224,11 @@ static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
// TODO: honor laddr..
ut64 vaddr = string->vaddr;
ut64 paddr = string->paddr;
if (string->length<minstr)
continue;
if (maxstr && string->length>maxstr) {
continue;
}
section = r_bin_get_section_at (r_bin_cur_object (bin), string->paddr, 0);
if (mode) {
r_cons_printf ("f str.%s %"PFMT64d" @ 0x%08"PFMT64x"\n"

View File

@ -10,9 +10,32 @@ static void flagbars(RCore *core) {
}
if (!total) // avoid a division by zero
return;
cols-=15;
r_cons_printf ("Total: %d\n", total);
r_list_foreach (core->flags->flags, iter, flag) {
ut32 pbar_val = flag->offset>0 ? flag->offset : 1;
r_cons_printf ("%10s", flag->name);
r_cons_printf ("%10s %.8"PFMT64d, flag->name, flag->offset);
r_print_progressbar (core->print,
(pbar_val*100)/total, cols);
r_cons_newline ();
}
}
static void flagbars_dos(RCore *core) {
int total = 0;
int cols = r_cons_get_size (NULL);
RListIter *iter;
RFlagItem *flag;
r_list_foreach (core->flags->flags, iter, flag) {
total = R_MAX(total,flag->offset);
}
if (!total) // avoid a division by zero
return;
cols-=15;
r_cons_printf ("Total: %d\n", total);
r_list_foreach (core->flags->flags, iter, flag) {
ut32 pbar_val = flag->offset>0 ? flag->offset : 1;
r_cons_printf ("%10s %.8"PFMT64d, flag->name, flag->offset);
r_print_progressbar (core->print,
(pbar_val*100)/total, cols);
r_cons_newline ();
@ -30,8 +53,18 @@ static int cmd_flag(void *data, const char *input) {
if (*input)
str = strdup (input+1);
switch (*input) {
case '=':
flagbars (core);
case '=': // "f="
switch (input[1]) {
case '=':
flagbars_dos (core);
break;
case '?':
eprintf ("Usage: f= or f== to display flag bars\n");
break;
default:
flagbars (core);
break;
}
break;
case 'a':
if (input[1]==' '){

View File

@ -722,6 +722,20 @@ static int cb_rawstr(void *user, void *data) {
return R_TRUE;
}
static int cb_binmaxstr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core->bin) {
int v = node->i_value;
if (v<1) v = 4; // HACK
core->bin->maxstrlen = v;
// TODO: Do not refresh if nothing changed (minstrlen ?)
r_core_bin_refresh_strings (core);
return R_TRUE;
}
return R_TRUE;
}
static int cb_binminstr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
@ -833,6 +847,7 @@ R_API int r_core_config_init(RCore *core) {
SETI("bin.laddr", 0, "Set base address for loading binaries ('o')");
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, "Minimum string length for r_bin");
SETCB("bin.rawstr", "false", &cb_rawstr, "Load strings from raw binaries");
SETPREF("bin.strings", "true", "Load strings from rbin on startup");

View File

@ -162,6 +162,7 @@ typedef struct r_bin_t {
int narch;
void *user;
int minstrlen;
int maxstrlen;
int rawstr;
Sdb *sdb;
RList/*<RBinPlugin>*/ *plugins;

View File

@ -66,8 +66,8 @@ List supported bin plugins
Show address of 'main' symbol
.It Fl m Ar addr
Show source line reference from a given address
.It Fl N Ar minlen
Force minimum number of chars per string (see -z)
.It Fl N Ar minlen:maxlen
Force minimum and maximum number of chars per string (see -z and -zz). if (strlen>minlen && (!maxlen || strlen<=maxlen))
.It Fl n Ar str
Show information (symbol, section, import) at string offset
.It Fl o Ar str