diff --git a/libEXEIO/include/exeio.h b/libEXEIO/include/exeio.h index 1380e42ffb7c18b7d2cac44b13631b0ade75f171..b434d90f2a6e855899ca1967f8d20e77c2568b6a 100644 --- a/libEXEIO/include/exeio.h +++ b/libEXEIO/include/exeio.h @@ -13,6 +13,7 @@ namespace EXEIO class exeio_t; // forward decl typedef enum { ELF64, ELF32, PE32, PE64 } execlass_t; + typedef enum { mtX86_64, mtI386, mtArm32, mtAarch64 } MachineType_t; typedef uintptr_t virtual_offset_t; @@ -46,6 +47,7 @@ namespace EXEIO virtual void dump_section_headers(std::ostream& stream) =0; virtual void load(exeio_t* main, const char* filename) =0; virtual execlass_t get_class() =0; + virtual MachineType_t getMachineType() const =0; virtual virtual_offset_t get_entry() =0; virtual void* get_elfio() { return NULL; } virtual bool isDLL() =0; @@ -116,6 +118,7 @@ namespace EXEIO virtual void dump_header(std::ostream& stream) { assert(backend); backend->dump_header(stream); } virtual void dump_section_headers(std::ostream& stream) { assert(backend); backend->dump_section_headers(stream); } virtual execlass_t get_class() { assert(backend); return backend->get_class(); } + virtual MachineType_t getMachineType() const { assert(backend); return backend->getMachineType(); } virtual void* get_elfio() { assert(backend); return backend->get_elfio(); } virtual bool isDLL() { assert(backend); return backend->isDLL(); } virtual bool isDynamicallyLinked() { assert(backend); return backend->isDynamicallyLinked(); } diff --git a/libEXEIO/include/exeio_elf.h b/libEXEIO/src/exeio_elf.h similarity index 90% rename from libEXEIO/include/exeio_elf.h rename to libEXEIO/src/exeio_elf.h index 0b3dd175acb3c8b9cd5dd6889868e46412ecc7ef..6b2ae5a6e90154a7d3ba9bb48d14475603e85f84 100644 --- a/libEXEIO/include/exeio_elf.h +++ b/libEXEIO/src/exeio_elf.h @@ -5,17 +5,15 @@ #include <vector> #include <assert.h> - -// #include "targ-config.h" #pragma GCC diagnostic ignored "-Wsign-compare" #include "elfio/elfio.hpp" #include "elfio/elfio_dump.hpp" +#include "elf.h" #pragma GCC diagnostic pop class exeio_backend; class exeio_section; - namespace EXEIO { class exeio_elf_section_t : public exeio_section_t @@ -94,6 +92,19 @@ namespace EXEIO default: assert(0); }; } + virtual MachineType_t getMachineType() const + { + assert(e); + switch(e->get_machine()) + { + case EM_ARM : return mtArm32; + case EM_AARCH64 : return mtAarch64; + case EM_386 : return mtI386; + case EM_X86_64 : return mtX86_64; + default: assert(0); + } + assert(0); + } // get entry point of function. virtual virtual_offset_t get_entry() diff --git a/libEXEIO/include/exeio_pe.h b/libEXEIO/src/exeio_pe.h similarity index 98% rename from libEXEIO/include/exeio_pe.h rename to libEXEIO/src/exeio_pe.h index 78f78d619cc488de5f2976534e89dfba06ece386..f4ab2eff6d92b9939eb18d046b4ab03e3c2c7d0f 100644 --- a/libEXEIO/include/exeio_pe.h +++ b/libEXEIO/src/exeio_pe.h @@ -129,6 +129,11 @@ namespace EXEIO } } + virtual MachineType_t getMachineType() const + { + assert(0); + } + virtual execlass_t get_class() { assert(e); diff --git a/libIRDB/include/core/archdesc.hpp b/libIRDB/include/core/archdesc.hpp index 89c2b40e1cffaf993d97682377516fd1640f1fe6..dc84aee5d3353bc0ed4d75b3838e99677e3e6673 100644 --- a/libIRDB/include/core/archdesc.hpp +++ b/libIRDB/include/core/archdesc.hpp @@ -19,23 +19,28 @@ */ -enum AD_FileType_t { AD_ELF, AD_CGC, AD_PE }; +enum ADFileType_t { AD_ELF, AD_CGC, AD_PE, AD_NONE }; +enum ADMachineType_t { admtAarch64, admtX86_64, admtI386, admtNone }; class ArchitectureDescription_t { public: - ArchitectureDescription_t() : bits(0) {} + ArchitectureDescription_t() : bits(0), ft(AD_NONE), mt(admtNone) {} - int GetBitWidth() { return bits; } - void SetBitWidth(int _bits) { bits=_bits; } + int GetBitWidth() const { return bits; } + void SetBitWidth(const int _bits) { bits=_bits; } - AD_FileType_t GetFileType() { return ft; } - void SetFileType(AD_FileType_t t) { ft=t; } + ADFileType_t GetFileType() const { return ft; } + void SetFileType(const ADFileType_t t) { ft=t; } + + ADMachineType_t getMachineType() const { return mt; } + void setMachineType(const ADMachineType_t t) { mt=t; } private: - int bits; - AD_FileType_t ft; + size_t bits; + ADFileType_t ft; + ADMachineType_t mt; }; diff --git a/libIRDB/include/core/decode.hpp b/libIRDB/include/core/decode.hpp index 8a59d7d9a109507e2694a09f7045168076cb0dba..c78aed0fc098636e41662a7bcc58f6ec989f47ed 100644 --- a/libIRDB/include/core/decode.hpp +++ b/libIRDB/include/core/decode.hpp @@ -1,18 +1,14 @@ #ifndef libdecode_decode_hpp #define libdecode_decode_hpp -#define USECS +#define USEMETA #if defined(USEMETA) -#include <core/decode_meta.hpp> -#include <core/operand_meta.hpp> +#include <core/decode_dispatch.hpp> +#include <core/operand_dispatch.hpp> #elif defined(USECS) -#include <core/decode_cs.hpp> -#include <core/operand_cs.hpp> -#elif defined(USEBEA) -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> -#else +#include <core/decode_csx86.hpp> +#include <core/operand_csx86.hpp> #pragma "Error: Source did not adaquately specify a disassembler. " #endif @@ -25,17 +21,13 @@ using namespace libIRDB; #if defined(USEMETA) -typedef DecodedInstructionMeta_t DecodedInstruction_t; -typedef DecodedOperandMeta_t DecodedOperand_t; +typedef DecodedInstructionDispatcher_t DecodedInstruction_t; +typedef DecodedOperandDispatcher_t DecodedOperand_t; typedef DecodedOperandMetaVector_t DecodedOperandVector_t; #elif defined(USECS) -typedef DecodedInstructionCapstone_t DecodedInstruction_t; -typedef DecodedOperandCapstone_t DecodedOperand_t; +typedef DecodedInstructionCapstoneX86_t DecodedInstruction_t; +typedef DecodedOperandCapstoneX86_t DecodedOperand_t; typedef DecodedOperandCapstoneVector_t DecodedOperandVector_t; -#elif defined(USEBEA) -typedef DecodedInstructionBea_t DecodedInstruction_t; -typedef DecodedOperandBea_t DecodedOperand_t; -typedef DecodedOperandBeaVector_t DecodedOperandVector_t; #else #pragma "Error: Source did not adaquately specify a disassembler. " #endif diff --git a/libIRDB/include/core/decode_bea.hpp b/libIRDB/include/core/decode_bea.hpp deleted file mode 100644 index 800cdd625713e4d882dc7506e93b54939b555386..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/decode_bea.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef libirdb_decodebea_hpp -#define libirdb_decodebea_hpp - -#include <stdint.h> -#include <vector> - -namespace libIRDB -{ - -using namespace libIRDB; -using namespace std; - -class DecodedOperandBea_t; -typedef std::vector<DecodedOperandBea_t> DecodedOperandBeaVector_t; - -class DecodedInstructionBea_t -{ - public: - DecodedInstructionBea_t()=delete; - DecodedInstructionBea_t(const Instruction_t*); - DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); - DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, const void* endptr); - DecodedInstructionBea_t(const DecodedInstructionBea_t& copy); - DecodedInstructionBea_t& operator=(const DecodedInstructionBea_t& copy); - - virtual ~DecodedInstructionBea_t(); - - string getDisassembly() const; - bool valid() const; - uint32_t length() const; - bool isBranch() const; - bool isCall() const; - bool isUnconditionalBranch() const; - bool isConditionalBranch() const; - bool isReturn() const; - string getMnemonic() const; - int64_t getImmediate() const; - virtual_offset_t getAddress() const; - bool setsStackPointer() const; - uint32_t getPrefixCount() const; - bool hasRelevantRepPrefix() const; - bool hasRelevantRepnePrefix() const; - bool hasRelevantOperandSizePrefix() const; - bool hasRexWPrefix() const; - bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandBea_t& t, const libIRDB::Instruction_t*) const; - - // 0-based. first operand is numbered 0. - bool hasOperand(const int op_num) const; - DecodedOperandBea_t getOperand(const int op_num) const; - DecodedOperandBeaVector_t getOperands() const; - - private: - - void Disassemble(const virtual_offset_t start_addr, const void *, uint32_t max_len); - void *disasm_data; - uint32_t disasm_length; -}; - -} - -#endif diff --git a/libIRDB/include/core/decode_cs.hpp b/libIRDB/include/core/decode_csx86.hpp similarity index 69% rename from libIRDB/include/core/decode_cs.hpp rename to libIRDB/include/core/decode_csx86.hpp index efc71323876e07b5e9d4bfdcb2b0f4b33989a7c6..6579af621ee3877132a1c6873ec906b90623c8cf 100644 --- a/libIRDB/include/core/decode_cs.hpp +++ b/libIRDB/include/core/decode_csx86.hpp @@ -11,20 +11,20 @@ namespace libIRDB using namespace libIRDB; using namespace std; -class DecodedOperandCapstone_t; -typedef std::vector<DecodedOperandCapstone_t> DecodedOperandCapstoneVector_t; +class DecodedOperandCapstoneX86_t; +typedef std::vector<DecodedOperandCapstoneX86_t> DecodedOperandCapstoneVector_t; -class DecodedInstructionCapstone_t +class DecodedInstructionCapstoneX86_t { public: - DecodedInstructionCapstone_t()=delete; - DecodedInstructionCapstone_t(const Instruction_t*); - DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); - DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, const void* endptr); - DecodedInstructionCapstone_t(const DecodedInstructionCapstone_t& copy); - DecodedInstructionCapstone_t& operator=(const DecodedInstructionCapstone_t& copy); + DecodedInstructionCapstoneX86_t()=delete; + DecodedInstructionCapstoneX86_t(const Instruction_t*); + DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy); + DecodedInstructionCapstoneX86_t& operator=(const DecodedInstructionCapstoneX86_t& copy); - virtual ~DecodedInstructionCapstone_t(); + virtual ~DecodedInstructionCapstoneX86_t(); string getDisassembly() const; bool valid() const; @@ -44,11 +44,11 @@ class DecodedInstructionCapstone_t bool hasRelevantOperandSizePrefix() const; bool hasRexWPrefix() const; bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const; + virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstoneX86_t& t, const Instruction_t* insn) const; // 0-based. first operand is numbered 0. bool hasOperand(const int op_num) const; - DecodedOperandCapstone_t getOperand(const int op_num) const; + DecodedOperandCapstoneX86_t getOperand(const int op_num) const; DecodedOperandCapstoneVector_t getOperands() const; private: @@ -89,9 +89,9 @@ class DecodedInstructionCapstone_t static CapstoneHandle_t *cs_handle; - friend class DecodedOperandCapstone_t; + friend class DecodedOperandCapstoneX86_t; - DecodedInstructionCapstone_t(const shared_ptr<void> &my_insn); + DecodedInstructionCapstoneX86_t(const shared_ptr<void> &my_insn); }; diff --git a/libIRDB/include/core/decode_dispatch.hpp b/libIRDB/include/core/decode_dispatch.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f201881feb8df3ece4aa98db53c2ba2c3bbbc54e --- /dev/null +++ b/libIRDB/include/core/decode_dispatch.hpp @@ -0,0 +1,63 @@ +#ifndef libirdb_decode_dispatch_hpp +#define libirdb_decode_dispatch_hpp + +#include <stdint.h> +#include <vector> +#include <core/decode_csx86.hpp> +#include <core/operand_csx86.hpp> + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandDispatcher_t; +typedef std::vector<DecodedOperandDispatcher_t> DecodedOperandMetaVector_t; + +class DecodedInstructionDispatcher_t +{ + public: + DecodedInstructionDispatcher_t()=delete; + DecodedInstructionDispatcher_t(const Instruction_t*); + DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); + DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr); + DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy); + DecodedInstructionDispatcher_t& operator=(const DecodedInstructionDispatcher_t& copy); + + virtual ~DecodedInstructionDispatcher_t(); + + string getDisassembly() const; + bool valid() const; + uint32_t length() const; + bool isBranch() const; + bool isCall() const; + bool isUnconditionalBranch() const; + bool isConditionalBranch() const; + bool isReturn() const; + string getMnemonic() const; + int64_t getImmediate() const; + virtual_offset_t getAddress() const; + bool setsStackPointer() const; + uint32_t getPrefixCount() const; + bool hasRelevantRepPrefix() const; + bool hasRelevantRepnePrefix() const; + bool hasRelevantOperandSizePrefix() const; + bool hasRexWPrefix() const; + bool hasImplicitlyModifiedRegs() const; + virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandDispatcher_t& t, const Instruction_t* insn) const; + + // 0-based. first operand is numbered 0. + bool hasOperand(const int op_num) const; + DecodedOperandDispatcher_t getOperand(const int op_num) const; + DecodedOperandMetaVector_t getOperands() const; + + private: + + std::unique_ptr<DecodedInstructionCapstoneX86_t> cs; + +}; + +} + +#endif diff --git a/libIRDB/include/core/decode_meta.hpp b/libIRDB/include/core/decode_meta.hpp deleted file mode 100644 index fe62bb089b70b8f89a1e484c05246b7d8ea17b51..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/decode_meta.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef libirdb_decodemeta_hpp -#define libirdb_decodemeta_hpp - -#include <stdint.h> -#include <vector> -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> -#include <core/decode_cs.hpp> -#include <core/operand_cs.hpp> - -namespace libIRDB -{ - -using namespace libIRDB; -using namespace std; - -class DecodedOperandMeta_t; -typedef std::vector<DecodedOperandMeta_t> DecodedOperandMetaVector_t; - -class DecodedInstructionMeta_t -{ - public: - DecodedInstructionMeta_t()=delete; - DecodedInstructionMeta_t(const Instruction_t*); - DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); - DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, const void* endptr); - DecodedInstructionMeta_t(const DecodedInstructionMeta_t& copy); - DecodedInstructionMeta_t& operator=(const DecodedInstructionMeta_t& copy); - - virtual ~DecodedInstructionMeta_t(); - - string getDisassembly() const; - bool valid() const; - uint32_t length() const; - bool isBranch() const; - bool isCall() const; - bool isUnconditionalBranch() const; - bool isConditionalBranch() const; - bool isReturn() const; - string getMnemonic() const; - int64_t getImmediate() const; - virtual_offset_t getAddress() const; - bool setsStackPointer() const; - uint32_t getPrefixCount() const; - bool hasRelevantRepPrefix() const; - bool hasRelevantRepnePrefix() const; - bool hasRelevantOperandSizePrefix() const; - bool hasRexWPrefix() const; - bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandMeta_t& t, const Instruction_t* insn) const; - - // 0-based. first operand is numbered 0. - bool hasOperand(const int op_num) const; - DecodedOperandMeta_t getOperand(const int op_num) const; - DecodedOperandMetaVector_t getOperands() const; - - private: - - DecodedInstructionBea_t bea; - DecodedInstructionCapstone_t cs; - -}; - -} - -#endif diff --git a/libIRDB/include/core/fileir.hpp b/libIRDB/include/core/fileir.hpp index d0b70244b35a70b1d3a796fb1ac889633840012b..c61fe787f11492cafa63a4a7790c32858cfc4ba0 100644 --- a/libIRDB/include/core/fileir.hpp +++ b/libIRDB/include/core/fileir.hpp @@ -92,7 +92,7 @@ class FileIR_t : public BaseObj_t void ChangeRegistryKey(Instruction_t* orig, Instruction_t* updated); static int GetArchitectureBitWidth() ; - static void SetArchitectureBitWidth(const int width); + static void SetArchitecture(const int width, const ADMachineType_t mt); void SetArchitecture(); // Lookup a scoop by address diff --git a/libIRDB/include/core/operand_bea.hpp b/libIRDB/include/core/operand_bea.hpp deleted file mode 100644 index 2650a18650536c68d52d28e32183a7b8893c5329..0000000000000000000000000000000000000000 --- a/libIRDB/include/core/operand_bea.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef libRIDB_decodedoperandbea_hpp -#define libRIDB_decodedoperandbea_hpp - -namespace libIRDB -{ - -using namespace std; -using namespace libIRDB; - - -class DecodedOperandBea_t -{ - public: - DecodedOperandBea_t() =delete; - DecodedOperandBea_t& operator=(const DecodedOperandBea_t& copy); - DecodedOperandBea_t(const DecodedOperandBea_t& copy); - virtual ~DecodedOperandBea_t(); - - bool isConstant() const; - string getString() const; - bool isRegister() const; - bool isGeneralPurposeRegister() const; - bool isMmxRegister() const; - bool isFpuRegister() const; - bool isSseRegister() const; - bool isAvxRegister() const; - bool isSpecialRegister() const; - bool isSegmentRegister() const; - uint32_t getRegNumber() const; - bool isMemory() const; - bool hasSegmentRegister() const; - uint32_t getSegmentRegister() const; - bool hasBaseRegister() const; - bool hasIndexRegister() const; - uint32_t getBaseRegister() const; - uint32_t getIndexRegister() const; - bool hasMemoryDisplacement() const; - virtual_offset_t getMemoryDisplacement() const; - bool isPcrel() const; - uint32_t getScaleValue() const; - uint32_t getMemoryDisplacementEncodingSize() const; - uint32_t getArgumentSizeInBytes() const; - uint32_t getArgumentSizeInBits() const; - bool isRead() const; - bool isWritten() const; - - - private: - - - void* arg_data; - DecodedOperandBea_t(void* arg_p); - - friend class DecodedInstructionBea_t; - -}; - -} -#endif diff --git a/libIRDB/include/core/operand_cs.hpp b/libIRDB/include/core/operand_csx86.hpp similarity index 75% rename from libIRDB/include/core/operand_cs.hpp rename to libIRDB/include/core/operand_csx86.hpp index 0d4e5e78b7518af34275377b105ca415d200e490..712461d1e0cee3f93c114876d0ef915bc4261ec2 100644 --- a/libIRDB/include/core/operand_cs.hpp +++ b/libIRDB/include/core/operand_csx86.hpp @@ -9,13 +9,13 @@ using namespace std; using namespace libIRDB; -class DecodedOperandCapstone_t +class DecodedOperandCapstoneX86_t { public: - DecodedOperandCapstone_t() =delete; - //DecodedOperandCapstone_t& operator=(const DecodedOperandCapstone_t& copy); - //DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy); - virtual ~DecodedOperandCapstone_t(); + DecodedOperandCapstoneX86_t() =delete; + //DecodedOperandCapstoneX86_t& operator=(const DecodedOperandCapstoneX86_t& copy); + //DecodedOperandCapstoneX86_t(const DecodedOperandCapstoneX86_t& copy); + virtual ~DecodedOperandCapstoneX86_t(); bool isConstant() const; uint64_t getConstant() const; @@ -50,12 +50,12 @@ class DecodedOperandCapstone_t private: - DecodedOperandCapstone_t( const shared_ptr<void> &my_insn, uint8_t op_num); + DecodedOperandCapstoneX86_t( const shared_ptr<void> &my_insn, uint8_t op_num); shared_ptr<void> my_insn; uint8_t op_num; - friend class DecodedInstructionCapstone_t; + friend class DecodedInstructionCapstoneX86_t; }; diff --git a/libIRDB/include/core/operand_meta.hpp b/libIRDB/include/core/operand_dispatch.hpp similarity index 62% rename from libIRDB/include/core/operand_meta.hpp rename to libIRDB/include/core/operand_dispatch.hpp index 38080e08f1ee0c13014c3c3a169e357801843b8e..6fee67bcd098949f234f0393e11b3016543f68d6 100644 --- a/libIRDB/include/core/operand_meta.hpp +++ b/libIRDB/include/core/operand_dispatch.hpp @@ -1,8 +1,8 @@ -#ifndef libRIDB_decodedoperandmeta_hpp -#define libRIDB_decodedoperandmeta_hpp +#ifndef libRIDB_decodedoperand_dispatch_hpp +#define libRIDB_decodedoperand_dispatch_hpp -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> +#include <core/decode_csx86.hpp> +#include <core/operand_csx86.hpp> namespace libIRDB { @@ -10,15 +10,16 @@ using namespace std; using namespace libIRDB; -class DecodedOperandMeta_t +class DecodedOperandDispatcher_t { public: - DecodedOperandMeta_t() =delete; - DecodedOperandMeta_t& operator=(const DecodedOperandMeta_t& copy); - DecodedOperandMeta_t(const DecodedOperandMeta_t& copy); - virtual ~DecodedOperandMeta_t(); + DecodedOperandDispatcher_t() =delete; + DecodedOperandDispatcher_t& operator=(const DecodedOperandDispatcher_t& copy); + DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy); + virtual ~DecodedOperandDispatcher_t(); bool isConstant() const; + uint64_t getConstant() const; string getString() const; bool isRegister() const; bool isGeneralPurposeRegister() const; @@ -48,11 +49,11 @@ class DecodedOperandMeta_t private: - DecodedOperandMeta_t(const DecodedOperandCapstone_t& in); + DecodedOperandDispatcher_t(const DecodedOperandCapstoneX86_t& in); - DecodedOperandCapstone_t cs; + std::unique_ptr<DecodedOperandCapstoneX86_t> cs; - friend class DecodedInstructionMeta_t; + friend class DecodedInstructionDispatcher_t; }; diff --git a/libIRDB/src/core/SConscript b/libIRDB/src/core/SConscript index b538b5836f21a88d19043920906a184377752fa9..101499941183973454edd31c40f325257f171a8f 100644 --- a/libIRDB/src/core/SConscript +++ b/libIRDB/src/core/SConscript @@ -23,15 +23,15 @@ files= ''' variantid.cpp eh.cpp reloc.cpp - decode_cs.cpp - operand_cs.cpp + decode_csx86.cpp + operand_csx86.cpp IRDB_Objects.cpp + decode_dispatch.cpp + operand_dispatch.cpp ''' unused_files=''' decode_bea.cpp operand_bea.cpp - decode_meta.cpp - operand_meta.cpp ''' # bea engine listed for core components. diff --git a/libIRDB/src/core/decode_bea.cpp b/libIRDB/src/core/decode_bea.cpp deleted file mode 100644 index 0b7fafb7a2f52aa96eb259b30e56af5ffc440530..0000000000000000000000000000000000000000 --- a/libIRDB/src/core/decode_bea.cpp +++ /dev/null @@ -1,280 +0,0 @@ - -#include <libIRDB-core.hpp> - -#include <bea_deprecated.hpp> -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> - -using namespace libIRDB; -using namespace std; - -// static functions -static inline bool my_SetsStackPointer(const ARGTYPE* arg) -{ - if((arg->AccessMode & WRITE ) == 0) - return false; - int access_type=arg->ArgType; - - if(access_type==REGISTER_TYPE + GENERAL_REG +REG4) - return true; - return false; - -} - -// constructors, destructors, operators. - -DecodedInstructionBea_t::DecodedInstructionBea_t(const Instruction_t* i) -{ - disasm_data=static_cast<void*>(new DISASM({})); - DISASM* d=(DISASM*)disasm_data; - disasm_length=::Disassemble(i,*d); -} - -DecodedInstructionBea_t::DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) -{ - disasm_data=static_cast<void*>(new DISASM({})); - const auto endptr=data+max_len; - Disassemble(start_addr, data, max_len); -} - -DecodedInstructionBea_t::DecodedInstructionBea_t(const virtual_offset_t start_addr, const void *data, const void* endptr) -{ - disasm_data=static_cast<void*>(new DISASM({})); - const auto length=(char*)endptr-(char*)data + 1; - Disassemble(start_addr,data,length); -} - -DecodedInstructionBea_t::DecodedInstructionBea_t(const DecodedInstructionBea_t& copy) -{ - DISASM* d=static_cast<DISASM*>(copy.disasm_data); - disasm_data=static_cast<void*>(new DISASM(*d)); - disasm_length=copy.disasm_length; -} - -DecodedInstructionBea_t::~DecodedInstructionBea_t() -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - delete d; - disasm_data=NULL; -} - -DecodedInstructionBea_t& DecodedInstructionBea_t::operator=(const DecodedInstructionBea_t& copy) -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - delete d; - disasm_data=NULL; - - d=static_cast<DISASM*>(copy.disasm_data); - disasm_data=static_cast<void*>(new DISASM(*d)); - disasm_length=copy.disasm_length; - return *this; -} - -// private methods - -void DecodedInstructionBea_t::Disassemble(const virtual_offset_t start_addr, const void *data, uint32_t max_len) -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - memset(d, 0, sizeof(DISASM)); - d->Options = NasmSyntax + PrefixedNumeral; - d->Archi = FileIR_t::GetArchitectureBitWidth(); - d->EIP = (UIntPtr)data; - d->SecurityBlock=max_len; - d->VirtualAddr = start_addr; - disasm_length=Disasm(d); - -} - -// public methods - -string DecodedInstructionBea_t::getDisassembly() const -{ - assert(valid()); - DISASM* d=static_cast<DISASM*>(disasm_data); - return string(d->CompleteInstr); -} - -bool DecodedInstructionBea_t::valid() const -{ - return disasm_length>=0; -} - -uint32_t DecodedInstructionBea_t::length() const -{ - assert(valid()); - return disasm_length; -} - - -bool DecodedInstructionBea_t::isBranch() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType!=0; -} - -bool DecodedInstructionBea_t::isCall() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType==CallType; -} - -bool DecodedInstructionBea_t::isUnconditionalBranch() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType==JmpType; -} - -bool DecodedInstructionBea_t::isConditionalBranch() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - assert(0); -} - -bool DecodedInstructionBea_t::isReturn() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.BranchType==RetType; -} - - -bool DecodedInstructionBea_t::hasOperand(const int op_num) const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - switch(op_num+1) - { - case 1: - return d->Argument1.ArgType!=NO_ARGUMENT; - case 2: - return d->Argument2.ArgType!=NO_ARGUMENT; - case 3: - return d->Argument3.ArgType!=NO_ARGUMENT; - case 4: - return d->Argument4.ArgType!=NO_ARGUMENT; - default: - return false; - } -} - - -// 0-based. first operand is numbered 0. -DecodedOperandBea_t DecodedInstructionBea_t::getOperand(const int op_num) const -{ - if(!hasOperand(op_num)) - throw std::out_of_range("op_num"); - - DISASM* d=static_cast<DISASM*>(disasm_data); - switch(op_num+1) - { - case 1: - return DecodedOperandBea_t(&d->Argument1); - case 2: - return DecodedOperandBea_t(&d->Argument2); - case 3: - return DecodedOperandBea_t(&d->Argument3); - case 4: - return DecodedOperandBea_t(&d->Argument4); - } -} - -DecodedOperandBeaVector_t DecodedInstructionBea_t::getOperands() const -{ - auto ret_val=DecodedOperandBeaVector_t(); - for(auto i=0;i<4;i++) - { - if(hasOperand(i)) - ret_val.push_back(getOperand(i)); - else - break; - } - return ret_val; -} - - -string DecodedInstructionBea_t::getMnemonic() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - const auto mnemonic=string(d->Instruction.Mnemonic); - return mnemonic.substr(0,mnemonic.size()-1); -} - -int64_t DecodedInstructionBea_t::getImmediate() const -{ - // find and return an immediate operand from this instruction - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.Immediat; -} - - -virtual_offset_t DecodedInstructionBea_t::getAddress() const -{ - // return anything that's explicitly an address, like a jmp/call target - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.AddrValue; -} - - -bool DecodedInstructionBea_t::setsStackPointer() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - - if(getMnemonic()== "push") - return true; - if(getMnemonic()== "pop") - return true; - if(getMnemonic()== "call") - return true; - if(d->Instruction.ImplicitModifiedRegs==REGISTER_TYPE+GENERAL_REG+REG4) - return true; - - if(my_SetsStackPointer(&d->Argument1)) return true; - if(my_SetsStackPointer(&d->Argument2)) return true; - if(my_SetsStackPointer(&d->Argument3)) return true; - if(my_SetsStackPointer(&d->Argument4)) return true; - - return false; -} - -uint32_t DecodedInstructionBea_t::getPrefixCount() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.Number; -} - -virtual_offset_t DecodedInstructionBea_t::getMemoryDisplacementOffset(const DecodedOperandBea_t& t, const libIRDB::Instruction_t*) const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - ARGTYPE* the_arg=static_cast<ARGTYPE*>(t.arg_data); - return the_arg->Memory.DisplacementAddr-d->EIP; -} - - -bool DecodedInstructionBea_t::hasRelevantRepPrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.RepPrefix==InUsePrefix; -} - -bool DecodedInstructionBea_t::hasRelevantRepnePrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.RepnePrefix==InUsePrefix; -} - -bool DecodedInstructionBea_t::hasRelevantOperandSizePrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.OperandSize!=NotUsedPrefix; -} - -bool DecodedInstructionBea_t::hasRexWPrefix() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Prefix.REX.W_; -} - -bool DecodedInstructionBea_t::hasImplicitlyModifiedRegs() const -{ - DISASM* d=static_cast<DISASM*>(disasm_data); - return d->Instruction.ImplicitModifiedRegs!=0; -} - diff --git a/libIRDB/src/core/decode_cs.cpp b/libIRDB/src/core/decode_csx86.cpp similarity index 87% rename from libIRDB/src/core/decode_cs.cpp rename to libIRDB/src/core/decode_csx86.cpp index ec824293540cf94c45ef18ac51ce895a61167310..fa968e2117e49f881984b8c34fa131e5581ce6cc 100644 --- a/libIRDB/src/core/decode_cs.cpp +++ b/libIRDB/src/core/decode_csx86.cpp @@ -14,9 +14,9 @@ using namespace std; #define ALLOF(a) begin(a),end(a) -DecodedInstructionCapstone_t::CapstoneHandle_t* DecodedInstructionCapstone_t::cs_handle=NULL ; +DecodedInstructionCapstoneX86_t::CapstoneHandle_t* DecodedInstructionCapstoneX86_t::cs_handle=NULL ; -DecodedInstructionCapstone_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp) +DecodedInstructionCapstoneX86_t::CapstoneHandle_t::CapstoneHandle_t(FileIR_t* firp) { const auto width=FileIR_t::GetArchitectureBitWidth(); const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32; @@ -120,7 +120,7 @@ static inline type insnToImmedHelper(cs_insn* the_insn, csh handle) // shared code // constructors, destructors, operators. -void DecodedInstructionCapstone_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len) +void DecodedInstructionCapstoneX86_t::Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len) { using namespace std::placeholders; auto insn=cs_malloc(cs_handle->getHandle()); @@ -192,7 +192,7 @@ void DecodedInstructionCapstone_t::Disassemble(const virtual_offset_t start_addr my_insn.reset(insn,cs_freer); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const Instruction_t* i) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const Instruction_t* i) { if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); if(!i) throw std::invalid_argument("No instruction given to DecodedInstruction_t(Instruction_t*)"); @@ -206,35 +206,35 @@ DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const Instruction_t* if(!valid()) throw std::invalid_argument("The Instruction_t::GetDataBits field is not a valid instruction."); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) { if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); Disassemble(start_addr, data, max_len); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const virtual_offset_t start_addr, const void *data, const void* endptr) { if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); const auto length=(char*)endptr-(char*)data; Disassemble(start_addr,data,length); } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const DecodedInstructionCapstone_t& copy) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const DecodedInstructionCapstoneX86_t& copy) { *this=copy; } -DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const shared_ptr<void> &p_my_insn) +DecodedInstructionCapstoneX86_t::DecodedInstructionCapstoneX86_t(const shared_ptr<void> &p_my_insn) : my_insn(p_my_insn) { } -DecodedInstructionCapstone_t::~DecodedInstructionCapstone_t() +DecodedInstructionCapstoneX86_t::~DecodedInstructionCapstoneX86_t() { // no need to cs_free(my_insn) because shared pointer will do that for us! } -DecodedInstructionCapstone_t& DecodedInstructionCapstone_t::operator=(const DecodedInstructionCapstone_t& copy) +DecodedInstructionCapstoneX86_t& DecodedInstructionCapstoneX86_t::operator=(const DecodedInstructionCapstoneX86_t& copy) { my_insn=copy.my_insn; return *this; @@ -242,7 +242,7 @@ DecodedInstructionCapstone_t& DecodedInstructionCapstone_t::operator=(const Deco // public methods -string DecodedInstructionCapstone_t::getDisassembly() const +string DecodedInstructionCapstoneX86_t::getDisassembly() const { const auto myReplace=[](std::string &str, const std::string& oldStr, @@ -338,27 +338,27 @@ string DecodedInstructionCapstone_t::getDisassembly() const return full_str; } -bool DecodedInstructionCapstone_t::valid() const +bool DecodedInstructionCapstoneX86_t::valid() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return the_insn->size!=0; } -uint32_t DecodedInstructionCapstone_t::length() const +uint32_t DecodedInstructionCapstoneX86_t::length() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return the_insn->size; } -bool DecodedInstructionCapstone_t::isBranch() const +bool DecodedInstructionCapstoneX86_t::isBranch() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return isCall() || isReturn() || isJmp(the_insn); } -bool DecodedInstructionCapstone_t::isCall() const +bool DecodedInstructionCapstoneX86_t::isCall() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -366,7 +366,7 @@ bool DecodedInstructionCapstone_t::isCall() const return isPartOfGroup(the_insn,X86_GRP_CALL); } -bool DecodedInstructionCapstone_t::isUnconditionalBranch() const +bool DecodedInstructionCapstoneX86_t::isUnconditionalBranch() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -374,21 +374,21 @@ bool DecodedInstructionCapstone_t::isUnconditionalBranch() const return isJmp(the_insn) && !isConditionalBranch(); } -bool DecodedInstructionCapstone_t::isConditionalBranch() const +bool DecodedInstructionCapstoneX86_t::isConditionalBranch() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return isJmp(the_insn) && getMnemonic()!="jmp"; } -bool DecodedInstructionCapstone_t::isReturn() const +bool DecodedInstructionCapstoneX86_t::isReturn() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return isPartOfGroup(the_insn,X86_GRP_RET); } -bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const +bool DecodedInstructionCapstoneX86_t::hasOperand(const int op_num) const { if(op_num<0) throw std::logic_error(string("Called ")+ __FUNCTION__+" with opnum="+to_string(op_num)); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -397,16 +397,16 @@ bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const } // 0-based. first operand is numbered 0. -DecodedOperandCapstone_t DecodedInstructionCapstone_t::getOperand(const int op_num) const +DecodedOperandCapstoneX86_t DecodedInstructionCapstoneX86_t::getOperand(const int op_num) const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true"); - return DecodedOperandCapstone_t(my_insn,(uint8_t)op_num); + return DecodedOperandCapstoneX86_t(my_insn,(uint8_t)op_num); } -DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const +DecodedOperandCapstoneVector_t DecodedInstructionCapstoneX86_t::getOperands() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -421,7 +421,7 @@ DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const return ret_val; } -string DecodedInstructionCapstone_t::getMnemonic() const +string DecodedInstructionCapstoneX86_t::getMnemonic() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -471,7 +471,7 @@ string DecodedInstructionCapstone_t::getMnemonic() const } -int64_t DecodedInstructionCapstone_t::getImmediate() const +int64_t DecodedInstructionCapstoneX86_t::getImmediate() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -485,7 +485,7 @@ int64_t DecodedInstructionCapstone_t::getImmediate() const } -virtual_offset_t DecodedInstructionCapstone_t::getAddress() const +virtual_offset_t DecodedInstructionCapstoneX86_t::getAddress() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -514,7 +514,7 @@ virtual_offset_t DecodedInstructionCapstone_t::getAddress() const } -bool DecodedInstructionCapstone_t::setsStackPointer() const +bool DecodedInstructionCapstoneX86_t::setsStackPointer() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -577,7 +577,7 @@ bool DecodedInstructionCapstone_t::setsStackPointer() const return is_op0; } -uint32_t DecodedInstructionCapstone_t::getPrefixCount() const +uint32_t DecodedInstructionCapstoneX86_t::getPrefixCount() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -588,7 +588,7 @@ uint32_t DecodedInstructionCapstone_t::getPrefixCount() const return count_with_rex; } -virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const +virtual_offset_t DecodedInstructionCapstoneX86_t::getMemoryDisplacementOffset(const DecodedOperandCapstoneX86_t& t, const Instruction_t* insn) const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); @@ -654,35 +654,35 @@ virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const -bool DecodedInstructionCapstone_t::hasRelevantRepPrefix() const +bool DecodedInstructionCapstoneX86_t::hasRelevantRepPrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return hasPrefix(the_insn,X86_PREFIX_REP); } -bool DecodedInstructionCapstone_t::hasRelevantRepnePrefix() const +bool DecodedInstructionCapstoneX86_t::hasRelevantRepnePrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return hasPrefix(the_insn,X86_PREFIX_REPNE); } -bool DecodedInstructionCapstone_t::hasRelevantOperandSizePrefix() const +bool DecodedInstructionCapstoneX86_t::hasRelevantOperandSizePrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return hasPrefix(the_insn,X86_PREFIX_OPSIZE); } -bool DecodedInstructionCapstone_t::hasRexWPrefix() const +bool DecodedInstructionCapstoneX86_t::hasRexWPrefix() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); return (the_insn->detail->x86.rex & 0x8) == 0x8; } -bool DecodedInstructionCapstone_t::hasImplicitlyModifiedRegs() const +bool DecodedInstructionCapstoneX86_t::hasImplicitlyModifiedRegs() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); diff --git a/libIRDB/src/core/decode_dispatch.cpp b/libIRDB/src/core/decode_dispatch.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cb888facc624077669a49a947b47313a2ec622c1 --- /dev/null +++ b/libIRDB/src/core/decode_dispatch.cpp @@ -0,0 +1,106 @@ + +#include <libIRDB-core.hpp> +#include <core/decode_dispatch.hpp> +#include <core/operand_dispatch.hpp> + +using namespace libIRDB; +using namespace std; + +// constructors, destructors, operators. + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const Instruction_t* i) +{ + cs.reset(new DecodedInstructionCapstoneX86_t(i)); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +{ + cs.reset(new DecodedInstructionCapstoneX86_t(start_addr,data,max_len)); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +{ + cs.reset(new DecodedInstructionCapstoneX86_t(start_addr,data,endptr)); +} + +DecodedInstructionDispatcher_t::DecodedInstructionDispatcher_t(const DecodedInstructionDispatcher_t& copy) +{ + cs.reset(new DecodedInstructionCapstoneX86_t(*copy.cs)); +} + +DecodedInstructionDispatcher_t::~DecodedInstructionDispatcher_t() +{ +} + +DecodedInstructionDispatcher_t& DecodedInstructionDispatcher_t::operator=(const DecodedInstructionDispatcher_t& copy) +{ + cs.reset(new DecodedInstructionCapstoneX86_t(*copy.cs)); + return *this; +} + + + +#define passthrough_to_cs(ret_type, method_name) \ + ret_type DecodedInstructionDispatcher_t::method_name() const \ + { \ + return cs->method_name(); \ + } + +// public methods + +/* demonstrating things are the same */ +passthrough_to_cs(bool, valid); +passthrough_to_cs(uint32_t, length); +passthrough_to_cs(bool, isBranch); +passthrough_to_cs(bool, isCall); +passthrough_to_cs(bool, isUnconditionalBranch); +passthrough_to_cs(bool, isConditionalBranch); +passthrough_to_cs(bool, isReturn); +passthrough_to_cs(uint32_t, getPrefixCount); +passthrough_to_cs(bool, hasRexWPrefix); +passthrough_to_cs(bool, setsStackPointer); +passthrough_to_cs(bool, hasRelevantRepPrefix); // rep ret disagreement. +passthrough_to_cs(bool, hasRelevantRepnePrefix); +passthrough_to_cs(bool, hasRelevantOperandSizePrefix); + +/* demonstrating when capstone is better */ +passthrough_to_cs(string, getMnemonic); +passthrough_to_cs(string,getDisassembly); +passthrough_to_cs(virtual_offset_t, getAddress); +passthrough_to_cs(int64_t, getImmediate); + +// demonstrating they different and trying to determine which is better. +passthrough_to_cs(bool, hasImplicitlyModifiedRegs); + +// not yet completed +// needs more complicated impl. + + +bool DecodedInstructionDispatcher_t::hasOperand(const int op_num) const +{ + const auto cs_res = cs->hasOperand(op_num); + return cs_res; +} + +// 0-based. first operand is numbered 0. +DecodedOperandDispatcher_t DecodedInstructionDispatcher_t::getOperand(const int op_num) const +{ + return DecodedOperandDispatcher_t(cs->getOperand(op_num)); +} + +DecodedOperandMetaVector_t DecodedInstructionDispatcher_t::getOperands() const +{ + auto ret_val=DecodedOperandMetaVector_t(); + auto cs_operands=cs->getOperands(); + for(const auto &op : cs_operands ) + ret_val.push_back(DecodedOperandDispatcher_t(op)); + return ret_val; +} + +virtual_offset_t DecodedInstructionDispatcher_t::getMemoryDisplacementOffset(const DecodedOperandDispatcher_t& t, const Instruction_t* insn) const +{ + return cs->getMemoryDisplacementOffset(*t.cs, insn); +} + + + diff --git a/libIRDB/src/core/decode_meta.cpp b/libIRDB/src/core/decode_meta.cpp deleted file mode 100644 index 0bd7a0f2e222a218f05724760640ea2aa269bf29..0000000000000000000000000000000000000000 --- a/libIRDB/src/core/decode_meta.cpp +++ /dev/null @@ -1,167 +0,0 @@ - -#include <libIRDB-core.hpp> -#include <core/decode_meta.hpp> -#include <core/operand_meta.hpp> - -using namespace libIRDB; -using namespace std; - -// constructors, destructors, operators. - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const Instruction_t* i) : - bea(i), - cs(i) -{ -} - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) : - bea(start_addr,data,max_len), - cs(start_addr,data,max_len) -{ -} - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const virtual_offset_t start_addr, const void *data, const void* endptr) : - bea(start_addr,data,endptr), - cs(start_addr,data,endptr) -{ -} - -DecodedInstructionMeta_t::DecodedInstructionMeta_t(const DecodedInstructionMeta_t& copy) : - bea(copy.bea), - cs(copy.cs) -{ -} - -DecodedInstructionMeta_t::~DecodedInstructionMeta_t() -{ -} - -DecodedInstructionMeta_t& DecodedInstructionMeta_t::operator=(const DecodedInstructionMeta_t& copy) -{ - bea=copy.bea; - cs=copy.cs; -} - - -void do_breakpoint(const char* s) { (void)s; } - - -#define passthrough_to_bea(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - return bea.method_name(); \ - } - - -#define compare_decoders(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - const auto bea_res= bea.method_name(); \ - const auto cs_res= cs.method_name(); \ - if(bea_res!=cs_res) \ - { \ - cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'" \ - <<" cs='"<<cs_res <<"'"; \ - cerr<<" in bea="<<bea.getDisassembly(); \ - cerr<<" or cs="<<bea.getDisassembly(); \ - cerr<<" at " <<__FUNCTION__<<endl; \ - do_breakpoint(__FUNCTION__); \ - } \ - return cs_res; \ - } - -#define compare_decoders_assert(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - const auto bea_res= bea.method_name(); \ - const auto cs_res= cs.method_name(); \ - if(bea_res!=cs_res) \ - { \ - cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'" \ - <<" cs='"<<cs_res <<"'"<<endl; \ - cerr<<" in bea="<<bea.getDisassembly(); \ - cerr<<" or cs="<<bea.getDisassembly(); \ - cerr<<" at " <<__FUNCTION__<<endl; \ - abort(); \ - } \ - return cs_res; \ - } - - -#define passthrough_to_cs(ret_type, method_name) \ - ret_type DecodedInstructionMeta_t::method_name() const \ - { \ - return cs.method_name(); \ - } - -// public methods - -/* demonstrating things are the same */ -compare_decoders_assert(bool, valid); -compare_decoders_assert(uint32_t, length); -compare_decoders_assert(bool, isBranch); -compare_decoders_assert(bool, isCall); -compare_decoders_assert(bool, isUnconditionalBranch); -compare_decoders_assert(bool, isConditionalBranch); -compare_decoders_assert(bool, isReturn); -compare_decoders_assert(uint32_t, getPrefixCount); -compare_decoders_assert(bool, hasRexWPrefix); -compare_decoders_assert(bool, setsStackPointer); -compare_decoders_assert(bool, hasRelevantRepPrefix); // rep ret disagreement. -compare_decoders_assert(bool, hasRelevantRepnePrefix); -compare_decoders_assert(bool, hasRelevantOperandSizePrefix); - -/* demonstrating when capstone is better */ -passthrough_to_cs(string, getMnemonic); -passthrough_to_cs(string,getDisassembly); -passthrough_to_cs(virtual_offset_t, getAddress); // bea sometimes calcs this wrong. way wrong. -passthrough_to_cs(int64_t, getImmediate); - -// demonstrating they different and trying to determine which is better. -compare_decoders(bool, hasImplicitlyModifiedRegs); // found div %sil insn that bea gets wrong. - -// not yet completed -// needs more complicated impl. - - -bool DecodedInstructionMeta_t::hasOperand(const int op_num) const -{ - const auto cs_res =cs .hasOperand(op_num); -/* - const auto bea_res=bea.hasOperand(op_num); - if(bea_res!=cs_res) - { - cerr<<"Bea/Capstone miscompare: bea='"<<bea_res<<"'" - <<" cs='"<<cs_res <<"'"<<endl; - cerr<<" in bea="<<bea.getDisassembly(); - cerr<<" or cs="<<bea.getDisassembly(); - cerr<<" at " <<__FUNCTION__<<endl; - abort(); - } - return bea_res; -*/ - return cs_res; -} - -// 0-based. first operand is numbered 0. -DecodedOperandMeta_t DecodedInstructionMeta_t::getOperand(const int op_num) const -{ - return DecodedOperandMeta_t(cs.getOperand(op_num)); -} - -DecodedOperandMetaVector_t DecodedInstructionMeta_t::getOperands() const -{ - auto ret_val=DecodedOperandMetaVector_t(); - auto cs_operands=cs.getOperands(); - for(const auto &op : cs_operands ) - ret_val.push_back(DecodedOperandMeta_t(op)); - return ret_val; -} - -virtual_offset_t DecodedInstructionMeta_t::getMemoryDisplacementOffset(const DecodedOperandMeta_t& t, const Instruction_t* insn) const -{ - return cs.getMemoryDisplacementOffset(t.cs, insn); -} - - - diff --git a/libIRDB/src/core/fileir.cpp b/libIRDB/src/core/fileir.cpp index 59ec13bcf49ea7734f7ec3b913527b09373e90a2..39c1a6f740b45266c697cd5674f873d8c18fdc12 100644 --- a/libIRDB/src/core/fileir.cpp +++ b/libIRDB/src/core/fileir.cpp @@ -990,27 +990,35 @@ int FileIR_t::GetArchitectureBitWidth() return archdesc->GetBitWidth(); } -void FileIR_t::SetArchitectureBitWidth(int width) +void FileIR_t::SetArchitecture(const int width, const ADMachineType_t mt) { if(archdesc==NULL) archdesc=new ArchitectureDescription_t; - archdesc->SetBitWidth(width); + archdesc->SetBitWidth(width); + archdesc->setMachineType(mt); } void FileIR_t::SetArchitecture() { /* the first 16 bytes of an ELF file define the magic number and ELF Class. */ - unsigned char e_ident[16]; + // unsigned char e_ident[16]; + union + { + Elf32_Ehdr ehdr32; + Elf64_Ehdr ehdr64; + } hdr_union; - DBinterface_t* myinter=BaseObj_t::GetInterface(); - pqxxDB_t *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter); + auto myinter=BaseObj_t::GetInterface(); + auto *mypqxxintr=dynamic_cast<pqxxDB_t*>(myinter); - int elfoid=GetFile()->GetELFOID(); + const auto elfoid=GetFile()->GetELFOID(); pqxx::largeobjectaccess loa(mypqxxintr->GetTransaction(), elfoid, PGSTD::ios::in); - loa.cread((char*)&e_ident, sizeof(e_ident)); + loa.cread((char*)&hdr_union, sizeof(hdr_union)); + + const auto e_ident=hdr_union.ehdr32.e_ident; archdesc=new ArchitectureDescription_t; @@ -1042,20 +1050,32 @@ void FileIR_t::SetArchitecture() if (archdesc->GetFileType() == AD_PE) { - // just assume 64 bit for Windows, o/w could also extract from file + // just assume x86-64 bit for Windows, o/w could also extract from file archdesc->SetBitWidth(64); + archdesc->setMachineType(admtX86_64); } else { switch(e_ident[4]) { case ELFCLASS32: + { archdesc->SetBitWidth(32); + if(hdr_union.ehdr32.e_machine!=EM_386) + throw std::invalid_argument("Arch not supported. 32-bit archs supported: I386"); + archdesc->setMachineType(admtI386); break; + } case ELFCLASS64: + { archdesc->SetBitWidth(64); + const auto mt= + hdr_union.ehdr64.e_machine==EM_AARCH64 ? admtAarch64 : + hdr_union.ehdr64.e_machine==EM_X86_64 ? admtX86_64 : + throw std::invalid_argument("Arch not supported. 64-bit archs supported: Aarch64, X86-64"); + archdesc->setMachineType(mt); break; - case ELFCLASSNONE: + } default: cerr << "Unknown ELF class " <<endl; exit(-1); diff --git a/libIRDB/src/core/operand_bea.cpp b/libIRDB/src/core/operand_bea.cpp deleted file mode 100644 index 422752dfc0dc3d02fe5db0cbfa85653549206bc7..0000000000000000000000000000000000000000 --- a/libIRDB/src/core/operand_bea.cpp +++ /dev/null @@ -1,258 +0,0 @@ - -#include <libIRDB-core.hpp> -#include <bea_deprecated.hpp> - -#include <core/decode_bea.hpp> -#include <core/operand_bea.hpp> - -using namespace std; -using namespace libIRDB; - -// static functions -static uint32_t beaRegNoToIRDBRegNo(uint32_t regno) -{ - switch(regno) - { - case 0: return -1; // no reg -> -1 - case REG0+REG2: /* eax:edx pair -- call it reg 0 */ return 0; - case REG0: return 0; - case REG1: return 1; - case REG2: return 2; - case REG3: return 3; - case REG4: return 4; - case REG5: return 5; - case REG6: return 6; - case REG7: return 7; - case REG8: return 8; - case REG9: return 9; - case REG10: return 10; - case REG11: return 11; - case REG12: return 12; - case REG13: return 13; - case REG14: return 14; - case REG15: return 15; - default: assert(0); // odd number from BEA? - }; -} - - -// methods -DecodedOperandBea_t::DecodedOperandBea_t(void* arg_voidptr) -{ - ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(arg_voidptr); - arg_data=(void*)new ARGTYPE(*arg_ptr); -} - -DecodedOperandBea_t::DecodedOperandBea_t(const DecodedOperandBea_t& copy) -{ - ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data); - arg_data=(void*)new ARGTYPE(*arg_ptr); -} - -DecodedOperandBea_t::~DecodedOperandBea_t() -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - delete t; - arg_data=NULL; -} - -DecodedOperandBea_t& DecodedOperandBea_t::operator=(const DecodedOperandBea_t& copy) -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - delete t; - arg_data=NULL; - ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data); - arg_data=(void*)new ARGTYPE(*arg_ptr); - - return *this; -} - -bool DecodedOperandBea_t::isConstant() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - assert(t); - return (t->ArgType & CONSTANT_TYPE)!=0; -} - -string DecodedOperandBea_t::getString() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - assert(t); - return t->ArgMnemonic; -} - -bool DecodedOperandBea_t::isRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->ArgType®ISTER_TYPE)==REGISTER_TYPE; -} - -bool DecodedOperandBea_t::isGeneralPurposeRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&GENERAL_REG)==GENERAL_REG; -} - -bool DecodedOperandBea_t::isMmxRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&MMX_REG)==MMX_REG; -} - -bool DecodedOperandBea_t::isFpuRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&FPU_REG)==FPU_REG; -} - -bool DecodedOperandBea_t::isSseRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&SSE_REG)==SSE_REG; -} - -bool DecodedOperandBea_t::isAvxRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&AVX_REG)==AVX_REG; -} - -bool DecodedOperandBea_t::isSpecialRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&SPECIAL_REG)==SPECIAL_REG; -} - -bool DecodedOperandBea_t::isSegmentRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return isRegister() && (t->ArgType&SEGMENT_REG)==SEGMENT_REG; -} - -uint32_t DecodedOperandBea_t::getRegNumber() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - if(!isRegister()) - throw std::logic_error("getRegNumber called on not register"); - const auto regno=(t->ArgType)&0xFFFF; - - return beaRegNoToIRDBRegNo(regno); -} - -bool DecodedOperandBea_t::isMemory() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->ArgType&MEMORY_TYPE)==MEMORY_TYPE; -} - -bool DecodedOperandBea_t::hasBaseRegister() const -{ - if(!isMemory()) - throw std::logic_error("hasBaseRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.BaseRegister!=0; -} - -bool DecodedOperandBea_t::hasIndexRegister() const -{ - if(!isMemory()) - throw std::logic_error("hasIndexRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.IndexRegister!=0; -} - -uint32_t DecodedOperandBea_t::getBaseRegister() const -{ - if(!isMemory() || !hasBaseRegister()) - throw std::logic_error("getBaseRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return beaRegNoToIRDBRegNo(t->Memory.BaseRegister); -} - -uint32_t DecodedOperandBea_t::getIndexRegister() const -{ - if(!isMemory() || !hasIndexRegister()) - throw std::logic_error("getIndexRegister called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return beaRegNoToIRDBRegNo(t->Memory.IndexRegister); -} - -uint32_t DecodedOperandBea_t::getScaleValue() const -{ - if(!isMemory()) - throw std::logic_error("getScaleValue called on not memory operand"); - - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.Scale; /* 0 indicates no scale */ -} - -bool DecodedOperandBea_t::hasMemoryDisplacement() const -{ - if(!isMemory()) - throw std::logic_error("GetBaseRegister called on not memory operand"); - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.DisplacementAddr!=0; -} - -virtual_offset_t DecodedOperandBea_t::getMemoryDisplacement() const -{ - if(!isMemory()) - throw std::logic_error("GetBaseRegister called on not memory operand"); - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (virtual_offset_t)t->Memory.Displacement; -} - -bool DecodedOperandBea_t::isPcrel() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->ArgType&RELATIVE_)==RELATIVE_; -} - -uint32_t DecodedOperandBea_t::getMemoryDisplacementEncodingSize() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->Memory.DisplacementSize; -} - -uint32_t DecodedOperandBea_t::getArgumentSizeInBytes() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->ArgSize/8; -} - -uint32_t DecodedOperandBea_t::getArgumentSizeInBits() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->ArgSize; -} - -bool DecodedOperandBea_t::hasSegmentRegister() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->SegmentReg!=0; - -} - -uint32_t DecodedOperandBea_t::getSegmentRegister() const -{ - if(!hasSegmentRegister()) - throw std::logic_error("getSegmentRegisterNumber called with no segment register"); - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return t->SegmentReg; -} - -bool DecodedOperandBea_t::isRead() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->AccessMode&READ)==READ; -} - -bool DecodedOperandBea_t::isWritten() const -{ - ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); - return (t->AccessMode&WRITE)==WRITE; -} diff --git a/libIRDB/src/core/operand_cs.cpp b/libIRDB/src/core/operand_csx86.cpp similarity index 88% rename from libIRDB/src/core/operand_cs.cpp rename to libIRDB/src/core/operand_csx86.cpp index f74aff7b91e04bac2020ac16bd3eb16d37e6f74a..d7d6c978488cae835a25c88b722bff212f468dc0 100644 --- a/libIRDB/src/core/operand_cs.cpp +++ b/libIRDB/src/core/operand_csx86.cpp @@ -1,8 +1,8 @@ #include <libIRDB-core.hpp> #include <memory> -#include <core/operand_cs.hpp> -#include <core/decode_cs.hpp> +#include <core/operand_csx86.hpp> +#include <core/decode_csx86.hpp> using namespace std; using namespace libIRDB; @@ -138,17 +138,17 @@ static uint32_t to_reg_number(const x86_reg ®) // methods -//DecodedOperandCapstone_t& DecodedOperandCapstone_t::operator=(const DecodedOperandCapstone_t& copy) +//DecodedOperandCapstoneX86_t& DecodedOperandCapstoneX86_t::operator=(const DecodedOperandCapstoneX86_t& copy) //{ // return *this; //} // -//DecodedOperandCapstone_t::DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy) +//DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t(const DecodedOperandCapstoneX86_t& copy) //{ // *this=copy; //} -DecodedOperandCapstone_t::DecodedOperandCapstone_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) +DecodedOperandCapstoneX86_t::DecodedOperandCapstoneX86_t( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) : my_insn(p_my_insn), op_num(p_op_num) @@ -156,12 +156,12 @@ DecodedOperandCapstone_t::DecodedOperandCapstone_t( const shared_ptr<void> & p_m } -DecodedOperandCapstone_t::~DecodedOperandCapstone_t() +DecodedOperandCapstoneX86_t::~DecodedOperandCapstoneX86_t() { } -bool DecodedOperandCapstone_t::isConstant() const +bool DecodedOperandCapstoneX86_t::isConstant() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); @@ -169,7 +169,7 @@ bool DecodedOperandCapstone_t::isConstant() const return op.type==X86_OP_IMM; } -uint64_t DecodedOperandCapstone_t::getConstant() const +uint64_t DecodedOperandCapstoneX86_t::getConstant() const { if(!isConstant()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-constant operand"); @@ -178,11 +178,11 @@ uint64_t DecodedOperandCapstone_t::getConstant() const return op.imm; } -string DecodedOperandCapstone_t::getString() const +string DecodedOperandCapstoneX86_t::getString() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); - const auto handle=DecodedInstructionCapstone_t::cs_handle->getHandle(); + const auto handle=DecodedInstructionCapstoneX86_t::cs_handle->getHandle(); switch(op.type) { @@ -227,14 +227,14 @@ string DecodedOperandCapstone_t::getString() const } } -bool DecodedOperandCapstone_t::isRegister() const +bool DecodedOperandCapstoneX86_t::isRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return op.type==X86_OP_REG; } -bool DecodedOperandCapstone_t::isGeneralPurposeRegister() const +bool DecodedOperandCapstoneX86_t::isGeneralPurposeRegister() const { const auto gp_regs=set<x86_reg>({ @@ -261,7 +261,7 @@ bool DecodedOperandCapstone_t::isGeneralPurposeRegister() const return isRegister() && gp_regs.find(op.reg)!=end(gp_regs); } -bool DecodedOperandCapstone_t::isMmxRegister() const +bool DecodedOperandCapstoneX86_t::isMmxRegister() const { const auto regs=set<x86_reg>({ X86_REG_MM0, X86_REG_MM1, @@ -272,7 +272,7 @@ bool DecodedOperandCapstone_t::isMmxRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isFpuRegister() const +bool DecodedOperandCapstoneX86_t::isFpuRegister() const { const auto regs=set<x86_reg>({ X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, @@ -283,7 +283,7 @@ bool DecodedOperandCapstone_t::isFpuRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isSseRegister() const +bool DecodedOperandCapstoneX86_t::isSseRegister() const { const auto regs=set<x86_reg>({ X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4, @@ -299,7 +299,7 @@ bool DecodedOperandCapstone_t::isSseRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isAvxRegister() const +bool DecodedOperandCapstoneX86_t::isAvxRegister() const { const auto regs=set<x86_reg>({ X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2, @@ -315,7 +315,7 @@ bool DecodedOperandCapstone_t::isAvxRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isZmmRegister() const +bool DecodedOperandCapstoneX86_t::isZmmRegister() const { const auto regs=set<x86_reg>({ X86_REG_ZMM0, X86_REG_ZMM1, X86_REG_ZMM2, @@ -331,7 +331,7 @@ bool DecodedOperandCapstone_t::isZmmRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isSpecialRegister() const +bool DecodedOperandCapstoneX86_t::isSpecialRegister() const { const auto regs=set<x86_reg>({ X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, @@ -345,7 +345,7 @@ bool DecodedOperandCapstone_t::isSpecialRegister() const return isRegister() && regs.find(op.reg)!=end(regs); } -bool DecodedOperandCapstone_t::isSegmentRegister() const +bool DecodedOperandCapstoneX86_t::isSegmentRegister() const { const auto regs=set<x86_reg>({ X86_REG_CS, @@ -362,7 +362,7 @@ bool DecodedOperandCapstone_t::isSegmentRegister() const -uint32_t DecodedOperandCapstone_t::getRegNumber() const +uint32_t DecodedOperandCapstoneX86_t::getRegNumber() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); @@ -384,28 +384,28 @@ uint32_t DecodedOperandCapstone_t::getRegNumber() const assert(0); } -bool DecodedOperandCapstone_t::isMemory() const +bool DecodedOperandCapstoneX86_t::isMemory() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return op.type==X86_OP_MEM; } -bool DecodedOperandCapstone_t::hasBaseRegister() const +bool DecodedOperandCapstoneX86_t::hasBaseRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return isMemory() && op.mem.base!=X86_REG_INVALID && op.mem.base!=X86_REG_RIP; } -bool DecodedOperandCapstone_t::hasIndexRegister() const +bool DecodedOperandCapstoneX86_t::hasIndexRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return isMemory() && op.mem.index!=X86_REG_INVALID; } -uint32_t DecodedOperandCapstone_t::getBaseRegister() const +uint32_t DecodedOperandCapstoneX86_t::getBaseRegister() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -413,7 +413,7 @@ uint32_t DecodedOperandCapstone_t::getBaseRegister() const return to_reg_number((x86_reg)op.mem.base); } -uint32_t DecodedOperandCapstone_t::getIndexRegister() const +uint32_t DecodedOperandCapstoneX86_t::getIndexRegister() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -421,7 +421,7 @@ uint32_t DecodedOperandCapstone_t::getIndexRegister() const return to_reg_number((x86_reg)op.mem.index); } -uint32_t DecodedOperandCapstone_t::getScaleValue() const +uint32_t DecodedOperandCapstoneX86_t::getScaleValue() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -429,7 +429,7 @@ uint32_t DecodedOperandCapstone_t::getScaleValue() const return op.mem.scale; } -bool DecodedOperandCapstone_t::hasMemoryDisplacement() const +bool DecodedOperandCapstoneX86_t::hasMemoryDisplacement() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); @@ -470,9 +470,9 @@ bool DecodedOperandCapstone_t::hasMemoryDisplacement() const assert(0); //unreachable } assert(0); // unreachable -} // end of DecodedOperandCapstone_t::hasMemoryDisplacement() +} // end of DecodedOperandCapstoneX86_t::hasMemoryDisplacement() -virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const +virtual_offset_t DecodedOperandCapstoneX86_t::getMemoryDisplacement() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -480,7 +480,7 @@ virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const return op.mem.disp; } -bool DecodedOperandCapstone_t::isPcrel() const +bool DecodedOperandCapstoneX86_t::isPcrel() const { if(!isMemory()) return false; const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -490,7 +490,7 @@ bool DecodedOperandCapstone_t::isPcrel() const } /* in bytes */ -uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const +uint32_t DecodedOperandCapstoneX86_t::getMemoryDisplacementEncodingSize() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -526,19 +526,19 @@ uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const assert(0); } -uint32_t DecodedOperandCapstone_t::getArgumentSizeInBytes() const +uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBytes() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); return op.size; } -uint32_t DecodedOperandCapstone_t::getArgumentSizeInBits() const +uint32_t DecodedOperandCapstoneX86_t::getArgumentSizeInBits() const { return getArgumentSizeInBytes()*8; } -bool DecodedOperandCapstone_t::hasSegmentRegister() const +bool DecodedOperandCapstoneX86_t::hasSegmentRegister() const { const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); @@ -546,7 +546,7 @@ bool DecodedOperandCapstone_t::hasSegmentRegister() const } -uint32_t DecodedOperandCapstone_t::getSegmentRegister() const +uint32_t DecodedOperandCapstoneX86_t::getSegmentRegister() const { if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of operand without memory operand"); const auto the_insn=static_cast<cs_insn*>(my_insn.get()); @@ -725,12 +725,12 @@ set<string> read_only_operand_mnemonics= -bool DecodedOperandCapstone_t::isRead() const +bool DecodedOperandCapstoneX86_t::isRead() const { if(!isWritten()) return true; - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); const auto d_mnemonic=d.getMnemonic(); const auto woom_it=write_only_operand_mnemonics.find(d_mnemonic); const auto in_woom=(woom_it!=end(write_only_operand_mnemonics)); @@ -744,7 +744,7 @@ bool DecodedOperandCapstone_t::isRead() const if(op_num!=0) return true; - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); if(d.isBranch()) return true; @@ -763,9 +763,9 @@ bool DecodedOperandCapstone_t::isRead() const */ } -bool DecodedOperandCapstone_t::isWritten() const +bool DecodedOperandCapstoneX86_t::isWritten() const { - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); const auto d_mnemonic=d.getMnemonic(); // special case check: all operands are reads @@ -802,7 +802,7 @@ bool DecodedOperandCapstone_t::isWritten() const /* if(op_num!=0) return false; - const auto d=DecodedInstructionCapstone_t(my_insn); + const auto d=DecodedInstructionCapstoneX86_t(my_insn); if(d.isBranch()) return false; diff --git a/libIRDB/src/core/operand_meta.cpp b/libIRDB/src/core/operand_dispatch.cpp similarity index 63% rename from libIRDB/src/core/operand_meta.cpp rename to libIRDB/src/core/operand_dispatch.cpp index c75220bd94ad2cde2b0abc2baa805862b21a231d..b6203eb7eee10ebbcbb5824d4531d6743ee2f5dc 100644 --- a/libIRDB/src/core/operand_meta.cpp +++ b/libIRDB/src/core/operand_dispatch.cpp @@ -1,42 +1,41 @@ #include <libIRDB-core.hpp> -#include <core/operand_cs.hpp> -#include <core/decode_cs.hpp> -#include <core/operand_bea.hpp> -#include <core/decode_bea.hpp> -#include <core/operand_meta.hpp> -#include <core/decode_meta.hpp> +#include <core/operand_csx86.hpp> +#include <core/decode_csx86.hpp> +#include <core/operand_dispatch.hpp> +#include <core/decode_dispatch.hpp> using namespace std; using namespace libIRDB; -DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandCapstone_t& copy_cs) : - cs(copy_cs) +DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const DecodedOperandCapstoneX86_t& copy_cs) { + cs.reset(new DecodedOperandCapstoneX86_t(copy_cs)); } -DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandMeta_t& copy) : - cs(copy.cs) +DecodedOperandDispatcher_t::DecodedOperandDispatcher_t(const DecodedOperandDispatcher_t& copy) { + cs.reset(new DecodedOperandCapstoneX86_t(*copy.cs)); } -DecodedOperandMeta_t::~DecodedOperandMeta_t() +DecodedOperandDispatcher_t::~DecodedOperandDispatcher_t() { } -DecodedOperandMeta_t& DecodedOperandMeta_t::operator=(const DecodedOperandMeta_t& copy) +DecodedOperandDispatcher_t& DecodedOperandDispatcher_t::operator=(const DecodedOperandDispatcher_t& copy) { - cs=copy.cs; + cs.reset(new DecodedOperandCapstoneX86_t(*copy.cs)); return *this; } #define passthrough_to_cs(ret_type, method_name) \ - ret_type DecodedOperandMeta_t::method_name() const \ + ret_type DecodedOperandDispatcher_t::method_name() const \ { \ - return cs.method_name(); \ + return cs->method_name(); \ } passthrough_to_cs(bool, isConstant); +passthrough_to_cs(uint64_t, getConstant); passthrough_to_cs(string, getString); passthrough_to_cs(bool, isRegister); passthrough_to_cs(bool, isGeneralPurposeRegister); diff --git a/tools/rida/rida.cpp b/tools/rida/rida.cpp index 08f9a9b1d9c191971f036be757a74168404c0593..a307377ff8160dc1e3820f1491679e90d9293042 100644 --- a/tools/rida/rida.cpp +++ b/tools/rida/rida.cpp @@ -9,7 +9,6 @@ #include <string> #include "capstone/capstone.h" #include <fstream> -//#include <elfio/elfio.hpp> #include <elf.h> #include <functional> @@ -48,6 +47,7 @@ class CreateFunctions_t csh cshandle; ofstream outfile; execlass_t file_class; + MachineType_t machine_type; friend ostream& operator<<(ostream& os, const CreateFunctions_t::RangeSet_t& rs); public: CreateFunctions_t(const string &input_pgm, const string &output_annot, const bool p_verbose) @@ -55,7 +55,8 @@ class CreateFunctions_t verbose(p_verbose), exeio(input_pgm), cshandle(), - file_class(exeio.get_class()) + file_class(exeio.get_class()), + machine_type(exeio.getMachineType()) { outfile.open(output_annot.c_str(), ofstream::out); if(!outfile.is_open()) @@ -73,8 +74,19 @@ class CreateFunctions_t 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) + const auto cs_mode= + machine_type==mtAarch64 ? CS_MODE_LITTLE_ENDIAN : + file_class==ELF64 ? CS_MODE_64 : + file_class==ELF32 ? CS_MODE_32 : + throw std::runtime_error("Cannot handle ELF class"); + + const auto my_cs_arch = + machine_type == mtX86_64 ? CS_ARCH_X86 : + machine_type == mtI386 ? CS_ARCH_X86 : + machine_type == mtAarch64 ? CS_ARCH_ARM64 : + throw std::runtime_error("Cannot handle architecture"); + + if (cs_open(my_cs_arch, cs_mode , &cshandle) != CS_ERR_OK) { cerr<<"Cannot initialize capstone"<<endl; exit(1); @@ -356,26 +368,57 @@ class CreateFunctions_t if(verbose) cout<<"Found plt function range is "<<hex<<startAddr<<"-"<<endAddr<<endl; - auto pltRange_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) + const auto pltRange_it=find_if(ALLOF(sccs), [&](const RangeSet_t& s) { return find_if(ALLOF(s), [&](const Range_t& r) { return r.contains(startAddr); }) != s.end(); }); - assert(pltRange_it!=sccs.end()); - sccs.erase(pltRange_it); // invalidates all iterators - - const auto plt_skip=16; - const auto plt_header_size=12; - const auto plt_entry_size=16; - const auto plt_entry_size_first_part=6; + // erase startAddr if found. + if(pltRange_it!=sccs.end()) + sccs.erase(pltRange_it); // invalidates all iterators - addRange(startAddr,plt_header_size); auto dynsymEntryIndex=0; - for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) + + const auto handle_x86_plt=[&]() { - addRange(i,plt_entry_size_first_part); - addRange(i+6,plt_entry_size-plt_entry_size_first_part); - addName(i,dynsymEntryIndex++); - } + const auto plt_skip=16; + const auto plt_header_size=12; + const auto plt_entry_size=16; + const auto plt_entry_size_first_part=6; + + addRange(startAddr,plt_header_size); + for(auto i=startAddr+plt_skip; i<endAddr; i+=plt_skip) + { + addRange(i,plt_entry_size_first_part); + addRange(i+6,plt_entry_size-plt_entry_size_first_part); + addName(i,dynsymEntryIndex++); + } + }; + const auto handle_arm_plt=[&]() + { + const auto plt_entry_size=16; + const auto plt_header_size=8*4; + + addRange(startAddr,plt_header_size); + for(auto i=startAddr+plt_header_size; i<endAddr; i+=plt_entry_size) + { + addRange(i,plt_entry_size); + addName(i,dynsymEntryIndex++); + } + }; + + switch(machine_type) + { + case mtX86_64: + case mtI386: + handle_x86_plt(); + break; + case mtAarch64: + handle_arm_plt(); + break; + default: + assert(0); + + }; cout<<"#ATTRIBUTE plt_entries="<<dec<<dynsymEntryIndex<<endl; diff --git a/xform/elfreader.cpp b/xform/elfreader.cpp index 799533edb7c353485bacfbb33518a31bcbdee2a6..0f748e1a59dfad86e3a05d1499c69f71a17d6c69 100644 --- a/xform/elfreader.cpp +++ b/xform/elfreader.cpp @@ -86,7 +86,7 @@ ElfReader::~ElfReader() /* * Read <p_numBytes> from ELF file for location <p_pc> */ -string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes) +string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes) const { for ( int i = 0; i < m_reader->sections.size(); ++i ) { @@ -109,7 +109,7 @@ string ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes) * No bounds checking is done on <p_buf> * Return false if address not in valid sections */ -bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) +bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) const { for ( int i = 0; i < m_reader->sections.size(); ++i ) { @@ -130,7 +130,7 @@ bool ElfReader::read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) /* * Return buffer for instruction off the ELF file */ -char* ElfReader::getInstructionBuffer(app_iaddr_t p_pc) +const char* ElfReader::getInstructionBuffer(app_iaddr_t p_pc) const { for ( int i = 0; i < m_reader->sections.size(); ++i ) { diff --git a/xform/elfreader.h b/xform/elfreader.h index 23ae15bd471132ab08312d8c6898e72d8aea9fff..20e1edf1350d7c2c03a65d6e04a43608dfd50214 100644 --- a/xform/elfreader.h +++ b/xform/elfreader.h @@ -2,10 +2,11 @@ #define _elfreader_H_ #include <vector> -// #include "elfio/elfio.hpp" #include "exeio.h" #include "targ-config.h" #include <assert.h> +#include <exception> +#include <libIRDB-core.hpp> // doing this is very bad. @@ -14,24 +15,35 @@ class ElfReader { - public: - ElfReader(char *); - virtual ~ElfReader(); - - std::string read(app_iaddr_t p_pc, unsigned p_numBytes); - bool read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf); - char* getInstructionBuffer(app_iaddr_t p_pc); - - bool isElf32() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; } - bool isElf64() { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; } - bool isPe32() { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; } - bool isPe64() { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; } - - private: -// ELFIO::elfio* m_reader; - EXEIO::exeio* m_reader; - -// std::vector < const ELFIO::section* > m_sections; + public: + + ElfReader(char *); + virtual ~ElfReader(); + + std::string read(app_iaddr_t p_pc, unsigned p_numBytes) const ; + bool read(app_iaddr_t p_pc, unsigned p_numBytes, char* p_buf) const ; + const char* getInstructionBuffer(app_iaddr_t p_pc) const ; + + bool isElf32() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF32; } + bool isElf64() const { assert(m_reader); return m_reader->get_class()==EXEIO::ELF64; } + bool isPe32() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE32; } + bool isPe64() const { assert(m_reader); return m_reader->get_class()==EXEIO::PE64; } + void SetArchitecture() + { + const auto width = + (isElf32() || isPe32()) ? 32 : + (isElf64() || isPe64()) ? 64 : + throw std::invalid_argument("Unknown architecture."); + const auto mt = m_reader->getMachineType() == EXEIO::mtI386 ? libIRDB::admtI386 : + m_reader->getMachineType() == EXEIO::mtX86_64 ? libIRDB::admtX86_64 : + m_reader->getMachineType() == EXEIO::mtAarch64 ? libIRDB::admtAarch64 : + throw std::invalid_argument("Unknown architecture."); + + libIRDB::FileIR_t::SetArchitecture(width,mt); + } + + private: + EXEIO::exeio* m_reader; }; diff --git a/xform/rewriter.cpp b/xform/rewriter.cpp index c5fe4c302d3ccae6fb1b237a3ee64d143a8ea3e3..e31f2d9c581d87c42469e88406c659c5b734666b 100644 --- a/xform/rewriter.cpp +++ b/xform/rewriter.cpp @@ -669,10 +669,13 @@ void Rewriter::readElfFile(char p_filename[]) */ void Rewriter::disassemble() { + getElfReader()->SetArchitecture(); + /* if(getElfReader()->isElf64() || getElfReader()->isPe64()) FileIR_t::SetArchitectureBitWidth(64); else FileIR_t::SetArchitectureBitWidth(32); + */ // for every instruction, grab from ELF // disassemble