diff --git a/.gitattributes b/.gitattributes index 346eae720208800830d1440a8417521f13370af2..bd11d7518c5d65c6daad2ce864bdaa6a11236668 100644 --- a/.gitattributes +++ b/.gitattributes @@ -223,8 +223,12 @@ libIRDB/include/core/reloc.hpp -text libIRDB/include/core/scoop.hpp -text libIRDB/include/core/type.hpp -text libIRDB/include/core/variantid.hpp -text -libIRDB/include/decode/decode.hpp -text -libIRDB/include/decode/operand.hpp -text +libIRDB/include/decode/decode_bea.hpp -text +libIRDB/include/decode/decode_cs.hpp -text +libIRDB/include/decode/decode_meta.hpp -text +libIRDB/include/decode/operand_bea.hpp -text +libIRDB/include/decode/operand_cs.hpp -text +libIRDB/include/decode/operand_meta.hpp -text libIRDB/include/libIRDB-cfg.hpp -text libIRDB/include/libIRDB-core.hpp -text libIRDB/include/libIRDB-decode.hpp -text @@ -264,8 +268,12 @@ libIRDB/src/core/scoop.cpp -text libIRDB/src/core/type.cpp -text libIRDB/src/core/variantid.cpp -text libIRDB/src/decode/SConscript -text -libIRDB/src/decode/decode.cpp -text -libIRDB/src/decode/operand.cpp -text +libIRDB/src/decode/decode_bea.cpp -text +libIRDB/src/decode/decode_cs.cpp -text +libIRDB/src/decode/decode_meta.cpp -text +libIRDB/src/decode/operand_bea.cpp -text +libIRDB/src/decode/operand_cs.cpp -text +libIRDB/src/decode/operand_meta.cpp -text libIRDB/src/syscall/Makefile.in -text libIRDB/src/syscall/SConscript -text libIRDB/src/syscall/SConstruct -text @@ -886,6 +894,7 @@ plugins_install/stratafy_with_pc_confine.sh -text plugins_install/test.exe -text plugins_install/test.sh -text plugins_install/watchdog.sh -text +/svn.externals.uva_dev -text third_party/ELFkickers-3.0a.tar.gz -text third_party/ELFkickers-3.0a/COPYING -text third_party/ELFkickers-3.0a/Changelog -text diff --git a/libIRDB/include/decode/decode.hpp b/libIRDB/include/decode/decode_bea.hpp similarity index 54% rename from libIRDB/include/decode/decode.hpp rename to libIRDB/include/decode/decode_bea.hpp index fe112b517de4600dc80d92bb7a6170213bfb55d5..2cc64e6f2fb71d6b9a74ed78e822bb1179ac5f30 100644 --- a/libIRDB/include/decode/decode.hpp +++ b/libIRDB/include/decode/decode_bea.hpp @@ -1,5 +1,5 @@ -#ifndef libirdb_decode_hpp -#define libirdb_decode_hpp +#ifndef libirdb_decodebea_hpp +#define libirdb_decodebea_hpp #include <stdint.h> #include <vector> @@ -10,20 +10,20 @@ namespace libIRDB using namespace libIRDB; using namespace std; -class DecodedOperand_t; -typedef std::vector<DecodedOperand_t> DecodedOperandVector_t; +class DecodedOperandBea_t; +typedef std::vector<DecodedOperandBea_t> DecodedOperandBeaVector_t; -class DecodedInstruction_t +class DecodedInstructionBea_t { public: - DecodedInstruction_t()=delete; - DecodedInstruction_t(const Instruction_t*); - DecodedInstruction_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len); - DecodedInstruction_t(const virtual_offset_t start_addr, const void *data, const void* endptr); - DecodedInstruction_t(const DecodedInstruction_t& copy); - DecodedInstruction_t& operator=(const DecodedInstruction_t& copy); + 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 ~DecodedInstruction_t(); + virtual ~DecodedInstructionBea_t(); string getDisassembly() const; bool valid() const; @@ -34,7 +34,7 @@ class DecodedInstruction_t bool isConditionalBranch() const; bool isReturn() const; string getMnemonic() const; - virtual_offset_t getImmediate() const; + int64_t getImmediate() const; virtual_offset_t getAddress() const; bool setsStackPointer() const; uint32_t getPrefixCount() const; @@ -43,12 +43,12 @@ class DecodedInstruction_t bool hasOperandSizePrefix() const; bool hasRexWPrefix() const; bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperand_t& t) const; + virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandBea_t& t) const; // 0-based. first operand is numbered 0. bool hasOperand(const int op_num) const; - DecodedOperand_t getOperand(const int op_num) const; - DecodedOperandVector_t getOperands() const; + DecodedOperandBea_t getOperand(const int op_num) const; + DecodedOperandBeaVector_t getOperands() const; private: diff --git a/libIRDB/include/decode/decode_cs.hpp b/libIRDB/include/decode/decode_cs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f52688a36b4e3bd5909b6a457aec0637b895df5a --- /dev/null +++ b/libIRDB/include/decode/decode_cs.hpp @@ -0,0 +1,64 @@ +#ifndef libirdb_decodecsa_hpp +#define libirdb_decodecsa_hpp + +#include <stdint.h> +#include <vector> +#include <memory> + +namespace libIRDB +{ + +using namespace libIRDB; +using namespace std; + +class DecodedOperandCapstone_t; +typedef std::vector<DecodedOperandCapstone_t> DecodedOperandCapstoneVector_t; + +class DecodedInstructionCapstone_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); + + virtual ~DecodedInstructionCapstone_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 hasRepPrefix() const; + bool hasRepnePrefix() const; + bool hasOperandSizePrefix() const; + bool hasRexWPrefix() const; + bool hasImplicitlyModifiedRegs() const; + virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t) const; + + // 0-based. first operand is numbered 0. + bool hasOperand(const int op_num) const; + DecodedOperandCapstone_t getOperand(const int op_num) const; + DecodedOperandCapstoneVector_t getOperands() const; + + private: + + void Disassemble(const virtual_offset_t start_addr, const void *data, const uint32_t max_len); + + shared_ptr<void> my_insn; + +}; + +} + +#endif diff --git a/libIRDB/include/decode/decode_meta.hpp b/libIRDB/include/decode/decode_meta.hpp new file mode 100644 index 0000000000000000000000000000000000000000..98db299c3bd674bc175835495a10c311cfcfb816 --- /dev/null +++ b/libIRDB/include/decode/decode_meta.hpp @@ -0,0 +1,66 @@ +#ifndef libirdb_decodemeta_hpp +#define libirdb_decodemeta_hpp + +#include <stdint.h> +#include <vector> +#include <decode/decode_bea.hpp> +#include <decode/operand_bea.hpp> +#include <decode/decode_cs.hpp> +#include <decode/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 hasRepPrefix() const; + bool hasRepnePrefix() const; + bool hasOperandSizePrefix() const; + bool hasRexWPrefix() const; + bool hasImplicitlyModifiedRegs() const; + virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandMeta_t& t) 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/decode/operand.hpp b/libIRDB/include/decode/operand_bea.hpp similarity index 74% rename from libIRDB/include/decode/operand.hpp rename to libIRDB/include/decode/operand_bea.hpp index 8a725f10e2c4cd2cf60f4e2046dad5a8865d1264..6a9f18ea4b07b8e36e6c1d49dbb7bdf81b1fbbde 100644 --- a/libIRDB/include/decode/operand.hpp +++ b/libIRDB/include/decode/operand_bea.hpp @@ -1,5 +1,5 @@ -#ifndef libRIDB_decodedoperand_hpp -#define libRIDB_decodedoperand_hpp +#ifndef libRIDB_decodedoperandbea_hpp +#define libRIDB_decodedoperandbea_hpp namespace libIRDB { @@ -8,13 +8,13 @@ using namespace std; using namespace libIRDB; -class DecodedOperand_t +class DecodedOperandBea_t { public: - DecodedOperand_t() =delete; - DecodedOperand_t& operator=(const DecodedOperand_t& copy); - DecodedOperand_t(const DecodedOperand_t& copy); - virtual ~DecodedOperand_t(); + 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; @@ -50,9 +50,9 @@ class DecodedOperand_t void* arg_data; - DecodedOperand_t(void* arg_p); + DecodedOperandBea_t(void* arg_p); - friend class DecodedInstruction_t; + friend class DecodedInstructionBea_t; }; diff --git a/libIRDB/include/decode/operand_cs.hpp b/libIRDB/include/decode/operand_cs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..bad019de7738d5820094ac56acbca6b925ef9935 --- /dev/null +++ b/libIRDB/include/decode/operand_cs.hpp @@ -0,0 +1,57 @@ +#ifndef libRIDB_decodedoperandcs_hpp +#define libRIDB_decodedoperandcs_hpp + +#include <memory> +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + + +class DecodedOperandCapstone_t +{ + public: + DecodedOperandCapstone_t() =delete; + DecodedOperandCapstone_t& operator=(const DecodedOperandCapstone_t& copy); + DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy); + virtual ~DecodedOperandCapstone_t(); + + bool isConstant() const; + string getString() const; + bool isWrite() 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: + + friend class DecodedInstructionCapstone_t; + +}; + +} +#endif diff --git a/libIRDB/include/decode/operand_meta.hpp b/libIRDB/include/decode/operand_meta.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3ec2cdfad3d03a36e0c9b420993ddb5bbae2aacf --- /dev/null +++ b/libIRDB/include/decode/operand_meta.hpp @@ -0,0 +1,61 @@ +#ifndef libRIDB_decodedoperandmeta_hpp +#define libRIDB_decodedoperandmeta_hpp + +#include <decode/decode_bea.hpp> +#include <decode/operand_bea.hpp> +namespace libIRDB +{ + +using namespace std; +using namespace libIRDB; + + +class DecodedOperandMeta_t +{ + public: + DecodedOperandMeta_t() =delete; + DecodedOperandMeta_t& operator=(const DecodedOperandMeta_t& copy); + DecodedOperandMeta_t(const DecodedOperandMeta_t& copy); + virtual ~DecodedOperandMeta_t(); + + bool isConstant() const; + string getString() const; + bool isWrite() 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: + DecodedOperandMeta_t(const DecodedOperandBea_t& in); + + DecodedOperandBea_t bea; + + friend class DecodedInstructionMeta_t; + +}; + +} +#endif diff --git a/libIRDB/include/libIRDB-decode.hpp b/libIRDB/include/libIRDB-decode.hpp index f05189c364d695042059b8132a2e824c996386cb..64b8f6ea8fd3d9e519077373ba7f400a83b97102 100644 --- a/libIRDB/include/libIRDB-decode.hpp +++ b/libIRDB/include/libIRDB-decode.hpp @@ -2,7 +2,6 @@ #define libIRDB_core_hpp #include <libIRDB-core.hpp> -#include <decode/operand.hpp> #include <decode/decode.hpp> #endif diff --git a/libIRDB/src/decode/decode.cpp b/libIRDB/src/decode/decode_bea.cpp similarity index 68% rename from libIRDB/src/decode/decode.cpp rename to libIRDB/src/decode/decode_bea.cpp index ae755dffac6552784d2326b6bd0344711efec9a1..f7ced5e55c7096c83b4451fae738bf7ab93550cf 100644 --- a/libIRDB/src/decode/decode.cpp +++ b/libIRDB/src/decode/decode_bea.cpp @@ -21,42 +21,42 @@ static inline bool my_SetsStackPointer(const ARGTYPE* arg) // constructors, destructors, operators. -DecodedInstruction_t::DecodedInstruction_t(const Instruction_t* i) +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); } -DecodedInstruction_t::DecodedInstruction_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +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); } -DecodedInstruction_t::DecodedInstruction_t(const virtual_offset_t start_addr, const void *data, const void* endptr) +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; Disassemble(start_addr,data,length); } -DecodedInstruction_t::DecodedInstruction_t(const DecodedInstruction_t& copy) +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; } -DecodedInstruction_t::~DecodedInstruction_t() +DecodedInstructionBea_t::~DecodedInstructionBea_t() { DISASM* d=static_cast<DISASM*>(disasm_data); delete d; disasm_data=NULL; } -DecodedInstruction_t& DecodedInstruction_t::operator=(const DecodedInstruction_t& copy) +DecodedInstructionBea_t& DecodedInstructionBea_t::operator=(const DecodedInstructionBea_t& copy) { DISASM* d=static_cast<DISASM*>(disasm_data); delete d; @@ -70,7 +70,7 @@ DecodedInstruction_t& DecodedInstruction_t::operator=(const DecodedInstruction_t // private methods -void DecodedInstruction_t::Disassemble(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +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)); @@ -85,57 +85,57 @@ void DecodedInstruction_t::Disassemble(const virtual_offset_t start_addr, const // public methods -string DecodedInstruction_t::getDisassembly() const +string DecodedInstructionBea_t::getDisassembly() const { assert(valid()); DISASM* d=static_cast<DISASM*>(disasm_data); return string(d->CompleteInstr); } -bool DecodedInstruction_t::valid() const +bool DecodedInstructionBea_t::valid() const { return disasm_length>=0; } -uint32_t DecodedInstruction_t::length() const +uint32_t DecodedInstructionBea_t::length() const { assert(valid()); return disasm_length; } -bool DecodedInstruction_t::isBranch() const +bool DecodedInstructionBea_t::isBranch() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Instruction.BranchType!=0; } -bool DecodedInstruction_t::isCall() const +bool DecodedInstructionBea_t::isCall() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Instruction.BranchType==CallType; } -bool DecodedInstruction_t::isUnconditionalBranch() const +bool DecodedInstructionBea_t::isUnconditionalBranch() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Instruction.BranchType==JmpType; } -bool DecodedInstruction_t::isConditionalBranch() const +bool DecodedInstructionBea_t::isConditionalBranch() const { DISASM* d=static_cast<DISASM*>(disasm_data); assert(0); } -bool DecodedInstruction_t::isReturn() const +bool DecodedInstructionBea_t::isReturn() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Instruction.BranchType==RetType; } -bool DecodedInstruction_t::hasOperand(const int op_num) const +bool DecodedInstructionBea_t::hasOperand(const int op_num) const { DISASM* d=static_cast<DISASM*>(disasm_data); switch(op_num+1) @@ -155,7 +155,7 @@ bool DecodedInstruction_t::hasOperand(const int op_num) const // 0-based. first operand is numbered 0. -DecodedOperand_t DecodedInstruction_t::getOperand(const int op_num) const +DecodedOperandBea_t DecodedInstructionBea_t::getOperand(const int op_num) const { if(!hasOperand(op_num)) throw std::out_of_range("op_num"); @@ -164,19 +164,19 @@ DecodedOperand_t DecodedInstruction_t::getOperand(const int op_num) const switch(op_num+1) { case 1: - return DecodedOperand_t(&d->Argument1); + return DecodedOperandBea_t(&d->Argument1); case 2: - return DecodedOperand_t(&d->Argument2); + return DecodedOperandBea_t(&d->Argument2); case 3: - return DecodedOperand_t(&d->Argument3); + return DecodedOperandBea_t(&d->Argument3); case 4: - return DecodedOperand_t(&d->Argument4); + return DecodedOperandBea_t(&d->Argument4); } } -DecodedOperandVector_t DecodedInstruction_t::getOperands() const +DecodedOperandBeaVector_t DecodedInstructionBea_t::getOperands() const { - auto ret_val=DecodedOperandVector_t(); + auto ret_val=DecodedOperandBeaVector_t(); for(auto i=0;i<4;i++) { if(hasOperand(i)) @@ -188,14 +188,14 @@ DecodedOperandVector_t DecodedInstruction_t::getOperands() const } -string DecodedInstruction_t::getMnemonic() const +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); } -virtual_offset_t DecodedInstruction_t::getImmediate() const +int64_t DecodedInstructionBea_t::getImmediate() const { // find and return an immediate operand from this instruction DISASM* d=static_cast<DISASM*>(disasm_data); @@ -203,7 +203,7 @@ virtual_offset_t DecodedInstruction_t::getImmediate() const } -virtual_offset_t DecodedInstruction_t::getAddress() const +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); @@ -211,7 +211,7 @@ virtual_offset_t DecodedInstruction_t::getAddress() const } -bool DecodedInstruction_t::setsStackPointer() const +bool DecodedInstructionBea_t::setsStackPointer() const { DISASM* d=static_cast<DISASM*>(disasm_data); @@ -232,13 +232,13 @@ bool DecodedInstruction_t::setsStackPointer() const return false; } -uint32_t DecodedInstruction_t::getPrefixCount() const +uint32_t DecodedInstructionBea_t::getPrefixCount() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Prefix.Number; } -virtual_offset_t DecodedInstruction_t::getMemoryDisplacementOffset(const DecodedOperand_t& t) const +virtual_offset_t DecodedInstructionBea_t::getMemoryDisplacementOffset(const DecodedOperandBea_t& t) const { DISASM* d=static_cast<DISASM*>(disasm_data); ARGTYPE* the_arg=static_cast<ARGTYPE*>(t.arg_data); @@ -246,31 +246,31 @@ virtual_offset_t DecodedInstruction_t::getMemoryDisplacementOffset(const Decoded } -bool DecodedInstruction_t::hasRepPrefix() const +bool DecodedInstructionBea_t::hasRepPrefix() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Prefix.RepnePrefix!=NotUsedPrefix; } -bool DecodedInstruction_t::hasRepnePrefix() const +bool DecodedInstructionBea_t::hasRepnePrefix() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Prefix.RepPrefix!=NotUsedPrefix; } -bool DecodedInstruction_t::hasOperandSizePrefix() const +bool DecodedInstructionBea_t::hasOperandSizePrefix() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Prefix.OperandSize!=NotUsedPrefix; } -bool DecodedInstruction_t::hasRexWPrefix() const +bool DecodedInstructionBea_t::hasRexWPrefix() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Prefix.REX.W_; } -bool DecodedInstruction_t::hasImplicitlyModifiedRegs() const +bool DecodedInstructionBea_t::hasImplicitlyModifiedRegs() const { DISASM* d=static_cast<DISASM*>(disasm_data); return d->Instruction.ImplicitModifiedRegs!=0; diff --git a/libIRDB/src/decode/decode_cs.cpp b/libIRDB/src/decode/decode_cs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0dc7b42a0c3f083b9ab433759013b1b55e3eb7ba --- /dev/null +++ b/libIRDB/src/decode/decode_cs.cpp @@ -0,0 +1,406 @@ + +#include <libIRDB-decode.hpp> + +#include <capstone.h> +#include <x86.h> +#include <string> +#include <functional> +#include <set> +#include <algorithm> + +using namespace libIRDB; +using namespace std; + +#define ALLOF(a) begin(a),end(a) + + +// static helpers +static bool isJmp(cs_insn* the_insn) +{ + const auto grp_it=find(ALLOF(the_insn->detail->groups), X86_GRP_JUMP); + return grp_it!=end(the_insn->detail->groups); + +} + +// shared code +class CapstoneHandle_t +{ + public: + CapstoneHandle_t(FileIR_t* firp=NULL) + { + + const auto width=FileIR_t::GetArchitectureBitWidth(); + const auto mode = (width==64) ? CS_MODE_64: CS_MODE_32; + auto err = cs_open(CS_ARCH_X86, mode, &handle); + + if (err) + { + const auto s=string("Failed on cs_open() with error returned: ")+to_string(err)+"\n"; + throw std::runtime_error(s); + } + cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); + cs_option(handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_INTEL); + + + } + inline csh getHandle() { return handle; } + + private: + csh handle; +}; +static CapstoneHandle_t *cs_handle=NULL; + +// constructors, destructors, operators. + +void DecodedInstructionCapstone_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()); + auto address=(uint64_t)start_addr; + auto size=(size_t)max_len; + const uint8_t* code=(uint8_t*)data; + const auto ok = cs_disasm_iter(cs_handle->getHandle(), &code, &size, &address, insn); + if(!ok) + insn->size=0; + + + const auto cs_freer=[](cs_insn * insn) -> void + { + cs_free(insn,1); + } ; + my_insn.reset(insn,cs_freer); +} + +DecodedInstructionCapstone_t::DecodedInstructionCapstone_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*)"); + + const auto length=i->GetDataBits().size(); + const auto data=i->GetDataBits().data(); + const auto address=i->GetAddress()->GetVirtualOffset(); + Disassemble(address,data,length); +} + +DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const virtual_offset_t start_addr, const void *data, uint32_t max_len) +{ + if(!cs_handle) cs_handle=new CapstoneHandle_t(NULL); + const auto endptr=data+max_len; + Disassemble(start_addr, data, max_len); +} + +DecodedInstructionCapstone_t::DecodedInstructionCapstone_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) +{ + *this=copy; +} + +DecodedInstructionCapstone_t::~DecodedInstructionCapstone_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) +{ + my_insn=copy.my_insn; + return *this; +} + +// public methods + +string DecodedInstructionCapstone_t::getDisassembly() const +{ + const auto myReplace=[](std::string str, + const std::string& oldStr, + const std::string& newStr) -> string + { + std::string::size_type pos = 0u; + while((pos = str.find(oldStr, pos)) != std::string::npos) + { + str.replace(pos, oldStr.length(), newStr); + pos += newStr.length(); + } + return str; + }; + + + // a list of special mnemonics that can't have a mem decoration because nasm sux. + const auto no_memdec_mnemonics=set<string>( + { + "lea", + "movd", + "pinsrw", + "psllw", + "pslld", + "psllq", + "psrlw", + "psrld", + "psrlq", + "psraw", + "psrad", + }); + + + // a list of prefixes and suffixes of mnemonics that can't have a mem decoration because nasm sux. + // helps deal with things like {mov,add,sub,mul,div, cmp}*{ss,sd,pd,pq}, esp when the cmp has a + // {l,le,ne,eq,g,gt} specifier. + const auto prefixes=set<string>( + { + "mov", + "movl", + "cmp", + "movh", + "add", + "sub", + "mul", + "div", + "ucomi", + "cvtsi2", + "cvtpi2", + "shuf", + }); + const auto suffixes=set<string>( + { + "sd", + "ss", + "ps", + "pd" + }); + + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto full_str=getMnemonic()+" "+the_insn->op_str; + + const auto noptr=myReplace(full_str," ptr ", " "); + const auto noxword=myReplace(noptr," xword ", " tword "); + const auto noxmmword=myReplace(noxword," xmmword ", " "); + + + const auto has_prefix_it=find_if(ALLOF(prefixes),[&](const string& prefix) + { const auto s=getMnemonic(); return s.substr(0,prefix.size())==prefix; } ); + const auto has_prefix = has_prefix_it != prefixes.end(); + const auto has_suffix_it=find_if(ALLOF(suffixes),[&](const string& suffix) + { const auto s=getMnemonic(); return s.rfind(suffix) == (s.size() - suffix.size()); } ); + const auto has_suffix = has_suffix_it != suffixes.end(); + + const auto needs_memdec_special=no_memdec_mnemonics.find(getMnemonic())==end(no_memdec_mnemonics); + const auto needs_memdec_shape=!(has_prefix && has_suffix); + const auto needs_memdec=needs_memdec_special && needs_memdec_shape; + + const auto no_dec1=needs_memdec ? noxmmword : (myReplace(noxmmword," qword ", " ")) ; + const auto no_dec2=needs_memdec ? no_dec1 : (myReplace(no_dec1," dword ", " ")) ; + + + return no_dec2; +} + +bool DecodedInstructionCapstone_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 +{ + 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 +{ + 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 +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto grp_it=find(ALLOF(the_insn->detail->groups), X86_GRP_CALL); + return grp_it!=end(the_insn->detail->groups); +} + +bool DecodedInstructionCapstone_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()); + + return isJmp(the_insn) && !isConditionalBranch(); +} + +bool DecodedInstructionCapstone_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 +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto grp_it=find(ALLOF(the_insn->detail->groups), X86_GRP_RET); + return grp_it!=end(the_insn->detail->groups); +} + +bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + + +// 0-based. first operand is numbered 0. +DecodedOperandCapstone_t DecodedInstructionCapstone_t::getOperand(const int op_num) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + assert(0); +} + +DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + assert(0); +} + + +string DecodedInstructionCapstone_t::getMnemonic() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + // list of opcodes to rename capstone to bea engine names + typedef pair<string,string> renamer_t; + const auto renamer=set<renamer_t>( + { + /* bea (right), capstone */ + { "mov", "movabs" } , + { "fucomip", "fucompi" }, + // { "cmovnb", "cmovae" }, + // { "cmovnbe", "cmova" }, + // { "cmovnle", "cmovg" }, +// { "jnbe", "ja"}, +// { "jnc", "jae"}, +// { "jng", "jle"}, +// { "jnl", "jge"}, +// { "jnle", "jg"}, + // { "movsd", "movsd" }, + // { "setnbe", "seta" }, + // { "setnle", "setg" }, + + }); + + + // get the cs insn via casting. + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + // get mnemonic as a string + auto mnemonic=string(the_insn->mnemonic); + + // remove any prefixes by finding the last space and removing anything before it. + const auto space_pos=mnemonic.rfind(" "); + if(space_pos!=string::npos) + mnemonic.erase(0,space_pos+1); + + // check if it needs a rename. + const auto finder_it=find_if(ALLOF(renamer), [&](const renamer_t& r) { return r.second==the_insn->mnemonic; } ); + if(finder_it!=end(renamer)) + mnemonic=finder_it->first; + + // return the new string. + return mnemonic; + + +} + +int64_t DecodedInstructionCapstone_t::getImmediate() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + // direct calls and jumps have a "immediate" which is really an address" those are returned by getAddress + if(isCall() || isJmp(the_insn)) + return 0; + + const auto count = cs_op_count(cs_handle->getHandle(), the_insn, X86_OP_IMM); + const auto x86 = &(the_insn->detail->x86); + + if (count==0) + return 0; /* no immediate is the same as an immediate of 0, i guess? */ + else if (count==1) + { + const auto index = cs_op_index(cs_handle->getHandle(), the_insn, X86_OP_IMM, 1); + return x86->operands[index].imm; + } + else + throw std::logic_error(string("Called ")+__FUNCTION__+" with number of immedaites not equal 1"); +} + + +virtual_offset_t DecodedInstructionCapstone_t::getAddress() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return 0; +} + + +bool DecodedInstructionCapstone_t::setsStackPointer() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +uint32_t DecodedInstructionCapstone_t::getPrefixCount() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t) const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + + +bool DecodedInstructionCapstone_t::hasRepPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstone_t::hasRepnePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstone_t::hasOperandSizePrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstone_t::hasRexWPrefix() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + +bool DecodedInstructionCapstone_t::hasImplicitlyModifiedRegs() const +{ + if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + return false; +} + diff --git a/libIRDB/src/decode/decode_meta.cpp b/libIRDB/src/decode/decode_meta.cpp new file mode 100644 index 0000000000000000000000000000000000000000..09b62262b209a2321d3774a3cac32dcb99d08549 --- /dev/null +++ b/libIRDB/src/decode/decode_meta.cpp @@ -0,0 +1,136 @@ + +#include <libIRDB-decode.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; +} + + + +#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.getDisassembly()<<" at " <<__FUNCTION__<<endl; \ + } \ + 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.getDisassembly()<<" 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 + +passthrough_to_cs(string,getDisassembly); +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); +passthrough_to_cs(string, getMnemonic); +compare_decoders(int64_t, getImmediate); +passthrough_to_bea(virtual_offset_t, getAddress); +passthrough_to_bea(bool, setsStackPointer); +passthrough_to_bea(uint32_t, getPrefixCount); +passthrough_to_bea(bool, hasRepPrefix); +passthrough_to_bea(bool, hasRepnePrefix); +passthrough_to_bea(bool, hasOperandSizePrefix); +passthrough_to_bea(bool, hasRexWPrefix); +passthrough_to_bea(bool, hasImplicitlyModifiedRegs); + + +bool DecodedInstructionMeta_t::hasOperand(const int op_num) const +{ + return bea.hasOperand(op_num); +} + + +// 0-based. first operand is numbered 0. +DecodedOperandMeta_t DecodedInstructionMeta_t::getOperand(const int op_num) const +{ + return DecodedOperandMeta_t(bea.getOperand(op_num)); +} + +DecodedOperandMetaVector_t DecodedInstructionMeta_t::getOperands() const +{ + auto ret_val=DecodedOperandMetaVector_t(); + auto bea_operands=bea.getOperands(); + for(const auto &op : bea_operands ) + ret_val.push_back(DecodedOperandMeta_t(op)); + return ret_val; +} + +virtual_offset_t DecodedInstructionMeta_t::getMemoryDisplacementOffset(const DecodedOperandMeta_t& t) const +{ + return bea.getMemoryDisplacementOffset(t.bea); +} + + + diff --git a/libIRDB/src/decode/operand.cpp b/libIRDB/src/decode/operand_bea.cpp similarity index 73% rename from libIRDB/src/decode/operand.cpp rename to libIRDB/src/decode/operand_bea.cpp index 8e9fbce38b156bdedece459af32458494c23f29f..5fbcf6625e6b7459bdb8f6d1224fb52a1d1f941a 100644 --- a/libIRDB/src/decode/operand.cpp +++ b/libIRDB/src/decode/operand_bea.cpp @@ -34,26 +34,26 @@ static uint32_t beaRegNoToIRDBRegNo(uint32_t regno) // methods -DecodedOperand_t::DecodedOperand_t(void* arg_voidptr) +DecodedOperandBea_t::DecodedOperandBea_t(void* arg_voidptr) { ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(arg_voidptr); arg_data=(void*)new ARGTYPE(*arg_ptr); } -DecodedOperand_t::DecodedOperand_t(const DecodedOperand_t& copy) +DecodedOperandBea_t::DecodedOperandBea_t(const DecodedOperandBea_t& copy) { ARGTYPE *arg_ptr=static_cast<ARGTYPE*>(copy.arg_data); arg_data=(void*)new ARGTYPE(*arg_ptr); } -DecodedOperand_t::~DecodedOperand_t() +DecodedOperandBea_t::~DecodedOperandBea_t() { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); delete t; arg_data=NULL; } -DecodedOperand_t& DecodedOperand_t::operator=(const DecodedOperand_t& copy) +DecodedOperandBea_t& DecodedOperandBea_t::operator=(const DecodedOperandBea_t& copy) { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); delete t; @@ -64,14 +64,14 @@ DecodedOperand_t& DecodedOperand_t::operator=(const DecodedOperand_t& copy) return *this; } -bool DecodedOperand_t::isConstant() const +bool DecodedOperandBea_t::isConstant() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); assert(t); return (t->ArgType & CONSTANT_TYPE)!=0; } -string DecodedOperand_t::getString() const +string DecodedOperandBea_t::getString() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); assert(t); @@ -79,61 +79,61 @@ string DecodedOperand_t::getString() const } -bool DecodedOperand_t::isWrite() const +bool DecodedOperandBea_t::isWrite() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return t->AccessMode==WRITE; } -bool DecodedOperand_t::isRegister() const +bool DecodedOperandBea_t::isRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return (t->ArgType®ISTER_TYPE)==REGISTER_TYPE; } -bool DecodedOperand_t::isGeneralPurposeRegister() const +bool DecodedOperandBea_t::isGeneralPurposeRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return isRegister() && (t->ArgType&GENERAL_REG)==GENERAL_REG; } -bool DecodedOperand_t::isMmxRegister() const +bool DecodedOperandBea_t::isMmxRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return isRegister() && (t->ArgType&MMX_REG)==MMX_REG; } -bool DecodedOperand_t::isFpuRegister() const +bool DecodedOperandBea_t::isFpuRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return isRegister() && (t->ArgType&FPU_REG)==FPU_REG; } -bool DecodedOperand_t::isSseRegister() const +bool DecodedOperandBea_t::isSseRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return isRegister() && (t->ArgType&SSE_REG)==SSE_REG; } -bool DecodedOperand_t::isAvxRegister() const +bool DecodedOperandBea_t::isAvxRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return isRegister() && (t->ArgType&AVX_REG)==AVX_REG; } -bool DecodedOperand_t::isSpecialRegister() const +bool DecodedOperandBea_t::isSpecialRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return isRegister() && (t->ArgType&SPECIAL_REG)==SPECIAL_REG; } -bool DecodedOperand_t::isSegmentRegister() const +bool DecodedOperandBea_t::isSegmentRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return isRegister() && (t->ArgType&SEGMENT_REG)==SEGMENT_REG; } -uint32_t DecodedOperand_t::getRegNumber() const +uint32_t DecodedOperandBea_t::getRegNumber() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); if(!isRegister()) @@ -143,13 +143,13 @@ uint32_t DecodedOperand_t::getRegNumber() const return beaRegNoToIRDBRegNo(regno); } -bool DecodedOperand_t::isMemory() const +bool DecodedOperandBea_t::isMemory() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return (t->ArgType&MEMORY_TYPE)==MEMORY_TYPE; } -bool DecodedOperand_t::hasBaseRegister() const +bool DecodedOperandBea_t::hasBaseRegister() const { if(!isMemory()) throw std::logic_error("hasBaseRegister called on not memory operand"); @@ -158,7 +158,7 @@ bool DecodedOperand_t::hasBaseRegister() const return t->Memory.BaseRegister!=0; } -bool DecodedOperand_t::hasIndexRegister() const +bool DecodedOperandBea_t::hasIndexRegister() const { if(!isMemory()) throw std::logic_error("hasIndexRegister called on not memory operand"); @@ -167,7 +167,7 @@ bool DecodedOperand_t::hasIndexRegister() const return t->Memory.IndexRegister!=0; } -uint32_t DecodedOperand_t::getBaseRegister() const +uint32_t DecodedOperandBea_t::getBaseRegister() const { if(!isMemory() || !hasBaseRegister()) throw std::logic_error("getBaseRegister called on not memory operand"); @@ -176,7 +176,7 @@ uint32_t DecodedOperand_t::getBaseRegister() const return beaRegNoToIRDBRegNo(t->Memory.BaseRegister); } -uint32_t DecodedOperand_t::getIndexRegister() const +uint32_t DecodedOperandBea_t::getIndexRegister() const { if(!isMemory() || !hasIndexRegister()) throw std::logic_error("getIndexRegister called on not memory operand"); @@ -185,7 +185,7 @@ uint32_t DecodedOperand_t::getIndexRegister() const return beaRegNoToIRDBRegNo(t->Memory.IndexRegister); } -uint32_t DecodedOperand_t::getScaleValue() const +uint32_t DecodedOperandBea_t::getScaleValue() const { if(!isMemory()) throw std::logic_error("getScaleValue called on not memory operand"); @@ -194,7 +194,7 @@ uint32_t DecodedOperand_t::getScaleValue() const return t->Memory.Scale; /* 0 indicates no scale */ } -bool DecodedOperand_t::hasMemoryDisplacement() const +bool DecodedOperandBea_t::hasMemoryDisplacement() const { if(!isMemory()) throw std::logic_error("GetBaseRegister called on not memory operand"); @@ -202,7 +202,7 @@ bool DecodedOperand_t::hasMemoryDisplacement() const return t->Memory.DisplacementAddr!=0; } -virtual_offset_t DecodedOperand_t::getMemoryDisplacement() const +virtual_offset_t DecodedOperandBea_t::getMemoryDisplacement() const { if(!isMemory()) throw std::logic_error("GetBaseRegister called on not memory operand"); @@ -210,38 +210,38 @@ virtual_offset_t DecodedOperand_t::getMemoryDisplacement() const return (virtual_offset_t)t->Memory.Displacement; } -bool DecodedOperand_t::isPcrel() const +bool DecodedOperandBea_t::isPcrel() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return (t->ArgType&RELATIVE_)==RELATIVE_; } -uint32_t DecodedOperand_t::getMemoryDisplacementEncodingSize() const +uint32_t DecodedOperandBea_t::getMemoryDisplacementEncodingSize() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return t->Memory.DisplacementSize; } -uint32_t DecodedOperand_t::getArgumentSizeInBytes() const +uint32_t DecodedOperandBea_t::getArgumentSizeInBytes() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return t->ArgSize/8; } -uint32_t DecodedOperand_t::getArgumentSizeInBits() const +uint32_t DecodedOperandBea_t::getArgumentSizeInBits() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return t->ArgSize; } -bool DecodedOperand_t::hasSegmentRegister() const +bool DecodedOperandBea_t::hasSegmentRegister() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return t->SegmentReg!=0; } -uint32_t DecodedOperand_t::getSegmentRegister() const +uint32_t DecodedOperandBea_t::getSegmentRegister() const { if(!hasSegmentRegister()) throw std::logic_error("getSegmentRegisterNumber called with no segment register"); @@ -249,13 +249,13 @@ uint32_t DecodedOperand_t::getSegmentRegister() const return t->SegmentReg; } -bool DecodedOperand_t::isRead() const +bool DecodedOperandBea_t::isRead() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return (t->AccessMode&READ)==READ; } -bool DecodedOperand_t::isWritten() const +bool DecodedOperandBea_t::isWritten() const { ARGTYPE *t=static_cast<ARGTYPE*>(arg_data); return (t->AccessMode&WRITE)==WRITE; diff --git a/libIRDB/src/decode/operand_cs.cpp b/libIRDB/src/decode/operand_cs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5dccde8173799e3dd9049b8b4a6e2cb3522548db --- /dev/null +++ b/libIRDB/src/decode/operand_cs.cpp @@ -0,0 +1,166 @@ + +#include <libIRDB-decode.hpp> + +using namespace std; +using namespace libIRDB; + +#include <capstone.h> + + +// methods + +DecodedOperandCapstone_t& DecodedOperandCapstone_t::operator=(const DecodedOperandCapstone_t& copy) +{ + return *this; +} + +DecodedOperandCapstone_t::DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy) +{ + *this=copy; +} + +DecodedOperandCapstone_t::~DecodedOperandCapstone_t() +{ +} + + +bool DecodedOperandCapstone_t::isConstant() const +{ + return false; +} + +string DecodedOperandCapstone_t::getString() const +{ + return ""; +} + + +bool DecodedOperandCapstone_t::isWrite() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isGeneralPurposeRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isMmxRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isFpuRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isSseRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isAvxRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isSpecialRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isSegmentRegister() const +{ + return false; +} + +uint32_t DecodedOperandCapstone_t::getRegNumber() const +{ + return 0; +} + +bool DecodedOperandCapstone_t::isMemory() const +{ + return false; +} + +bool DecodedOperandCapstone_t::hasBaseRegister() const +{ + return false; +} + +bool DecodedOperandCapstone_t::hasIndexRegister() const +{ + return false; +} + +uint32_t DecodedOperandCapstone_t::getBaseRegister() const +{ + return 0; +} + +uint32_t DecodedOperandCapstone_t::getIndexRegister() const +{ + return 0; +} + +uint32_t DecodedOperandCapstone_t::getScaleValue() const +{ + return 0; +} + +bool DecodedOperandCapstone_t::hasMemoryDisplacement() const +{ + return false; +} + +virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const +{ + return 0; +} + +bool DecodedOperandCapstone_t::isPcrel() const +{ + return false; +} + +uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const +{ + return 0; +} + +uint32_t DecodedOperandCapstone_t::getArgumentSizeInBytes() const +{ + return 0; +} + +uint32_t DecodedOperandCapstone_t::getArgumentSizeInBits() const +{ + return 0; +} + +bool DecodedOperandCapstone_t::hasSegmentRegister() const +{ + return false; + +} + +uint32_t DecodedOperandCapstone_t::getSegmentRegister() const +{ +} + +bool DecodedOperandCapstone_t::isRead() const +{ + return false; +} + +bool DecodedOperandCapstone_t::isWritten() const +{ + return false; +} diff --git a/libIRDB/src/decode/operand_meta.cpp b/libIRDB/src/decode/operand_meta.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ad1985b5f9f40da9975f91d3a4b2b37ebefaad3 --- /dev/null +++ b/libIRDB/src/decode/operand_meta.cpp @@ -0,0 +1,60 @@ + +#include <libIRDB-decode.hpp> + +using namespace std; +using namespace libIRDB; + +DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandBea_t& copy_bea) : + bea(copy_bea) +{ +} + +DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandMeta_t& copy) : + bea(copy.bea) +{ +} + +DecodedOperandMeta_t::~DecodedOperandMeta_t() +{ +} + +DecodedOperandMeta_t& DecodedOperandMeta_t::operator=(const DecodedOperandMeta_t& copy) +{ + bea=copy.bea; + return *this; +} + +#define passthrough_to_bea(ret_type, method_name) \ + ret_type DecodedOperandMeta_t::method_name() const \ + { \ + return bea.method_name(); \ + } + +passthrough_to_bea(bool, isConstant); +passthrough_to_bea(string, getString); +passthrough_to_bea(bool, isWrite); +passthrough_to_bea(bool, isRegister); +passthrough_to_bea(bool, isGeneralPurposeRegister); +passthrough_to_bea(bool, isMmxRegister); +passthrough_to_bea(bool, isFpuRegister); +passthrough_to_bea(bool, isSseRegister); +passthrough_to_bea(bool, isAvxRegister); +passthrough_to_bea(bool, isSpecialRegister); +passthrough_to_bea(bool, isSegmentRegister); +passthrough_to_bea(uint32_t, getRegNumber); +passthrough_to_bea(bool, isMemory); +passthrough_to_bea(bool, hasBaseRegister); +passthrough_to_bea(bool, hasIndexRegister); +passthrough_to_bea(uint32_t, getBaseRegister); +passthrough_to_bea(uint32_t, getIndexRegister); +passthrough_to_bea(uint32_t, getScaleValue); +passthrough_to_bea(bool, hasMemoryDisplacement); +passthrough_to_bea(virtual_offset_t, getMemoryDisplacement); +passthrough_to_bea(bool, isPcrel); +passthrough_to_bea(uint32_t, getMemoryDisplacementEncodingSize); +passthrough_to_bea(uint32_t, getArgumentSizeInBytes); +passthrough_to_bea(uint32_t, getArgumentSizeInBits); +passthrough_to_bea(bool, hasSegmentRegister); +passthrough_to_bea(uint32_t, getSegmentRegister); +passthrough_to_bea(bool, isRead); +passthrough_to_bea(bool, isWritten); diff --git a/svn.externals.uva_dev b/svn.externals.uva_dev new file mode 100644 index 0000000000000000000000000000000000000000..736fb6570108727f2a62ece51de65e7762a618b9 --- /dev/null +++ b/svn.externals.uva_dev @@ -0,0 +1 @@ +libcapstone https://github.com/aquynh/capstone/trunk diff --git a/tools/dump_map/dump_map.cpp b/tools/dump_map/dump_map.cpp index d7b1ec5e4d3ee56eaffa4d72e6fda84b250b4dce..3e403e059fe83390121be2ff4abf302445752bf1 100644 --- a/tools/dump_map/dump_map.cpp +++ b/tools/dump_map/dump_map.cpp @@ -21,6 +21,7 @@ #include <stdlib.h> #include <fstream> #include <libIRDB-core.hpp> +#include <libIRDB-decode.hpp> #include <libgen.h> #include <iomanip> #include <algorithm> @@ -45,7 +46,8 @@ void dump_icfs(Instruction_t* insn) cout<<"\tTargets: "<<boolalpha<<insn->GetIBTargets()->IsModuleComplete()<<endl; for_each(insn->GetIBTargets()->begin(), insn->GetIBTargets()->end(), [&](const Instruction_t* targ) { - cout<<"\t"<<targ->GetBaseID()<<":"<<targ->getDisassembly()<<endl; + const auto d=DecodedInstruction_t(targ); + cout<<"\t"<<targ->GetBaseID()<<":"<<d.getDisassembly()<<endl; }); } @@ -117,7 +119,8 @@ int main(int argc, char **argv) else cout<<setw(9)<<"NoFunc"; - cout<<" "<<insn->getDisassembly()<<endl; + const auto d=DecodedInstruction_t(insn); + cout<<" "<<d.getDisassembly()<<endl; if(dump_icfs_flag == insn->GetBaseID()) dump_icfs(insn); diff --git a/tools/transforms/PNRegularExpressions.cpp b/tools/transforms/PNRegularExpressions.cpp index 766c30a77c36b6ebed5a9e349905de3c848d5e2d..033bc4e0ea0a62ec6afab246a87e4113408f101f 100644 --- a/tools/transforms/PNRegularExpressions.cpp +++ b/tools/transforms/PNRegularExpressions.cpp @@ -29,9 +29,10 @@ using namespace std; #define FIRN(s) fill_in_reg_name((s)) -#define HEXNUM "[0][xX][0123456789abcdefABCDEF]+" +#define HEXNUM "([0][xX][0123456789abcdefABCDEF]+)|([01234356789]+)" #define REGSTRING "[[:blank:]]*[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]+[[:blank:]]*" #define SCALE "[[:blank:]]*[*][[:blank:]]*[1248][[:blank:]]*" +#define WS "[[:blank:]]*" static char* fill_in_reg_name(const char *instring) { @@ -93,7 +94,7 @@ PNRegularExpressions::PNRegularExpressions() } // match "[esp+reg*scale+disp]" - if(regcomp(®ex_esp_scaled, FIRN(".*\\[%sp[+].*[+](.+)\\].*"),REG_EXTENDED | REG_ICASE) !=0) + if(regcomp(®ex_esp_scaled, FIRN(".*\\[%sp"WS"[+].*[+](.+)\\].*"),REG_EXTENDED | REG_ICASE) !=0) { fprintf(stderr,"Error: regular expression for esp scaled addresses failed\n"); exit(1); @@ -105,7 +106,7 @@ PNRegularExpressions::PNRegularExpressions() fprintf(stderr,"Error: regular expression for regex_lea_rsp failed, code: %s\n", buf); exit(1); } - if((errcode=regcomp(®ex_esp_scaled_nodisp, FIRN(".*\\[%sp[+]"REGSTRING SCALE"(\\]).*"),REG_EXTENDED | REG_ICASE)) !=0) + if((errcode=regcomp(®ex_esp_scaled_nodisp, FIRN(".*\\[%sp"WS"[+]"WS""REGSTRING SCALE"(\\]).*"),REG_EXTENDED | REG_ICASE)) !=0) { char buf[1000]; regerror(errcode,®ex_esp_scaled_nodisp,buf,sizeof(buf)); @@ -113,13 +114,13 @@ PNRegularExpressions::PNRegularExpressions() exit(1); } - if(regcomp(®ex_ebp_scaled,FIRN(".*\\[%bp[+].*[-](.+)\\].*"),REG_EXTENDED | REG_ICASE) !=0) + if(regcomp(®ex_ebp_scaled,FIRN(".*\\[%bp"WS"[+]"WS".*[-](.+)\\].*"),REG_EXTENDED | REG_ICASE) !=0) { fprintf(stderr,"Error: regular expression for ebp scaled addresses failed\n"); exit(1); } - if((errcode=regcomp(®ex_esp_direct, FIRN(".*\\[%sp[+]("HEXNUM")\\].*"),REG_EXTENDED | REG_ICASE)) !=0) + if((errcode=regcomp(®ex_esp_direct, FIRN(".*\\[%sp"WS"[+]"WS"("HEXNUM")\\].*"),REG_EXTENDED | REG_ICASE)) !=0) { char buf[1000]; regerror(errcode,®ex_esp_direct,buf,sizeof(buf)); @@ -127,7 +128,7 @@ PNRegularExpressions::PNRegularExpressions() exit(1); } - if((errcode=regcomp(®ex_esp_direct_negoffset,FIRN(".*\\[%sp[-]("HEXNUM")\\].*"),REG_EXTENDED | REG_ICASE)) !=0) + if((errcode=regcomp(®ex_esp_direct_negoffset,FIRN(".*\\[%sp"WS"[-]"WS"("HEXNUM")\\].*"),REG_EXTENDED | REG_ICASE)) !=0) { char buf[1000]; regerror(errcode,®ex_esp_direct_negoffset,buf,sizeof(buf)); @@ -136,7 +137,7 @@ PNRegularExpressions::PNRegularExpressions() } - if(regcomp(®ex_ebp_direct,FIRN(".*\\[%bp[-]("HEXNUM")\\].*"),REG_EXTENDED | REG_ICASE) !=0) + if(regcomp(®ex_ebp_direct,FIRN(".*\\[%bp"WS"[-]"WS"("HEXNUM")\\].*"),REG_EXTENDED | REG_ICASE) !=0) { fprintf(stderr,"Error: regular expression for esp direct addresses failed\n"); exit(1); @@ -186,7 +187,7 @@ PNRegularExpressions::PNRegularExpressions() //Unlike other expressions, there are two pattern matches here //the first is the scaling factor (if one exists), the second is the //offset. - if (regcomp(®ex_scaled_ebp_index, FIRN(".*\\[.*[+]%bp[*]?(.*)[-](.+)\\].*"), REG_EXTENDED | REG_ICASE) != 0) + if (regcomp(®ex_scaled_ebp_index, FIRN(".*\\[.*[+]"WS"%bp[*]?(.*)[-](.+)\\].*"), REG_EXTENDED | REG_ICASE) != 0) { fprintf(stderr,"Error: regular expression for scaled ebp index failed to compile\n"); exit(1);