From 75c322b613b5ecdb852ec4454cf1cadaa724aeba Mon Sep 17 00:00:00 2001 From: pancake Date: Sat, 10 Jan 2015 01:00:01 +0100 Subject: [PATCH] Add bin.lang, rabin2 -D and iD commands to demangle from commandline - Fix some warnings in windbg - Minor fix for ARM analysis (wip) --- binr/rabin2/rabin2.c | 42 ++++++++++++++++++++++----- libr/anal/p/anal_arm_cs.c | 6 +++- libr/bin/demangle.c | 24 +++++++++++---- libr/core/bin.c | 14 ++++++--- libr/core/cmd_info.c | 61 ++++++++++++++++++++++++++++++++------- libr/core/cmd_search.c | 2 +- libr/core/config.c | 1 + libr/include/r_bin.h | 3 +- libr/include/r_io.h | 1 - libr/io/p/io_windbg.c | 7 ++--- man/rabin2.1 | 5 +++- shlr/wind/wind.c | 6 ++-- shlr/wind/wind.h | 6 ++-- 13 files changed, 137 insertions(+), 41 deletions(-) diff --git a/binr/rabin2/rabin2.c b/binr/rabin2/rabin2.c index 6f993e3753..f0796e5dcc 100644 --- a/binr/rabin2/rabin2.c +++ b/binr/rabin2/rabin2.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2009-2014 - nibble, pancake */ +/* radare - LGPL - Copyright 2009-2015 - nibble, pancake */ #include #include @@ -39,13 +39,14 @@ static char* file = NULL; static char *name = NULL; static int rw = R_FALSE; static int va = R_TRUE; +static const char *do_demangle = NULL; static ut64 at = 0LL; static RLib *l; static int rabin_show_help(int v) { printf ("Usage: rabin2 [-ACdehHiIjlLMqrRsSvVxzZ] [-@ addr] [-a arch] [-b bits]\n" " [-B addr] [-c F:C:D] [-f str] [-m addr] [-n str] [-N m:M]\n" - " [-o str] [-O str] [-k query] file\n"); + " [-o str] [-O str] [-k query] [-D lang symname] | file>\n"); if (v) printf ( " -@ [addr] show section, symbol or import at addr\n" " -A list archs\n" @@ -55,6 +56,7 @@ static int rabin_show_help(int v) { " -c [fmt:C:D] create [elf,mach0,pe] with Code and Data hexpairs (see -a)\n" " -C list classes\n" " -d show debug/dwarf information\n" + " -D name demangle symbol name\n" " -P show debug/pdb information\n" " -PP download pdb file for binary\n" " -e entrypoint\n" @@ -386,7 +388,7 @@ int main(int argc, char **argv) { #define is_active(x) (action&x) #define set_action(x) actions++; action |= x #define unset_action(x) action &= ~x - while ((c = getopt (argc, argv, "jgqAf:a:B:b:c:Ck:K:dMm:n:N:@:isSIHelRwO:o:pPrvLhxzZ")) != -1) { + while ((c = getopt (argc, argv, "DjgqAf:a:B:b:c:Ck:K:dD:Mm:n:N:@:isSIHelRwO:o:pPrvLhxzZ")) != -1) { switch (c) { case 'g': set_action (ACTION_CLASSES); @@ -446,11 +448,12 @@ int main(int argc, char **argv) { case 'd': set_action (ACTION_DWARF); break; case 'P': if (is_active(ACTION_PDB)) { - set_action(ACTION_PDB_DWNLD); + set_action (ACTION_PDB_DWNLD); } else { set_action (ACTION_PDB); } break; + case 'D': do_demangle = argv[optind]; break; case 'e': set_action (ACTION_ENTRIES); break; case 'M': set_action (ACTION_MAIN); break; case 'l': set_action (ACTION_LIBS); break; @@ -499,13 +502,38 @@ int main(int argc, char **argv) { } break; //case 'V': return blob_version ("rabin2"); case 'h': - r_core_fini (&core); - return rabin_show_help (1); + r_core_fini (&core); + return rabin_show_help (1); default: action |= ACTION_HELP; } } - file = argv[optind]; + if (do_demangle) { + char *res = NULL; + int type; + if ((argc-optind)<2) { + return rabin_show_help (0); + } + type = r_bin_demangle_type (do_demangle); + file = argv[optind +1]; + switch (type) { + case R_BIN_NM_CXX: res = r_bin_demangle_cxx (file); 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); break; + default: + eprintf ("Unknown lang to demangle. Use: cxx, java, objc, swift\n"); + return 1; + } + if (res && *res) { + printf ("%s\n", res); + return 0; + } + free (res); + //eprintf ("%s\n", file); + return 1; + } + file = argv[optind ]; if (!query) if (action & ACTION_HELP || action == ACTION_UNK || file == NULL) { r_core_fini (&core); diff --git a/libr/anal/p/anal_arm_cs.c b/libr/anal/p/anal_arm_cs.c index 5523a61b38..cb9d296fc0 100644 --- a/libr/anal/p/anal_arm_cs.c +++ b/libr/anal/p/anal_arm_cs.c @@ -217,7 +217,9 @@ static void anop64 (RAnalOp *op, cs_insn *insn) { case ARM64_INS_LSR: break; case ARM64_INS_STR: - //case ARM64_INS_POP: + op->type = R_ANAL_OP_TYPE_STORE; +// 0x00008160 04202de5 str r2, [sp, -4]! + break; case ARM64_INS_LDR: op->type = R_ANAL_OP_TYPE_LOAD; break; @@ -294,6 +296,8 @@ static void anop32 (RAnalOp *op, cs_insn *insn) { case ARM_INS_PUSH: case ARM_INS_STR: //case ARM_INS_POP: + op->type = R_ANAL_OP_TYPE_STORE; + break; case ARM_INS_LDR: if (insn->detail->arm.operands[0].reg == ARM_REG_PC) { op->type = R_ANAL_OP_TYPE_UJMP; diff --git a/libr/bin/demangle.c b/libr/bin/demangle.c index a9995cdef4..05ff57496b 100644 --- a/libr/bin/demangle.c +++ b/libr/bin/demangle.c @@ -212,6 +212,8 @@ R_API int r_bin_demangle_type (const char *str) { return R_BIN_NM_NONE; if (!strcmp (str, "swift")) return R_BIN_NM_SWIFT; + if (!strcmp (str, "java")) + return R_BIN_NM_JAVA; if (!strcmp (str, "objc")) return R_BIN_NM_OBJC; if (!strcmp (str, "cxx")) @@ -219,17 +221,29 @@ R_API int r_bin_demangle_type (const char *str) { return R_BIN_NM_NONE; } -extern char *r_bin_demangle_swift(const char *s); - -R_API char *r_bin_demangle (RBinFile *binfile, const char *str) { +R_API int r_bin_lang_type(RBinFile *binfile, const char *def) { int type; - RBinPlugin *plugin = r_bin_file_cur_plugin (binfile); + RBinPlugin *plugin; + if (def && *def) { + type = r_bin_demangle_type (def); + if (type != R_BIN_NM_NONE) + return type; + } + plugin = r_bin_file_cur_plugin (binfile); if (plugin && plugin->demangle_type) - type = plugin->demangle_type (str); + type = plugin->demangle_type (def); else type = r_bin_demangle_type (binfile->o->info->lang); + if (type == R_BIN_NM_NONE) + type = r_bin_demangle_type (def); + return type; +} + +R_API char *r_bin_demangle (RBinFile *binfile, const char *def, const char *str) { + 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); } return NULL; diff --git a/libr/core/bin.c b/libr/core/bin.c index e836e6b68b..c6d2735269 100644 --- a/libr/core/bin.c +++ b/libr/core/bin.c @@ -330,6 +330,8 @@ static int bin_info (RCore *r, int mode) { r_config_set (r->config, "asm.arch", info->arch); r_core_cmdf (r, "m /root %s 0", info->arch); } else { + if (info->lang) + r_config_set (r->config, "bin.lang", info->lang); r_config_set (r->config, "asm.os", info->os); r_config_set (r->config, "asm.arch", info->arch); r_config_set (r->config, "anal.arch", info->arch); @@ -350,6 +352,7 @@ static int bin_info (RCore *r, int mode) { //int has_va = (!strcmp (info->rclass, "elf-object"))? 0: 1; //if (!strcmp (info->type, "REL"))...relocatable object.. r_cons_printf ( + "e bin.lang=%s\n" "e file.type=%s\n" "e cfg.bigendian=%s\n" "e asm.os=%s\n" @@ -357,6 +360,7 @@ static int bin_info (RCore *r, int mode) { "e anal.arch=%s\n" "e asm.bits=%i\n" "e asm.dwarf=%s\n", + info->lang? info->lang: "", info->rclass, r_str_bool (info->big_endian), info->os, info->arch, info->arch, info->bits, r_str_bool (R_BIN_DBG_STRIPPED &info->dbg_info)); @@ -662,6 +666,7 @@ static int bin_relocs (RCore *r, int mode, ut64 baddr, int va) { } else if ((mode & R_CORE_BIN_SET)) { int bin_demangle = r_config_get_i (r->config, "bin.demangle"); + const char *lang = r_config_get (r->config, "bin.lang"); int is_pe = 1; // TODO: optimize int is_sandbox = r_sandbox_enable (0); char *sdb_module = NULL; @@ -720,7 +725,7 @@ static int bin_relocs (RCore *r, int mode, ut64 baddr, int va) { snprintf (str, R_FLAG_NAME_SIZE, "reloc.%s_%d", reloc->import->name, (int)(addr&0xff)); if (bin_demangle) - demname = r_bin_demangle (r->bin->cur, str); + demname = r_bin_demangle (r->bin->cur, lang, str); r_name_filter (str, 0); //r_str_replace_char (str, '$', '_'); fi = r_flag_set (r->flags, str, addr, bin_reloc_size (reloc), 0); @@ -893,6 +898,7 @@ static int bin_imports (RCore *r, int mode, ut64 baddr, int va, const char *name static int bin_symbols (RCore *r, int mode, ut64 baddr, ut64 laddr, int va, ut64 at, const char *name) { int bin_demangle = r_config_get_i (r->config, "bin.demangle"); + const char *lang = r_config_get (r->config, "bin.lang"); RBinInfo *info = r_bin_get_info (r->bin); int is_arm = info && !strcmp (info->arch, "arm"); char str[R_FLAG_NAME_SIZE]; @@ -948,7 +954,7 @@ static int bin_symbols (RCore *r, int mode, ut64 baddr, ut64 laddr, int va, ut64 demname = NULL; if (bin_demangle) { - demname = r_bin_demangle (r->bin->cur, name); + demname = r_bin_demangle (r->bin->cur, lang, name); } r_name_filter (name, 80); if (!demname) @@ -998,7 +1004,7 @@ static int bin_symbols (RCore *r, int mode, ut64 baddr, ut64 laddr, int va, ut64 addr + symbol->size, name); } #endif - dname = r_bin_demangle (r->bin->cur, symbol->name); + dname = r_bin_demangle (r->bin->cur, lang, symbol->name); if (dname) { r_meta_add (r->anal, R_META_TYPE_COMMENT, addr, symbol->size, dname); @@ -1023,7 +1029,7 @@ static int bin_symbols (RCore *r, int mode, ut64 baddr, ut64 laddr, int va, ut64 r_cons_printf ("%s\n", symbol->name); } else { if (mode) { - char *mn = r_bin_demangle (r->bin->cur, symbol->name); + char *mn = r_bin_demangle (r->bin->cur, lang, symbol->name); if (mn) { //r_name_filter (mn, strlen (mn)); r_cons_printf ("s 0x%08"PFMT64x"\n\"CC %s\"\n", diff --git a/libr/core/cmd_info.c b/libr/core/cmd_info.c index aa041b491e..905b0f7f4c 100644 --- a/libr/core/cmd_info.c +++ b/libr/core/cmd_info.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2009-2014 - pancake */ +/* radare - LGPL - Copyright 2009-2015 - pancake */ #define PAIR_WIDTH 9 static void pair(const char *a, const char *b) { @@ -6,12 +6,48 @@ static void pair(const char *a, const char *b) { int al = strlen (a); if (!b) b = ""; memset (ws, ' ', sizeof (ws)); - al = PAIR_WIDTH-al; + al = PAIR_WIDTH - al; if (al<0) al = 0; ws[al] = 0; r_cons_printf ("%s%s%s\n", a, ws, b); } +static int demangle_internal(const char *lang, const char *s) { + char *res = NULL; + int type = r_bin_demangle_type (lang); + switch (type) { + case R_BIN_NM_CXX: res = r_bin_demangle_cxx (s); 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); break; + default: + eprintf ("Unknown lang to demangle. Use: cxx, java, objc, swift\n"); + return 1; + } + if (res && *res) { + printf ("%s\n", res); + return 0; + } + free (res); +} + +static int demangle(RCore *core, const char *s) { + char *p, *q; + const char *ss = strchr (s, ' '); + if (!*s) return 0; + if (!ss) { + const char *lang = r_config_get (core->config, "bin.lang"); + demangle_internal (lang, s); + return 1; + } + p = strdup (s); + q = p + (ss-s); + *q = 0; + demangle_internal (p, q+1); + free (p); + return 1; +} + #define STR(x) (x)?(x):"" static void r_core_file_info (RCore *core, int mode) { const char *fn = NULL; @@ -112,18 +148,18 @@ static int cmd_info(void *data, const char *input) { ut64 offset = r_bin_get_offset (core->bin); RBinObject *o = r_bin_cur_object (core->bin); RCoreFile *cf = core->file; - - int va = core->io->va || core->io->debug; + int i, va = core->io->va || core->io->debug; int mode = 0; //R_CORE_BIN_SIMPLE; int is_array = 0; Sdb *db; - if (strchr (input, '*')) - mode = R_CORE_BIN_RADARE; - if (strchr (input, 'j')) - mode = R_CORE_BIN_JSON; - if (strchr (input, 'q')) - mode = R_CORE_BIN_SIMPLE; + for (i = 0; i<2; i++) { + switch (input[i]) { + case '*': mode = R_CORE_BIN_RADARE; break; + case 'j': mode = R_CORE_BIN_JSON; break; + case 'q': mode = R_CORE_BIN_SIMPLE; break; + } + } if (mode == R_CORE_BIN_JSON) { if (strlen (input+1)>1) @@ -242,6 +278,11 @@ static int cmd_info(void *data, const char *input) { break; case 'c': case 'C': RBININFO ("classes", R_CORE_BIN_ACC_CLASSES); break; + case 'D': + if (input[1]!=' ' || !demangle (core, input+2)) { + eprintf ("|Usage: iD lang symbolname\n"); + } + return 0; case 'a': { switch (mode) { diff --git a/libr/core/cmd_search.c b/libr/core/cmd_search.c index 3d5c779184..2c2a3a19e4 100644 --- a/libr/core/cmd_search.c +++ b/libr/core/cmd_search.c @@ -283,8 +283,8 @@ static int __cb_hit(RSearchKeyword *kw, void *user, ut64 addr) { return R_TRUE; } - static int c = 0; + static inline void print_search_progress(ut64 at, ut64 to, int n) { if ((++c%64) || (json)) return; diff --git a/libr/core/config.c b/libr/core/config.c index 580d032473..afa86dd2f0 100644 --- a/libr/core/config.c +++ b/libr/core/config.c @@ -926,6 +926,7 @@ R_API int r_core_config_init(RCore *core) { SETPREF("asm.functions", "true", "Show functions in disassembly"); SETPREF("asm.xrefs", "true", "Show xrefs in disassembly"); SETPREF("asm.demangle", "true", "Show demangled symbols in disasm"); + SETPREF("bin.lang", "", "Language for bin.demangle"); SETPREF("bin.demangle", "false", "Import demangled symbols from RBin"); #if 0 r_config_set (cfg, "asm.offseg", "false"); diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index 03a2680216..768bef8480 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -383,10 +383,11 @@ R_API void r_bin_set_baddr(RBin *bin, ut64 baddr); R_API ut64 r_bin_get_boffset(RBin *bin); R_API RBinAddr* r_bin_get_sym(RBin *bin, int sym); -R_API char* r_bin_demangle(RBinFile *binfile, const char *str); +R_API char* r_bin_demangle(RBinFile *binfile, const char *lang, const char *str); R_API int r_bin_demangle_type (const char *str); R_API char *r_bin_demangle_java(const char *str); R_API char *r_bin_demangle_cxx(const char *str); +R_API char *r_bin_demangle_swift(const char *s); 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_cxx(RBinFile *binfile); diff --git a/libr/include/r_io.h b/libr/include/r_io.h index 24b885e58d..bd0498f101 100644 --- a/libr/include/r_io.h +++ b/libr/include/r_io.h @@ -459,7 +459,6 @@ extern RIOPlugin r_io_plugin_http; extern RIOPlugin r_io_plugin_haret; extern RIOPlugin r_io_plugin_bfdbg; extern RIOPlugin r_io_plugin_w32; -extern RIOPlugin r_io_plugin_ewf; extern RIOPlugin r_io_plugin_zip; extern RIOPlugin r_io_plugin_mmap; extern RIOPlugin r_io_plugin_default; diff --git a/libr/io/p/io_windbg.c b/libr/io/p/io_windbg.c index 83a682f807..fb2615f20a 100644 --- a/libr/io/p/io_windbg.c +++ b/libr/io/p/io_windbg.c @@ -37,7 +37,6 @@ static int __plugin_open(RIO *io, const char *file, ut8 many) { static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { void *io_ctx; WindCtx *ctx; - char *transport, *args; if (!__plugin_open (io, file, 0)) return NULL; @@ -47,7 +46,7 @@ static RIODesc *__open(RIO *io, const char *file, int rw, int mode) { return NULL; } - io_ctx = iob_open(file + 9); + io_ctx = iob_open (file + 9); if (!io_ctx) { eprintf("Could not open the pipe\n"); return NULL; @@ -66,13 +65,13 @@ static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { return -1; if (wind_get_target(fd->data)) { - ut64 va; + uint64_t va; if (!wind_va_to_pa(fd->data, io->off, &va)) return -1; return wind_write_at_phys(fd->data, buf, va, count); } - return wind_write_at(fd->data, buf, io->off, count); + return wind_write_at (fd->data, buf, io->off, count); } static ut64 __lseek(RIO *io, RIODesc *fd, ut64 offset, int whence) { diff --git a/man/rabin2.1 b/man/rabin2.1 index 3a43a33a9c..b752d91302 100644 --- a/man/rabin2.1 +++ b/man/rabin2.1 @@ -1,4 +1,4 @@ -.Dd Sep 30, 2014 +.Dd Jan 10, 2015 .Dt RABIN2 1 .Sh NAME .Nm RABIN2 @@ -10,6 +10,7 @@ .Op Fl b Ar bits .Op Fl B Ar addr .Op Fl c Ar fmt:C:[D] +.Op Fl D Ar lang .Op Fl f Ar subbin .Op Fl k Ar query .Op Fl K Ar algo @@ -38,6 +39,8 @@ Create [elf,mach0,pe] for arm and x86-32/64 tiny binaries where 'C' is an hexpai List classes .It Fl d Show debug/dwarf information +.It Fl D Ar lang symbolname +Demangle symbol name for lang .It Fl e Show entrypoints for disk and on-memory .It Fl f Ar subbin diff --git a/shlr/wind/wind.c b/shlr/wind/wind.c index 818898e868..a9af7c37a8 100644 --- a/shlr/wind/wind.c +++ b/shlr/wind/wind.c @@ -716,7 +716,7 @@ wind_continue (WindCtx *ctx) { } int -wind_write_reg (WindCtx *ctx, uint8_t *buf, int size) { +wind_write_reg (WindCtx *ctx, const uint8_t *buf, int size) { kd_packet_t *pkt; kd_req_t req; int ret; @@ -1029,7 +1029,7 @@ wind_read_at (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int count } int -wind_write_at (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int count) { +wind_write_at (WindCtx *ctx, const uint8_t *buf, const uint64_t offset, const int count) { kd_packet_t *pkt; kd_req_t req; int ret; @@ -1082,7 +1082,7 @@ wind_write_at (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int coun } int -wind_write_at_phys (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int count) { +wind_write_at_phys (WindCtx *ctx, const uint8_t *buf, const uint64_t offset, const int count) { kd_packet_t *pkt; kd_req_t req; int ret; diff --git a/shlr/wind/wind.h b/shlr/wind/wind.h index 13d9bb5465..ea314ad9f5 100644 --- a/shlr/wind/wind.h +++ b/shlr/wind/wind.h @@ -43,13 +43,13 @@ int wind_wait_packet (WindCtx *ctx, const uint32_t type, kd_packet_t **p); int wind_sync (WindCtx *ctx); int wind_read_ver (WindCtx *ctx); int wind_continue (WindCtx *ctx); -int wind_write_reg (WindCtx *ctx, uint8_t *buf, int size); +int wind_write_reg (WindCtx *ctx, const uint8_t *buf, int size); int wind_read_reg (WindCtx *ctx, uint8_t *buf, int size); int wind_query_mem (WindCtx *ctx, const uint64_t addr, int *address_space, int *flags); int wind_bkpt (WindCtx *ctx, const uint64_t addr, const int set, const int hw, int *handle); int wind_read_at (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int count); int wind_read_at_phys (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int count); -int wind_write_at (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int count); -int wind_write_at_phys (WindCtx *ctx, uint8_t *buf, const uint64_t offset, const int count); +int wind_write_at (WindCtx *ctx, const uint8_t *buf, const uint64_t offset, const int count); +int wind_write_at_phys (WindCtx *ctx, const uint8_t *buf, const uint64_t offset, const int count); int wind_va_to_pa (WindCtx *ctx, uint64_t va, uint64_t *pa); #endif