From a89e0eb1c0b1d1959e936872a39bcf9e051ea376 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 25 Apr 2015 23:52:11 +0200 Subject: [PATCH] DBG: disasm_helper now uses capstone instead of BeaEngine --- x64_dbg_dbg/capstone_wrapper.cpp | 16 ++- x64_dbg_dbg/capstone_wrapper.h | 1 + x64_dbg_dbg/disasm_helper.cpp | 227 ++++++++++--------------------- x64_dbg_dbg/instruction.cpp | 2 +- x64_dbg_dbg/stackinfo.cpp | 1 - 5 files changed, 86 insertions(+), 161 deletions(-) diff --git a/x64_dbg_dbg/capstone_wrapper.cpp b/x64_dbg_dbg/capstone_wrapper.cpp index 004e4192..0484c1f9 100644 --- a/x64_dbg_dbg/capstone_wrapper.cpp +++ b/x64_dbg_dbg/capstone_wrapper.cpp @@ -111,9 +111,16 @@ String Capstone::OperandText(int opindex) } if(mem.disp) { + char operatorText = '+'; + if(mem.disp < 0) + { + operatorText = '-'; + sprintf_s(temp, "%"fext"X", mem.disp * -1); + } + else + sprintf_s(temp, "%"fext"X", mem.disp); if(prependPlus) - result += "+"; - sprintf_s(temp, "%"fext"X", mem.disp); + result += operatorText; result += temp; } } @@ -148,4 +155,9 @@ bool Capstone::IsFilling() { uint8_t opcode = x86().opcode[0]; return opcode == 0x90 || opcode == 0xCC; +} + +x86_insn Capstone::GetId() +{ + return (x86_insn)mInstr->id; } \ No newline at end of file diff --git a/x64_dbg_dbg/capstone_wrapper.h b/x64_dbg_dbg/capstone_wrapper.h index 127e1967..3faf9199 100644 --- a/x64_dbg_dbg/capstone_wrapper.h +++ b/x64_dbg_dbg/capstone_wrapper.h @@ -22,6 +22,7 @@ public: const uint Address(); const cs_x86 & x86(); bool IsFilling(); + x86_insn GetId(); private: csh mHandle; diff --git a/x64_dbg_dbg/disasm_helper.cpp b/x64_dbg_dbg/disasm_helper.cpp index 1d8039c0..e82c7d5c 100644 --- a/x64_dbg_dbg/disasm_helper.cpp +++ b/x64_dbg_dbg/disasm_helper.cpp @@ -5,7 +5,6 @@ */ #include "disasm_helper.h" -#include "BeaEngine\BeaEngine.h" #include "value.h" #include "console.h" #include "debugger.h" @@ -19,15 +18,9 @@ uint disasmback(unsigned char* data, uint base, uint size, uint ip, int n) int i; uint abuf[131], addr, back, cmdsize; unsigned char* pdata; - int len; // Reset Disasm Structure - DISASM disasm; - memset(&disasm, 0, sizeof(DISASM)); -#ifdef _WIN64 - disasm.Archi = 64; -#endif - disasm.Options = NoformatNumeral | ShowSegmentRegs; + Capstone cp; // Check if the pointer is not null if(data == NULL) @@ -50,7 +43,7 @@ uint disasmback(unsigned char* data, uint base, uint size, uint ip, int n) if(ip < (uint)n) return ip; - back = 16 * (n + 3); // Instruction length limited to 16 + back = MAX_DISASM_BUFFER * (n + 3); // Instruction length limited to 16 if(ip < back) back = ip; @@ -63,13 +56,15 @@ uint disasmback(unsigned char* data, uint base, uint size, uint ip, int n) { abuf[i % 128] = addr; - disasm.EIP = (UIntPtr)pdata; - len = Disasm(&disasm); - cmdsize = (len < 1) ? 1 : len ; + if(!cp.Disassemble(0, pdata, size)) + cmdsize = 1; + else + cmdsize = cp.Size(); pdata += cmdsize; addr += cmdsize; back -= cmdsize; + size -= cmdsize; } if(i < n) @@ -83,15 +78,9 @@ uint disasmnext(unsigned char* data, uint base, uint size, uint ip, int n) int i; uint cmdsize; unsigned char* pdata; - int len; // Reset Disasm Structure - DISASM disasm; - memset(&disasm, 0, sizeof(DISASM)); -#ifdef _WIN64 - disasm.Archi = 64; -#endif - disasm.Options = NoformatNumeral | ShowSegmentRegs; + Capstone cp; if(data == NULL) return 0; @@ -107,10 +96,10 @@ uint disasmnext(unsigned char* data, uint base, uint size, uint ip, int n) for(i = 0; i < n && size > 0; i++) { - disasm.EIP = (UIntPtr)pdata; - disasm.SecurityBlock = (UInt32)size; - len = Disasm(&disasm); - cmdsize = (len < 1) ? 1 : len; + if(!cp.Disassemble(0, pdata, size)) + cmdsize = 1; + else + cmdsize = cp.Size(); pdata += cmdsize; ip += cmdsize; @@ -122,113 +111,75 @@ uint disasmnext(unsigned char* data, uint base, uint size, uint ip, int n) const char* disasmtext(uint addr) { - unsigned char buffer[16] = ""; - DbgMemRead(addr, buffer, 16); - DISASM disasm; - disasm.Options = NoformatNumeral | ShowSegmentRegs; -#ifdef _WIN64 - disasm.Archi = 64; -#endif // _WIN64 - disasm.VirtualAddr = addr; - disasm.EIP = (UIntPtr)buffer; - int len = Disasm(&disasm); - static char instruction[INSTRUCT_LENGTH] = ""; - if(len == UNKNOWN_OPCODE) + unsigned char buffer[MAX_DISASM_BUFFER] = ""; + DbgMemRead(addr, buffer, sizeof(buffer)); + Capstone cp; + static char instruction[64] = ""; + if(!cp.Disassemble(addr, buffer)) strcpy_s(instruction, "???"); else - strcpy_s(instruction, disasm.CompleteInstr); + sprintf_s(instruction, "%s %s", cp.GetInstr()->mnemonic, cp.GetInstr()->op_str); return instruction; } -static SEGMENTREG ConvertBeaSeg(int beaSeg) +static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg) { - switch(beaSeg) + const cs_x86 & x86 = cp.x86(); + const cs_x86_op & op = x86.operands[opindex]; + arg->segment = SEG_DEFAULT; + strcpy_s(arg->mnemonic, cp.OperandText(opindex).c_str()); + switch(op.type) { - case ESReg: - return SEG_ES; - break; - case DSReg: - return SEG_DS; - break; - case FSReg: - return SEG_FS; - break; - case GSReg: - return SEG_GS; - break; - case CSReg: - return SEG_CS; - break; - case SSReg: - return SEG_SS; - break; + case X86_OP_REG: + { + const char* regname = cp.RegName((x86_reg)op.reg); + arg->type = arg_normal; + uint value; + if(!valfromstring(regname, &value, true, true)) + value = 0; + arg->constant = arg->value = value; } - return SEG_DEFAULT; -} + break; -static bool HandleArgument(ARGTYPE* Argument, INSTRTYPE* Instruction, DISASM_ARG* arg, uint addr) -{ - int argtype = Argument->ArgType; - const char* argmnemonic = Argument->ArgMnemonic; - if(!*argmnemonic) - return false; - arg->memvalue = 0; - strcpy_s(arg->mnemonic, argmnemonic); - if((argtype & MEMORY_TYPE) == MEMORY_TYPE) + case X86_OP_IMM: + { + arg->type = arg_normal; + arg->constant = arg->value = (duint)op.imm; + } + break; + + case X86_OP_MEM: { arg->type = arg_memory; - arg->segment = ConvertBeaSeg(Argument->SegmentReg); - uint value = (uint)Argument->Memory.Displacement; - if((Argument->ArgType & RELATIVE_) == RELATIVE_) - value = (uint)Instruction->AddrValue; - arg->constant = value; - arg->value = 0; - if(!valfromstring(argmnemonic, &value, true, true)) - return false; + const x86_op_mem & mem = op.mem; + if(mem.base == X86_REG_RIP) //rip-relative + arg->constant = cp.Address() + (duint)mem.disp + cp.Size(); + else + arg->constant = (duint)mem.disp; + uint value; + if(!valfromstring(arg->mnemonic, &value, true, true)) + return; + arg->value = value; if(DbgMemIsValidReadPtr(value)) { - arg->value = value; - switch(Argument->ArgSize) //TODO: segments + switch(op.size) { - case 8: + case 1: DbgMemRead(value, (unsigned char*)&arg->memvalue, 1); break; - case 16: + case 2: DbgMemRead(value, (unsigned char*)&arg->memvalue, 2); break; - case 32: + case 4: DbgMemRead(value, (unsigned char*)&arg->memvalue, 4); break; - case 64: + case 8: DbgMemRead(value, (unsigned char*)&arg->memvalue, 8); break; } } } - else - { - arg->segment = SEG_DEFAULT; - arg->type = arg_normal; - uint value = 0; - if(!valfromstring(argmnemonic, &value, true, true)) - return false; - arg->value = value; - char sValue[64] = ""; - sprintf(sValue, "%"fext"X", value); - if(_stricmp(argmnemonic, sValue)) - value = 0; - arg->constant = value; - } - return true; -} - -static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg) -{ - const cs_x86 & x86 = cp.GetInstr()->detail->x86; - const cs_x86_op & op = x86.operands[opindex]; - switch(op.type) - { - + break; } } @@ -242,56 +193,26 @@ void disasmget(unsigned char* buffer, uint addr, DISASM_INSTR* instr) } memset(instr, 0, sizeof(DISASM_INSTR)); Capstone cp; - unsigned char buf[MAX_DISASM_BUFFER]; - memcpy(buf, buffer, sizeof(buf)); - if(!cp.Disassemble(addr, buf)) + if(!cp.Disassemble(addr, buffer, MAX_DISASM_BUFFER)) { + strcpy_s(instr->instruction, "???"); instr->instr_size = 1; instr->type = instr_normal; instr->argcount = 0; return; } + sprintf_s(instr->instruction, "%s %s", cp.GetInstr()->mnemonic, cp.GetInstr()->op_str); const cs_x86 & x86 = cp.GetInstr()->detail->x86; instr->instr_size = cp.GetInstr()->size; - if(cp.InGroup(CS_GRP_JUMP)) + if(cp.InGroup(CS_GRP_JUMP) || cp.InGroup(CS_GRP_RET) || cp.InGroup(CS_GRP_CALL)) instr->type = instr_branch; else if(strstr(cp.GetInstr()->op_str, "sp") || strstr(cp.GetInstr()->op_str, "bp")) instr->type = instr_stack; else instr->type = instr_normal; - - - //old code under here - DISASM disasm; - memset(&disasm, 0, sizeof(DISASM)); - disasm.Options = NoformatNumeral | ShowSegmentRegs; -#ifdef _WIN64 - disasm.Archi = 64; -#endif // _WIN64 - disasm.VirtualAddr = addr; - disasm.EIP = (UIntPtr)buffer; - int len = Disasm(&disasm); - strcpy_s(instr->instruction, disasm.CompleteInstr); - if(len == UNKNOWN_OPCODE) - { - instr->instr_size = 1; - instr->type = instr_normal; - instr->argcount = 0; - return; - } - instr->instr_size = len; - if(disasm.Instruction.BranchType) - instr->type = instr_branch; - else if(strstr(disasm.CompleteInstr, "sp") or strstr(disasm.CompleteInstr, "bp")) - instr->type = instr_stack; - else - instr->type = instr_normal; - if(HandleArgument(&disasm.Argument1, &disasm.Instruction, &instr->arg[instr->argcount], addr)) - instr->argcount++; - if(HandleArgument(&disasm.Argument2, &disasm.Instruction, &instr->arg[instr->argcount], addr)) - instr->argcount++; - if(HandleArgument(&disasm.Argument3, &disasm.Instruction, &instr->arg[instr->argcount], addr)) - instr->argcount++; + instr->argcount = cp.x86().op_count <= 3 ? cp.x86().op_count : 3; + for(int i = 0; i < instr->argcount; i++) + HandleCapstoneOperand(cp, i, &instr->arg[i]); } void disasmget(uint addr, DISASM_INSTR* instr) @@ -302,8 +223,8 @@ void disasmget(uint addr, DISASM_INSTR* instr) instr->argcount = 0; return; } - unsigned char buffer[16] = ""; - DbgMemRead(addr, buffer, 16); + unsigned char buffer[MAX_DISASM_BUFFER] = ""; + DbgMemRead(addr, buffer, sizeof(buffer)); disasmget(buffer, addr, instr); } @@ -463,23 +384,15 @@ bool disasmgetstringat(uint addr, STRING_TYPE* type, char* ascii, char* unicode, int disasmgetsize(uint addr, unsigned char* data) { - DISASM disasm; - memset(&disasm, 0, sizeof(DISASM)); - disasm.Options = NoformatNumeral | ShowSegmentRegs; -#ifdef _WIN64 - disasm.Archi = 64; -#endif // _WIN64 - disasm.VirtualAddr = addr; - disasm.EIP = (UIntPtr)data; - int len = Disasm(&disasm); - if(len == UNKNOWN_OPCODE) - len = 1; - return len; + Capstone cp; + if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER)) + return 1; + return cp.Size(); } int disasmgetsize(uint addr) { - char data[16]; + char data[MAX_DISASM_BUFFER]; if(!MemRead((void*)addr, data, sizeof(data), 0)) return 1; return disasmgetsize(addr, (unsigned char*)data); diff --git a/x64_dbg_dbg/instruction.cpp b/x64_dbg_dbg/instruction.cpp index 65bb215f..72f45acc 100644 --- a/x64_dbg_dbg/instruction.cpp +++ b/x64_dbg_dbg/instruction.cpp @@ -1844,7 +1844,7 @@ CMDRESULT cbInstrCapstone(int argc, char* argv[]) } const cs_insn* instr = cp.GetInstr(); - const cs_x86 & x86 = instr->detail->x86; + const cs_x86 & x86 = cp.x86(); int argcount = x86.op_count; dprintf("%s %s\n", instr->mnemonic, instr->op_str); for(int i = 0; i < argcount; i++) diff --git a/x64_dbg_dbg/stackinfo.cpp b/x64_dbg_dbg/stackinfo.cpp index 910a9555..168c9c25 100644 --- a/x64_dbg_dbg/stackinfo.cpp +++ b/x64_dbg_dbg/stackinfo.cpp @@ -9,7 +9,6 @@ #include "memory.h" #include "disasm_helper.h" #include "disasm_fast.h" -#include "BeaEngine\BeaEngine.h" #include "addrinfo.h" #include "_exports.h" #include "module.h"