mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-07 18:43:45 +00:00
Implement bin.debase64 and RABIN2_DEBASE64 in RBin for r2 and rabin2
This commit is contained in:
parent
09594bdde9
commit
28c7ec564a
@ -89,6 +89,7 @@ static int rabin_show_help(int v) {
|
||||
" 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"
|
||||
" RABIN2_DEBASE64: e bin.debase64 # Try to debase64 all strings\n"
|
||||
" RABIN2_DMNGLRCMD: e bin.demanglercmd # try to purge false positives\n"
|
||||
" RABIN2_PREFIX: e bin.prefix # prefix symbols/sections/relocs with a specific string\n");
|
||||
}
|
||||
@ -579,6 +580,10 @@ int main(int argc, char **argv) {
|
||||
r_config_set (core.config, "bin.strpurge", tmp);
|
||||
free (tmp);
|
||||
}
|
||||
if ((tmp = r_sys_getenv ("RABIN2_DEBASE64"))) {
|
||||
r_config_set (core.config, "bin.debase64", tmp);
|
||||
free (tmp);
|
||||
}
|
||||
|
||||
#define is_active(x) (action & x)
|
||||
#define set_action(x) actions++; action |= x
|
||||
|
@ -66,6 +66,37 @@ static int r_bin_file_object_add(RBinFile *binfile, RBinObject *o);
|
||||
static void binobj_set_baddr(RBinObject *o, ut64 baddr);
|
||||
static ut64 binobj_a2b(RBinObject *o, ut64 addr);
|
||||
|
||||
static void filterStrings (RBin *bin, RList *strings) {
|
||||
RBinString *ptr;
|
||||
RListIter *iter;
|
||||
r_list_foreach (strings, iter, ptr) {
|
||||
char *dec = (char *)r_base64_decode_dyn (ptr->string, -1);
|
||||
if (dec) {
|
||||
char *s = ptr->string;
|
||||
do {
|
||||
char *dec2 = (char *)r_base64_decode_dyn (s, -1);
|
||||
if (!dec2) {
|
||||
break;
|
||||
}
|
||||
if (!r_str_is_printable (dec2)) {
|
||||
free (dec2);
|
||||
break;
|
||||
}
|
||||
free (dec);
|
||||
s = dec = dec2;
|
||||
} while (true);
|
||||
if (r_str_is_printable (dec) && strlen (dec) > 3) {
|
||||
free (ptr->string);
|
||||
ptr->string = dec;
|
||||
ptr->type = R_STRING_TYPE_BASE64;
|
||||
// eprintf ("--> 0x%08"PFMT64x" %s\n", ptr->vaddr, ptr->string);
|
||||
} else {
|
||||
free (dec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_bin_iobind(RBin *bin, RIO *io) {
|
||||
r_io_bind (io, &bin->iob);
|
||||
}
|
||||
@ -94,6 +125,16 @@ R_API RBinXtrData *r_bin_xtrdata_new(RBuffer *buf, ut64 offset, ut64 size, ut32
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API const char *r_bin_string_type (int type) {
|
||||
switch (type) {
|
||||
case 'a': return "ascii";
|
||||
case 'u': return "utf8";
|
||||
case 'w': return "wide";
|
||||
case 'b': return "base64";
|
||||
}
|
||||
return "ascii"; // XXX
|
||||
}
|
||||
|
||||
R_API void r_bin_xtrdata_free(void /*RBinXtrData*/ *data_) {
|
||||
RBinXtrData *data = data_;
|
||||
if (data) {
|
||||
@ -131,13 +172,6 @@ R_API int r_bin_file_cur_set_plugin(RBinFile *binfile, RBinPlugin *plugin) {
|
||||
return false;
|
||||
}
|
||||
|
||||
enum {
|
||||
R_STRING_TYPE_DETECT = '?',
|
||||
R_STRING_TYPE_ASCII = 'a',
|
||||
R_STRING_TYPE_UTF8 = 'u',
|
||||
R_STRING_TYPE_WIDE = 'w',
|
||||
};
|
||||
|
||||
#define R_STRING_SCAN_BUFFER_SIZE 2048
|
||||
|
||||
static int string_scan_range(RList *list, const ut8 *buf, int min, const ut64 from, const ut64 to, int type) {
|
||||
@ -148,7 +182,6 @@ static int string_scan_range(RList *list, const ut8 *buf, int min, const ut64 fr
|
||||
if (type == -1) {
|
||||
type = R_STRING_TYPE_DETECT;
|
||||
}
|
||||
|
||||
if (!buf || !min) {
|
||||
return -1;
|
||||
}
|
||||
@ -592,13 +625,17 @@ static int r_bin_object_set_items(RBinFile *binfile, RBinObject *o) {
|
||||
} else {
|
||||
o->strings = get_strings (binfile, minlen, 0);
|
||||
}
|
||||
if (bin->debase64) {
|
||||
filterStrings (bin, o->strings);
|
||||
}
|
||||
REBASE_PADDR (o, o->strings, RBinString);
|
||||
}
|
||||
if (bin->filter_rules & R_BIN_REQ_CLASSES) {
|
||||
if (cp->classes) {
|
||||
o->classes = cp->classes (binfile);
|
||||
if (bin->filter)
|
||||
if (bin->filter) {
|
||||
r_bin_filter_classes (o->classes);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cp->lines) {
|
||||
@ -666,13 +703,16 @@ R_API int r_bin_reload(RBin *bin, RIODesc *desc, ut64 baseaddr) {
|
||||
ut8 *buf_bytes = NULL;
|
||||
ut64 len_bytes = UT64_MAX, sz = UT64_MAX;
|
||||
|
||||
if (!io) return false;
|
||||
|
||||
if (!desc || !io) return false;
|
||||
|
||||
if (!io) {
|
||||
return false;
|
||||
}
|
||||
if (!desc || !io) {
|
||||
return false;
|
||||
}
|
||||
bf = r_bin_file_find_by_name (bin, desc->name);
|
||||
if (!bf) return false;
|
||||
|
||||
if (!bf) {
|
||||
return false;
|
||||
}
|
||||
the_obj_list = bf->objs;
|
||||
bf->objs = r_list_newf ((RListFree)r_bin_object_free);
|
||||
// invalidate current object reference
|
||||
@ -686,7 +726,9 @@ R_API int r_bin_reload(RBin *bin, RIODesc *desc, ut64 baseaddr) {
|
||||
// load the bin-properly. Many of the plugins require all content and are not
|
||||
// stream based loaders
|
||||
RIODesc *tdesc = iob->desc_open (io, desc->name, desc->flags, R_IO_READ);
|
||||
if (!tdesc) return false;
|
||||
if (!tdesc) {
|
||||
return false;
|
||||
}
|
||||
sz = iob->desc_size (io, tdesc);
|
||||
if (sz == UT64_MAX) {
|
||||
iob->desc_close (io, tdesc);
|
||||
@ -697,10 +739,8 @@ R_API int r_bin_reload(RBin *bin, RIODesc *desc, ut64 baseaddr) {
|
||||
} else if (sz == UT64_MAX || sz > (64 * 1024 * 1024)) { // too big, probably wrong
|
||||
eprintf ("Too big\n");
|
||||
return false;
|
||||
} else {
|
||||
buf_bytes = iob->desc_read (io, desc, &len_bytes);
|
||||
}
|
||||
|
||||
buf_bytes = iob->desc_read (io, desc, &len_bytes);
|
||||
if (!buf_bytes) {
|
||||
sz = 0;
|
||||
buf_bytes = iob->desc_read (io, desc, &sz);
|
||||
@ -720,7 +760,8 @@ R_API int r_bin_reload(RBin *bin, RIODesc *desc, ut64 baseaddr) {
|
||||
RBinObject *old_o;
|
||||
r_list_foreach (the_obj_list, iter, old_o) {
|
||||
// XXX - naive. do we need a way to prevent multiple "anys" from being opened?
|
||||
res = r_bin_load_io_at_offset_as (bin, desc, baseaddr, old_o->loadaddr, 0, old_o->boffset, old_o->plugin->name);
|
||||
res = r_bin_load_io_at_offset_as (bin, desc, baseaddr,
|
||||
old_o->loadaddr, 0, old_o->boffset, old_o->plugin->name);
|
||||
}
|
||||
}
|
||||
bf->o = r_list_get_n (bf->objs, 0);
|
||||
@ -1495,8 +1536,9 @@ R_API RBinSection *r_bin_get_section_at(RBinObject *o, ut64 off, int va) {
|
||||
from = va? binobj_a2b (o, section->vaddr): section->paddr;
|
||||
to = va? (binobj_a2b (o, section->vaddr) + section->vsize) :
|
||||
(section->paddr + section->size);
|
||||
if (off >= from && off < to)
|
||||
if (off >= from && off < to) {
|
||||
return section;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -1525,6 +1567,9 @@ R_API RList *r_bin_reset_strings(RBin *bin) {
|
||||
} else {
|
||||
o->strings = get_strings (a, bin->minstrlen, 0);
|
||||
}
|
||||
if (bin->debase64) {
|
||||
filterStrings (bin, o->strings);
|
||||
}
|
||||
return o->strings;
|
||||
}
|
||||
|
||||
|
@ -397,13 +397,13 @@ static RList *strings(RBinFile *arch) {
|
||||
len = dex_read_uleb128 (buf);
|
||||
|
||||
if (len > 1 && len < R_BIN_SIZEOF_STRINGS) {
|
||||
ptr->string = malloc (len + 1);
|
||||
ptr->string = calloc (len + 1, 1);
|
||||
if (!ptr->string) {
|
||||
goto out_error;
|
||||
}
|
||||
off = bin->strings[i] + dex_uleb128_len (buf);
|
||||
if (off > bin->size || off + len > bin->size) {
|
||||
free (ptr->string);
|
||||
R_FREE (ptr->string);
|
||||
goto out_error;
|
||||
}
|
||||
r_buf_read_at (bin->b, off, (ut8*)ptr->string, len);
|
||||
|
@ -326,7 +326,7 @@ static void _print_strings(RCore *r, RList *list, int mode, int va) {
|
||||
|
||||
section = r_bin_get_section_at (r_bin_cur_object (bin), paddr, 0);
|
||||
section_name = section ? section->name : "unknown";
|
||||
type_string = string->type == 'w' ? "wide" : "ascii";
|
||||
type_string = r_bin_string_type (string->type);
|
||||
if (IS_MODE_SET (mode)) {
|
||||
char *f_name, *str;
|
||||
if (r_cons_singleton()->breaked) {
|
||||
|
@ -1360,6 +1360,13 @@ static int cb_rawstr(void *user, void *data) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cb_debase64(void *user, void *data) {
|
||||
RCore *core = (RCore *) user;
|
||||
RConfigNode *node = (RConfigNode *) data;
|
||||
core->bin->debase64 = node->i_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cb_binstrings(void *user, void *data) {
|
||||
const ut32 req = R_BIN_REQ_STRINGS;
|
||||
RCore *core = (RCore *) user;
|
||||
@ -1801,6 +1808,7 @@ R_API int r_core_config_init(RCore *core) {
|
||||
SETCB("bin.prefix", NULL, &cb_binprefix, "Prefix all symbols/sections/relocs with a specific string");
|
||||
SETCB("bin.rawstr", "false", &cb_rawstr, "Load strings from raw binaries");
|
||||
SETCB("bin.strings", "true", &cb_binstrings, "Load strings from rbin on startup");
|
||||
SETCB("bin.debase64", "false", &cb_debase64, "Try to debase64 all strings");
|
||||
SETPREF("bin.classes", "true", "Load classes from rbin on startup");
|
||||
SETPREF("bin.mergeflags", "true", "Merge symbols with the same name into the same flag");
|
||||
|
||||
|
@ -86,6 +86,14 @@ enum {
|
||||
R_BIN_NM_ANY = -1,
|
||||
};
|
||||
|
||||
enum {
|
||||
R_STRING_TYPE_DETECT = '?',
|
||||
R_STRING_TYPE_ASCII = 'a',
|
||||
R_STRING_TYPE_UTF8 = 'u',
|
||||
R_STRING_TYPE_WIDE = 'w',
|
||||
R_STRING_TYPE_BASE64 = 'b',
|
||||
};
|
||||
|
||||
enum {
|
||||
R_BIN_CLASS_PRIVATE,
|
||||
R_BIN_CLASS_PUBLIC,
|
||||
@ -214,6 +222,7 @@ typedef struct r_bin_t {
|
||||
int narch;
|
||||
void *user;
|
||||
/* preconfigured values */
|
||||
int debase64;
|
||||
int minstrlen;
|
||||
int maxstrlen;
|
||||
ut64 maxstrbuf;
|
||||
@ -415,7 +424,7 @@ typedef struct r_bin_string_t {
|
||||
ut32 ordinal;
|
||||
ut32 size; // size of buffer containing the string in bytes
|
||||
ut32 length; // length of string in chars
|
||||
char type; // Ascii Wide cp850 utf8 ...
|
||||
char type; // Ascii Wide cp850 utf8 base64 ...
|
||||
} RBinString;
|
||||
|
||||
typedef struct r_bin_field_t {
|
||||
@ -570,6 +579,7 @@ R_API RBinFile * r_bin_file_find_by_name_n (RBin * bin, const char * name, int i
|
||||
R_API int r_bin_file_set_cur_binfile (RBin * bin, RBinFile *bf);
|
||||
R_API RBinPlugin * r_bin_file_cur_plugin (RBinFile *binfile);
|
||||
R_API void r_bin_force_plugin (RBin *bin, const char *pname);
|
||||
R_API const char *r_bin_string_type (int type);
|
||||
|
||||
/* dbginfo.c */
|
||||
R_API int r_bin_addr2line(RBin *bin, ut64 addr, char *file, int len, int *line);
|
||||
|
@ -133,6 +133,8 @@ RABIN2_DEMANGLE demangle symbols
|
||||
.Pp
|
||||
RABIN2_MAXSTRBUF same as r2 -e bin.maxstrbuf for rabin2
|
||||
.Pp
|
||||
RABIN2_DEBASE64 try to decode all strings as base64 if possible
|
||||
.Pp
|
||||
RABIN2_STRFILTER same as r2 -e bin.strfilter for rabin2
|
||||
.Pp
|
||||
RABIN2_STRPURGE same as r2 -e bin.strpurge for rabin2
|
||||
|
Loading…
Reference in New Issue
Block a user