1
0
Fork 0

Replace Capstone with Zydis

- While at it, added branch info logic to disassembler class
  - Thus reduce direct checks by mnemonic in GUI and analysis code
- Replaced direct disassembler struct access with disassembler class calls where trivially possible
- Removed workarounds for empty segment registers
- Temp. disabled `cbInstrCapstone` command
- Temp. disabled flag stuff in `QBeaEngine`
This commit is contained in:
Joel Höner 2017-09-20 08:17:34 +02:00 committed by Duncan Ogilvie
parent 103866eafe
commit 5338a0a85b
31 changed files with 292 additions and 319 deletions

3
.gitmodules vendored
View File

@ -10,3 +10,6 @@
[submodule "deps"] [submodule "deps"]
path = deps path = deps
url = https://github.com/x64dbg/deps url = https://github.com/x64dbg/deps
[submodule "src/zydis_wrapper"]
path = src/zydis_wrapper
url = https://athre0z@github.com/athre0z/zydis-x64dbg-module.git

View File

@ -1,5 +1,5 @@
#include "TraceRecord.h" #include "TraceRecord.h"
#include "capstone_wrapper.h" #include "zydis_wrapper.h"
#include "module.h" #include "module.h"
#include "memory.h" #include "memory.h"
#include "threading.h" #include "threading.h"

View File

