diff --git a/beaengine/beaengineSources/Includes/instr_set/opcodes_A_M.c b/beaengine/beaengineSources/Includes/instr_set/opcodes_A_M.c index a82e6987eee5ad661ff563aa5626f0756e13d660..6e4eab58ff57779587ec3c2fbff62cc12bc281af 100644 --- a/beaengine/beaengineSources/Includes/instr_set/opcodes_A_M.c +++ b/beaengine/beaengineSources/Includes/instr_set/opcodes_A_M.c @@ -1826,11 +1826,11 @@ void __bea_callspec__ cli_(PDISASM pMyDisasm) void __bea_callspec__ cpuid_(PDISASM pMyDisasm) { (*pMyDisasm).Instruction.Category = GENERAL_PURPOSE_INSTRUCTION+MISCELLANEOUS_INSTRUCTION; - (*pMyDisasm).Argument1.ArgType = REGISTER_TYPE+GENERAL_REG+REG0+REG1+REG2+REG3; +// (*pMyDisasm).Argument1.ArgType = REGISTER_TYPE+GENERAL_REG+REG0+REG1+REG2+REG3; #ifndef BEA_LIGHT_DISASSEMBLY (void) strcpy ((*pMyDisasm).Instruction.Mnemonic, "cpuid "); #endif - (*pMyDisasm).Argument1.ArgSize = 32; +// (*pMyDisasm).Argument1.ArgSize = 32; GV.EIP_++; } diff --git a/beaengine/beaengineSources/Includes/instr_set/opcodes_N_Z.c b/beaengine/beaengineSources/Includes/instr_set/opcodes_N_Z.c index 64a8995b37377a9a0bfd94cc9720a1f047c1f72b..a697203f9f39638600d3846ecfb5196012a174df 100644 --- a/beaengine/beaengineSources/Includes/instr_set/opcodes_N_Z.c +++ b/beaengine/beaengineSources/Includes/instr_set/opcodes_N_Z.c @@ -1815,9 +1815,9 @@ void __bea_callspec__ retn_(PDISASM pMyDisasm) * ======================================= */ void __bea_callspec__ ret_(PDISASM pMyDisasm) { - if ((*pMyDisasm).Prefix.RepPrefix == SuperfluousPrefix) { - (*pMyDisasm).Prefix.RepPrefix = InUsePrefix; - } +// if ((*pMyDisasm).Prefix.RepPrefix == SuperfluousPrefix) { +// (*pMyDisasm).Prefix.RepPrefix = InUsePrefix; +// } (*pMyDisasm).Instruction.Category = GENERAL_PURPOSE_INSTRUCTION+CONTROL_TRANSFER; (*pMyDisasm).Instruction.BranchType = RetType; #ifndef BEA_LIGHT_DISASSEMBLY @@ -2208,8 +2208,8 @@ void __bea_callspec__ syscall_(PDISASM pMyDisasm) (void) strcpy ((*pMyDisasm).Instruction.Mnemonic, "syscall "); #endif GV.EIP_++; - (*pMyDisasm).Argument1.ArgType = REGISTER_TYPE+GENERAL_REG+REG1+REG11; - (*pMyDisasm).Argument1.ArgSize = 64; + //(*pMyDisasm).Argument1.ArgType = REGISTER_TYPE+GENERAL_REG+REG1+REG11; + //(*pMyDisasm).Argument1.ArgSize = 64; } else { FailDecode(pMyDisasm); diff --git a/libIRDB/include/core/decode_cs.hpp b/libIRDB/include/core/decode_cs.hpp index 462aa5d9c8db76e9e948c8279c49c55703d86668..efc71323876e07b5e9d4bfdcb2b0f4b33989a7c6 100644 --- a/libIRDB/include/core/decode_cs.hpp +++ b/libIRDB/include/core/decode_cs.hpp @@ -44,7 +44,7 @@ class DecodedInstructionCapstone_t bool hasRelevantOperandSizePrefix() const; bool hasRexWPrefix() const; bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t) const; + virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const; // 0-based. first operand is numbered 0. bool hasOperand(const int op_num) const; @@ -57,6 +57,42 @@ class DecodedInstructionCapstone_t shared_ptr<void> my_insn; + class CapstoneHandle_t + { + public: + CapstoneHandle_t(FileIR_t* firp=NULL); +#if 0 + { + + 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); + + + } +#endif + // inline unsigned long getHandle() { return handle; }// this is the real type, but it's an alias and I don't want to export capstone values. + inline unsigned long getHandle() { return handle; } + + private: + // csh handle; // this is the real type, but it's an alias and I don't want to export capstone values. + unsigned long handle; + }; + static CapstoneHandle_t *cs_handle; + + + friend class DecodedOperandCapstone_t; + + DecodedInstructionCapstone_t(const shared_ptr<void> &my_insn); + }; } diff --git a/libIRDB/include/core/decode_meta.hpp b/libIRDB/include/core/decode_meta.hpp index 8937fd869c10219d774e80bbc3fc4fd1000e155d..fe62bb089b70b8f89a1e484c05246b7d8ea17b51 100644 --- a/libIRDB/include/core/decode_meta.hpp +++ b/libIRDB/include/core/decode_meta.hpp @@ -47,7 +47,7 @@ class DecodedInstructionMeta_t bool hasRelevantOperandSizePrefix() const; bool hasRexWPrefix() const; bool hasImplicitlyModifiedRegs() const; - virtual_offset_t getMemoryDisplacementOffset(const DecodedOperandMeta_t& t) 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; diff --git a/libIRDB/include/core/operand_cs.hpp b/libIRDB/include/core/operand_cs.hpp index bad019de7738d5820094ac56acbca6b925ef9935..f2ac0acd1305b83ed56eca07189f0e7784e76737 100644 --- a/libIRDB/include/core/operand_cs.hpp +++ b/libIRDB/include/core/operand_cs.hpp @@ -13,8 +13,8 @@ class DecodedOperandCapstone_t { public: DecodedOperandCapstone_t() =delete; - DecodedOperandCapstone_t& operator=(const DecodedOperandCapstone_t& copy); - DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy); + //DecodedOperandCapstone_t& operator=(const DecodedOperandCapstone_t& copy); + //DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy); virtual ~DecodedOperandCapstone_t(); bool isConstant() const; @@ -49,6 +49,11 @@ class DecodedOperandCapstone_t private: + DecodedOperandCapstone_t( const shared_ptr<void> &my_insn, uint8_t op_num); + + shared_ptr<void> my_insn; + uint8_t op_num; + friend class DecodedInstructionCapstone_t; }; diff --git a/libIRDB/include/core/operand_meta.hpp b/libIRDB/include/core/operand_meta.hpp index 43dad4017de719daa290da2725002cd4158f16b6..364d276c02bf35b4e22dbd80e42a2f541b46d466 100644 --- a/libIRDB/include/core/operand_meta.hpp +++ b/libIRDB/include/core/operand_meta.hpp @@ -49,9 +49,9 @@ class DecodedOperandMeta_t private: - DecodedOperandMeta_t(const DecodedOperandBea_t& in); + DecodedOperandMeta_t(const DecodedOperandCapstone_t& in); - DecodedOperandBea_t bea; + DecodedOperandCapstone_t cs; friend class DecodedInstructionMeta_t; diff --git a/libIRDB/src/core/decode_bea.cpp b/libIRDB/src/core/decode_bea.cpp index 6f508adce3e8d201fbf82c2ecd9369e75ae59263..4430c54c78691177d46431af86283fdca4f43739 100644 --- a/libIRDB/src/core/decode_bea.cpp +++ b/libIRDB/src/core/decode_bea.cpp @@ -215,11 +215,11 @@ bool DecodedInstructionBea_t::setsStackPointer() const { DISASM* d=static_cast<DISASM*>(disasm_data); - if(strstr(d->Instruction.Mnemonic, "push")!=NULL) + if(getMnemonic()== "push") return true; - if(strstr(d->Instruction.Mnemonic, "pop")!=NULL) + if(getMnemonic()== "pop") return true; - if(strstr(d->Instruction.Mnemonic, "call")!=NULL) + if(getMnemonic()== "call") return true; if(d->Instruction.ImplicitModifiedRegs==REGISTER_TYPE+GENERAL_REG+REG4) return true; diff --git a/libIRDB/src/core/decode_cs.cpp b/libIRDB/src/core/decode_cs.cpp index d2f6f019c3b1f0e1b5622c28280c90279d9420ff..3b5d39ee1fefa58478e427198e90bc3e4fe7a3fa 100644 --- a/libIRDB/src/core/decode_cs.cpp +++ b/libIRDB/src/core/decode_cs.cpp @@ -7,12 +7,35 @@ #include <functional> #include <set> #include <algorithm> +#include <stdexcept> using namespace libIRDB; using namespace std; #define ALLOF(a) begin(a),end(a) +DecodedInstructionCapstone_t::CapstoneHandle_t* DecodedInstructionCapstone_t::cs_handle=NULL ; + +DecodedInstructionCapstone_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; + 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); + + +} + + + typedef struct special_instruction special_instruction_t; struct special_instruction { @@ -46,6 +69,7 @@ static bool isJmp(cs_insn* the_insn) return isPartOfGroup(the_insn,X86_GRP_JUMP); } +#if 0 class CapstoneHandle_t { public: @@ -72,18 +96,19 @@ class CapstoneHandle_t csh handle; }; static CapstoneHandle_t *cs_handle=NULL; +#endif template<class type> -static inline type insnToImmedHelper(cs_insn* the_insn) +static inline type insnToImmedHelper(cs_insn* the_insn, csh handle) { - const auto count = cs_op_count(cs_handle->getHandle(), the_insn, X86_OP_IMM); + const auto count = cs_op_count(handle, 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); + const auto index = cs_op_index(handle, the_insn, X86_OP_IMM, 1); return x86->operands[index].imm; } else @@ -144,6 +169,8 @@ DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const Instruction_t* const auto data=i->GetDataBits().data(); const auto address=i->GetAddress()->GetVirtualOffset(); Disassemble(address,data,length); + + if(!valid()) throw std::invalid_argument("The Insruction_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) @@ -165,6 +192,11 @@ DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const DecodedInstruct *this=copy; } +DecodedInstructionCapstone_t::DecodedInstructionCapstone_t(const shared_ptr<void> &p_my_insn) + : my_insn(p_my_insn) +{ +} + DecodedInstructionCapstone_t::~DecodedInstructionCapstone_t() { // no need to cs_free(my_insn) because shared pointer will do that for us! @@ -316,75 +348,35 @@ bool DecodedInstructionCapstone_t::isReturn() const bool DecodedInstructionCapstone_t::hasOperand(const int op_num) const { - const auto needs_additional_memop=[&]() -> bool - { - return (getMnemonic()=="pop" || getMnemonic()=="push"); - }; - const auto needs_no_dest_shift=[&]() -> bool - { - return (getMnemonic()=="nop"); - }; - const auto needs_additional_regop=[&]() -> bool - { - return (getMnemonic()=="cbw" || - getMnemonic()=="cwde" || - getMnemonic()=="cdqe" || - getMnemonic()=="div" || - getMnemonic()=="mul" || - getMnemonic()=="fild" || - getMnemonic()=="fist" || - getMnemonic()=="fistp" || - getMnemonic()=="fld" || - getMnemonic()=="fst" || - getMnemonic()=="fstp" || - getMnemonic()=="faddp" || - getMnemonic()=="fdivp" || - getMnemonic()=="fdivrp" || - getMnemonic()=="fmulp" || - getMnemonic()=="fsubp" || - getMnemonic()=="fsubrp" || - getMnemonic()=="fcomip" || - getMnemonic()=="fcomp" || - getMnemonic()=="fcompp" || - getMnemonic()=="ficomp" || - getMnemonic()=="fucomip" || - getMnemonic()=="fucomp" || - getMnemonic()=="fucompp" - - - - ); - }; - - - - if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); + 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()); - const auto cs_op_count=the_insn->detail->x86.op_count; - - // calc space for extra operands that bea has that cs doens't. - const auto cs_op_count1=(needs_additional_memop() ? cs_op_count+1 : cs_op_count); - const auto cs_op_count2=(needs_additional_regop() ? cs_op_count1+1 : cs_op_count1); - const auto real_op_count=cs_op_count2; - - // shift the op over so bea matches cs. - const auto real_op_num1=(needs_no_dest_shift() ? op_num-1 : op_num); - const auto real_op_num=real_op_num1; - - return 0 <= real_op_num && real_op_num < real_op_count; + const auto &x86 = (the_insn->detail->x86); + return 0 <= op_num && op_num < x86.op_count; } // 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); + if(!hasOperand(op_num)) throw std::logic_error(string("Called ")+__FUNCTION__+" on without hasOperand()==true"); + + return DecodedOperandCapstone_t(my_insn,(uint8_t)op_num); + } DecodedOperandCapstoneVector_t DecodedInstructionCapstone_t::getOperands() const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); - assert(0); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &x86 = (the_insn->detail->x86); + const auto opcount=x86.op_count; + + auto ret_val=DecodedOperandCapstoneVector_t(); + + for(auto i=0;i<opcount;i++) + ret_val.push_back(getOperand(i)); + + return ret_val; } string DecodedInstructionCapstone_t::getMnemonic() const @@ -446,7 +438,7 @@ int64_t DecodedInstructionCapstone_t::getImmediate() const if(isCall() || isJmp(the_insn)) return 0; - return insnToImmedHelper<int64_t>(the_insn); + return insnToImmedHelper<int64_t>(the_insn, cs_handle->getHandle()); } @@ -457,7 +449,7 @@ virtual_offset_t DecodedInstructionCapstone_t::getAddress() const const auto the_insn=static_cast<cs_insn*>(my_insn.get()); if(isCall() || isJmp(the_insn)) - return insnToImmedHelper<virtual_offset_t>(the_insn); + return insnToImmedHelper<virtual_offset_t>(the_insn, cs_handle->getHandle()); const auto count = cs_op_count(cs_handle->getHandle(), the_insn, X86_OP_MEM); @@ -512,8 +504,9 @@ bool DecodedInstructionCapstone_t::setsStackPointer() const // now check each operand + const auto operands_begin=begin(the_insn->detail->x86.operands); const auto operands_end=begin(the_insn->detail->x86.operands)+the_insn->detail->x86.op_count; - const auto operands_it=find_if + const auto rsp_it=find_if ( begin(the_insn->detail->x86.operands), operands_end, @@ -522,11 +515,23 @@ bool DecodedInstructionCapstone_t::setsStackPointer() const return op.type==X86_OP_REG && sp_regs.find(op.reg)!=sp_regs.end(); } ); - if(operands_it!=operands_end) - return true; + // not found in the operands, we're done. + if(rsp_it==operands_end) + return false; + + // now decide if it's a register that's read or written. - // didn't find this anywhere, return false; - return false; + // special check for things without a destation (as op[0]) + if(getMnemonic()=="push" || + getMnemonic()=="cmp" || + getMnemonic()=="call" || + getMnemonic()=="test") + return false; + + // standard check -- is the reg op 0 + const auto is_op0=(rsp_it==operands_begin); + + return is_op0; } uint32_t DecodedInstructionCapstone_t::getPrefixCount() const @@ -540,10 +545,57 @@ uint32_t DecodedInstructionCapstone_t::getPrefixCount() const return count_with_rex; } -virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t) const +virtual_offset_t DecodedInstructionCapstone_t::getMemoryDisplacementOffset(const DecodedOperandCapstone_t& t, const Instruction_t* insn) const { if(!valid()) throw std::logic_error(string("Called ")+__FUNCTION__+" on invalid instruction"); - return false; + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + + const auto encoding_size=t.getMemoryDisplacementEncodingSize(); + const auto x86 = &(the_insn->detail->x86); + const auto imm_count = cs_op_count(cs_handle->getHandle(), the_insn, X86_OP_IMM); + const auto disp_size=t.getMemoryDisplacementEncodingSize(); + const auto imm=getImmediate(); + const auto disp=t.getMemoryDisplacement(); + + if(imm_count==0) + return the_insn->size - disp_size; + + // shifts can an immediate that's note encoded in the instruction + // but never an immediate encoded in the instruction. + if( + string((char*)the_insn->detail->x86.opcode)=="\xd0" || // shift left or right with an immediate that's not actually encoded in the insn + string((char*)the_insn->detail->x86.opcode)=="\xd1" + ) + return the_insn->size - disp_size; + + const auto possible_imm_sizes= string(the_insn->mnemonic)=="movabs" ? set<int>({8}) : set<int>({1,2,4}); + + for(const auto imm_size : possible_imm_sizes) + { + if(the_insn->size < disp_size + imm_size) + continue; + + const auto disp_start=the_insn->size-imm_size-disp_size; + const auto imm_start=the_insn->size-imm_size; + + const auto candidate_disp_eq = disp_size==4 ? *(int32_t*)(&insn->GetDataBits().c_str()[disp_start])==(int32_t)disp : + disp_size==2 ? *(int16_t*)(&insn->GetDataBits().c_str()[disp_start])==(int16_t)disp : + disp_size==1 ? *(int8_t *)(&insn->GetDataBits().c_str()[disp_start])==(int8_t )disp : (assert(0),false); + + const auto candidate_imm_eq = imm_size==8 ? *(int64_t*)(&insn->GetDataBits().c_str()[imm_start])==(int64_t)imm : + imm_size==4 ? *(int32_t*)(&insn->GetDataBits().c_str()[imm_start])==(int32_t)imm : + imm_size==2 ? *(int16_t*)(&insn->GetDataBits().c_str()[imm_start])==(int16_t)imm : + imm_size==1 ? *(int8_t *)(&insn->GetDataBits().c_str()[imm_start])==(int8_t )imm : (int64_t)(assert(0),false); + + if(candidate_disp_eq && candidate_imm_eq) + return disp_start; + + } + + assert(0); + + } diff --git a/libIRDB/src/core/decode_meta.cpp b/libIRDB/src/core/decode_meta.cpp index 0e89ca2e0210c9acde6052fc5d1670eee448f302..d57c4158bb8fa7b9629e1bf92a888ad72ba0f8d4 100644 --- a/libIRDB/src/core/decode_meta.cpp +++ b/libIRDB/src/core/decode_meta.cpp @@ -105,6 +105,9 @@ 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); @@ -114,9 +117,6 @@ 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. -compare_decoders(bool, hasRelevantRepPrefix); // rep ret disagreement. -compare_decoders(bool, hasRelevantRepnePrefix); -compare_decoders(bool, hasRelevantOperandSizePrefix); // not yet completed // needs more complicated impl. @@ -124,9 +124,9 @@ compare_decoders(bool, hasRelevantOperandSizePrefix); bool DecodedInstructionMeta_t::hasOperand(const int op_num) const { - const auto bea_res=bea.hasOperand(op_num); -/* 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<<"'" @@ -136,29 +136,29 @@ bool DecodedInstructionMeta_t::hasOperand(const int op_num) const cerr<<" at " <<__FUNCTION__<<endl; abort(); } - return cs_res; -*/ 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(bea.getOperand(op_num)); + return DecodedOperandMeta_t(cs.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 ) + 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 +virtual_offset_t DecodedInstructionMeta_t::getMemoryDisplacementOffset(const DecodedOperandMeta_t& t, const Instruction_t* insn) const { - return bea.getMemoryDisplacementOffset(t.bea); + return cs.getMemoryDisplacementOffset(t.cs, insn); } diff --git a/libIRDB/src/core/instruction.cpp b/libIRDB/src/core/instruction.cpp index f574953f9496160e573398f3dc8b4948a0e1d5d0..acef37f5d25141b020335d400673824729016a7a 100644 --- a/libIRDB/src/core/instruction.cpp +++ b/libIRDB/src/core/instruction.cpp @@ -24,7 +24,6 @@ #include <fstream> #include <sstream> #include <iomanip> -#include <bea_deprecated.hpp> #undef EIP @@ -94,9 +93,12 @@ int Instruction_t::Disassemble(DISASM &disasm) const std::string Instruction_t::getDisassembly() const { - DISASM disasm; - Disassemble(this,disasm); - return std::string(disasm.CompleteInstr); +// DISASM disasm; +// Disassemble(this,disasm); +// return std::string(disasm.CompleteInstr); + + const auto d=DecodedInstruction_t(this); + return d.getDisassembly(); } // diff --git a/libIRDB/src/core/operand_cs.cpp b/libIRDB/src/core/operand_cs.cpp index 739af2c0ed0e6f55cf0ffd1218542b627a832ec4..4def46db5ef2b5a6be9e4c595a5a59ebbea128af 100644 --- a/libIRDB/src/core/operand_cs.cpp +++ b/libIRDB/src/core/operand_cs.cpp @@ -1,5 +1,6 @@ #include <libIRDB-core.hpp> +#include <memory> using namespace std; using namespace libIRDB; @@ -7,16 +8,149 @@ using namespace libIRDB; #include <capstone.h> -// methods +// static helpers. + -DecodedOperandCapstone_t& DecodedOperandCapstone_t::operator=(const DecodedOperandCapstone_t& copy) +static uint32_t to_seg_reg_number(const x86_reg ®) { - return *this; + switch(reg) + { + case X86_REG_ES: return 0; + case X86_REG_CS: return 1; + case X86_REG_SS: return 2; + case X86_REG_DS: return 3; + case X86_REG_FS: return 4; + case X86_REG_GS: return 5; + defaut: assert(0); + } + assert(0); } -DecodedOperandCapstone_t::DecodedOperandCapstone_t(const DecodedOperandCapstone_t& copy) +static uint32_t to_reg_number(const x86_reg ®) { - *this=copy; + switch(reg) + { + case X86_REG_AH: + case X86_REG_AL: + case X86_REG_AX: + case X86_REG_EAX: + case X86_REG_RAX: + return 0; + + case X86_REG_CH: + case X86_REG_CL: + case X86_REG_CX: + case X86_REG_ECX: + case X86_REG_RCX: + return 1; + + case X86_REG_DH: + case X86_REG_DX: + case X86_REG_DL: + case X86_REG_EDX: + case X86_REG_RDX: + return 2; + + case X86_REG_BH: + case X86_REG_BL: + case X86_REG_BX: + case X86_REG_EBX: + case X86_REG_RBX: + return 3; + + case X86_REG_ESP: + case X86_REG_RSP: + case X86_REG_SP: + case X86_REG_SPL: + return 4; + + case X86_REG_BP: + case X86_REG_BPL: + case X86_REG_EBP: + case X86_REG_RBP: + return 5; + + case X86_REG_ESI: + case X86_REG_RSI: + case X86_REG_SI: + case X86_REG_SIL: + return 6; + + case X86_REG_DI: + case X86_REG_DIL: + case X86_REG_EDI: + case X86_REG_RDI: + return 7; + + case X86_REG_R8: + case X86_REG_R8B: + case X86_REG_R8D: + case X86_REG_R8W: + return 8; + + case X86_REG_R9: + case X86_REG_R9B: + case X86_REG_R9D: + case X86_REG_R9W: + return 9; + + case X86_REG_R10: + case X86_REG_R10B: + case X86_REG_R10D: + case X86_REG_R10W: + return 10; + + case X86_REG_R11: + case X86_REG_R11B: + case X86_REG_R11D: + case X86_REG_R11W: + return 11; + + case X86_REG_R12: + case X86_REG_R12B: + case X86_REG_R12D: + case X86_REG_R12W: + return 12; + + case X86_REG_R13: + case X86_REG_R13B: + case X86_REG_R13D: + case X86_REG_R13W: + return 13; + + case X86_REG_R14: + case X86_REG_R14B: + case X86_REG_R14D: + case X86_REG_R14W: + return 14; + + case X86_REG_R15: + case X86_REG_R15B: + case X86_REG_R15D: + case X86_REG_R15W: + return 15; + } + assert(0); +} + +// 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( const shared_ptr<void> & p_my_insn, uint8_t p_op_num) + : + my_insn(p_my_insn), + op_num(p_op_num) +{ + } DecodedOperandCapstone_t::~DecodedOperandCapstone_t() @@ -26,12 +160,47 @@ DecodedOperandCapstone_t::~DecodedOperandCapstone_t() bool DecodedOperandCapstone_t::isConstant() const { - return false; + 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_IMM; } string DecodedOperandCapstone_t::getString() const { - return ""; + 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(); + + switch(op.type) + { + case X86_OP_REG: + return string(cs_reg_name(handle, op.reg)); + case X86_OP_IMM: + return to_string(op.imm); + case X86_OP_MEM: + { + string ret_val; +// if (op.mem.segment != X86_REG_INVALID) +// ret_val+=cs_reg_name(handle, op.mem.segment) +" : " ; + if (op.mem.base != X86_REG_INVALID) + ret_val+=cs_reg_name(handle, op.mem.base); + + if (op.mem.index != X86_REG_INVALID) + ret_val+=string(" + ") +cs_reg_name(handle, op.mem.index); + + if (op.mem.scale != 1) + ret_val+=string(" * ") + to_string(op.mem.scale); + + if (op.mem.disp != 0) + ret_val+=" + "+ to_string(op.mem.disp); + return ret_val; + } + case X86_OP_FP: + case X86_OP_INVALID: + default: + assert(0); + } } @@ -42,125 +211,319 @@ bool DecodedOperandCapstone_t::isWrite() const bool DecodedOperandCapstone_t::isRegister() const { - return false; + 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 { - return false; + + const auto gp_regs=set<x86_reg>({ + X86_REG_AH, X86_REG_AL, X86_REG_AX, X86_REG_BH, X86_REG_BL, + X86_REG_BP, X86_REG_BPL, X86_REG_BX, X86_REG_CH, X86_REG_CL, + X86_REG_CX, X86_REG_DH, X86_REG_DI, X86_REG_DIL, + X86_REG_DL, X86_REG_DX, X86_REG_EAX, X86_REG_EBP, + X86_REG_EBX, X86_REG_ECX, X86_REG_EDI, X86_REG_EDX, + X86_REG_ESI, X86_REG_ESP, X86_REG_RAX, + X86_REG_RBP, X86_REG_RBX, X86_REG_RCX, X86_REG_RDI, X86_REG_RDX, + X86_REG_RSI, X86_REG_RSP, X86_REG_SI, + X86_REG_SIL, X86_REG_SP, X86_REG_SPL, + X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, + X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15, + X86_REG_R8B, X86_REG_R9B, X86_REG_R10B, X86_REG_R11B, + X86_REG_R12B, X86_REG_R13B, X86_REG_R14B, X86_REG_R15B, X86_REG_R8D, + X86_REG_R9D, X86_REG_R10D, X86_REG_R11D, X86_REG_R12D, X86_REG_R13D, + X86_REG_R14D, X86_REG_R15D, X86_REG_R8W, X86_REG_R9W, X86_REG_R10W, + X86_REG_R11W, X86_REG_R12W, X86_REG_R13W, X86_REG_R14W, X86_REG_R15W + }); + + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && gp_regs.find(op.reg)!=end(gp_regs); } bool DecodedOperandCapstone_t::isMmxRegister() const { - return false; + const auto regs=set<x86_reg>({ + X86_REG_MM0, X86_REG_MM1, + X86_REG_MM2, X86_REG_MM3, X86_REG_MM4, X86_REG_MM5, X86_REG_MM6, + X86_REG_MM7, X86_REG_R8}); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); } bool DecodedOperandCapstone_t::isFpuRegister() const { - return false; + const auto regs=set<x86_reg>({ + X86_REG_ST0, X86_REG_ST1, X86_REG_ST2, X86_REG_ST3, + X86_REG_ST4, X86_REG_ST5, X86_REG_ST6, X86_REG_ST7, + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); } bool DecodedOperandCapstone_t::isSseRegister() const { - return false; + const auto regs=set<x86_reg>({ + X86_REG_XMM0, X86_REG_XMM1, X86_REG_XMM2, X86_REG_XMM3, X86_REG_XMM4, + X86_REG_XMM5, X86_REG_XMM6, X86_REG_XMM7, X86_REG_XMM8, X86_REG_XMM9, + X86_REG_XMM10, X86_REG_XMM11, X86_REG_XMM12, X86_REG_XMM13, X86_REG_XMM14, + X86_REG_XMM15, X86_REG_XMM16, X86_REG_XMM17, X86_REG_XMM18, X86_REG_XMM19, + X86_REG_XMM20, X86_REG_XMM21, X86_REG_XMM22, X86_REG_XMM23, X86_REG_XMM24, + X86_REG_XMM25, X86_REG_XMM26, X86_REG_XMM27, X86_REG_XMM28, X86_REG_XMM29, + X86_REG_XMM30, X86_REG_XMM31 + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); } bool DecodedOperandCapstone_t::isAvxRegister() const { - return false; + const auto regs=set<x86_reg>({ + X86_REG_YMM0, X86_REG_YMM1, X86_REG_YMM2, + X86_REG_YMM3, X86_REG_YMM4, X86_REG_YMM5, X86_REG_YMM6, X86_REG_YMM7, + X86_REG_YMM8, X86_REG_YMM9, X86_REG_YMM10, X86_REG_YMM11, X86_REG_YMM12, + X86_REG_YMM13, X86_REG_YMM14, X86_REG_YMM15, X86_REG_YMM16, X86_REG_YMM17, + X86_REG_YMM18, X86_REG_YMM19, X86_REG_YMM20, X86_REG_YMM21, X86_REG_YMM22, + X86_REG_YMM23, X86_REG_YMM24, X86_REG_YMM25, X86_REG_YMM26, X86_REG_YMM27, + X86_REG_YMM28, X86_REG_YMM29, X86_REG_YMM30, X86_REG_YMM31, + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); } bool DecodedOperandCapstone_t::isSpecialRegister() const { - return false; + const auto regs=set<x86_reg>({ + X86_REG_CR1, X86_REG_CR2, X86_REG_CR3, X86_REG_CR4, X86_REG_CR5, + X86_REG_CR6, X86_REG_CR7, X86_REG_CR8, X86_REG_CR9, X86_REG_CR10, + X86_REG_CR11, X86_REG_CR12, X86_REG_CR13, X86_REG_CR14, X86_REG_CR15, + X86_REG_DR0, X86_REG_DR1, X86_REG_DR2, X86_REG_DR3, X86_REG_DR4, + X86_REG_DR5, X86_REG_DR6, X86_REG_DR7, + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); } bool DecodedOperandCapstone_t::isSegmentRegister() const { - return false; + const auto regs=set<x86_reg>({ + X86_REG_CS, + X86_REG_DS, + X86_REG_ES, + X86_REG_FS, + X86_REG_GS, + + }); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return isRegister() && regs.find(op.reg)!=end(regs); } + + uint32_t DecodedOperandCapstone_t::getRegNumber() const { - return 0; + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + if(isGeneralPurposeRegister()) + return to_reg_number(op.reg); + else if(isMmxRegister()) + return op.reg-X86_REG_MM0; + else if(isFpuRegister()) + return op.reg-X86_REG_ST0; + else if(isSseRegister()) + return op.reg-X86_REG_XMM0; + else if(isAvxRegister()) + return op.reg-X86_REG_YMM0; + else if(isSegmentRegister()) + return to_seg_reg_number(op.reg); + else + assert(0); } bool DecodedOperandCapstone_t::isMemory() const { - return false; + 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 { - return false; + 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; } bool DecodedOperandCapstone_t::hasIndexRegister() const { - return false; + 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 { - return 0; + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return to_reg_number((x86_reg)op.mem.base); } uint32_t DecodedOperandCapstone_t::getIndexRegister() const { - return 0; + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return to_reg_number((x86_reg)op.mem.index); } uint32_t DecodedOperandCapstone_t::getScaleValue() const { - return 0; + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.mem.scale; } bool DecodedOperandCapstone_t::hasMemoryDisplacement() const { - return false; + 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.disp!=0; } virtual_offset_t DecodedOperandCapstone_t::getMemoryDisplacement() const { - return 0; + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return op.mem.disp; } bool DecodedOperandCapstone_t::isPcrel() const { - return false; + if(!isMemory()) return false; + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + + return (op.mem.base==X86_REG_RIP || op.mem.base==X86_REG_EIP || op.mem.base==X86_REG_IP); } +/* in bytes */ uint32_t DecodedOperandCapstone_t::getMemoryDisplacementEncodingSize() const { - return 0; + if(!isMemory()) throw std::logic_error(string("Cannot ")+__FUNCTION__+" of non-memory operand"); + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + + const auto modrm=the_insn->detail->x86.modrm; + const auto mod=(modrm>>6)&0x3; + const auto rm=(modrm)&0x7; + const auto sib=the_insn->detail->x86.sib; + const auto sib_base=(sib>>0)&0x7; + const auto sib_index=(sib>>3)&0x7; + + switch(mod) + { + case 0 /* 00 */: + if(rm==4 && // indicates SIB is present. + sib_base==0x5 // indicates disp32 when sib present and mod=00. + ) + return 4; // abs 32-bit + + if(rm==5) + return 4; // pcrel or abs 32-bit depending on if 32-bit or 64-bit arch. + + throw std::logic_error(string("Cannot ")+__FUNCTION__+" of operand without displacement"); + + case 1 /* 01 */: return 1; + case 2 /* 10 */: return 4; + + case 3 /* 11 */: + throw std::logic_error(string("Cannot ")+__FUNCTION__+" of operand without displacement"); + default: assert(0); + } + assert(0); } uint32_t DecodedOperandCapstone_t::getArgumentSizeInBytes() const { - return 0; + const auto the_insn=static_cast<cs_insn*>(my_insn.get()); + return the_insn->detail->x86.addr_size; } uint32_t DecodedOperandCapstone_t::getArgumentSizeInBits() const { - return 0; + return getArgumentSizeInBytes()*8; } bool DecodedOperandCapstone_t::hasSegmentRegister() const { - return false; + 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.segment != X86_REG_INVALID); } uint32_t DecodedOperandCapstone_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()); + const auto &op = (the_insn->detail->x86.operands[op_num]); + return to_seg_reg_number((x86_reg)op.mem.segment); } + +set<string> read_only_operand_mnemonics= + { + "push" + "cmp" + "test" + }; + bool DecodedOperandCapstone_t::isRead() const { - return false; + if(op_num!=0) + return true; + + const auto d=DecodedInstructionCapstone_t(my_insn); + if(d.isBranch()) + return true; + + const auto room_it=read_only_operand_mnemonics.find(d.getMnemonic()); + const auto in_room=(room_it!=end(read_only_operand_mnemonics)); + if(in_room) + return true; + + if(d.getMnemonic().substr(0,3)=="mov") + return false; + + // op0 is typically read/write + return true; + + assert(0); } bool DecodedOperandCapstone_t::isWritten() const -{ - return false; +{ + if(op_num!=0) + return false; + const auto d=DecodedInstructionCapstone_t(my_insn); + if(d.isBranch()) + return false; + + const auto room_it=read_only_operand_mnemonics.find(d.getMnemonic()); + const auto in_room=(room_it!=end(read_only_operand_mnemonics)); + if(in_room) + return false; + + return true; } diff --git a/libIRDB/src/core/operand_meta.cpp b/libIRDB/src/core/operand_meta.cpp index e62ae20f07dc8cac20e864f425f8f49e614c2de0..819cca85a5ce7aedb70da55ccb632228e70eca22 100644 --- a/libIRDB/src/core/operand_meta.cpp +++ b/libIRDB/src/core/operand_meta.cpp @@ -4,13 +4,13 @@ using namespace std; using namespace libIRDB; -DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandBea_t& copy_bea) : - bea(copy_bea) +DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandCapstone_t& copy_cs) : + cs(copy_cs) { } DecodedOperandMeta_t::DecodedOperandMeta_t(const DecodedOperandMeta_t& copy) : - bea(copy.bea) + cs(copy.cs) { } @@ -20,41 +20,41 @@ DecodedOperandMeta_t::~DecodedOperandMeta_t() DecodedOperandMeta_t& DecodedOperandMeta_t::operator=(const DecodedOperandMeta_t& copy) { - bea=copy.bea; + cs=copy.cs; return *this; } -#define passthrough_to_bea(ret_type, method_name) \ +#define passthrough_to_cs(ret_type, method_name) \ ret_type DecodedOperandMeta_t::method_name() const \ { \ - return bea.method_name(); \ + return cs.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); +passthrough_to_cs(bool, isConstant); +passthrough_to_cs(string, getString); +passthrough_to_cs(bool, isWrite); +passthrough_to_cs(bool, isRegister); +passthrough_to_cs(bool, isGeneralPurposeRegister); +passthrough_to_cs(bool, isMmxRegister); +passthrough_to_cs(bool, isFpuRegister); +passthrough_to_cs(bool, isSseRegister); +passthrough_to_cs(bool, isAvxRegister); +passthrough_to_cs(bool, isSpecialRegister); +passthrough_to_cs(bool, isSegmentRegister); +passthrough_to_cs(uint32_t, getRegNumber); +passthrough_to_cs(bool, isMemory); +passthrough_to_cs(bool, hasBaseRegister); +passthrough_to_cs(bool, hasIndexRegister); +passthrough_to_cs(uint32_t, getBaseRegister); +passthrough_to_cs(uint32_t, getIndexRegister); +passthrough_to_cs(uint32_t, getScaleValue); +passthrough_to_cs(bool, hasMemoryDisplacement); +passthrough_to_cs(virtual_offset_t, getMemoryDisplacement); +passthrough_to_cs(bool, isPcrel); +passthrough_to_cs(uint32_t, getMemoryDisplacementEncodingSize); +passthrough_to_cs(uint32_t, getArgumentSizeInBytes); +passthrough_to_cs(uint32_t, getArgumentSizeInBits); +passthrough_to_cs(bool, hasSegmentRegister); +passthrough_to_cs(uint32_t, getSegmentRegister); +passthrough_to_cs(bool, isRead); +passthrough_to_cs(bool, isWritten); diff --git a/libIRDB/test/fill_in_cfg.cpp b/libIRDB/test/fill_in_cfg.cpp index 96523bfbc07a52e9f93f33d8a5f835b41ad5cec8..808fdadc18c1273d85a3997c587d330e8502822d 100644 --- a/libIRDB/test/fill_in_cfg.cpp +++ b/libIRDB/test/fill_in_cfg.cpp @@ -155,7 +155,7 @@ void set_target /* get the offset */ // virtual_offset_t virtual_offset=strtoul(disasm->Argument1.ArgMnemonic, NULL, 16); - virtual_offset_t virtual_offset=strtoul(disasm->getOperand(0).getString().c_str(), NULL, 16); + virtual_offset_t virtual_offset=disasm->getAddress(); /* create a pair of offset/file */ pair<db_id_t,virtual_offset_t> p(insn->GetAddress()->GetFileID(),virtual_offset); @@ -704,7 +704,6 @@ main(int argc, char* argv[]) assert(pidp); - delete pidp; pidp=NULL; } diff --git a/libIRDB/test/fix_calls.cpp b/libIRDB/test/fix_calls.cpp index 647ea664e677c226b3ef89c2d9324cd22efbd148..102fa81678c842f91e12bd2f39402aea00d5900a 100644 --- a/libIRDB/test/fix_calls.cpp +++ b/libIRDB/test/fix_calls.cpp @@ -906,7 +906,7 @@ void fix_other_pcrel(FileIR_t* firp, Instruction_t *insn, UIntPtr virt_offset) const auto the_arg=*relop_it; - int offset=disasm.getMemoryDisplacementOffset(the_arg); /*the_arg->Memory.DisplacementAddr-disasm.EIP*/; + int offset=disasm.getMemoryDisplacementOffset(the_arg, insn); /*the_arg->Memory.DisplacementAddr-disasm.EIP*/; assert(offset>=0 && offset <=15); int size=the_arg.getMemoryDisplacementEncodingSize(); // the_arg->Memory.DisplacementSize; assert(size==1 || size==2 || size==4 || size==8); diff --git a/tools/transforms/OffsetInference.cpp b/tools/transforms/OffsetInference.cpp index 29904cd9ef77eb20f6e790a94e21e614288acb73..b5a96df1de1f2e99a8c983d98096754c8384d658 100644 --- a/tools/transforms/OffsetInference.cpp +++ b/tools/transforms/OffsetInference.cpp @@ -230,7 +230,7 @@ StackLayout* OffsetInference::SetupLayout(Function_t *func) //if the push is a constant, then check if the next instruction //is an unconditional jmp, if so, ignore the push, assume //the push is part of fixed calls. - if(disasm.getOperand(1).isConstant() /* (disasm.Argument2.ArgType & 0xF0000000) == CONSTANT_TYPE */) + if(disasm.getOperand(0).isConstant() /* (disasm.Argument2.ArgType & 0xF0000000) == CONSTANT_TYPE */) { //Grab the pushed value assert(pmatch[1].rm_so >=0 && pmatch[1].rm_eo >=0); diff --git a/tools/transforms/PNTransformDriver.cpp b/tools/transforms/PNTransformDriver.cpp index 01462f6267652ed8025263c169b4fca859a76d5f..8ad761da1904dddd067f5d5ae8ffb7e7842f31fd 100644 --- a/tools/transforms/PNTransformDriver.cpp +++ b/tools/transforms/PNTransformDriver.cpp @@ -569,7 +569,7 @@ static pair<int,int> get_prologue_data(Function_t *func) } else if(d.getMnemonic() /*string(d.Instruction.Mnemonic)*/ == "push") { - if( d.getOperand(1).isConstant() /*d.Argument2.ArgType&CONSTANT_TYPE)==CONSTANT_TYPE */ //&& + if( d.getOperand(0).isConstant() /*d.Argument2.ArgType&CONSTANT_TYPE)==CONSTANT_TYPE */ //&& // insn->GetFallthrough()!=NULL && // insn->GetFallthrough()->GetTarget()!=NULL && // func->GetInstructions().find(insn->GetFallthrough()->GetTarget())!=func->GetInstructions().end() diff --git a/tools/transforms/Rewrite_Utility.cpp b/tools/transforms/Rewrite_Utility.cpp index 8e4366952a367d2eac27f43ea9c0a21e9671312f..8ddd9a5873cb094042f6afe3ae596191b5861ebf 100644 --- a/tools/transforms/Rewrite_Utility.cpp +++ b/tools/transforms/Rewrite_Utility.cpp @@ -214,7 +214,7 @@ void setInstructionAssembly(FileIR_t* virp,Instruction_t *p_instr, string p_asse virp->RegisterAssembly(p_instr,p_assembly); // p_instr->Assemble(p_assembly); - p_instr->SetComment(p_instr->getDisassembly()); + p_instr->SetComment(p_assembly); p_instr->SetFallthrough(p_fallThrough); p_instr->SetTarget(p_target);