From 0db52b80fd2ee0dd26538c0be4b0d6757d4c1241 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdhiser@gmail.com> Date: Thu, 20 Sep 2018 09:10:39 +0000 Subject: [PATCH] rida and libdecode fixes for 32-bit Former-commit-id: b3fd546b39016b2ea1544a1de97236208753e333 --- libIRDB/src/core/operand_cs.cpp | 4 ++ tools/rida/rida.cpp | 70 +++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/libIRDB/src/core/operand_cs.cpp b/libIRDB/src/core/operand_cs.cpp index 5360bd994..3b4901519 100644 --- a/libIRDB/src/core/operand_cs.cpp +++ b/libIRDB/src/core/operand_cs.cpp @@ -213,6 +213,10 @@ string DecodedOperandCapstone_t::getString() const if (op.mem.disp != 0) ret_val+=" + "+ to_string(op.mem.disp); + + if(ret_val=="") + return "0"; + return ret_val; } assert(0); diff --git a/tools/rida/rida.cpp b/tools/rida/rida.cpp index 98d07a1c7..ffcc98ede 100644 --- a/tools/rida/rida.cpp +++ b/tools/rida/rida.cpp @@ -11,6 +11,7 @@ #include <fstream> //#include <elfio/elfio.hpp> #include <elf.h> +#include <functional> using namespace std; @@ -46,12 +47,14 @@ class CreateFunctions_t exeio_t exeio; csh cshandle; ofstream outfile; + execlass_t file_class; public: CreateFunctions_t(const string &input_pgm, const string &output_annot, const bool p_verbose) : verbose(p_verbose), exeio(input_pgm), - cshandle() + cshandle(), + file_class(exeio.get_class()) { outfile.open(output_annot.c_str(), ofstream::out); if(!outfile.is_open()) @@ -63,7 +66,14 @@ class CreateFunctions_t if(verbose) ehp->print(); - if (cs_open(CS_ARCH_X86, CS_MODE_64, &cshandle) != CS_ERR_OK) + if(file_class!=ELF64 && file_class != ELF32) + { + cerr<<"Rida can only process ELF files."<<endl; + exit(1); + } + + const auto cs_mode= file_class==ELF64 ? CS_MODE_64 : CS_MODE_32 ; + if (cs_open(CS_ARCH_X86, cs_mode , &cshandle) != CS_ERR_OK) { cerr<<"Cannot initialize capstone"<<endl; exit(1); @@ -77,23 +87,47 @@ class CreateFunctions_t void calculate() { + + ehframeToSccs(); addSectionToSccs(".init"); addSectionToSccs(".fini"); - pltSplit<Elf64_Sym, Elf64_Rela, Elf64_Rel>(".plt", ".plt.got"); - // if exeio->elf class == 64-bit - nameFunctions<Elf64_Sym>(); - // else - // nameFunctions<Elf32_Rela, Elf32_Rel, Elf32_Sym>(); + + if(file_class==64) + { + class Extracter64 + { + public: + Elf64_Xword elf_r_sym (Elf64_Xword a) { return ELF64_R_SYM (a); } + Elf64_Xword elf_r_type(Elf64_Xword a) { return ELF64_R_TYPE(a); } + unsigned char elf_st_bind(unsigned char a) { return ELF64_ST_BIND(a); } + unsigned char elf_st_type(unsigned char a) { return ELF64_ST_TYPE(a); } + }; + pltSplit<Elf64_Sym, Elf64_Rela, Elf64_Rel, Extracter64>(".plt", ".plt.got"); + nameFunctions<Elf64_Sym, Extracter64>(); + } + else + { + class Extracter32 + { + public: + Elf32_Word elf_r_sym (Elf32_Word a) { return ELF32_R_SYM (a); } + Elf32_Word elf_r_type(Elf32_Word a) { return ELF32_R_TYPE(a); } + unsigned char elf_st_bind(unsigned char a) { return ELF32_ST_BIND(a); } + unsigned char elf_st_type(unsigned char a) { return ELF32_ST_TYPE(a); } + }; + pltSplit<Elf32_Sym, Elf32_Rela, Elf32_Rel, Extracter32>(".plt", ".plt.got"); + nameFunctions<Elf32_Sym, Extracter32>(); + } } - template<class T_Sym> + template<class T_Sym, class T_Extracter> void nameFunctions() { // do symbol names. - parseSyms<T_Sym>(".dynsym", ".dynstr"); - parseSyms<T_Sym>(".symtab", ".strtab"); + parseSyms<T_Sym, T_Extracter>(".dynsym", ".dynstr"); + parseSyms<T_Sym, T_Extracter>(".symtab", ".strtab"); auto namedFunctions=0U; auto unnamedFunctions=0U; @@ -128,7 +162,7 @@ class CreateFunctions_t } - template<class T_Sym> + template<class T_Sym, class T_Extracter> void parseSyms(const string& secName, const string & stringSecName) { const auto sec=exeio.sections[secName]; @@ -148,7 +182,7 @@ class CreateFunctions_t continue; // works for both ELF64 and ELF32, macros defined the same. - const auto type=ELF64_ST_TYPE(sym->st_info); + const auto type=T_Extracter().elf_st_type(sym->st_info); if(type!=STT_FUNC) continue; @@ -230,7 +264,7 @@ class CreateFunctions_t sccs.insert(ranges); } - template<class T_Sym, class T_Rela, class T_Rel> + template<class T_Sym, class T_Rela, class T_Rel, class T_Extracter> void pltSplit(const string &pltSecName, const string &endSecName) { const auto dynsymSec=exeio.sections[".dynsym"]; @@ -261,7 +295,7 @@ class CreateFunctions_t const auto &relEntry=*relDataAsSymPtr; // calculate index into dynsym, section. - const auto dynsymIndex=ELF64_R_SYM(relEntry.r_info); + const auto dynsymIndex=T_Extracter().elf_r_sym(relEntry.r_info); const auto dynsymData=dynsymSec->get_data(); const auto dynstrData=dynstrSec->get_data(); @@ -337,7 +371,7 @@ class CreateFunctions_t if(gotPltSec==NULL) return; - // 64-bit, at least, entries are 6 bytes, with 2 bytes of padding. + // both 32- and 64-bit, entries are 6 bytes, with 2 bytes of padding. const auto gotPltEntrySize=8; const auto gotPltRangeSize=6; const auto gotPltStartAddr=gotPltSec->get_address(); @@ -420,12 +454,14 @@ class CreateFunctions_t const auto &ehprogram=fde->getProgram(); const auto ehprogramInstructions=ehprogram.getInstructions(); - const auto def_cfa_rbp_it = find_if(ALLOF(*ehprogramInstructions), [](const shared_ptr<EHProgramInstruction_t> insn) + const auto def_cfa_rbp_it = find_if(ALLOF(*ehprogramInstructions), [&](const shared_ptr<EHProgramInstruction_t> insn) { assert(insn); const auto &insnBytes=insn->getBytes(); + // 0xd, 0x5 is "def_cfa_register ebp" // 0xd, 0x6 is "def_cfa_register rbp" - return insnBytes==EHProgramInstructionByteVector_t({(uint8_t)0xd,(uint8_t)0x6}); + const auto reg=file_class==ELF64 ? (uint8_t)0x6 : (uint8_t)0x5; + return insnBytes==EHProgramInstructionByteVector_t({(uint8_t)0xd, reg }); }); return def_cfa_rbp_it == ehprogramInstructions->end() ? "NOFP" : "USEFP"; } -- GitLab