Handle RBin demanglers from plugins and support D language

This commit is contained in:
pancake 2015-02-11 02:05:22 +01:00
parent 18c451f2c2
commit 31e08131d1
7 changed files with 91 additions and 5 deletions

View File

@ -22,6 +22,7 @@ OBJS+=mangling/demangler.o
OBJS+=mangling/microsoft_demangle.o
OBJS+=mangling/objc.o mangling/cxx.o
OBJS+=mangling/swift.o mangling/swift-sd.o
OBJS+=mangling/dlang.o
OBJS+=pdb/pdb_downloader.o pdb/omap.o pdb/pe.o pdb/gdata.o pdb/fpo.o pdb/dbi.o pdb/tpi.o pdb/stream_file.o pdb/pdb.o
LINK+=$(SHLR)/java/libr_java.a

View File

@ -308,6 +308,8 @@ R_API int r_bin_load_languages(RBinFile *binfile) {
return R_BIN_NM_OBJC;
if (r_bin_lang_cxx (binfile))
return R_BIN_NM_CXX;
if (r_bin_lang_dlang (binfile))
return R_BIN_NM_DLANG;
return R_BIN_NM_NONE;
}
@ -1013,6 +1015,7 @@ static RBinFile * r_bin_file_new_from_bytes (RBin *bin, const char *file, const
return bf;
}
// rename to r_bin_plugin_add like the rest
R_API int r_bin_add(RBin *bin, RBinPlugin *foo) {
RListIter *it;
RBinPlugin *plugin;

View File

@ -6,6 +6,34 @@
//TODO: mangler_branch: remove?
#include "mangling/demangler.h"
R_API void r_bin_demangle_list(RBin *bin) {
const char *langs[] = { "cxx", "java", "objc", "swift", NULL };
RBinPlugin *plugin;
RListIter *it;
int i;
if (!bin) return;
for (i=0; langs[i]; i++) {
eprintf ("%s\n", langs[i]);
}
r_list_foreach (bin->plugins, it, plugin) {
if (plugin->demangle) {
eprintf ("%s\n", plugin->name);
}
}
}
R_API char *r_bin_demangle_plugin(RBin *bin, const char *name, const char *str) {
RBinPlugin *plugin;
RListIter *it;
if (!bin || !name || !str) return NULL;
r_list_foreach (bin->plugins, it, plugin) {
if (plugin->demangle) {
return plugin->demangle (str);
}
}
return NULL;
}
// http://code.google.com/p/smali/wiki/TypesMethodsAndFields
R_API char *r_bin_demangle_java(const char *str) {
const char *w = NULL;
@ -241,6 +269,8 @@ R_API int r_bin_demangle_type (const char *str) {
return R_BIN_NM_OBJC;
if (!strcmp (str, "cxx"))
return R_BIN_NM_CXX;
if (!strcmp (str, "dlang"))
return R_BIN_NM_DLANG;
return R_BIN_NM_NONE;
}
@ -262,12 +292,14 @@ R_API int r_bin_lang_type(RBinFile *binfile, const char *def) {
}
R_API char *r_bin_demangle (RBinFile *binfile, const char *def, const char *str) {
RBin *bin = binfile->rbin;
int type = r_bin_lang_type (binfile, def);
switch (type) {
case R_BIN_NM_JAVA: return r_bin_demangle_java (str);
case R_BIN_NM_CXX: return r_bin_demangle_cxx (str);
case R_BIN_NM_OBJC: return r_bin_demangle_objc (NULL, str);
case R_BIN_NM_SWIFT: return r_bin_demangle_swift (str);
case R_BIN_NM_DLANG: return r_bin_demangle_plugin (bin, "dlang", str);
}
return NULL;
}

42
libr/bin/mangling/dlang.c Normal file
View File

@ -0,0 +1,42 @@
/* radare - LGPL - Copyright 2015 - pancake */
#include <r_bin.h>
// The dlang-demangler is written in D and available at radare2-extras
static int is_dlang_symbol (const char *name) {
if (!strncmp (name, "_D2", 2))
return 1;
if (!strncmp (name, "_D4", 2))
return 1;
return 0;
}
R_API int r_bin_lang_dlang(RBinFile *binfile) {
RBinObject *o = binfile ? binfile->o : NULL;
RBinInfo *info = o ? o->info : NULL;
RBinSymbol *sym;
RListIter *iter;
int hasdlang = R_FALSE;
const char *lib;
if (!info)
return R_FALSE;
r_list_foreach (o->libs, iter, lib) {
if (strstr (lib, "phobos")) {
hasdlang = R_TRUE;
break;
}
}
if (!hasdlang) {
r_list_foreach (o->symbols, iter, sym) {
if (is_dlang_symbol (sym->name)) {
hasdlang = R_TRUE;
break;
}
}
}
if (hasdlang)
info->lang = "dlang";
return hasdlang;
}

View File

@ -12,7 +12,7 @@ static void pair(const char *a, const char *b) {
r_cons_printf ("%s%s%s\n", a, ws, b);
}
static int demangle_internal(const char *lang, const char *s) {
static int demangle_internal(RCore *core, const char *lang, const char *s) {
char *res = NULL;
int type = r_bin_demangle_type (lang);
switch (type) {
@ -20,9 +20,10 @@ static int demangle_internal(const char *lang, const char *s) {
case R_BIN_NM_JAVA: res = r_bin_demangle_java (s); break;
case R_BIN_NM_OBJC: res = r_bin_demangle_objc (NULL, s); break;
case R_BIN_NM_SWIFT: res = r_bin_demangle_swift (s); break;
case R_BIN_NM_DLANG: res = r_bin_demangle_plugin (core->bin, "dlang", s); break;
default:
eprintf ("Unknown lang to demangle. Use: cxx, java, objc, swift\n");
return 1;
r_bin_demangle_list (core->bin);
return 1;
}
if (res) {
if (*res)
@ -39,13 +40,13 @@ static int demangle(RCore *core, const char *s) {
if (!*s) return 0;
if (!ss) {
const char *lang = r_config_get (core->config, "bin.lang");
demangle_internal (lang, s);
demangle_internal (core, lang, s);
return 1;
}
p = strdup (s);
q = p + (ss-s);
*q = 0;
demangle_internal (p, q+1);
demangle_internal (core, p, q+1);
free (p);
return 1;
}

View File

@ -52,6 +52,7 @@ R_API int r_core_loadlibs(RCore *core, int where, const char *path) {
r_lib_opendir (core->lib, getenv (R_LIB_ENV));
if (where & R_CORE_LOADLIBS_HOME) {
char *homeplugindir = r_str_home (R2_HOMEDIR"/plugins");
// eprintf ("OPENDIR (%s)\n", homeplugindir);
r_lib_opendir (core->lib, homeplugindir);
free (homeplugindir);
}

View File

@ -46,6 +46,7 @@ enum {
R_BIN_NM_CXX = 2,
R_BIN_NM_OBJC= 3,
R_BIN_NM_SWIFT = 4,
R_BIN_NM_DLANG = 5,
R_BIN_NM_ANY = -1,
};
@ -246,6 +247,7 @@ typedef struct r_bin_plugin_t {
int (*get_offset)(RBinFile *arch, int type, int idx);
ut64 (*get_vaddr)(RBinFile *arch, ut64 baddr, ut64 paddr, ut64 vaddr);
RBuffer* (*create)(RBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen);
char* (*demangle)(const char *str);
/* default value if not specified by user */
int minstrlen;
void *user;
@ -394,6 +396,7 @@ R_API char *r_bin_demangle_objc(RBinFile *binfile, const char *sym);
R_API int r_bin_lang_objc(RBinFile *binfile);
R_API int r_bin_lang_swift(RBinFile *binfile);
R_API int r_bin_lang_cxx(RBinFile *binfile);
R_API int r_bin_lang_dlang(RBinFile *binfile);
R_API RList* r_bin_get_entries(RBin *bin);
R_API RList* r_bin_get_fields(RBin *bin);
@ -465,6 +468,9 @@ R_API RBinDwarfDebugAbbrev *r_bin_dwarf_parse_abbrev(RBin *a, int mode);
R_API RBinPlugin * r_bin_get_binplugin_by_bytes (RBin *bin, const ut8* bytes, ut64 sz);
R_API void r_bin_demangle_list(RBin *bin);
R_API char *r_bin_demangle_plugin(RBin *bin, const char *name, const char *str);
/* plugin pointers */
extern RBinPlugin r_bin_plugin_any;
extern RBinPlugin r_bin_plugin_fs;