Fix flag name demangling on local DLL symbols ##disasm (#14692)

This commit is contained in:
GustavoLCR 2019-08-05 10:46:05 -03:00 committed by radare
parent 1bc3648358
commit 7a29e7e195
10 changed files with 59 additions and 33 deletions

View File

@ -62,7 +62,7 @@ R_API int r_bin_demangle_type(const char *str) {
return R_BIN_NM_NONE;
}
R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64 vaddr) {
R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64 vaddr, bool libs) {
int type = -1;
if (!str || !*str) {
return NULL;
@ -81,6 +81,7 @@ R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64
str += 4;
}
if (o) {
bool found = false;
r_list_foreach (o->libs, iter, lib) {
size_t len = strlen (lib);
if (!r_str_ncasecmp (str, lib, len)) {
@ -88,9 +89,21 @@ R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64
if (*str == '_') {
str++;
}
found = true;
break;
}
}
if (!found) {
lib = NULL;
}
size_t len = strlen (bin->file);
if (!r_str_ncasecmp (str, bin->file, len)) {
lib = bin->file;
str += len;
if (*str == '_') {
str++;
}
}
}
if (!strncmp (str, "__", 2)) {
if (str[2] == 'T') {
@ -107,16 +120,22 @@ R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64
if (type == -1) {
type = r_bin_lang_type (bf, def, str);
}
char *demangled = NULL;
switch (type) {
case R_BIN_NM_JAVA: return r_bin_demangle_java (str);
case R_BIN_NM_RUST: return r_bin_demangle_rust (bf, str, vaddr);
case R_BIN_NM_OBJC: return r_bin_demangle_objc (NULL, str);
case R_BIN_NM_SWIFT: return r_bin_demangle_swift (str, bin? bin->demanglercmd: false);
case R_BIN_NM_CXX: return r_bin_demangle_cxx (bf, str, vaddr);
case R_BIN_NM_MSVC: return r_bin_demangle_msvc (str);
case R_BIN_NM_DLANG: return r_bin_demangle_plugin (bin, "dlang", str);
case R_BIN_NM_JAVA: demangled = r_bin_demangle_java (str); break;
case R_BIN_NM_RUST: demangled = r_bin_demangle_rust (bf, str, vaddr); break;
case R_BIN_NM_OBJC: demangled = r_bin_demangle_objc (NULL, str); break;
case R_BIN_NM_SWIFT: demangled = r_bin_demangle_swift (str, bin? bin->demanglercmd: false); break;
case R_BIN_NM_CXX: demangled = r_bin_demangle_cxx (bf, str, vaddr); break;
case R_BIN_NM_MSVC: demangled = r_bin_demangle_msvc (str); break;
case R_BIN_NM_DLANG: demangled = r_bin_demangle_plugin (bin, "dlang", str); break;
}
return NULL;
if (libs && demangled && lib) {
char *d = r_str_newf ("%s_%s", lib, demangled);
free (demangled);
demangled = d;
}
return demangled;
}
#ifdef TEST

View File

@ -68,7 +68,7 @@ R_API void r_bin_filter_sym(RBinFile *bf, HtPP *ht, ut64 vaddr, RBinSymbol *sym)
// demangle symbol name depending on the language specs if any
if (bf && bf->o && bf->o->lang) {
const char *lang = r_bin_lang_tostring (bf->o->lang);
char *dn = r_bin_demangle (bf, lang, sym->name, sym->vaddr);
char *dn = r_bin_demangle (bf, lang, sym->name, sym->vaddr, false);
if (dn && *dn) {
sym->dname = dn;
// XXX this is wrong but is required for this test to pass

View File

@ -1245,7 +1245,7 @@ void symbols_from_bin(RList *ret, RBinFile *bf, RDyldBinImage *bin) {
sym->name = strdup (symbols[i].name);
sym->vaddr = symbols[i].addr;
if (sym->name[0] == '_') {
char *dn = r_bin_demangle (bf, sym->name, sym->name, sym->vaddr);
char *dn = r_bin_demangle (bf, sym->name, sym->name, sym->vaddr, false);
if (dn) {
sym->dname = dn;
char *p = strchr (dn, '.');

View File

@ -209,7 +209,7 @@ static RList *symbols(RBinFile *bf) {
}
ptr->name = strdup ((char*)syms[i].name);
if (ptr->name[0] == '_' && strncmp (ptr->name, "imp.", 4)) {
char *dn = r_bin_demangle (bf, ptr->name, ptr->name, ptr->vaddr);
char *dn = r_bin_demangle (bf, ptr->name, ptr->name, ptr->vaddr, false);
if (dn) {
ptr->dname = dn;
char *p = strchr (dn, '.');

View File

@ -1115,7 +1115,7 @@ static void symbols_from_mach0(RList *ret, struct MACH0_(obj_t) *mach0, RBinFile
sym->name = strdup (symbols[i].name);
sym->vaddr = symbols[i].addr;
if (sym->name[0] == '_') {
char *dn = r_bin_demangle (bf, sym->name, sym->name, sym->vaddr);
char *dn = r_bin_demangle (bf, sym->name, sym->name, sym->vaddr, false);
if (dn) {
sym->dname = dn;
char *p = strchr (dn, '.');

View File

@ -2450,14 +2450,12 @@ static int fcnlist_gather_metadata(RAnal *anal, RList *fcns) {
}
R_API char *r_core_anal_fcn_name(RCore *core, RAnalFunction *fcn) {
bool demangle;
const char *lang;
demangle = r_config_get_i (core->config, "bin.demangle");
lang = demangle ? r_config_get (core->config, "bin.lang") : NULL;
bool demangle = r_config_get_i (core->config, "bin.demangle");
const char *lang = demangle ? r_config_get (core->config, "bin.lang") : NULL;
bool keep_lib = r_config_get_i (core->config, "bin.demangle.libs");
char *name = strdup (fcn->name ? fcn->name : "");
if (demangle) {
char *tmp = r_bin_demangle (core->bin->cur, lang, name, fcn->addr);
char *tmp = r_bin_demangle (core->bin->cur, lang, name, fcn->addr, keep_lib);
if (tmp) {
free (name);
name = tmp;

View File

@ -1270,9 +1270,10 @@ static char *get_reloc_name(RCore *r, RBinReloc *reloc, ut64 addr) {
char *demangled_name = NULL;
const char *lang = r_config_get (r->config, "bin.lang");
int bin_demangle = r_config_get_i (r->config, "bin.demangle");
bool keep_lib = r_config_get_i (r->config, "bin.demangle.libs");
if (reloc->import && reloc->import->name) {
if (bin_demangle) {
demangled_name = r_bin_demangle (r->bin->cur, lang, reloc->import->name, addr);
demangled_name = r_bin_demangle (r->bin->cur, lang, reloc->import->name, addr, keep_lib);
}
reloc_name = sdb_fmt ("reloc.%s_%d", demangled_name ? demangled_name : reloc->import->name,
(int)(addr & 0xff));
@ -1283,7 +1284,7 @@ static char *get_reloc_name(RCore *r, RBinReloc *reloc, ut64 addr) {
r_str_replace_char (reloc_name, '$', '_');
} else if (reloc->symbol && reloc->symbol->name) {
if (bin_demangle) {
demangled_name = r_bin_demangle (r->bin->cur, lang, reloc->symbol->name, addr);
demangled_name = r_bin_demangle (r->bin->cur, lang, reloc->symbol->name, addr, keep_lib);
}
reloc_name = sdb_fmt ("reloc.%s_%d", demangled_name ? demangled_name : reloc->symbol->name,
(int)(addr & 0xff));
@ -1304,6 +1305,7 @@ static char *get_reloc_name(RCore *r, RBinReloc *reloc, ut64 addr) {
static void set_bin_relocs(RCore *r, RBinReloc *reloc, ut64 addr, Sdb **db, char **sdb_module) {
int bin_demangle = r_config_get_i (r->config, "bin.demangle");
bool keep_lib = r_config_get_i (r->config, "bin.demangle.libs");
const char *lang = r_config_get (r->config, "bin.lang");
char *reloc_name, *demname = NULL;
bool is_pe = true;
@ -1370,7 +1372,7 @@ static void set_bin_relocs(RCore *r, RBinReloc *reloc, ut64 addr, Sdb **db, char
snprintf (str, R_FLAG_NAME_SIZE, "reloc.%s", reloc_name);
}
if (bin_demangle) {
demname = r_bin_demangle (r->bin->cur, lang, str, addr);
demname = r_bin_demangle (r->bin->cur, lang, str, addr, keep_lib);
if (demname) {
snprintf (str, R_FLAG_NAME_SIZE, "reloc.%s", demname);
}
@ -1445,6 +1447,7 @@ static bool is_file_reloc(RBinReloc *r) {
static int bin_relocs(RCore *r, int mode, int va) {
bool bin_demangle = r_config_get_i (r->config, "bin.demangle");
bool keep_lib = r_config_get_i (r->config, "bin.demangle.libs");
const char *lang = r_config_get (r->config, "bin.lang");
RBIter iter;
RBinReloc *reloc = NULL;
@ -1493,7 +1496,7 @@ static int bin_relocs(RCore *r, int mode, int va) {
? strdup (reloc->import->name)
: (reloc->symbol ? strdup (reloc->symbol->name) : NULL);
if (name && bin_demangle) {
char *mn = r_bin_demangle (r->bin->cur, NULL, name, addr);
char *mn = r_bin_demangle (r->bin->cur, NULL, name, addr, keep_lib);
if (mn) {
free (name);
name = mn;
@ -1515,10 +1518,10 @@ static int bin_relocs(RCore *r, int mode, int va) {
// take care with very long symbol names! do not use sdb_fmt or similar
if (reloc->import) {
mn = r_bin_demangle (r->bin->cur, lang, reloc->import->name, addr);
mn = r_bin_demangle (r->bin->cur, lang, reloc->import->name, addr, keep_lib);
relname = strdup (reloc->import->name);
} else if (reloc->symbol) {
mn = r_bin_demangle (r->bin->cur, lang, reloc->symbol->name, addr);
mn = r_bin_demangle (r->bin->cur, lang, reloc->symbol->name, addr, keep_lib);
relname = strdup (reloc->symbol->name);
}
@ -1547,7 +1550,7 @@ static int bin_relocs(RCore *r, int mode, int va) {
? strdup (reloc->symbol->name)
: strdup ("null");
if (bin_demangle) {
char *mn = r_bin_demangle (r->bin->cur, NULL, name, addr);
char *mn = r_bin_demangle (r->bin->cur, NULL, name, addr, keep_lib);
if (mn && *mn) {
free (name);
name = mn;
@ -1702,6 +1705,7 @@ R_API ut64 r_core_bin_impaddr(RBin *bin, int va, const char *name) {
static int bin_imports(RCore *r, int mode, int va, const char *name) {
RBinInfo *info = r_bin_get_info (r->bin);
int bin_demangle = r_config_get_i (r->config, "bin.demangle");
bool keep_lib = r_config_get_i (r->config, "bin.demangle.libs");
RBinImport *import;
RListIter *iter;
bool lit = info ? info->has_lit: false;
@ -1729,7 +1733,7 @@ static int bin_imports(RCore *r, int mode, int va, const char *name) {
char *symname = strdup (import->name);
ut64 addr = lit ? r_core_bin_impaddr (r->bin, va, symname): 0;
if (bin_demangle) {
char *dname = r_bin_demangle (r->bin->cur, NULL, symname, addr);
char *dname = r_bin_demangle (r->bin->cur, NULL, symname, addr, keep_lib);
if (dname) {
free (symname);
symname = r_str_newf ("sym.imp.%s", dname);
@ -1844,6 +1848,7 @@ typedef struct {
static void snInit(RCore *r, SymName *sn, RBinSymbol *sym, const char *lang) {
#define MAXFLAG_LEN 128
int bin_demangle = lang != NULL;
bool keep_lib = r_config_get_i (r->config, "bin.demangle.libs");
const char *pfx;
if (!r || !sym || !sym->name) {
return;
@ -1869,7 +1874,7 @@ static void snInit(RCore *r, SymName *sn, RBinSymbol *sym, const char *lang) {
sn->demname = NULL;
sn->demflag = NULL;
if (bin_demangle && sym->paddr) {
sn->demname = r_bin_demangle (r->bin->cur, lang, sn->name, sym->vaddr);
sn->demname = r_bin_demangle (r->bin->cur, lang, sn->name, sym->vaddr, keep_lib);
if (sn->demname) {
sn->demflag = r_str_newf ("%s.%s", pfx, sn->demname);
r_name_filter (sn->demflag, -1);

View File

@ -3064,6 +3064,7 @@ R_API int r_core_config_init(RCore *core) {
SETCB ("bin.force", "", &cb_binforce, "Force that rbin plugin");
SETPREF ("bin.lang", "", "Language for bin.demangle");
SETPREF ("bin.demangle", "true", "Import demangled symbols from RBin");
SETPREF ("bin.demangle.libs", "false", "Show library name on demangled symbols names");
SETCB ("bin.demanglecmd", "false", &cb_bdc, "run xcrun swift-demangle and similar if available (SLOW)");
SETI ("bin.baddr", -1, "Base address of the binary");
SETI ("bin.laddr", 0, "Base address for loading library ('*.so')");

View File

@ -1770,6 +1770,7 @@ static void ds_show_functions(RDisasmState *ds) {
return;
}
bool demangle = r_config_get_i (core->config, "bin.demangle");
bool keep_lib = r_config_get_i (core->config, "bin.demangle.libs");
bool call = r_config_get_i (core->config, "asm.calls");
const char *lang = demangle ? r_config_get (core->config, "bin.lang") : NULL;
f = r_anal_get_fcn_in (core->anal, ds->at, R_ANAL_FCN_TYPE_NULL);
@ -1777,7 +1778,7 @@ static void ds_show_functions(RDisasmState *ds) {
return;
}
if (demangle) {
fcn_name = r_bin_demangle (core->bin->cur, lang, f->name, f->addr);
fcn_name = r_bin_demangle (core->bin->cur, lang, f->name, f->addr, keep_lib);
if (fcn_name) {
fcn_name_alloc = true;
} else {
@ -2166,6 +2167,7 @@ static void ds_show_flags(RDisasmState *ds) {
int count = 0;
bool outline = !ds->flags_inline;
const char *comma = "";
bool keep_lib = r_config_get_i (core->config, "bin.demangle.libs");
r_list_foreach (uniqlist, iter, flag) {
if (f && f->addr == flag->offset && !strcmp (flag->name, f->name)) {
// do not show flags that have the same name as the function
@ -2252,7 +2254,7 @@ static void ds_show_flags(RDisasmState *ds) {
case_prev = case_current;
} else {
const char *lang = r_config_get (core->config, "bin.lang");
char *name = r_bin_demangle (core->bin->cur, lang, flag->realname, flag->offset);
char *name = r_bin_demangle (core->bin->cur, lang, flag->realname, flag->offset, keep_lib);
if (!name) {
const char *n = flag->realname? flag->realname: flag->name;
if (n) {
@ -4065,6 +4067,7 @@ static void ds_print_relocs(RDisasmState *ds) {
RCore *core = ds->core;
const char *lang = r_config_get (core->config, "bin.lang");
bool demangle = r_config_get_i (core->config, "asm.demangle");
bool keep_lib = r_config_get_i (core->config, "bin.demangle.libs");
RBinReloc *rel = r_core_getreloc (core, ds->at, ds->analop.size);
if (rel) {
int cstrlen = 0;
@ -4076,12 +4079,12 @@ static void ds_print_relocs(RDisasmState *ds) {
r_cons_memset (' ', len);
if (rel->import) {
if (demangle) {
demname = r_bin_demangle (core->bin->cur, lang, rel->import->name, rel->vaddr);
demname = r_bin_demangle (core->bin->cur, lang, rel->import->name, rel->vaddr, keep_lib);
}
r_cons_printf ("; RELOC %d %s", rel->type, demname ? demname : rel->import->name);
} else if (rel->symbol) {
if (demangle) {
demname = r_bin_demangle (core->bin->cur, lang, rel->symbol->name, rel->symbol->vaddr);
demname = r_bin_demangle (core->bin->cur, lang, rel->symbol->name, rel->symbol->vaddr, keep_lib);
}
r_cons_printf ("; RELOC %d %s @ 0x%08" PFMT64x " + 0x%" PFMT64x,
rel->type, demname ? demname : rel->symbol->name,

View File

@ -763,7 +763,7 @@ R_API bool r_bin_object_delete(RBin *bin, ut32 binfile_id);
R_API void r_bin_mem_free(void *data);
// demangle functions
R_API char *r_bin_demangle(RBinFile *binfile, const char *lang, const char *str, ut64 vaddr);
R_API char *r_bin_demangle(RBinFile *binfile, const char *lang, const char *str, ut64 vaddr, bool libs);
R_API char *r_bin_demangle_java(const char *str);
R_API char *r_bin_demangle_cxx(RBinFile *binfile, const char *str, ut64 vaddr);
R_API char *r_bin_demangle_msvc(const char *str);