Improve swift demangler and add bin.demangle.trylib config ##bin

- May fix the macos testsuite as long as latest macOS comes with libSwift
This commit is contained in:
pancake 2021-10-05 09:05:49 +02:00 committed by GitHub
parent e4f13622e4
commit f427fc77cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 69 additions and 39 deletions

View File

@ -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;

View File

@ -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, " -> ");

View File

@ -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;
}

View File

@ -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')");

View File

@ -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;

View File

@ -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);

View File

@ -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 (;;) {

View File

@ -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=<bool> - try to dynamically load libraries to demangle
.Sh EXAMPLES
.Pp
List symbols of a program

View File

@ -1495,7 +1495,7 @@ NAME=iD
FILE=bins/elf/libmagic.so
CMDS=iD swift _TFSSCfT21_builtinStringLiteralBp8byteSizeBw7isASCIIBi1__SS
EXPECT=<<EOF
Swift.String.init (_builtinStringLiteral(Builtin.RawPointer byteSize__Builtin.Word isASCII__Builtin.Int1 _) -> String
Swift.String.init (_builtinStringLiteral: Builtin.RawPointer, byteSize: Builtin.Word, isASCII: Builtin.Int1) -> String
EOF
RUN

View File

@ -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=<<EOF
0x004009e0 16 Swift.String.init (_builtinStringLiteral(Builtin.RawPointer byteSize__Builtin.Word isASCII__Builtin.Int1 _) -> String
0x004009e0 16 Swift.String.init (_builtinStringLiteral: Builtin.RawPointer, byteSize: Builtin.Word, isASCII: Builtin.Int1) -> String
EOF
RUN

View File

@ -879,7 +879,7 @@ NAME=rabin2 -D swift
FILE=bins/elf/libc.so.0
CMDS=!rabin2 -D swift _TFSSCfT21_builtinStringLiteralBp8byteSizeBw7isASCIIBi1__SS
EXPECT=<<EOF
Swift.String.init (_builtinStringLiteral(Builtin.RawPointer byteSize__Builtin.Word isASCII__Builtin.Int1 _) -> String
Swift.String.init (_builtinStringLiteral: Builtin.RawPointer, byteSize: Builtin.Word, isASCII: Builtin.Int1) -> String
EOF
RUN