diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76473eb1..7c28c22a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,7 @@ jobs: - name: Installing Radare2 run: sudo dpkg -i radare2/dist/debian/*/*.deb - name: Building r2ghidra with cmake - run: git submodule update --init ; mkdir build && cd build && cmake .. && make -j4 && sudo make install + run: git submodule update --init ; make ghidra/ghidra/Ghidra ; mkdir build && cd build && cmake .. && make -j4 && sudo make install - name: Packaging r2ghidra for Debian run: make -C scripts/debian - name: Testing r2ghidra oneliner @@ -144,9 +144,9 @@ jobs: set PATH=%CD%\radare2\bin;%PATH% set ARCH=x64 git submodule update --init + make ghidra/ghidra/Ghidra call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 - mkdir destdir - mkdir build + mkdir destdir build cd build cmake -GNinja .. cmake --build . diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index 9b5069db..00000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: docker -on: - push: - branches: - - master - pull_request: - -jobs: - build: - name: docker - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Checkout submodules - run: | - git submodule init - git submodule update - - name: Docker Build - run: cd scripts && docker build -t r2ghidra . -f Dockerfile.buster && cd .. - - name: Build and Test - run: docker run --rm -v "`pwd`:/build" -t r2ghidra /bin/bash -c "cd /build && scripts/ci-script" - diff --git a/.gitmodules b/.gitmodules index 4a841fea..7d783820 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,3 @@ -[submodule "ghidra/ghidra"] - path = ghidra/ghidra - branch = r2ghidra - url = https://github.com/radareorg/ghidra.git [submodule "third-party/pugixml"] path = third-party/pugixml url = https://github.com/zeux/pugixml.git diff --git a/Makefile b/Makefile index ca14d3d7..d801c5fb 100644 --- a/Makefile +++ b/Makefile @@ -13,16 +13,23 @@ endif ghidra-processors.txt: cp -f ghidra-processors.txt.default ghidra-processors.txt -asan: - CFLAGS="-fsanitize=address" $(MAKE) -C src +asan: ghidra/ghidra/Ghidra ghidra-processors.txt + #touch ghidra/ghidra/Ghidra/Features/Decompiler/src/decompile/cpp/*.cc src/*.cpp + touch src/*.cpp + CFLAGS="-fsanitize=address -g" $(MAKE) -C src -j + make user-install + +asan-run: + DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib r2 -s 9664 /Users/pancake/Downloads/usr-4/bin/bc help: @echo - @echo "./configure # first you need to run configure" - @echo "make # build r2ghidra plugins" - @echo "make install # install plugin and sleighs into prefix" - @echo "make user-install # install in your home" - @echo "make uninstall # uninstall r2ghidra from prefix (see user-uninstall)" + @echo "./configure # first you need to run configure" + @echo "make # build r2ghidra plugins" + @echo "make install # install plugin and sleighs into prefix" + @echo "make uninstall # uninstall r2ghidra from prefix (see user-uninstall)" + @echo "make user-install # install in your home" + @echo "make user-uninstall # uninstall r2ghidra from prefix (see user-uninstall)" @echo clean: @@ -53,8 +60,16 @@ user-uninstall: $(MAKE) -C src sleigh-uninstall rm -f $(DESTDIR)/$(BINDIR)/sleighc +gclean: + rm -rf ghidra-native ghidra/ghidra/Ghidra + ghidra/ghidra/Ghidra: - $(MAKE) -C ghidra + git clone https://github.com/radareorg/ghidra-native + $(MAKE) -C ghidra-native patch + mkdir -p ghidra/ghidra/Ghidra/Features/Decompiler/src/decompile/cpp + cp -rf ghidra-native/src/decompiler/* ghidra/ghidra/Ghidra/Features/Decompiler/src/decompile/cpp + mkdir -p ghidra/ghidra/Ghidra/Processors + cp -rf ghidra-native/src/Processors/* ghidra/ghidra/Ghidra/Processors/ mrproper: clean git submodule deinit --all -f diff --git a/README.md b/README.md index f60fcd2a..5bd2f404 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,8 @@ At the moment there is no way to select which processors to support, so it build First, make sure the submodule contained within this repository is fetched and up to date: ``` -git submodule init -git submodule update +git submodule update --init +make ghidra/ghidra/Ghidra ``` Then, the radare2 plugin can be built and installed as follows: diff --git a/configure b/configure index 3e5c1a15..c0ef1e8e 100755 --- a/configure +++ b/configure @@ -109,12 +109,12 @@ done : ${INSTALL_PROGRAM_STRIP:=${INSTALL} -m 755 -s} : ${INSTALL_MAN:=${INSTALL} -m 444} : ${INSTALL_LIB:=${INSTALL} -m 755 -c} - PKGNAME='r2ghidra' ; VERSION='5.2.1' ; VERSION_MAJOR=5; VERSION_MINOR=2; VERSION_PATCH=1; VERSION_NUMBER=50201; CONTACT_MAIL="pancake@nopcode.org" ; CONTACT_NAME="pancake" ; CONTACT="pancake " ; + PKGNAME='r2ghidra' ; VERSION='5.3.1' ; VERSION_MAJOR=5; VERSION_MINOR=3; VERSION_PATCH=1; VERSION_NUMBER=50301; CONTACT_MAIL="pancake@nopcode.org" ; CONTACT_NAME="pancake" ; CONTACT="pancake " ; } show_usage() { cat <." exit 0 @@ -218,7 +218,7 @@ case $flag in show_version ; ;; -r|--r|--report) echo "PKGNAME: r2ghidra" -echo "VERSION: 5.2.1" +echo "VERSION: 5.3.1" echo "LANGS: c++" echo "PKG-CONFIG: r_core r_asm r_anal" exit 0 diff --git a/configure.acr b/configure.acr index 2099db6a..e3f42ff2 100644 --- a/configure.acr +++ b/configure.acr @@ -1,5 +1,5 @@ PKGNAME r2ghidra -VERSION 5.2.1 +VERSION 5.3.1 CONTACT pancake ; pancake@nopcode.org LANG_CXX! diff --git a/ghidra-processors.txt.all b/ghidra-processors.txt.all index ea77d41e..aff4f87f 100644 --- a/ghidra-processors.txt.all +++ b/ghidra-processors.txt.all @@ -21,6 +21,7 @@ PIC PowerPC RISCV Sparc +STM8 SuperH SuperH4 TI_MSP430 diff --git a/ghidra/ghidra b/ghidra/ghidra deleted file mode 160000 index 5560ac17..00000000 --- a/ghidra/ghidra +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5560ac1711a07705e8fdb232726593f957d6dd5a diff --git a/meson.build b/meson.build index 1d2db8a6..83069fbd 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'cpp', license : 'LGPL3', meson_version : '>=0.50.1', -version : '5.2.1', +version : '5.3.1', default_options : ['c_std=c11', 'cpp_std=c++11'] ) diff --git a/src/ArchMap.cpp b/src/ArchMap.cpp index 28d595f5..a2ae9ac1 100644 --- a/src/ArchMap.cpp +++ b/src/ArchMap.cpp @@ -87,6 +87,7 @@ static const std::map arch_map = { { "pic24", { "PIC-24F", "default", 24 } }, { "z80", { "z80", "default", 8 } }, { "sparc", { "sparc" } }, + { "stm8", { "STM8" } }, { "sh", { "SuperH4" } }, { "msp430", { "TI_MSP430" } }, { "m68k", { diff --git a/src/CodeXMLParse.cpp b/src/CodeXMLParse.cpp index c66161cd..6ed4f53f 100644 --- a/src/CodeXMLParse.cpp +++ b/src/CodeXMLParse.cpp @@ -60,6 +60,7 @@ void AnnotateOpref(ANNOTATOR_PARAMS) annotation.type = R_CODEMETA_TYPE_OFFSET; annotation.offset.offset = op->getAddr().getOffset(); } + void AnnotateFunctionName(ANNOTATOR_PARAMS) { const char *func_name = node.child_value(); @@ -180,10 +181,9 @@ void AnnotateLocalVariable(Symbol *symbol, std::vector *out) return; RCodeMetaItem annotation = {}; annotation.variable.name = strdup(symbol->getName().c_str()); - if(symbol->getCategory() == 0) - annotation.type = R_CODEMETA_TYPE_FUNCTION_PARAMETER; - else - annotation.type = R_CODEMETA_TYPE_LOCAL_VARIABLE; + annotation.type = (symbol->getCategory() == 0) + ? R_CODEMETA_TYPE_FUNCTION_PARAMETER + : R_CODEMETA_TYPE_LOCAL_VARIABLE; out->push_back(annotation); } @@ -297,13 +297,8 @@ static void ParseNode(pugi::xml_node node, ParseCodeXMLContext *ctx, std::ostrea for(auto &annotation : annotations) { annotation.end = stream.tellp(); -#if R2_VERSION_MAJOR == 5 && R2_VERSION_MINOR == 2 && R2_VERSION_PATCH == 0 - r_codemeta_add_annotation (code, &annotation); -#else r_codemeta_add_item (code, &annotation); -#endif } - #ifdef TEST_UNKNOWN_NODES if(close_test) stream << ""; diff --git a/src/R2PrintC.cpp b/src/R2PrintC.cpp index 5133d36d..06164469 100644 --- a/src/R2PrintC.cpp +++ b/src/R2PrintC.cpp @@ -24,7 +24,7 @@ R2PrintC::R2PrintC(Architecture *g, const string &nm) : PrintC(g, nm) { option_NULL = true; - option_space_after_comma = true; +// option_space_after_comma = true; // option_nocasts = true; /// option_convention = true; /// option_hide_exts = true; diff --git a/src/R2Scope.cpp b/src/R2Scope.cpp index 173cbc1f..233c713e 100644 --- a/src/R2Scope.cpp +++ b/src/R2Scope.cpp @@ -123,7 +123,7 @@ FunctionSymbol *R2Scope::registerFunction(RAnalFunction *fcn) const auto flag = reinterpret_cast(pos); if(flag->space && flag->space->name && !strcmp(flag->space->name, R_FLAGS_FS_SECTIONS)) continue; - if (flag->realname && *flag->realname) { + if (!R_STR_ISEMPTY (flag->realname)) { fcn_name = flag->realname; break; } @@ -180,10 +180,7 @@ FunctionSymbol *R2Scope::registerFunction(RAnalFunction *fcn) const { uintb off; int delta = var->delta + fcn->bp_off - extraPop; // not 100% sure if extraPop is correct here - if(delta >= 0) - off = delta; - else - off = stackSpace->getHighest() + delta + 1; + off = (delta >= 0)? delta: stackSpace->getHighest() + delta + 1; return Address(stackSpace, off); } case R_ANAL_VAR_KIND_REG: @@ -496,7 +493,7 @@ Symbol *R2Scope::queryR2Absolute(ut64 addr, bool contain) const RCoreLock core(arch->getCore()); RAnalFunction *fcn = r_anal_get_function_at(core->anal, addr); -#if 0 +#if 1 // This can cause functions to be registered twice (hello-arm test) if(!fcn && contain) { @@ -642,5 +639,7 @@ LabSymbol *R2Scope::findCodeLabel(const Address &addr) const Funcdata *R2Scope::resolveExternalRefFunction(ExternRefSymbol *sym) const { + if (!sym) + return nullptr; return queryFunction(sym->getRefAddr()); } diff --git a/src/SleighInstruction.cpp b/src/SleighInstruction.cpp index fbd79de4..7f5d4192 100644 --- a/src/SleighInstruction.cpp +++ b/src/SleighInstruction.cpp @@ -43,7 +43,7 @@ SleighInstruction *R2Sleigh::getInstruction(Address &addr) void SleighParserContext::setPrototype(SleighInstructionPrototype *p) { prototype = p; - *getBaseState() = &prototype->rootState; + *getBaseState() = &prototype->rootState; } void R2Sleigh::reconstructContext(ParserContext &protoContext) diff --git a/src/asm_ghidra.cpp b/src/asm_ghidra.cpp index 5d7770be..41862552 100644 --- a/src/asm_ghidra.cpp +++ b/src/asm_ghidra.cpp @@ -86,7 +86,7 @@ static RAsmPlugin r_asm_plugin_ghidra = { KV(.arch, "sleigh"), KV(.author, "FXTi"), KV(.version, nullptr), - KV(.cpus, "6502,6805,8051,arm,avr,cr16,dalvik,hppa,java,m68k,m8c,mips,mcs96,msp430,pic24,ppc,sh,sparc,tricore,toy,v850,x86,z80"), + KV(.cpus, "6502,6805,8051,arm,avr,cr16,dalvik,hppa,java,m68k,m8c,mips,mcs96,msp430,pic24,ppc,sh,sparc,stm8,tricore,toy,v850,x86,z80"), KV(.desc, "SLEIGH Disassembler from Ghidra"), KV(.license, "GPL3"), KV(.user, nullptr), diff --git a/src/core_ghidra.cpp b/src/core_ghidra.cpp index 287b3194..62e1f9e2 100644 --- a/src/core_ghidra.cpp +++ b/src/core_ghidra.cpp @@ -19,6 +19,8 @@ #include #include +#undef DEBUG_EXCEPTIONS + #define CMD_PREFIX "pdg" #define CFG_PREFIX "r2ghidra" @@ -60,8 +62,10 @@ static const ConfigVar cfg_var_sleighhome ("sleighhome", "", "SLEIGHH static const ConfigVar cfg_var_sleighid ("lang", "", "Custom Sleigh ID to override auto-detection (e.g. x86:LE:32:default)"); static const ConfigVar cfg_var_cmt_cpp ("cmt.cpp", "true", "C++ comment style"); static const ConfigVar cfg_var_cmt_indent ("cmt.indent", "4", "Comment indent"); +#if 0 static const ConfigVar cfg_var_nl_brace ("nl.brace", "false", "Newline before opening '{'"); static const ConfigVar cfg_var_nl_else ("nl.else", "false", "Newline before else"); +#endif static const ConfigVar cfg_var_indent ("indent", "4", "Indent increment"); static const ConfigVar cfg_var_linelen ("linelen", "120", "Max line length"); static const ConfigVar cfg_var_maximplref ("maximplref", "2", "Maximum number of references to an expression before showing an explicit variable."); @@ -116,8 +120,6 @@ static void PrintUsage(const RCore *const core) enum class DecompileMode { DEFAULT, XML, DEBUG_XML, OFFSET, STATEMENTS, JSON }; -//#define DEBUG_EXCEPTIONS - static void ApplyPrintCConfig(RConfig *cfg, PrintC *print_c) { if(!print_c) @@ -128,11 +130,13 @@ static void ApplyPrintCConfig(RConfig *cfg, PrintC *print_c) else print_c->setCStyleComments(); +/* print_c->setSpaceAfterComma(true); print_c->setNewlineBeforeOpeningBrace(cfg_var_nl_brace.GetBool(cfg)); print_c->setNewlineBeforeElse(cfg_var_nl_else.GetBool(cfg)); print_c->setNewlineAfterPrototype(false); +*/ print_c->setIndentIncrement(cfg_var_indent.GetInt(cfg)); print_c->setLineCommentIndent(cfg_var_cmt_indent.GetInt(cfg)); print_c->setMaxLineSize(cfg_var_linelen.GetInt(cfg)); @@ -144,18 +148,20 @@ static void Decompile(RCore *core, ut64 addr, DecompileMode mode, std::stringstr if(!function) throw LowlevelError("No function at this offset"); R2Architecture arch(core, cfg_var_sleighid.GetString(core->config)); - DocumentStorage store; + DocumentStorage store = DocumentStorage(); arch.max_implied_ref = cfg_var_maximplref.GetInt(core->config); arch.setRawPtr(cfg_var_rawptr.GetBool(core->config)); arch.init(store); - Funcdata *func = arch.symboltab->getGlobalScope()->findFunction(Address(arch.getDefaultCodeSpace(), function->addr)); + + auto faddr = Address(arch.getDefaultCodeSpace(), function->addr); + Funcdata *func = arch.symboltab->getGlobalScope()->findFunction(faddr); arch.print->setOutputStream(&out_stream); arch.setPrintLanguage("r2-c-language"); auto r2c = dynamic_cast(arch.print); bool showCasts = cfg_var_casts.GetBool(core->config); r2c->setOptionNoCasts(!showCasts); ApplyPrintCConfig(core->config, dynamic_cast(arch.print)); - if(!func) + if(func == nullptr) throw LowlevelError("No function in Scope"); arch.getCore()->sleepBegin(); auto action = arch.allacts.getCurrent(); @@ -545,7 +551,7 @@ static int r2ghidra_cmd(void *user, const char *input) RCore *core = (RCore *) user; if (!strncmp (input, CMD_PREFIX, strlen(CMD_PREFIX))) { - _cmd (core, input + 3); + _cmd (core, input + strlen(CMD_PREFIX)); return true; } return false;