diff --git a/libr/bin/demangle.c b/libr/bin/demangle.c index 9522096009..00b79cfa69 100644 --- a/libr/bin/demangle.c +++ b/libr/bin/demangle.c @@ -68,6 +68,7 @@ R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64 return NULL; } RBin *bin = bf? bf->rbin: NULL; + bool trylib = bin? bin->demangle_trylib: true; RBinObject *o = bf? bf->o: NULL; RListIter *iter; const char *lib = NULL; @@ -124,7 +125,7 @@ R_API char *r_bin_demangle(RBinFile *bf, const char *def, const char *str, ut64 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_SWIFT: demangled = r_bin_demangle_swift (str, bin? bin->demangle_usecmd: false, trylib); 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; diff --git a/libr/bin/mangling/swift-sd.c b/libr/bin/mangling/swift-sd.c index 1c86cf73e4..986355eeec 100644 --- a/libr/bin/mangling/swift-sd.c +++ b/libr/bin/mangling/swift-sd.c @@ -171,7 +171,7 @@ static char *swift_demangle_lib(const char *s) { return NULL; } -R_API char *r_bin_demangle_swift(const char *s, bool syscmd) { +R_API char *r_bin_demangle_swift(const char *s, bool syscmd, bool trylib) { #define STRCAT_BOUNDS(x) if (((x) + 2 + strlen (out)) > sizeof (out)) break; char out[1024]; int i, len, is_generic = 0; @@ -191,18 +191,15 @@ R_API char *r_bin_demangle_swift(const char *s, bool syscmd) { return NULL; } } - if (!strncmp (s, "__", 2)) { s = s + 2; } -#if 0 - const char *element[] = { - "module", "class", "method", NULL - }; -#endif - char *res = swift_demangle_lib (s); - if (res) { - return res; + char *res = NULL; + if (trylib) { + res = swift_demangle_lib (s); + if (res) { + return res; + } } const char *attr = NULL; const char *attr2 = NULL; @@ -516,27 +513,29 @@ R_API char *r_bin_demangle_swift(const char *s, bool syscmd) { const char *s = getstring (q, len); if (s && *s) { if (is_first) { - strcat (out, is_generic?"<":"("); + strcat (out, is_generic?"<":": "); is_first = 0; } //printf ("ISLAST (%s)\n", q+len); - is_last = q[len]; + is_last = strlen (q+len) < 5; if (attr) { STRCAT_BOUNDS (strlen (attr)); strcat (out, attr); - strcat (out, " "); + if (!is_last) { + strcat (out, ", "); + } } STRCAT_BOUNDS (strlen (s)); - strcat (out, s); - if (is_last) { - strcat (out, is_generic?">":")"); - is_first = (*s != '_'); - if (is_generic && !is_first) { - break; + if (strcmp (s, "_")) { + strcat (out, s); + strcat (out, is_generic?">":""); + is_first = (*s != '_'); + if (is_generic && !is_first) { + break; + } + } else { + strcat(out, ")"); } - } else { - strcat (out, ", "); - } } else { if (attr) { strcat (out, " -> "); diff --git a/libr/core/cbin.c b/libr/core/cbin.c index a0a153454c..de0bc15440 100644 --- a/libr/core/cbin.c +++ b/libr/core/cbin.c @@ -1961,7 +1961,7 @@ R_API ut64 r_core_bin_impaddr(RBin *bin, int va, const char *name) { static int bin_imports(RCore *r, PJ *pj, 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"); + bool keep_lib = r_config_get_b (r->config, "bin.demangle.libs"); RTable *table = r_core_table (r, "imports"); r_return_val_if_fail (table, false); RBinImport *import; @@ -2130,7 +2130,7 @@ typedef struct { static void snInit(RCore *r, SymName *sn, RBinSymbol *sym, const char *lang) { int bin_demangle = lang != NULL; - bool keep_lib = r_config_get_i (r->config, "bin.demangle.libs"); + bool keep_lib = r_config_get_b (r->config, "bin.demangle.libs"); if (!r || !sym || !sym->name) { return; } diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index 2555f9e0db..6fc40eb654 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -1082,7 +1082,7 @@ static bool cb_binfilter(void *user, void *data) { static bool cb_bdc(void *user, void *data) { RCore *core = (RCore*) user; RConfigNode *node = (RConfigNode*) data; - core->bin->demanglercmd = node->i_value; + core->bin->demangle_usecmd = node->i_value; return true; } @@ -2693,6 +2693,16 @@ static bool cb_binstrings(void *user, void *data) { return true; } +static bool cb_demangle_trylib(void *user, void *data) { + RCore *core = (RCore *) user; + RConfigNode *node = (RConfigNode *) data; + if (!core || !core->bin) { + return false; + } + core->bin->demangle_trylib = node->i_value; + return true; +} + static bool cb_bindbginfo(void *user, void *data) { RCore *core = (RCore *) user; RConfigNode *node = (RConfigNode *) data; @@ -3501,6 +3511,7 @@ R_API int r_core_config_init(RCore *core) { SETPREF ("bin.cache", "false", "Use io.cache.read if bin needs to patch relocs"); SETPREF ("bin.lang", "", "Language for bin.demangle"); SETBPREF ("bin.demangle", "true", "Import demangled symbols from RBin"); + SETCB("bin.demangle.trylib", "true", &cb_demangle_trylib, "Try to use system available libraries to demangle"); SETBPREF ("bin.demangle.libs", "false", "Show library name on demangled symbols names"); SETI ("bin.baddr", -1, "Base address of the binary"); SETI ("bin.laddr", 0, "Base address for loading library ('*.so')"); diff --git a/libr/core/cmd_info.c b/libr/core/cmd_info.c index 3309ee5ebb..ca245d8fc6 100644 --- a/libr/core/cmd_info.c +++ b/libr/core/cmd_info.c @@ -97,7 +97,7 @@ static bool demangle_internal(RCore *core, const char *lang, const char *s) { case R_BIN_NM_CXX: res = r_bin_demangle_cxx (core->bin->cur, s, 0); break; 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, core->bin->demanglercmd); break; + case R_BIN_NM_SWIFT: res = r_bin_demangle_swift (s, core->bin->demangle_usecmd, core->bin->demangle_trylib); break; case R_BIN_NM_DLANG: res = r_bin_demangle_plugin (core->bin, "dlang", s); break; case R_BIN_NM_MSVC: res = r_bin_demangle_msvc (s); break; case R_BIN_NM_RUST: res = r_bin_demangle_rust (core->bin->cur, s, 0); break; diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index 4ec94160ab..09dd00f18e 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -338,7 +338,8 @@ struct r_bin_t { char *prefix; // bin.prefix char *strenc; ut64 filter_rules; - bool demanglercmd; + bool demangle_usecmd; + bool demangle_trylib; bool verbose; bool use_xtr; // use extract plugins when loading a file? bool use_ldr; // use loader plugins when loading a file? @@ -786,7 +787,7 @@ R_API char *r_bin_demangle(RBinFile *binfile, const char *lang, const char *str, 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); -R_API char *r_bin_demangle_swift(const char *s, bool syscmd); +R_API char *r_bin_demangle_swift(const char *s, bool syscmd, bool trylib); R_API char *r_bin_demangle_objc(RBinFile *binfile, const char *sym); R_API char *r_bin_demangle_rust(RBinFile *binfile, const char *str, ut64 vaddr); R_API int r_bin_demangle_type(const char *str); diff --git a/libr/main/rabin2.c b/libr/main/rabin2.c index aa23dd7bbd..3f9fe6b55e 100644 --- a/libr/main/rabin2.c +++ b/libr/main/rabin2.c @@ -81,12 +81,14 @@ static int rabin_show_help(int v) { " RABIN2_DMNGLRCMD: e bin.demanglercmd # try to purge false positives\n" " RABIN2_LANG: e bin.lang # assume lang for demangling\n" " RABIN2_MAXSTRBUF: e bin.maxstrbuf # specify maximum buffer size\n" - " RABIN2_NOPLUGINS: # do not load shared plugins (speedup loading)\n" + " RABIN2_NOPLUGINS: 1|0| # do not load shared plugins (speedup loading)\n" " RABIN2_PDBSERVER: e pdb.server # use alternative PDB server\n" " RABIN2_PREFIX: e bin.prefix # prefix symbols/sections/relocs with a specific string\n" - " RABIN2_STRFILTER: e bin.str.filter # r2 -qc 'e bin.str.filter=?" "?' -\n" + " RABIN2_STRFILTER: e bin.str.filter # r2 -qc 'e bin.str.filter=?" "?' -\n" " RABIN2_STRPURGE: e bin.str.purge # try to purge false positives\n" - " RABIN2_SYMSTORE: e pdb.symstore # path to downstream symbol store\n"); + " RABIN2_SYMSTORE: e pdb.symstore # path to downstream symbol store\n" + " RABIN2_SWIFTLIB: 1|0| # load Swift libsto demangle (default: true)\n" + ); } return 1; } @@ -510,14 +512,27 @@ static int __lib_bin_ldr_dt(RLibPlugin *pl, void *p, void *u) { return true; } +static void setup_trylib_from_environment(RBin *bin, int type) { + bool trylib = false; + if (type == R_BIN_NM_SWIFT) { + trylib = true; + char *swiftlib = r_sys_getenv ("RABIN2_TRYLIB"); + if (swiftlib) { + trylib = r_str_is_true (swiftlib); + free (swiftlib); + } + } + bin->demangle_trylib = trylib; +} + static char *__demangleAs(RBin *bin, int type, const char *file) { - bool syscmd = bin? bin->demanglercmd: false; + bool syscmd = bin? bin->demangle_usecmd: false; char *res = NULL; switch (type) { case R_BIN_NM_CXX: res = r_bin_demangle_cxx (NULL, file, 0); break; case R_BIN_NM_JAVA: res = r_bin_demangle_java (file); break; case R_BIN_NM_OBJC: res = r_bin_demangle_objc (NULL, file); break; - case R_BIN_NM_SWIFT: res = r_bin_demangle_swift (file, syscmd); break; + case R_BIN_NM_SWIFT: res = r_bin_demangle_swift (file, syscmd, bin->demangle_trylib); break; case R_BIN_NM_MSVC: res = r_bin_demangle_msvc (file); break; case R_BIN_NM_RUST: res = r_bin_demangle_rust (NULL, file, 0); break; default: @@ -865,12 +880,12 @@ R_API int r_main_rabin2(int argc, const char **argv) { if (do_demangle) { char *res = NULL; - int type; if ((argc - opt.ind) < 2) { r_core_fini (&core); return rabin_show_help (0); } - type = r_bin_demangle_type (do_demangle); + int type = r_bin_demangle_type (do_demangle); + setup_trylib_from_environment (bin, type); file = argv[opt.ind + 1]; if (!strcmp (file, "-")) { for (;;) { diff --git a/man/rabin2.1 b/man/rabin2.1 index da53107a87..57cdb612c7 100644 --- a/man/rabin2.1 +++ b/man/rabin2.1 @@ -150,6 +150,8 @@ RABIN2_DEBASE64 try to decode all strings as base64 if possible RABIN2_STRFILTER same as r2 -e bin.str.filter for rabin2 .Pp RABIN2_STRPURGE same as r2 -e bin.str.purge for rabin2 +.Pp +RABIN2_DEMANGLE_TRYLIB same as r2 -e bin.demangle.trylib= - try to dynamically load libraries to demangle .Sh EXAMPLES .Pp List symbols of a program diff --git a/test/db/cmd/cmd_i b/test/db/cmd/cmd_i index a072cd8a6a..53d7f59ea0 100644 --- a/test/db/cmd/cmd_i +++ b/test/db/cmd/cmd_i @@ -1495,7 +1495,7 @@ NAME=iD FILE=bins/elf/libmagic.so CMDS=iD swift _TFSSCfT21_builtinStringLiteralBp8byteSizeBw7isASCIIBi1__SS EXPECT=< String +Swift.String.init (_builtinStringLiteral: Builtin.RawPointer, byteSize: Builtin.Word, isASCII: Builtin.Int1) -> String EOF RUN diff --git a/test/db/formats/mangling/swift b/test/db/formats/mangling/swift index 174b2f1942..854b5f6635 100644 --- a/test/db/formats/mangling/swift +++ b/test/db/formats/mangling/swift @@ -8,8 +8,9 @@ RUN NAME=elf swift demangle (requires swift-demangle program) FILE=bins/elf/analysis/hello-swift +ARGS=-e bin.demangle.trylib=false CMDS=isq~0x004009e0 EXPECT=< String +0x004009e0 16 Swift.String.init (_builtinStringLiteral: Builtin.RawPointer, byteSize: Builtin.Word, isASCII: Builtin.Int1) -> String EOF RUN diff --git a/test/db/tools/rabin2 b/test/db/tools/rabin2 index 5c768aa3ae..0c230c5f46 100644 --- a/test/db/tools/rabin2 +++ b/test/db/tools/rabin2 @@ -879,7 +879,7 @@ NAME=rabin2 -D swift FILE=bins/elf/libc.so.0 CMDS=!rabin2 -D swift _TFSSCfT21_builtinStringLiteralBp8byteSizeBw7isASCIIBi1__SS EXPECT=< String +Swift.String.init (_builtinStringLiteral: Builtin.RawPointer, byteSize: Builtin.Word, isASCII: Builtin.Int1) -> String EOF RUN