@ -355,9 +355,9 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, BRID
if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label
{ {
auto constant = instr.arg[i].constant; auto constant = instr.arg[i].constant;
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.InGroup(CS_GRP_CALL)) if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsCall())
temp_string.assign("call $0"); temp_string.assign("call $0");
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.InGroup(CS_GRP_JUMP)) else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsJump())
temp_string.assign("jmp $0"); temp_string.assign("jmp $0");
else if(instr.type == instr_branch) else if(instr.type == instr_branch)
continue; continue;
@ -738,77 +738,77 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
Capstone cp; Capstone cp;
if(!cp.Disassemble(addr, data)) if(!cp.Disassemble(addr, data))
return 0; return 0;
if(cp.InGroup(CS_GRP_JUMP) || cp.InGroup(CS_GRP_CALL) || cp.IsLoop()) if(cp.IsBranchType(Capstone::BT_Jmp | Capstone::BT_Call | Capstone::BT_Loop))
{ {
auto opValue = cp.ResolveOpValue(0, [](x86_reg reg) -> size_t auto opValue = cp.ResolveOpValue(0, [](ZydisRegister reg) -> size_t
{ {
switch(reg) switch(reg)
{ {
#ifndef _WIN64 //x32 #ifndef _WIN64 //x32
case X86_REG_EAX: case ZYDIS_REGISTER_EAX:
return titcontext.cax; return titcontext.cax;
case X86_REG_EBX: case ZYDIS_REGISTER_EBX:
return titcontext.cbx; return titcontext.cbx;
case X86_REG_ECX: case ZYDIS_REGISTER_ECX:
return titcontext.ccx; return titcontext.ccx;
case X86_REG_EDX: case ZYDIS_REGISTER_EDX:
return titcontext.cdx; return titcontext.cdx;
case X86_REG_EBP: case ZYDIS_REGISTER_EBP:
return titcontext.cbp; return titcontext.cbp;
case X86_REG_ESP: case ZYDIS_REGISTER_ESP:
return titcontext.csp; return titcontext.csp;
case X86_REG_ESI: case ZYDIS_REGISTER_ESI:
return titcontext.csi; return titcontext.csi;
case X86_REG_EDI: case ZYDIS_REGISTER_EDI:
return titcontext.cdi; return titcontext.cdi;
case X86_REG_EIP: case ZYDIS_REGISTER_EIP:
return titcontext.cip; return titcontext.cip;
#else //x64 #else //x64
case X86_REG_RAX: case ZYDIS_REGISTER_RAX:
return titcontext.cax; return titcontext.cax;
case X86_REG_RBX: case ZYDIS_REGISTER_RBX:
return titcontext.cbx; return titcontext.cbx;
case X86_REG_RCX: case ZYDIS_REGISTER_RCX:
return titcontext.ccx; return titcontext.ccx;
case X86_REG_RDX: case ZYDIS_REGISTER_RDX:
return titcontext.cdx; return titcontext.cdx;
case X86_REG_RBP: case ZYDIS_REGISTER_RBP:
return titcontext.cbp; return titcontext.cbp;
case X86_REG_RSP: case ZYDIS_REGISTER_RSP:
return titcontext.csp; return titcontext.csp;
case X86_REG_RSI: case ZYDIS_REGISTER_RSI:
return titcontext.csi; return titcontext.csi;
case X86_REG_RDI: case ZYDIS_REGISTER_RDI:
return titcontext.cdi; return titcontext.cdi;
case X86_REG_RIP: case ZYDIS_REGISTER_RIP:
return titcontext.cip; return titcontext.cip;
case X86_REG_R8: case ZYDIS_REGISTER_R8:
return titcontext.r8; return titcontext.r8;
case X86_REG_R9: case ZYDIS_REGISTER_R9:
return titcontext.r9; return titcontext.r9;
case X86_REG_R10: case ZYDIS_REGISTER_R10:
return titcontext.r10; return titcontext.r10;
case X86_REG_R11: case ZYDIS_REGISTER_R11:
return titcontext.r11; return titcontext.r11;
case X86_REG_R12: case ZYDIS_REGISTER_R12:
return titcontext.r12; return titcontext.r12;
case X86_REG_R13: case ZYDIS_REGISTER_R13:
return titcontext.r13; return titcontext.r13;
case X86_REG_R14: case ZYDIS_REGISTER_R14:
return titcontext.r14; return titcontext.r14;
case X86_REG_R15: case ZYDIS_REGISTER_R15:
return titcontext.r15; return titcontext.r15;
#endif //_WIN64 #endif //_WIN64
default: default:
return 0; return 0;
} }
}); });
if(cp[0].type == X86_OP_MEM) if(cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
#ifdef _WIN64 #ifdef _WIN64
auto const tebseg = X86_REG_GS; auto const tebseg = ZYDIS_REGISTER_GS;
#else #else
auto const tebseg = X86_REG_FS; auto const tebseg = ZYDIS_REGISTER_FS;
#endif //_WIN64 #endif //_WIN64
if(cp[0].mem.segment == tebseg) if(cp[0].mem.segment == tebseg)
opValue += duint(GetTEBLocation(hActiveThread)); opValue += duint(GetTEBLocation(hActiveThread));
@ -818,7 +818,7 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
else else
return opValue; return opValue;
} }
if(cp.InGroup(CS_GRP_RET)) if(cp.IsRet())
{ {
auto csp = titcontext.csp; auto csp = titcontext.csp;
duint dest = 0; duint dest = 0;

View File

@ -31,16 +31,16 @@ bool CodeFollowPass::Analyse()
return false; return false;
} }
duint CodeFollowPass::GetReferenceOperand(const cs_x86 & Context) duint CodeFollowPass::GetReferenceOperand(const ZydisDecodedInstruction & Context)
{ {
for(int i = 0; i < Context.op_count; i++) for(int i = 0; i < Context.operandCount; i++)
{ {
auto operand = Context.operands[i]; auto operand = Context.operands[i];
// Looking for immediate references // Looking for immediate references
if(operand.type == X86_OP_IMM) if(operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{ {
duint dest = (duint)operand.imm; duint dest = (duint)operand.imm.value.u;
if(ValidateAddress(dest)) if(ValidateAddress(dest))
return dest; return dest;
@ -50,25 +50,25 @@ duint CodeFollowPass::GetReferenceOperand(const cs_x86 & Context)
return 0; return 0;
} }
duint CodeFollowPass::GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context, bool* Indirect) duint CodeFollowPass::GetMemoryOperand(Capstone & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect)
{ {
if(Context.op_count <= 0) if(Context.operandCount <= 0)
return 0; return 0;
// Only the first operand matters // Only the first operand matters
auto operand = Context.operands[0]; auto operand = Context.operands[0];
// Jumps and calls only // Jumps and calls only
if(Disasm.InGroup(CS_GRP_CALL) || Disasm.InGroup(CS_GRP_JUMP)) if(Disasm.IsCall() || Disasm.IsJump())
{ {
// Looking for memory references // Looking for memory references
if(operand.type == X86_OP_MEM) if(operand.type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
// Notify if the operand was indirect // Notify if the operand was indirect
if(Indirect) if(Indirect)
{ {
if(operand.mem.base != X86_REG_INVALID || if(operand.mem.base != ZYDIS_REGISTER_NONE ||
operand.mem.index != X86_REG_INVALID || operand.mem.index != ZYDIS_REGISTER_NONE ||
operand.mem.scale != 0) operand.mem.scale != 0)
{ {
*Indirect = true; *Indirect = true;
@ -81,7 +81,7 @@ duint CodeFollowPass::GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context
// TODO: Translate RIP-Relative // TODO: Translate RIP-Relative
return 0; return 0;
duint dest = (duint)operand.mem.disp; duint dest = (duint)operand.mem.disp.value;
if(ValidateAddress(dest)) if(ValidateAddress(dest))
return dest; return dest;

View File

@ -2,7 +2,7 @@
#include "AnalysisPass.h" #include "AnalysisPass.h"
#include "BasicBlock.h" #include "BasicBlock.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
class CodeFollowPass : public AnalysisPass class CodeFollowPass : public AnalysisPass
{ {
@ -14,6 +14,6 @@ public:
virtual bool Analyse() override; virtual bool Analyse() override;
private: private:
duint GetReferenceOperand(const cs_x86 & Context); duint GetReferenceOperand(const ZydisDecodedInstruction & Context);
duint GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context, bool* Indirect); duint GetMemoryOperand(Capstone & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect);
}; };

View File

@ -2,7 +2,7 @@
#include <ppl.h> #include <ppl.h>
#include "AnalysisPass.h" #include "AnalysisPass.h"
#include "LinearPass.h" #include "LinearPass.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
LinearPass::LinearPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) LinearPass::LinearPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks)
: AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks)
@ -167,9 +167,9 @@ void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks)
insnCount++; insnCount++;
// The basic block ends here if it is a branch // The basic block ends here if it is a branch
bool call = disasm.InGroup(CS_GRP_CALL); // CALL bool call = disasm.IsCall(); // CALL
bool jmp = disasm.InGroup(CS_GRP_JUMP); // JUMP bool jmp = disasm.IsJump(); // JUMP
bool ret = disasm.InGroup(CS_GRP_RET); // RETURN bool ret = disasm.IsRet(); // RETURN
bool padding = disasm.IsFilling(); // INSTRUCTION PADDING bool padding = disasm.IsFilling(); // INSTRUCTION PADDING
if(padding) if(padding)
@ -211,25 +211,25 @@ void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks)
if(!padding) if(!padding)
{ {
// Check if absolute jump, regardless of operand // Check if absolute jump, regardless of operand
if(disasm.GetId() == X86_INS_JMP) if(disasm.GetId() == ZYDIS_MNEMONIC_JMP)
block->SetFlag(BASIC_BLOCK_FLAG_ABSJMP); block->SetFlag(BASIC_BLOCK_FLAG_ABSJMP);
// Figure out the operand type(s) // Figure out the operand type(s)
const auto & operand = disasm.x86().operands[0]; const auto & operand = disasm[0];
if(operand.type == X86_OP_IMM) if(operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{ {
// Branch target immediate // Branch target immediate
block->Target = (duint)operand.imm; block->Target = (duint)operand.imm.value.u;
} }
else else
{ {
// Indirects (no operand, register, or memory) // Indirects (no operand, register, or memory)
block->SetFlag(BASIC_BLOCK_FLAG_INDIRECT); block->SetFlag(BASIC_BLOCK_FLAG_INDIRECT);
if(operand.type == X86_OP_MEM && if(operand.type == ZYDIS_OPERAND_TYPE_MEMORY &&
operand.mem.base == X86_REG_RIP && operand.mem.base == ZYDIS_REGISTER_RIP &&
operand.mem.index == X86_REG_INVALID && operand.mem.index == ZYDIS_REGISTER_NONE &&
operand.mem.scale == 1) operand.mem.scale == 1)
{ {
/* /*

View File

@ -106,11 +106,11 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
for(int i = 1; i < mCp.Size(); i++) for(int i = 1; i < mCp.Size(); i++)
mEncMap[node.end - mBase + i] = (byte)enc_middle; mEncMap[node.end - mBase + i] = (byte)enc_middle;
} }
if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) //jump if(mCp.IsJump() || mCp.IsLoop()) //jump
{ {
//set the branch destinations //set the branch destinations
node.brtrue = mCp.BranchDestination(); node.brtrue = mCp.BranchDestination();
if(mCp.GetId() != X86_INS_JMP) //unconditional jumps dont have a brfalse if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mCp.Size(); node.brfalse = node.end + mCp.Size();
//add node to the function graph //add node to the function graph
@ -124,14 +124,14 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
break; break;
} }
if(mCp.InGroup(CS_GRP_CALL)) //call if(mCp.IsCall()) //call
{ {
//TODO: handle no return //TODO: handle no return
duint target = mCp.BranchDestination(); duint target = mCp.BranchDestination();
if(inRange(target) && mEntryPoints.find(target) == mEntryPoints.end()) if(inRange(target) && mEntryPoints.find(target) == mEntryPoints.end())
mCandidateEPs.insert(target); mCandidateEPs.insert(target);
} }
if(mCp.InGroup(CS_GRP_RET)) //return if(mCp.IsRet()) //return
{ {
node.terminal = true; node.terminal = true;
graph.AddNode(node); graph.AddNode(node);
@ -164,7 +164,7 @@ void AdvancedAnalysis::linearXrefPass()
xref.from = mCp.Address(); xref.from = mCp.Address();
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mCp.OpCount(); i++)
{ {
duint dest = mCp.ResolveOpValue(i, [](x86_reg)->size_t duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
{ {
return 0; return 0;
}); });
@ -176,9 +176,9 @@ void AdvancedAnalysis::linearXrefPass()
} }
if(xref.addr) if(xref.addr)
{ {
if(mCp.InGroup(CS_GRP_CALL)) if(mCp.IsCall())
xref.type = XREF_CALL; xref.type = XREF_CALL;
else if(mCp.InGroup(CS_GRP_JUMP)) else if(mCp.IsJump())
xref.type = XREF_JMP; xref.type = XREF_JMP;
else else
xref.type = XREF_DATA; xref.type = XREF_DATA;
@ -218,21 +218,21 @@ void AdvancedAnalysis::findInvalidXrefs()
} }
} }
bool isFloatInstruction(x86_insn opcode) bool isFloatInstruction(ZydisMnemonic opcode)
{ {
switch(opcode) switch(opcode)
{ {
case X86_INS_FLD: case ZYDIS_MNEMONIC_FLD:
case X86_INS_FST: case ZYDIS_MNEMONIC_FST:
case X86_INS_FSTP: case ZYDIS_MNEMONIC_FSTP:
case X86_INS_FADD: case ZYDIS_MNEMONIC_FADD:
case X86_INS_FSUB: case ZYDIS_MNEMONIC_FSUB:
case X86_INS_FSUBR: case ZYDIS_MNEMONIC_FSUBR:
case X86_INS_FMUL: case ZYDIS_MNEMONIC_FMUL:
case X86_INS_FDIV: case ZYDIS_MNEMONIC_FDIV:
case X86_INS_FDIVR: case ZYDIS_MNEMONIC_FDIVR:
case X86_INS_FCOM: case ZYDIS_MNEMONIC_FCOM:
case X86_INS_FCOMP: case ZYDIS_MNEMONIC_FCOMP:
return true; return true;
default: default:
@ -261,7 +261,7 @@ void AdvancedAnalysis::writeDataXrefs()
ENCODETYPE type = enc_unknown; ENCODETYPE type = enc_unknown;
//Todo: Analyze op type and set correct type //Todo: Analyze op type and set correct type
if(op.type == X86_OP_MEM) if(op.type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
duint datasize = op.size; duint datasize = op.size;
duint size = datasize; duint size = datasize;

View File

@ -2,7 +2,7 @@
#define _ANALYSIS_H #define _ANALYSIS_H
#include "_global.h" #include "_global.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
class Analysis class Analysis
{ {

View File

@ -150,15 +150,15 @@ void ControlFlowAnalysis::BasicBlockStarts()
mBlockStarts.insert(addr); mBlockStarts.insert(addr);
} }
} }
else if(mCp.InGroup(CS_GRP_RET)) //RET breaks control flow else if(mCp.IsRet()) //RET breaks control flow
{ {
bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow) bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow)
} }
else if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) //branches else if(mCp.IsJump() || mCp.IsLoop()) //branches
{ {
auto dest1 = getReferenceOperand(); auto dest1 = getReferenceOperand();
duint dest2 = 0; duint dest2 = 0;
if(mCp.GetId() != X86_INS_JMP) //conditional jump if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump
dest2 = addr + mCp.Size(); dest2 = addr + mCp.Size();
if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted) if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted)
@ -168,7 +168,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
if(dest2) if(dest2)
mBlockStarts.insert(dest2); mBlockStarts.insert(dest2);
} }
else if(mCp.InGroup(CS_GRP_CALL)) else if(mCp.IsCall())
{ {
auto dest1 = getReferenceOperand(); auto dest1 = getReferenceOperand();
if(dest1) if(dest1)
@ -206,15 +206,15 @@ void ControlFlowAnalysis::BasicBlocks()
prevaddr = addr; prevaddr = addr;
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER)) if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
{ {
if(mCp.InGroup(CS_GRP_RET)) if(mCp.IsRet())
{ {
insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block
break; break;
} }
else if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) else if(mCp.IsJump() || mCp.IsLoop())
{ {
auto dest1 = getReferenceOperand(); auto dest1 = getReferenceOperand();
auto dest2 = mCp.GetId() != X86_INS_JMP ? addr + mCp.Size() : 0; auto dest2 = mCp.GetId() != ZYDIS_MNEMONIC_JMP ? addr + mCp.Size() : 0;
insertBlock(BasicBlock(start, addr, dest1, dest2)); insertBlock(BasicBlock(start, addr, dest1, dest2));
insertParent(dest1, start); insertParent(dest1, start);
insertParent(dest2, start); insertParent(dest2, start);
@ -415,17 +415,17 @@ duint ControlFlowAnalysis::getReferenceOperand() const
{ {
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mCp.OpCount(); i++)
{ {
const auto & op = mCp.x86().operands[i]; const auto & op = mCp[i];
if(op.type == X86_OP_IMM) if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{ {
auto dest = duint(op.imm); auto dest = duint(op.imm.value.u);
if(inRange(dest)) if(inRange(dest))
return dest; return dest;
} }
else if(op.type == X86_OP_MEM) else if(op.type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
auto dest = duint(op.mem.disp); auto dest = duint(op.mem.disp.value);
if(op.mem.base == X86_REG_RIP) //rip-relative if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative
dest += mCp.Address() + mCp.Size(); dest += mCp.Address() + mCp.Size();
if(inRange(dest)) if(inRange(dest))
return dest; return dest;

View File

@ -86,7 +86,7 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
if(mCp.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER)) if(mCp.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
{ {
//JMP [123456] ; import //JMP [123456] ; import
if(mCp.InGroup(CS_GRP_JUMP) && mCp.x86().operands[0].type == X86_OP_MEM) if(mCp.IsJump() && mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
return 0; return 0;
} }
@ -100,10 +100,10 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
if(addr + mCp.Size() > maxaddr) //we went past the maximum allowed address if(addr + mCp.Size() > maxaddr) //we went past the maximum allowed address
break; break;
const auto & op = mCp.x86().operands[0]; const auto & op = mCp[0];
if((mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) && op.type == X86_OP_IMM) //jump if((mCp.IsJump() || mCp.IsLoop()) && op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
{ {
auto dest = duint(op.imm); auto dest = duint(op.imm.value.u);
if(dest >= maxaddr) //jump across function boundaries if(dest >= maxaddr) //jump across function boundaries
{ {
@ -113,12 +113,12 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
{ {
fardest = dest; fardest = dest;
} }
else if(end && dest < end && (mCp.GetId() == X86_INS_JMP || mCp.GetId() == X86_INS_LOOP)) //save the last JMP backwards else if(end && dest < end && (mCp.GetId() == ZYDIS_MNEMONIC_JMP || mCp.GetId() == ZYDIS_MNEMONIC_LOOP)) //save the last JMP backwards
{ {
jumpback = addr; jumpback = addr;
} }
} }
else if(mCp.InGroup(CS_GRP_RET)) //possible function end? else if(mCp.IsRet()) //possible function end?
{ {
end = addr; end = addr;
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
@ -137,12 +137,12 @@ duint LinearAnalysis::getReferenceOperand() const
{ {
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mCp.OpCount(); i++)
{ {
const auto & op = mCp.x86().operands[i]; const auto & op = mCp[i];
if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) //skip jumps/loops if(mCp.IsJump() || mCp.IsLoop()) //skip jumps/loops
continue; continue;
if(op.type == X86_OP_IMM) //we are looking for immediate references if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //we are looking for immediate references
{ {
auto dest = duint(op.imm); auto dest = duint(op.imm.value.u);
if(inRange(dest)) if(inRange(dest))
return dest; return dest;
} }

View File

@ -103,7 +103,7 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
xref.from = mCp.Address(); xref.from = mCp.Address();
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mCp.OpCount(); i++)
{ {
duint dest = mCp.ResolveOpValue(i, [](x86_reg)->size_t duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
{ {
return 0; return 0;
}); });
@ -116,23 +116,23 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
if(xref.addr) if(xref.addr)
mXrefs.push_back(xref); mXrefs.push_back(xref);
if(!mCp.IsNop() && (mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop())) //non-nop jump if(!mCp.IsNop() && (mCp.IsJump() || mCp.IsLoop())) //non-nop jump
{ {
//set the branch destinations //set the branch destinations
node.brtrue = mCp.BranchDestination(); node.brtrue = mCp.BranchDestination();
if(mCp.GetId() != X86_INS_JMP && mCp.GetId() != X86_INS_LJMP) //unconditional jumps dont have a brfalse if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
node.brfalse = node.end + mCp.Size(); node.brfalse = node.end + mCp.Size();
//consider register/memory branches as terminal nodes //consider register/memory branches as terminal nodes
if(mCp[0].type != X86_OP_IMM) if(mCp[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
{ {
//jmp ptr [index * sizeof(duint) + switchTable] //jmp ptr [index * sizeof(duint) + switchTable]
if(mCp[0].type == X86_OP_MEM && mCp[0].mem.base == X86_OP_INVALID && mCp[0].mem.index != X86_OP_INVALID if(mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY && mCp[0].mem.base == ZYDIS_REGISTER_NONE && mCp[0].mem.index != ZYDIS_REGISTER_NONE
&& mCp[0].mem.scale == sizeof(duint) && MemIsValidReadPtr(duint(mCp[0].mem.disp))) && mCp[0].mem.scale == sizeof(duint) && MemIsValidReadPtr(duint(mCp[0].mem.disp.value)))
{ {
Memory<duint*> switchTable(512 * sizeof(duint)); Memory<duint*> switchTable(512 * sizeof(duint));
duint actualSize, index; duint actualSize, index;
MemRead(duint(mCp[0].mem.disp), switchTable(), 512 * sizeof(duint), &actualSize); MemRead(duint(mCp[0].mem.disp.value), switchTable(), 512 * sizeof(duint), &actualSize);
actualSize /= sizeof(duint); actualSize /= sizeof(duint);
for(index = 0; index < actualSize; index++) for(index = 0; index < actualSize; index++)
if(MemIsCodePage(switchTable()[index], false) == false) if(MemIsCodePage(switchTable()[index], false) == false)
@ -168,11 +168,11 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
break; break;
} }
if(mCp.InGroup(CS_GRP_CALL)) //call if(mCp.IsCall())
{ {
//TODO: add this to a queue to be analyzed later //TODO: add this to a queue to be analyzed later
} }
if(mCp.InGroup(CS_GRP_RET)) //return if(mCp.IsRet())
{ {
node.terminal = true; node.terminal = true;
graph.AddNode(node); graph.AddNode(node);
@ -224,17 +224,17 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
while(addr <= node.end) //disassemble all instructions while(addr <= node.end) //disassemble all instructions
{ {
auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1; auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1;
if(mCp.InGroup(CS_GRP_CALL) && mCp.OpCount()) //call reg / call [reg+X] if(mCp.IsCall() && mCp.OpCount()) //call reg / call [reg+X]
{ {
auto & op = mCp[0]; auto & op = mCp[0];
switch(op.type) switch(op.type)
{ {
case X86_OP_REG: case ZYDIS_OPERAND_TYPE_REGISTER:
node.indirectcall = true; node.indirectcall = true;
break; break;
case X86_OP_MEM: case ZYDIS_OPERAND_TYPE_MEMORY:
node.indirectcall |= op.mem.base != X86_REG_RIP && node.indirectcall |= op.mem.base != ZYDIS_REGISTER_RIP &&
(op.mem.base != X86_REG_INVALID || op.mem.index != X86_REG_INVALID); (op.mem.base != ZYDIS_REGISTER_NONE || op.mem.index != ZYDIS_REGISTER_NONE);
break; break;
default: default:
break; break;

View File

@ -21,7 +21,7 @@ void XrefsAnalysis::Analyse()
xref.from = mCp.Address(); xref.from = mCp.Address();
for(auto i = 0; i < mCp.OpCount(); i++) for(auto i = 0; i < mCp.OpCount(); i++)
{ {
duint dest = mCp.ResolveOpValue(i, [](x86_reg)->size_t duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
{ {
return 0; return 0;
}); });

View File

@ -570,8 +570,8 @@ static bool cbModCallFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, R
} }
switch(disasm->GetId()) switch(disasm->GetId())
{ {
case X86_INS_CALL: //call dword ptr: [&api] case ZYDIS_MNEMONIC_CALL: //call dword ptr: [&api]
case X86_INS_MOV: //mov reg, dword ptr:[&api] case ZYDIS_MNEMONIC_MOV: //mov reg, dword ptr:[&api]
if(!foundaddr && basicinfo->memory.value) if(!foundaddr && basicinfo->memory.value)
{ {
duint memaddr; duint memaddr;

View File

@ -7,7 +7,7 @@
#include "debugger.h" #include "debugger.h"
#include "variable.h" #include "variable.h"
#include "loop.h" #include "loop.h"
#include "capstone_wrapper.h" #include "zydis_wrapper.h"
#include "mnemonichelp.h" #include "mnemonichelp.h"
#include "value.h" #include "value.h"
#include "symbolinfo.h" #include "symbolinfo.h"
@ -209,6 +209,9 @@ bool cbInstrCopystr(int argc, char* argv[])
bool cbInstrCapstone(int argc, char* argv[]) bool cbInstrCapstone(int argc, char* argv[])
{ {
return false;
/*
if(IsArgumentsLessThan(argc, 2)) if(IsArgumentsLessThan(argc, 2))
return false; return false;
@ -237,10 +240,8 @@ bool cbInstrCapstone(int argc, char* argv[])
return false; return false;
} }
const cs_insn* instr = cp.GetInstr(); auto instr = cp.GetInstr();
const cs_detail* detail = instr->detail; int argcount = instr->operandCount;
const cs_x86 & x86 = cp.x86();
int argcount = x86.op_count;
dprintf_untranslated("%s %s | %s\n", instr->mnemonic, instr->op_str, cp.InstructionText(true).c_str()); dprintf_untranslated("%s %s | %s\n", instr->mnemonic, instr->op_str, cp.InstructionText(true).c_str());
dprintf_untranslated("size: %d, id: %d, opcount: %d\n", cp.Size(), cp.GetId(), cp.OpCount()); dprintf_untranslated("size: %d, id: %d, opcount: %d\n", cp.Size(), cp.GetId(), cp.OpCount());
if(detail->regs_read_count) if(detail->regs_read_count)
@ -301,6 +302,7 @@ bool cbInstrCapstone(int argc, char* argv[])
} }
return true; return true;
*/
} }
bool cbInstrVisualize(int argc, char* argv[]) bool cbInstrVisualize(int argc, char* argv[])
@ -357,10 +359,10 @@ bool cbInstrVisualize(int argc, char* argv[])
if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address
break; break;
const cs_x86_op & operand = _cp.x86().operands[0]; const auto & operand = _cp[0];
if((_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) && operand.type == X86_OP_IMM) //jump if((_cp.IsJump() || _cp.IsLoop()) && operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
{ {
duint dest = (duint)operand.imm; duint dest = (duint)operand.imm.value.u;
if(dest >= maxaddr) //jump across function boundaries if(dest >= maxaddr) //jump across function boundaries
{ {
@ -370,12 +372,12 @@ bool cbInstrVisualize(int argc, char* argv[])
{ {
fardest = dest; fardest = dest;
} }
else if(end && dest < end && _cp.GetId() == X86_INS_JMP) //save the last JMP backwards else if(end && dest < end && _cp.GetId() == ZYDIS_MNEMONIC_JMP) //save the last JMP backwards
{ {
jumpback = addr; jumpback = addr;
} }
} }
else if(_cp.InGroup(CS_GRP_RET)) //possible function end? else if(_cp.IsRet()) //possible function end?
{ {
end = addr; end = addr;
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET

View File

@ -2,7 +2,7 @@
#include "encodemap.h" #include "encodemap.h"
#include "stringutils.h" #include "stringutils.h"
#include "value.h" #include "value.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
#include <algorithm> #include <algorithm>
std::unordered_map<ENCODETYPE, std::string> disasmMap; std::unordered_map<ENCODETYPE, std::string> disasmMap;

View File

@ -27,7 +27,7 @@
#include "taskthread.h" #include "taskthread.h"
#include "animate.h" #include "animate.h"
#include "simplescript.h" #include "simplescript.h"
#include "capstone_wrapper.h" #include "zydis_wrapper.h"
#include "cmd-watch-control.h" #include "cmd-watch-control.h"
#include "filemap.h" #include "filemap.h"
#include "jit.h" #include "jit.h"
@ -1164,7 +1164,7 @@ void cbRtrStep()
unsigned char data[MAX_DISASM_BUFFER]; unsigned char data[MAX_DISASM_BUFFER];
memset(data, 0, sizeof(data)); memset(data, 0, sizeof(data));
MemRead(cip, data, MAX_DISASM_BUFFER); MemRead(cip, data, MAX_DISASM_BUFFER);
if(cp.Disassemble(cip, data) && cp.GetId() == X86_INS_RET) if(cp.Disassemble(cip, data) && cp.IsRet())
cbRtrFinalStep(true); cbRtrFinalStep(true);
else else
StepOver((void*)cbRtrStep); StepOver((void*)cbRtrStep);

View File

@ -34,53 +34,53 @@ void fillbasicinfo(Capstone* cp, BASIC_INSTRUCTION_INFO* basicinfo, bool instrTe
//instruction size //instruction size
basicinfo->size = cp->Size(); basicinfo->size = cp->Size();
//branch/call info //branch/call info
if(cp->InGroup(CS_GRP_CALL)) if(cp->IsCall())
{ {
basicinfo->branch = true; basicinfo->branch = true;
basicinfo->call = true; basicinfo->call = true;
} }
else if(cp->InGroup(CS_GRP_JUMP) || cp->IsLoop()) else if(cp->IsJump() || cp->IsLoop())
{ {
basicinfo->branch = true; basicinfo->branch = true;
} }
//handle operands //handle operands
for(int i = 0; i < cp->x86().op_count; i++) for(int i = 0; i < cp->OpCount(); i++)
{ {
const cs_x86_op & op = cp->x86().operands[i]; const auto & op = (*cp)[i];
switch(op.type) switch(op.type)
{ {
case X86_OP_IMM: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
{ {
if(basicinfo->branch) if(basicinfo->branch)
{ {
basicinfo->type |= TYPE_ADDR; basicinfo->type |= TYPE_ADDR;
basicinfo->addr = duint(op.imm); basicinfo->addr = duint(op.imm.value.u);
basicinfo->value.value = duint(op.imm); basicinfo->value.value = duint(op.imm.value.u);
} }
else else
{ {
basicinfo->type |= TYPE_VALUE; basicinfo->type |= TYPE_VALUE;
basicinfo->value.size = VALUE_SIZE(op.size); basicinfo->value.size = VALUE_SIZE(op.size);
basicinfo->value.value = duint(op.imm); basicinfo->value.value = duint(op.imm.value.u);
} }
} }
break; break;
case X86_OP_MEM: case ZYDIS_OPERAND_TYPE_MEMORY:
{ {
const x86_op_mem & mem = op.mem; const auto & mem = op.mem;
if(instrText) if(instrText)
strcpy_s(basicinfo->memory.mnemonic, cp->OperandText(i).c_str()); strcpy_s(basicinfo->memory.mnemonic, cp->OperandText(i).c_str());
basicinfo->memory.size = MEMORY_SIZE(op.size); basicinfo->memory.size = MEMORY_SIZE(op.size);
if(op.mem.base == X86_REG_RIP) //rip-relative if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative
{ {
basicinfo->memory.value = ULONG_PTR(cp->Address() + op.mem.disp + basicinfo->size); basicinfo->memory.value = ULONG_PTR(cp->Address() + op.mem.disp.value + basicinfo->size);
basicinfo->type |= TYPE_MEMORY; basicinfo->type |= TYPE_MEMORY;
} }
else if(mem.disp) else if(mem.disp.value)
{ {
basicinfo->type |= TYPE_MEMORY; basicinfo->type |= TYPE_MEMORY;
basicinfo->memory.value = ULONG_PTR(mem.disp); basicinfo->memory.value = ULONG_PTR(mem.disp.value);
} }
} }
break; break;

View File

@ -2,7 +2,7 @@
#define _DISASM_FAST_H #define _DISASM_FAST_H
#include "_global.h" #include "_global.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
void fillbasicinfo(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, bool instrText = true); void fillbasicinfo(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, bool instrText = true);
bool disasmfast(duint addr, BASIC_INSTRUCTION_INFO* basicinfo, bool cache = false); bool disasmfast(duint addr, BASIC_INSTRUCTION_INFO* basicinfo, bool cache = false);

View File

@ -11,7 +11,7 @@
#include "debugger.h" #include "debugger.h"
#include "value.h" #include "value.h"
#include "encodemap.h" #include "encodemap.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
#include "datainst_helper.h" #include "datainst_helper.h"
duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n) duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n)
@ -113,7 +113,7 @@ duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n)
static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg, bool getregs) static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg, bool getregs)
{ {
auto value = cp.ResolveOpValue(opindex, [&cp, getregs](x86_reg reg) auto value = cp.ResolveOpValue(opindex, [&cp, getregs](ZydisRegister reg)
{ {
auto regName = getregs ? cp.RegName(reg) : nullptr; auto regName = getregs ? cp.RegName(reg) : nullptr;
return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching
@ -123,34 +123,34 @@ static void HandleCapstoneOperand(Capstone & cp, int opindex, DISASM_ARG* arg, b
strcpy_s(arg->mnemonic, cp.OperandText(opindex).c_str()); strcpy_s(arg->mnemonic, cp.OperandText(opindex).c_str());
switch(op.type) switch(op.type)
{ {
case X86_OP_REG: case ZYDIS_OPERAND_TYPE_REGISTER:
{ {
arg->type = arg_normal; arg->type = arg_normal;
arg->value = value; arg->value = value;
} }
break; break;
case X86_OP_IMM: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
{ {
arg->type = arg_normal; arg->type = arg_normal;
arg->constant = arg->value = value; arg->constant = arg->value = value;
} }
break; break;
case X86_OP_MEM: case ZYDIS_OPERAND_TYPE_MEMORY:
{ {
arg->type = arg_memory; arg->type = arg_memory;
const x86_op_mem & mem = op.mem; const auto & mem = op.mem;
if(mem.base == X86_REG_RIP) //rip-relative if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative
arg->constant = cp.Address() + duint(mem.disp) + cp.Size(); arg->constant = cp.Address() + duint(mem.disp.value) + cp.Size();
else else
arg->constant = duint(mem.disp); arg->constant = duint(mem.disp.value);
#ifdef _WIN64 #ifdef _WIN64
if(mem.segment == X86_REG_GS) if(mem.segment == ZYDIS_REGISTER_GS)
{ {
arg->segment = SEG_GS; arg->segment = SEG_GS;
#else //x86 #else //x86
if(mem.segment == X86_REG_FS) if(mem.segment == ZYDIS_REGISTER_FS)
{ {
arg->segment = SEG_FS; arg->segment = SEG_FS;
#endif #endif
@ -199,16 +199,16 @@ void disasmget(Capstone & cp, unsigned char* buffer, duint addr, DISASM_INSTR* i
instr->argcount = 0; instr->argcount = 0;
return; return;
} }
const cs_insn* cpInstr = cp.GetInstr(); auto cpInstr = cp.GetInstr();
sprintf_s(instr->instruction, "%s %s", cpInstr->mnemonic, cpInstr->op_str); strcpy_s(instr->instruction, cp.InstructionText().c_str());
instr->instr_size = cpInstr->size; instr->instr_size = cpInstr->length;
if(cp.InGroup(CS_GRP_JUMP) || cp.IsLoop() || cp.InGroup(CS_GRP_RET) || cp.InGroup(CS_GRP_CALL)) if(cp.IsBranchType(Capstone::BT_Jmp | Capstone::BT_Loop | Capstone::BT_Ret | Capstone::BT_Call))
instr->type = instr_branch; instr->type = instr_branch;
else if(strstr(cpInstr->op_str, "sp") || strstr(cpInstr->op_str, "bp")) else if(strstr(instr->instruction, "sp") || strstr(instr->instruction, "bp"))
instr->type = instr_stack; instr->type = instr_stack;
else else
instr->type = instr_normal; instr->type = instr_normal;
instr->argcount = cp.x86().op_count <= 3 ? cp.x86().op_count : 3; instr->argcount = cp.OpCount() <= 3 ? cp.OpCount() : 3;
for(int i = 0; i < instr->argcount; i++) for(int i = 0; i < instr->argcount; i++)
HandleCapstoneOperand(cp, i, &instr->arg[i], getregs); HandleCapstoneOperand(cp, i, &instr->arg[i], getregs);
} }

View File

@ -2,7 +2,7 @@
#define _DISASM_HELPER_H #define _DISASM_HELPER_H
#include "_global.h" #include "_global.h"
#include "capstone_wrapper.h" #include "zydis_wrapper.h"
//functions //functions
duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n); duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n);

View File

@ -1,7 +1,7 @@
#include "encodemap.h" #include "encodemap.h"
#include <unordered_map> #include <unordered_map>
#include "addrinfo.h" #include "addrinfo.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
struct ENCODEMAP : AddrInfo struct ENCODEMAP : AddrInfo
{ {

View File

@ -16,7 +16,7 @@
#include "watch.h" #include "watch.h"
#include "plugin_loader.h" #include "plugin_loader.h"
#include "_dbgfunctions.h" #include "_dbgfunctions.h"
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
#include "_scriptapi_gui.h" #include "_scriptapi_gui.h"
#include "filehelper.h" #include "filehelper.h"
#include "database.h" #include "database.h"

View File

@ -389,13 +389,13 @@
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\x64\</OutDir> <OutDir>$(ProjectDir)..\..\bin\x64\</OutDir>
<TargetName>x64dbg</TargetName> <TargetName>x64dbg</TargetName>
<IncludePath>$(ProjectDir)..\capstone_wrapper;$(ProjectDir);$(ProjectDir)analysis;$(ProjectDir)commands;$(IncludePath)</IncludePath> <IncludePath>$(ProjectDir)..\zydis_wrapper;$(ProjectDir)..\capstone_wrapper;$(ProjectDir);$(ProjectDir)analysis;$(ProjectDir)commands;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\x64d\</OutDir> <OutDir>$(ProjectDir)..\..\bin\x64d\</OutDir>
<TargetName>x64dbg</TargetName> <TargetName>x64dbg</TargetName>
<IncludePath>$(ProjectDir)..\capstone_wrapper;$(ProjectDir);$(ProjectDir)analysis;$(ProjectDir)commands;$(IncludePath)</IncludePath> <IncludePath>$(ProjectDir)..\zydis_wrapper;$(ProjectDir)..\capstone_wrapper;$(ProjectDir);$(ProjectDir)analysis;$(ProjectDir)commands;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
@ -467,7 +467,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>ntdll\ntdll_x64.lib;keystone\keystone_x64.lib;$(ProjectDir)..\capstone_wrapper\bin\x64\capstone_wrapper.lib;$(ProjectDir)..\capstone_wrapper\capstone\capstone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;ws2_32.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>$(ProjectDir)..\zydis_wrapper\bin\x64\zydis_wrapper.lib;$(ProjectDir)..\zydis_wrapper\Zydis\Zydis_x64.lib;$(ProjectDir)..\capstone_wrapper\bin\x64\capstone_wrapper.lib;$(ProjectDir)..\capstone_wrapper\capstone\capstone_x64.lib;ntdll\ntdll_x64.lib;keystone\keystone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;ws2_32.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -491,7 +491,7 @@
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>false</EnableCOMDATFolding> <EnableCOMDATFolding>false</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences> <OptimizeReferences>false</OptimizeReferences>
<AdditionalDependencies>ntdll\ntdll_x64.lib;keystone\keystone_x64.lib;$(ProjectDir)..\capstone_wrapper\bin\x64d\capstone_wrapper.lib;$(ProjectDir)..\capstone_wrapper\capstone\capstone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64d\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;ws2_32.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>$(ProjectDir)..\zydis_wrapper\bin\x64d\zydis_wrapper.lib;$(ProjectDir)..\zydis_wrapper\Zydis\Zydis_x64.lib;$(ProjectDir)..\capstone_wrapper\bin\x64d\capstone_wrapper.lib;$(ProjectDir)..\capstone_wrapper\capstone\capstone_x64.lib;ntdll\ntdll_x64.lib;keystone\keystone_x64.lib;yara\yara_x64.lib;lz4\lz4_x64.lib;jansson\jansson_x64.lib;DeviceNameResolver\DeviceNameResolver_x64.lib;XEDParse\XEDParse_x64.lib;$(SolutionDir)bin\x64d\x64bridge.lib;dbghelp\dbghelp_x64.lib;TitanEngine\TitanEngine_x64.lib;ws2_32.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -200,23 +200,15 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
auto branchType = Instruction_t::None; auto branchType = Instruction_t::None;
Instruction_t wInst; Instruction_t wInst;
if(success && (cp.InGroup(CS_GRP_JUMP) || cp.IsLoop() || cp.InGroup(CS_GRP_CALL) || cp.InGroup(CS_GRP_RET))) if(success && (cp.IsBranchType(Capstone::BT_Jmp | Capstone::BT_Call | Capstone::BT_Ret | Capstone::BT_Loop)))
{ {
wInst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA); wInst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA);
switch(cp.GetId()) if(cp.IsBranchType(Capstone::BT_UncondJmp))
{
case X86_INS_JMP:
case X86_INS_LJMP:
branchType = Instruction_t::Unconditional; branchType = Instruction_t::Unconditional;
break; else if(cp.IsBranchType(Capstone::BT_Call))
case X86_INS_CALL:
case X86_INS_LCALL:
branchType = Instruction_t::Call; branchType = Instruction_t::Call;
break; else if(cp.IsBranchType(Capstone::BT_CondJmp))
default: branchType = Instruction_t::Conditional;
branchType = cp.InGroup(CS_GRP_RET) ? Instruction_t::None : Instruction_t::Conditional;
break;
}
} }
else else
wInst.branchDestination = 0; wInst.branchDestination = 0;
@ -233,8 +225,9 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
if(success) if(success)
{ {
/* TODO
auto instr = cp.GetInstr();
cp.RegInfo(reginfo); cp.RegInfo(reginfo);
cp.FlagInfo(flaginfo);
auto flaginfo2reginfo = [](uint8_t info) auto flaginfo2reginfo = [](uint8_t info)
{ {
@ -253,14 +246,15 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
for(uint8_t i = Capstone::FLAG_INVALID; i < Capstone::FLAG_ENDING; i++) for(uint8_t i = Capstone::FLAG_INVALID; i < Capstone::FLAG_ENDING; i++)
if(flaginfo[i]) if(flaginfo[i])
{ {
reginfo[X86_REG_EFLAGS] = Capstone::None; reginfo[ZYDIS_REGISTER_FLAGS] = Capstone::None;
wInst.regsReferenced.push_back({cp.FlagName(Capstone::Flag(i)), flaginfo2reginfo(flaginfo[i])}); wInst.regsReferenced.push_back({cp.FlagName(Capstone::Flag(i)), flaginfo2reginfo(flaginfo[i])});
} }
reginfo[ArchValue(X86_REG_EIP, X86_REG_RIP)] = Capstone::None; reginfo[ArchValue(ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_RIP)] = Capstone::None;
for(uint8_t i = X86_REG_INVALID; i < X86_REG_ENDING; i++) for(uint8_t i = ZYDIS_REGISTER_NONE; i < ZYDIS_REGISTER_ENUM_COUNT; i++)
if(reginfo[i]) if(reginfo[i])
wInst.regsReferenced.push_back({cp.RegName(x86_reg(i)), reginfo[i]}); wInst.regsReferenced.push_back({cp.RegName(x86_reg(i)), reginfo[i]});
*/
} }
return wInst; return wInst;

View File

@ -67,8 +67,8 @@ private:
bool _bLongDataInst; bool _bLongDataInst;
EncodeMap* mEncodeMap; EncodeMap* mEncodeMap;
CodeFoldingHelper* mCodeFoldingManager; CodeFoldingHelper* mCodeFoldingManager;
uint8_t reginfo[X86_REG_ENDING]; uint8_t reginfo[ZYDIS_REGISTER_ENUM_COUNT];
uint8_t flaginfo[Capstone::FLAG_ENDING]; uint8_t flaginfo[ZYDIS_CPUFLAG_ENUM_COUNT];
}; };
#endif // QBEAENGINE_H #endif // QBEAENGINE_H

View File

@ -362,21 +362,26 @@ bool CapstoneTokenizer::tokenizePrefix()
{ {
bool hasPrefix = true; bool hasPrefix = true;
QString prefixText; QString prefixText;
//TODO: look at multiple prefixes on one instruction (https://github.com/aquynh/capstone/blob/921904888d7c1547c558db3a24fa64bcf97dede4/arch/X86/X86DisassemblerDecoder.c#L540)
switch(_cp.x86().prefix[0]) //TODO: look at multiple prefixes on one instruction
{ auto attr = _cp.GetInstr()->attributes;
case X86_PREFIX_LOCK:
if(attr & ZYDIS_ATTRIB_HAS_LOCK)
prefixText = "lock"; prefixText = "lock";
break; else if(attr & ZYDIS_ATTRIB_HAS_REP)
case X86_PREFIX_REP:
prefixText = "rep"; prefixText = "rep";
break; else if(attr & ZYDIS_ATTRIB_HAS_REPNE)
case X86_PREFIX_REPNE: prefixText = "repe";
else if(attr & ZYDIS_ATTRIB_HAS_REPNE)
prefixText = "repne"; prefixText = "repne";
break; else if(attr & ZYDIS_ATTRIB_HAS_BOUND)
default: prefixText = "bnd";
else if(attr & ZYDIS_ATTRIB_HAS_XACQUIRE)
prefixText = "xacquire";
else if(attr & ZYDIS_ATTRIB_HAS_XRELEASE)
prefixText = "xrelease";
else
hasPrefix = false; hasPrefix = false;
}
if(hasPrefix) if(hasPrefix)
{ {
@ -391,52 +396,25 @@ bool CapstoneTokenizer::tokenizeMnemonic()
{ {
QString mnemonic = QString(_cp.Mnemonic().c_str()); QString mnemonic = QString(_cp.Mnemonic().c_str());
_mnemonicType = TokenType::MnemonicNormal; _mnemonicType = TokenType::MnemonicNormal;
auto id = _cp.GetId(); auto id = _cp.GetId();
if(isNop) if(isNop)
_mnemonicType = TokenType::MnemonicNop; _mnemonicType = TokenType::MnemonicNop;
else if(_cp.InGroup(CS_GRP_CALL)) else if(_cp.IsCall())
_mnemonicType = TokenType::MnemonicCall; _mnemonicType = TokenType::MnemonicCall;
else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) else if(_cp.IsJump() || _cp.IsLoop())
{ {
switch(id) _mnemonicType = (id == ZYDIS_MNEMONIC_JMP) ?
{ TokenType::MnemonicUncondJump : TokenType::MnemonicCondJump;
case X86_INS_JMP:
case X86_INS_LJMP:
_mnemonicType = TokenType::MnemonicUncondJump;
break;
default:
_mnemonicType = TokenType::MnemonicCondJump;
break;
}
} }
else if(_cp.IsInt3()) else if(_cp.IsInt3())
_mnemonicType = TokenType::MnemonicInt3; _mnemonicType = TokenType::MnemonicInt3;
else if(_cp.IsUnusual()) else if(_cp.IsUnusual())
_mnemonicType = TokenType::MnemonicUnusual; _mnemonicType = TokenType::MnemonicUnusual;
else if(_cp.InGroup(CS_GRP_RET)) else if(_cp.IsRet())
_mnemonicType = TokenType::MnemonicRet; _mnemonicType = TokenType::MnemonicRet;
else else if(_cp.IsPushPop())
{
switch(id)
{
case X86_INS_PUSH:
case X86_INS_PUSHF:
case X86_INS_PUSHFD:
case X86_INS_PUSHFQ:
case X86_INS_PUSHAL:
case X86_INS_PUSHAW:
case X86_INS_POP:
case X86_INS_POPF:
case X86_INS_POPFD:
case X86_INS_POPFQ:
case X86_INS_POPAL:
case X86_INS_POPAW:
_mnemonicType = TokenType::MnemonicPushPop; _mnemonicType = TokenType::MnemonicPushPop;
break;
default:
break;
}
}
tokenizeMnemonic(_mnemonicType, mnemonic); tokenizeMnemonic(_mnemonicType, mnemonic);
@ -459,57 +437,65 @@ bool CapstoneTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemoni
return true; return true;
} }
bool CapstoneTokenizer::tokenizeOperand(const cs_x86_op & op) bool CapstoneTokenizer::tokenizeOperand(const ZydisDecodedOperand & op)
{ {
switch(op.type) switch(op.type)
{ {
case X86_OP_REG: case ZYDIS_OPERAND_TYPE_REGISTER:
return tokenizeRegOperand(op); return tokenizeRegOperand(op);
case X86_OP_IMM: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
return tokenizeImmOperand(op); return tokenizeImmOperand(op);
case X86_OP_MEM: case ZYDIS_OPERAND_TYPE_MEMORY:
return tokenizeMemOperand(op); return tokenizeMemOperand(op);
case X86_OP_INVALID: case ZYDIS_OPERAND_TYPE_UNUSED:
return tokenizeInvalidOperand(op); return tokenizeInvalidOperand(op);
default: default:
return false; return false;
} }
} }
bool CapstoneTokenizer::tokenizeRegOperand(const cs_x86_op & op) bool CapstoneTokenizer::tokenizeRegOperand(const ZydisDecodedOperand & op)
{ {
auto registerType = TokenType::GeneralRegister; auto registerType = TokenType::GeneralRegister;
auto reg = op.reg; auto reg = op.reg;
if(reg >= X86_REG_FP0 && reg <= X86_REG_FP7) auto regClass = ZydisRegisterGetClass(reg);
registerType = TokenType::FpuRegister;
else if(reg >= X86_REG_ST0 && reg <= X86_REG_ST7) switch(regClass)
registerType = TokenType::FpuRegister; {
else if(reg >= X86_REG_MM0 && reg <= X86_REG_MM7) case ZYDIS_REGCLASS_X87: registerType = TokenType::FpuRegister; break;
registerType = TokenType::MmxRegister; case ZYDIS_REGCLASS_MMX: registerType = TokenType::MmxRegister; break;
else if(reg >= X86_REG_XMM0 && reg <= X86_REG_XMM31) case ZYDIS_REGCLASS_XMM: registerType = TokenType::XmmRegister; break;
registerType = TokenType::XmmRegister; case ZYDIS_REGCLASS_YMM: registerType = TokenType::YmmRegister; break;
else if(reg >= X86_REG_YMM0 && reg <= X86_REG_YMM31) case ZYDIS_REGCLASS_ZMM: registerType = TokenType::ZmmRegister; break;
registerType = TokenType::YmmRegister; }
else if(reg >= X86_REG_ZMM0 && reg <= X86_REG_ZMM31)
registerType = TokenType::ZmmRegister; if(reg == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS))
else if(reg == ArchValue(X86_REG_FS, X86_REG_GS))
registerType = TokenType::MnemonicUnusual; registerType = TokenType::MnemonicUnusual;
addToken(registerType, _cp.RegName(reg)); addToken(registerType, _cp.RegName(reg));
return true; return true;
} }
bool CapstoneTokenizer::tokenizeImmOperand(const cs_x86_op & op) bool CapstoneTokenizer::tokenizeImmOperand(const ZydisDecodedOperand & op)
{ {
auto value = duint(op.imm) & (duint(-1) >> (op.size ? 8 * (sizeof(duint) - op.size) : 0)); duint value;
auto valueType = TokenType::Value; TokenType valueType;
if(_cp.InGroup(CS_GRP_JUMP) || _cp.InGroup(CS_GRP_CALL) || _cp.IsLoop()) if(_cp.IsBranchType(Capstone::BT_Jmp | Capstone::BT_Call | Capstone::BT_Loop))
{
value = _cp.BranchDestination();
valueType = TokenType::Address; valueType = TokenType::Address;
}
else
{
value = duint(op.imm.value.u) & (duint(-1) >> (op.size ? (8 * sizeof(duint) - op.size) : 0));
valueType = TokenType::Value;
}
auto tokenValue = TokenValue(op.size, value); auto tokenValue = TokenValue(op.size, value);
addToken(valueType, printValue(tokenValue, true, _maxModuleLength), tokenValue); addToken(valueType, printValue(tokenValue, true, _maxModuleLength), tokenValue);
return true; return true;
} }
bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op) bool CapstoneTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
{ {
//memory size //memory size
const char* sizeText = _cp.MemSizeName(op.size); const char* sizeText = _cp.MemSizeName(op.size);
@ -520,37 +506,19 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
//memory segment //memory segment
const auto & mem = op.mem; const auto & mem = op.mem;
const char* segmentText = _cp.RegName(mem.segment); auto segmentType = op.reg == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS)
if(mem.segment == X86_REG_INVALID) //segment not set ? TokenType::MnemonicUnusual : TokenType::MemorySegment;
{ addToken(segmentType, _cp.RegName(mem.segment));
switch(mem.base)
{
#ifdef _WIN64
case X86_REG_RSP:
case X86_REG_RBP:
#else //x86
case X86_REG_ESP:
case X86_REG_EBP:
#endif //_WIN64
segmentText = "ss";
break;
default:
segmentText = "ds";
break;
}
}
auto segmentType = op.reg == ArchValue(X86_REG_FS, X86_REG_GS) ? TokenType::MnemonicUnusual : TokenType::MemorySegment;
addToken(segmentType, segmentText);
addToken(TokenType::Uncategorized, ":"); addToken(TokenType::Uncategorized, ":");
//memory opening bracket //memory opening bracket
auto bracketsType = TokenType::MemoryBrackets; auto bracketsType = TokenType::MemoryBrackets;
switch(mem.base) switch(mem.base)
{ {
case X86_REG_ESP: case ZYDIS_REGISTER_ESP:
case X86_REG_RSP: case ZYDIS_REGISTER_RSP:
case X86_REG_EBP: case ZYDIS_REGISTER_EBP:
case X86_REG_RBP: case ZYDIS_REGISTER_RBP:
bracketsType = TokenType::MemoryStackBrackets; bracketsType = TokenType::MemoryStackBrackets;
default: default:
break; break;
@ -558,9 +526,9 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
addToken(bracketsType, "["); addToken(bracketsType, "[");
//stuff inside the brackets //stuff inside the brackets
if(mem.base == X86_REG_RIP) //rip-relative (#replacement) if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative (#replacement)
{ {
duint addr = _cp.Address() + duint(mem.disp) + _cp.Size(); duint addr = _cp.Address() + duint(mem.disp.value) + _cp.Size();
TokenValue value = TokenValue(op.size, addr); TokenValue value = TokenValue(op.size, addr);
auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::Value; auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::Value;
addToken(displacementType, printValue(value, false, _maxModuleLength), value); addToken(displacementType, printValue(value, false, _maxModuleLength), value);
@ -568,12 +536,12 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
else //#base + #index * #scale + #displacement else //#base + #index * #scale + #displacement
{ {
bool prependPlus = false; bool prependPlus = false;
if(mem.base != X86_REG_INVALID) //base register if(mem.base != ZYDIS_REGISTER_NONE) //base register
{ {
addToken(TokenType::MemoryBaseRegister, _cp.RegName(mem.base)); addToken(TokenType::MemoryBaseRegister, _cp.RegName(mem.base));
prependPlus = true; prependPlus = true;
} }
if(mem.index != X86_REG_INVALID) //index register if(mem.index != ZYDIS_REGISTER_NONE) //index register
{ {
if(prependPlus) if(prependPlus)
addMemoryOperator('+'); addMemoryOperator('+');
@ -585,16 +553,16 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
} }
prependPlus = true; prependPlus = true;
} }
if(mem.disp) if(mem.disp.value)
{ {
char operatorText = '+'; char operatorText = '+';
TokenValue value(op.size, duint(mem.disp)); TokenValue value(op.size, duint(mem.disp.value));
auto displacementType = DbgMemIsValidReadPtr(duint(mem.disp)) ? TokenType::Address : TokenType::Value; auto displacementType = DbgMemIsValidReadPtr(duint(mem.disp.value)) ? TokenType::Address : TokenType::Value;
QString valueText; QString valueText;
if(mem.disp < 0) if(mem.disp.value < 0)
{ {
operatorText = '-'; operatorText = '-';
valueText = printValue(TokenValue(op.size, duint(mem.disp * -1)), false, _maxModuleLength); valueText = printValue(TokenValue(op.size, duint(mem.disp.value * -1)), false, _maxModuleLength);
} }
else else
valueText = printValue(value, false, _maxModuleLength); valueText = printValue(value, false, _maxModuleLength);
@ -611,7 +579,7 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
return true; return true;
} }
bool CapstoneTokenizer::tokenizeInvalidOperand(const cs_x86_op & op) bool CapstoneTokenizer::tokenizeInvalidOperand(const ZydisDecodedOperand & op)
{ {
addToken(TokenType::MnemonicUnusual, "???"); addToken(TokenType::MnemonicUnusual, "???");
return true; return true;

View File

@ -1,7 +1,7 @@
#ifndef _CAPSTONE_GUI_H #ifndef _CAPSTONE_GUI_H
#define _CAPSTONE_GUI_H #define _CAPSTONE_GUI_H
#include <capstone_wrapper.h> #include <zydis_wrapper.h>
#include "RichTextPainter.h" #include "RichTextPainter.h"
#include "Configuration.h" #include "Configuration.h"
#include <map> #include <map>
@ -187,11 +187,11 @@ private:
bool tokenizePrefix(); bool tokenizePrefix();
bool tokenizeMnemonic(); bool tokenizeMnemonic();
bool tokenizeMnemonic(TokenType type, const QString & mnemonic); bool tokenizeMnemonic(TokenType type, const QString & mnemonic);
bool tokenizeOperand(const cs_x86_op & op); bool tokenizeOperand(const ZydisDecodedOperand & op);
bool tokenizeRegOperand(const cs_x86_op & op); bool tokenizeRegOperand(const ZydisDecodedOperand & op);
bool tokenizeImmOperand(const cs_x86_op & op); bool tokenizeImmOperand(const ZydisDecodedOperand & op);
bool tokenizeMemOperand(const cs_x86_op & op); bool tokenizeMemOperand(const ZydisDecodedOperand & op);
bool tokenizeInvalidOperand(const cs_x86_op & op); bool tokenizeInvalidOperand(const ZydisDecodedOperand & op);
}; };
#endif //_CAPSTONE_GUI_H #endif //_CAPSTONE_GUI_H

View File

@ -1,5 +1,5 @@
#include "LocalVarsView.h" #include "LocalVarsView.h"
#include "capstone_wrapper.h" #include "zydis_wrapper.h"
#include "CPUMultiDump.h" #include "CPUMultiDump.h"
#include "MiscUtil.h" #include "MiscUtil.h"
#include "WordEditDialog.h" #include "WordEditDialog.h"
@ -210,18 +210,22 @@ void LocalVarsView::updateSlot()
} }
for(int i = 0; i < dis.OpCount(); i++) for(int i = 0; i < dis.OpCount(); i++)
{ {
if(dis[i].type != X86_OP_MEM) if(dis[i].type != ZYDIS_OPERAND_TYPE_MEMORY)
continue; continue;
if(dis[i].mem.base == X86_REG_INVALID) //mov eax, [10000000], global variable if(dis[i].mem.base == ZYDIS_REGISTER_NONE) //mov eax, [10000000], global variable
continue; continue;
if(dis[i].mem.index != X86_REG_INVALID) //mov eax, dword ptr ds:[ebp+ecx*4-10], indexed array if(dis[i].mem.index != ZYDIS_REGISTER_NONE) //mov eax, dword ptr ds:[ebp+ecx*4-10], indexed array
continue; continue;
const x86_reg registers[] = const ZydisRegister registers[] =
{ {
#ifdef _WIN64 #ifdef _WIN64
X86_REG_RAX, X86_REG_RBX, X86_REG_RCX, X86_REG_RDX, X86_REG_RBP, X86_REG_RSP, X86_REG_RSI, X86_REG_RDI, X86_REG_R8, X86_REG_R9, X86_REG_R10, X86_REG_R11, X86_REG_R12, X86_REG_R13, X86_REG_R14, X86_REG_R15 ZYDIS_REGISTER_RAX, ZYDIS_REGISTER_RBX, ZYDIS_REGISTER_RCX, ZYDIS_REGISTER_RDX,
ZYDIS_REGISTER_RBP, ZYDIS_REGISTER_RSP, ZYDIS_REGISTER_RSI, ZYDIS_REGISTER_RDI,
ZYDIS_REGISTER_R8, ZYDIS_REGISTER_R9, ZYDIS_REGISTER_R10, ZYDIS_REGISTER_R11,
ZYDIS_REGISTER_R12, ZYDIS_REGISTER_R13, ZYDIS_REGISTER_R14, ZYDIS_REGISTER_R15
#else //x86 #else //x86
X86_REG_EAX, X86_REG_EBX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBP, X86_REG_ESP, X86_REG_ESI, X86_REG_EDI ZYDIS_REGISTER_EAX, ZYDIS_REGISTER_EBX, ZYDIS_REGISTER_ECX, ZYDIS_REGISTER_EDX,
ZYDIS_REGISTER_EBP, ZYDIS_REGISTER_ESP, ZYDIS_REGISTER_ESI, ZYDIS_REGISTER_EDI
#endif //_WIN64 #endif //_WIN64
}; };
for(char j = 0; j < ArchValue(8, 16); j++) for(char j = 0; j < ArchValue(8, 16); j++)
@ -229,7 +233,7 @@ void LocalVarsView::updateSlot()
if(!baseRegisters[j]->isChecked()) if(!baseRegisters[j]->isChecked())
continue; continue;
if(dis[i].mem.base == registers[j]) if(dis[i].mem.base == registers[j])
usedOffsets[j].insert(dis[i].mem.disp); usedOffsets[j].insert(dis[i].mem.disp.value);
} }
} }
address += dis.Size(); address += dis.Size();

View File

@ -1,5 +1,5 @@
#include "main.h" #include "main.h"
#include "capstone_wrapper.h" #include "zydis_wrapper.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "Configuration.h" #include "Configuration.h"
#include <QTextCodec> #include <QTextCodec>

View File

@ -67,7 +67,8 @@ INCLUDEPATH += \
Src/Utils \ Src/Utils \
Src/ThirdPartyLibs/snowman \ Src/ThirdPartyLibs/snowman \
Src/ThirdPartyLibs/ldconvert \ Src/ThirdPartyLibs/ldconvert \
../capstone_wrapper ../capstone_wrapper \
../zydis_wrapper
# Resources, sources, headers, and forms # Resources, sources, headers, and forms
RESOURCES += \ RESOURCES += \
@ -347,15 +348,15 @@ LIBS += -luser32 -ladvapi32 -lwinmm -lshell32
!contains(QMAKE_HOST.arch, x86_64) { !contains(QMAKE_HOST.arch, x86_64) {
# Windows x86 (32bit) specific build # Windows x86 (32bit) specific build
LIBS += -L"$$PWD/../capstone_wrapper/capstone" -lcapstone_x86 LIBS += -L"$$PWD/../zydis_wrapper/Zydis" -lZydis_x86
LIBS += -L"$$PWD/../capstone_wrapper/bin/x32$${DIR_SUFFIX}" -lcapstone_wrapper LIBS += -L"$$PWD/../zydis_wrapper/bin/x32$${DIR_SUFFIX}" -lzydis_wrapper
LIBS += -L"$$PWD/Src/ThirdPartyLibs/snowman" -lsnowman_x86 LIBS += -L"$$PWD/Src/ThirdPartyLibs/snowman" -lsnowman_x86
LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x86 LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x86
LIBS += -L"$${X64_BIN_DIR}" -lx32bridge LIBS += -L"$${X64_BIN_DIR}" -lx32bridge
} else { } else {
# Windows x64 (64bit) specific build # Windows x64 (64bit) specific build
LIBS += -L"$$PWD/../capstone_wrapper/capstone" -lcapstone_x64 LIBS += -L"$$PWD/../zydis_wrapper/Zydis" -lZydis_x64
LIBS += -L"$$PWD/../capstone_wrapper/bin/x64$${DIR_SUFFIX}" -lcapstone_wrapper LIBS += -L"$$PWD/../zydis_wrapper/bin/x64$${DIR_SUFFIX}" -lzydis_wrapper
LIBS += -L"$$PWD/Src/ThirdPartyLibs/snowman" -lsnowman_x64 LIBS += -L"$$PWD/Src/ThirdPartyLibs/snowman" -lsnowman_x64
LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x64 LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x64
LIBS += -L"$${X64_BIN_DIR}" -lx64bridge LIBS += -L"$${X64_BIN_DIR}" -lx64bridge

1
src/zydis_wrapper Submodule

@ -0,0 +1 @@
Subproject commit 093fbde4acbe897ecd080ed157b3d4bfb95323f3