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:
parent
103866eafe
commit
5338a0a85b
|
@ -10,3 +10,6 @@
|
|||
[submodule "deps"]
|
||||
path = 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "TraceRecord.h"
|
||||
#include "capstone_wrapper.h"
|
||||
#include "zydis_wrapper.h"
|
||||
#include "module.h"
|
||||
#include "memory.h"
|
||||
#include "threading.h"
|
||||
|
|
|
@ -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
|
||||
{
|
||||
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");
|
||||
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");
|
||||
else if(instr.type == instr_branch)
|
||||
continue;
|
||||
|
@ -738,77 +738,77 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
|
|||
Capstone cp;
|
||||
if(!cp.Disassemble(addr, data))
|
||||
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)
|
||||
{
|
||||
#ifndef _WIN64 //x32
|
||||
case X86_REG_EAX:
|
||||
case ZYDIS_REGISTER_EAX:
|
||||
return titcontext.cax;
|
||||
case X86_REG_EBX:
|
||||
case ZYDIS_REGISTER_EBX:
|
||||
return titcontext.cbx;
|
||||
case X86_REG_ECX:
|
||||
case ZYDIS_REGISTER_ECX:
|
||||
return titcontext.ccx;
|
||||
case X86_REG_EDX:
|
||||
case ZYDIS_REGISTER_EDX:
|
||||
return titcontext.cdx;
|
||||
case X86_REG_EBP:
|
||||
case ZYDIS_REGISTER_EBP:
|
||||
return titcontext.cbp;
|
||||
case X86_REG_ESP:
|
||||
case ZYDIS_REGISTER_ESP:
|
||||
return titcontext.csp;
|
||||
case X86_REG_ESI:
|
||||
case ZYDIS_REGISTER_ESI:
|
||||
return titcontext.csi;
|
||||
case X86_REG_EDI:
|
||||
case ZYDIS_REGISTER_EDI:
|
||||
return titcontext.cdi;
|
||||
case X86_REG_EIP:
|
||||
case ZYDIS_REGISTER_EIP:
|
||||
return titcontext.cip;
|
||||
#else //x64
|
||||
case X86_REG_RAX:
|
||||
case ZYDIS_REGISTER_RAX:
|
||||
return titcontext.cax;
|
||||
case X86_REG_RBX:
|
||||
case ZYDIS_REGISTER_RBX:
|
||||
return titcontext.cbx;
|
||||
case X86_REG_RCX:
|
||||
case ZYDIS_REGISTER_RCX:
|
||||
return titcontext.ccx;
|
||||
case X86_REG_RDX:
|
||||
case ZYDIS_REGISTER_RDX:
|
||||
return titcontext.cdx;
|
||||
case X86_REG_RBP:
|
||||
case ZYDIS_REGISTER_RBP:
|
||||
return titcontext.cbp;
|
||||
case X86_REG_RSP:
|
||||
case ZYDIS_REGISTER_RSP:
|
||||
return titcontext.csp;
|
||||
case X86_REG_RSI:
|
||||
case ZYDIS_REGISTER_RSI:
|
||||
return titcontext.csi;
|
||||
case X86_REG_RDI:
|
||||
case ZYDIS_REGISTER_RDI:
|
||||
return titcontext.cdi;
|
||||
case X86_REG_RIP:
|
||||
case ZYDIS_REGISTER_RIP:
|
||||
return titcontext.cip;
|
||||
case X86_REG_R8:
|
||||
case ZYDIS_REGISTER_R8:
|
||||
return titcontext.r8;
|
||||
case X86_REG_R9:
|
||||
case ZYDIS_REGISTER_R9:
|
||||
return titcontext.r9;
|
||||
case X86_REG_R10:
|
||||
case ZYDIS_REGISTER_R10:
|
||||
return titcontext.r10;
|
||||
case X86_REG_R11:
|
||||
case ZYDIS_REGISTER_R11:
|
||||
return titcontext.r11;
|
||||
case X86_REG_R12:
|
||||
case ZYDIS_REGISTER_R12:
|
||||
return titcontext.r12;
|
||||
case X86_REG_R13:
|
||||
case ZYDIS_REGISTER_R13:
|
||||
return titcontext.r13;
|
||||
case X86_REG_R14:
|
||||
case ZYDIS_REGISTER_R14:
|
||||
return titcontext.r14;
|
||||
case X86_REG_R15:
|
||||
case ZYDIS_REGISTER_R15:
|
||||
return titcontext.r15;
|
||||
#endif //_WIN64
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
if(cp[0].type == X86_OP_MEM)
|
||||
if(cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
auto const tebseg = X86_REG_GS;
|
||||
auto const tebseg = ZYDIS_REGISTER_GS;
|
||||
#else
|
||||
auto const tebseg = X86_REG_FS;
|
||||
auto const tebseg = ZYDIS_REGISTER_FS;
|
||||
#endif //_WIN64
|
||||
if(cp[0].mem.segment == tebseg)
|
||||
opValue += duint(GetTEBLocation(hActiveThread));
|
||||
|
@ -818,7 +818,7 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
|
|||
else
|
||||
return opValue;
|
||||
}
|
||||
if(cp.InGroup(CS_GRP_RET))
|
||||
if(cp.IsRet())
|
||||
{
|
||||
auto csp = titcontext.csp;
|
||||
duint dest = 0;
|
||||
|
|
|
@ -31,16 +31,16 @@ bool CodeFollowPass::Analyse()
|
|||
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];
|
||||
|
||||
// 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))
|
||||
return dest;
|
||||
|
@ -50,25 +50,25 @@ duint CodeFollowPass::GetReferenceOperand(const cs_x86 & Context)
|
|||
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;
|
||||
|
||||
// Only the first operand matters
|
||||
auto operand = Context.operands[0];
|
||||
|
||||
// Jumps and calls only
|
||||
if(Disasm.InGroup(CS_GRP_CALL) || Disasm.InGroup(CS_GRP_JUMP))
|
||||
if(Disasm.IsCall() || Disasm.IsJump())
|
||||
{
|
||||
// Looking for memory references
|
||||
if(operand.type == X86_OP_MEM)
|
||||
if(operand.type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
// Notify if the operand was indirect
|
||||
if(Indirect)
|
||||
{
|
||||
if(operand.mem.base != X86_REG_INVALID ||
|
||||
operand.mem.index != X86_REG_INVALID ||
|
||||
if(operand.mem.base != ZYDIS_REGISTER_NONE ||
|
||||
operand.mem.index != ZYDIS_REGISTER_NONE ||
|
||||
operand.mem.scale != 0)
|
||||
{
|
||||
*Indirect = true;
|
||||
|
@ -81,7 +81,7 @@ duint CodeFollowPass::GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context
|
|||
// TODO: Translate RIP-Relative
|
||||
return 0;
|
||||
|
||||
duint dest = (duint)operand.mem.disp;
|
||||
duint dest = (duint)operand.mem.disp.value;
|
||||
|
||||
if(ValidateAddress(dest))
|
||||
return dest;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "AnalysisPass.h"
|
||||
#include "BasicBlock.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
|
||||
class CodeFollowPass : public AnalysisPass
|
||||
{
|
||||
|
@ -14,6 +14,6 @@ public:
|
|||
virtual bool Analyse() override;
|
||||
|
||||
private:
|
||||
duint GetReferenceOperand(const cs_x86 & Context);
|
||||
duint GetMemoryOperand(Capstone & Disasm, const cs_x86 & Context, bool* Indirect);
|
||||
duint GetReferenceOperand(const ZydisDecodedInstruction & Context);
|
||||
duint GetMemoryOperand(Capstone & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect);
|
||||
};
|
|
@ -2,7 +2,7 @@
|
|||
#include <ppl.h>
|
||||
#include "AnalysisPass.h"
|
||||
#include "LinearPass.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
|
||||
LinearPass::LinearPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks)
|
||||
: AnalysisPass(VirtualStart, VirtualEnd, MainBlocks)
|
||||
|
@ -167,10 +167,10 @@ void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks)
|
|||
insnCount++;
|
||||
|
||||
// The basic block ends here if it is a branch
|
||||
bool call = disasm.InGroup(CS_GRP_CALL); // CALL
|
||||
bool jmp = disasm.InGroup(CS_GRP_JUMP); // JUMP
|
||||
bool ret = disasm.InGroup(CS_GRP_RET); // RETURN
|
||||
bool padding = disasm.IsFilling(); // INSTRUCTION PADDING
|
||||
bool call = disasm.IsCall(); // CALL
|
||||
bool jmp = disasm.IsJump(); // JUMP
|
||||
bool ret = disasm.IsRet(); // RETURN
|
||||
bool padding = disasm.IsFilling(); // INSTRUCTION PADDING
|
||||
|
||||
if(padding)
|
||||
{
|
||||
|
@ -211,25 +211,25 @@ void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks)
|
|||
if(!padding)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
block->Target = (duint)operand.imm;
|
||||
block->Target = (duint)operand.imm.value.u;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Indirects (no operand, register, or memory)
|
||||
block->SetFlag(BASIC_BLOCK_FLAG_INDIRECT);
|
||||
|
||||
if(operand.type == X86_OP_MEM &&
|
||||
operand.mem.base == X86_REG_RIP &&
|
||||
operand.mem.index == X86_REG_INVALID &&
|
||||
if(operand.type == ZYDIS_OPERAND_TYPE_MEMORY &&
|
||||
operand.mem.base == ZYDIS_REGISTER_RIP &&
|
||||
operand.mem.index == ZYDIS_REGISTER_NONE &&
|
||||
operand.mem.scale == 1)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -106,11 +106,11 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
|
|||
for(int i = 1; i < mCp.Size(); i++)
|
||||
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
|
||||
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();
|
||||
|
||||
//add node to the function graph
|
||||
|
@ -124,14 +124,14 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
|
|||
|
||||
break;
|
||||
}
|
||||
if(mCp.InGroup(CS_GRP_CALL)) //call
|
||||
if(mCp.IsCall()) //call
|
||||
{
|
||||
//TODO: handle no return
|
||||
duint target = mCp.BranchDestination();
|
||||
if(inRange(target) && mEntryPoints.find(target) == mEntryPoints.end())
|
||||
mCandidateEPs.insert(target);
|
||||
}
|
||||
if(mCp.InGroup(CS_GRP_RET)) //return
|
||||
if(mCp.IsRet()) //return
|
||||
{
|
||||
node.terminal = true;
|
||||
graph.AddNode(node);
|
||||
|
@ -164,7 +164,7 @@ void AdvancedAnalysis::linearXrefPass()
|
|||
xref.from = mCp.Address();
|
||||
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;
|
||||
});
|
||||
|
@ -176,9 +176,9 @@ void AdvancedAnalysis::linearXrefPass()
|
|||
}
|
||||
if(xref.addr)
|
||||
{
|
||||
if(mCp.InGroup(CS_GRP_CALL))
|
||||
if(mCp.IsCall())
|
||||
xref.type = XREF_CALL;
|
||||
else if(mCp.InGroup(CS_GRP_JUMP))
|
||||
else if(mCp.IsJump())
|
||||
xref.type = XREF_JMP;
|
||||
else
|
||||
xref.type = XREF_DATA;
|
||||
|
@ -218,21 +218,21 @@ void AdvancedAnalysis::findInvalidXrefs()
|
|||
}
|
||||
}
|
||||
|
||||
bool isFloatInstruction(x86_insn opcode)
|
||||
bool isFloatInstruction(ZydisMnemonic opcode)
|
||||
{
|
||||
switch(opcode)
|
||||
{
|
||||
case X86_INS_FLD:
|
||||
case X86_INS_FST:
|
||||
case X86_INS_FSTP:
|
||||
case X86_INS_FADD:
|
||||
case X86_INS_FSUB:
|
||||
case X86_INS_FSUBR:
|
||||
case X86_INS_FMUL:
|
||||
case X86_INS_FDIV:
|
||||
case X86_INS_FDIVR:
|
||||
case X86_INS_FCOM:
|
||||
case X86_INS_FCOMP:
|
||||
case ZYDIS_MNEMONIC_FLD:
|
||||
case ZYDIS_MNEMONIC_FST:
|
||||
case ZYDIS_MNEMONIC_FSTP:
|
||||
case ZYDIS_MNEMONIC_FADD:
|
||||
case ZYDIS_MNEMONIC_FSUB:
|
||||
case ZYDIS_MNEMONIC_FSUBR:
|
||||
case ZYDIS_MNEMONIC_FMUL:
|
||||
case ZYDIS_MNEMONIC_FDIV:
|
||||
case ZYDIS_MNEMONIC_FDIVR:
|
||||
case ZYDIS_MNEMONIC_FCOM:
|
||||
case ZYDIS_MNEMONIC_FCOMP:
|
||||
|
||||
return true;
|
||||
default:
|
||||
|
@ -261,7 +261,7 @@ void AdvancedAnalysis::writeDataXrefs()
|
|||
ENCODETYPE type = enc_unknown;
|
||||
|
||||
//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 size = datasize;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define _ANALYSIS_H
|
||||
|
||||
#include "_global.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
|
||||
class Analysis
|
||||
{
|
||||
|
|
|
@ -150,15 +150,15 @@ void ControlFlowAnalysis::BasicBlockStarts()
|
|||
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)
|
||||
}
|
||||
else if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) //branches
|
||||
else if(mCp.IsJump() || mCp.IsLoop()) //branches
|
||||
{
|
||||
auto dest1 = getReferenceOperand();
|
||||
duint dest2 = 0;
|
||||
if(mCp.GetId() != X86_INS_JMP) //conditional jump
|
||||
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump
|
||||
dest2 = addr + mCp.Size();
|
||||
|
||||
if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted)
|
||||
|
@ -168,7 +168,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
|
|||
if(dest2)
|
||||
mBlockStarts.insert(dest2);
|
||||
}
|
||||
else if(mCp.InGroup(CS_GRP_CALL))
|
||||
else if(mCp.IsCall())
|
||||
{
|
||||
auto dest1 = getReferenceOperand();
|
||||
if(dest1)
|
||||
|
@ -206,15 +206,15 @@ void ControlFlowAnalysis::BasicBlocks()
|
|||
prevaddr = addr;
|
||||
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
|
||||
break;
|
||||
}
|
||||
else if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop())
|
||||
else if(mCp.IsJump() || mCp.IsLoop())
|
||||
{
|
||||
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));
|
||||
insertParent(dest1, start);
|
||||
insertParent(dest2, start);
|
||||
|
@ -415,17 +415,17 @@ duint ControlFlowAnalysis::getReferenceOperand() const
|
|||
{
|
||||
for(auto i = 0; i < mCp.OpCount(); i++)
|
||||
{
|
||||
const auto & op = mCp.x86().operands[i];
|
||||
if(op.type == X86_OP_IMM)
|
||||
const auto & op = mCp[i];
|
||||
if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
|
||||
{
|
||||
auto dest = duint(op.imm);
|
||||
auto dest = duint(op.imm.value.u);
|
||||
if(inRange(dest))
|
||||
return dest;
|
||||
}
|
||||
else if(op.type == X86_OP_MEM)
|
||||
else if(op.type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
auto dest = duint(op.mem.disp);
|
||||
if(op.mem.base == X86_REG_RIP) //rip-relative
|
||||
auto dest = duint(op.mem.disp.value);
|
||||
if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative
|
||||
dest += mCp.Address() + mCp.Size();
|
||||
if(inRange(dest))
|
||||
return dest;
|
||||
|
|
|
@ -86,7 +86,7 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
|
|||
if(mCp.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
|
||||
{
|
||||
//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;
|
||||
}
|
||||
|
||||
|
@ -100,10 +100,10 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
|
|||
if(addr + mCp.Size() > maxaddr) //we went past the maximum allowed address
|
||||
break;
|
||||
|
||||
const auto & op = mCp.x86().operands[0];
|
||||
if((mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) && op.type == X86_OP_IMM) //jump
|
||||
const auto & op = mCp[0];
|
||||
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
|
||||
{
|
||||
|
@ -113,12 +113,12 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if(mCp.InGroup(CS_GRP_RET)) //possible function end?
|
||||
else if(mCp.IsRet()) //possible function end?
|
||||
{
|
||||
end = addr;
|
||||
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++)
|
||||
{
|
||||
const auto & op = mCp.x86().operands[i];
|
||||
if(mCp.InGroup(CS_GRP_JUMP) || mCp.IsLoop()) //skip jumps/loops
|
||||
const auto & op = mCp[i];
|
||||
if(mCp.IsJump() || mCp.IsLoop()) //skip jumps/loops
|
||||
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))
|
||||
return dest;
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
xref.from = mCp.Address();
|
||||
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;
|
||||
});
|
||||
|
@ -116,23 +116,23 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
if(xref.addr)
|
||||
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
|
||||
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();
|
||||
|
||||
//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]
|
||||
if(mCp[0].type == X86_OP_MEM && mCp[0].mem.base == X86_OP_INVALID && mCp[0].mem.index != X86_OP_INVALID
|
||||
&& mCp[0].mem.scale == sizeof(duint) && MemIsValidReadPtr(duint(mCp[0].mem.disp)))
|
||||
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.value)))
|
||||
{
|
||||
Memory<duint*> switchTable(512 * sizeof(duint));
|
||||
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);
|
||||
for(index = 0; index < actualSize; index++)
|
||||
if(MemIsCodePage(switchTable()[index], false) == false)
|
||||
|
@ -168,11 +168,11 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
|
||||
break;
|
||||
}
|
||||
if(mCp.InGroup(CS_GRP_CALL)) //call
|
||||
if(mCp.IsCall())
|
||||
{
|
||||
//TODO: add this to a queue to be analyzed later
|
||||
}
|
||||
if(mCp.InGroup(CS_GRP_RET)) //return
|
||||
if(mCp.IsRet())
|
||||
{
|
||||
node.terminal = true;
|
||||
graph.AddNode(node);
|
||||
|
@ -224,17 +224,17 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
while(addr <= node.end) //disassemble all instructions
|
||||
{
|
||||
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];
|
||||
switch(op.type)
|
||||
{
|
||||
case X86_OP_REG:
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
node.indirectcall = true;
|
||||
break;
|
||||
case X86_OP_MEM:
|
||||
node.indirectcall |= op.mem.base != X86_REG_RIP &&
|
||||
(op.mem.base != X86_REG_INVALID || op.mem.index != X86_REG_INVALID);
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
node.indirectcall |= op.mem.base != ZYDIS_REGISTER_RIP &&
|
||||
(op.mem.base != ZYDIS_REGISTER_NONE || op.mem.index != ZYDIS_REGISTER_NONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -21,7 +21,7 @@ void XrefsAnalysis::Analyse()
|
|||
xref.from = mCp.Address();
|
||||
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;
|
||||
});
|
||||
|
|
|
@ -570,8 +570,8 @@ static bool cbModCallFind(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, R
|
|||
}
|
||||
switch(disasm->GetId())
|
||||
{
|
||||
case X86_INS_CALL: //call dword ptr: [&api]
|
||||
case X86_INS_MOV: //mov reg, dword ptr:[&api]
|
||||
case ZYDIS_MNEMONIC_CALL: //call dword ptr: [&api]
|
||||
case ZYDIS_MNEMONIC_MOV: //mov reg, dword ptr:[&api]
|
||||
if(!foundaddr && basicinfo->memory.value)
|
||||
{
|
||||
duint memaddr;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "debugger.h"
|
||||
#include "variable.h"
|
||||
#include "loop.h"
|
||||
#include "capstone_wrapper.h"
|
||||
#include "zydis_wrapper.h"
|
||||
#include "mnemonichelp.h"
|
||||
#include "value.h"
|
||||
#include "symbolinfo.h"
|
||||
|
@ -209,6 +209,9 @@ bool cbInstrCopystr(int argc, char* argv[])
|
|||
|
||||
bool cbInstrCapstone(int argc, char* argv[])
|
||||
{
|
||||
return false;
|
||||
|
||||
/*
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return false;
|
||||
|
||||
|
@ -237,10 +240,8 @@ bool cbInstrCapstone(int argc, char* argv[])
|
|||
return false;
|
||||
}
|
||||
|
||||
const cs_insn* instr = cp.GetInstr();
|
||||
const cs_detail* detail = instr->detail;
|
||||
const cs_x86 & x86 = cp.x86();
|
||||
int argcount = x86.op_count;
|
||||
auto instr = cp.GetInstr();
|
||||
int argcount = instr->operandCount;
|
||||
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());
|
||||
if(detail->regs_read_count)
|
||||
|
@ -301,6 +302,7 @@ bool cbInstrCapstone(int argc, char* argv[])
|
|||
}
|
||||
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
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
|
||||
break;
|
||||
|
||||
const cs_x86_op & operand = _cp.x86().operands[0];
|
||||
if((_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop()) && operand.type == X86_OP_IMM) //jump
|
||||
const auto & operand = _cp[0];
|
||||
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
|
||||
{
|
||||
|
@ -370,12 +372,12 @@ bool cbInstrVisualize(int argc, char* argv[])
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if(_cp.InGroup(CS_GRP_RET)) //possible function end?
|
||||
else if(_cp.IsRet()) //possible function end?
|
||||
{
|
||||
end = addr;
|
||||
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "encodemap.h"
|
||||
#include "stringutils.h"
|
||||
#include "value.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
#include <algorithm>
|
||||
|
||||
std::unordered_map<ENCODETYPE, std::string> disasmMap;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "taskthread.h"
|
||||
#include "animate.h"
|
||||
#include "simplescript.h"
|
||||
#include "capstone_wrapper.h"
|
||||
#include "zydis_wrapper.h"
|
||||
#include "cmd-watch-control.h"
|
||||
#include "filemap.h"
|
||||
#include "jit.h"
|
||||
|
@ -1164,7 +1164,7 @@ void cbRtrStep()
|
|||
unsigned char data[MAX_DISASM_BUFFER];
|
||||
memset(data, 0, sizeof(data));
|
||||
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);
|
||||
else
|
||||
StepOver((void*)cbRtrStep);
|
||||
|
|
|
@ -34,53 +34,53 @@ void fillbasicinfo(Capstone* cp, BASIC_INSTRUCTION_INFO* basicinfo, bool instrTe
|
|||
//instruction size
|
||||
basicinfo->size = cp->Size();
|
||||
//branch/call info
|
||||
if(cp->InGroup(CS_GRP_CALL))
|
||||
if(cp->IsCall())
|
||||
{
|
||||
basicinfo->branch = true;
|
||||
basicinfo->call = true;
|
||||
}
|
||||
else if(cp->InGroup(CS_GRP_JUMP) || cp->IsLoop())
|
||||
else if(cp->IsJump() || cp->IsLoop())
|
||||
{
|
||||
basicinfo->branch = true;
|
||||
}
|
||||
//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)
|
||||
{
|
||||
case X86_OP_IMM:
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
{
|
||||
if(basicinfo->branch)
|
||||
{
|
||||
basicinfo->type |= TYPE_ADDR;
|
||||
basicinfo->addr = duint(op.imm);
|
||||
basicinfo->value.value = duint(op.imm);
|
||||
basicinfo->addr = duint(op.imm.value.u);
|
||||
basicinfo->value.value = duint(op.imm.value.u);
|
||||
}
|
||||
else
|
||||
{
|
||||
basicinfo->type |= TYPE_VALUE;
|
||||
basicinfo->value.size = VALUE_SIZE(op.size);
|
||||
basicinfo->value.value = duint(op.imm);
|
||||
basicinfo->value.value = duint(op.imm.value.u);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case X86_OP_MEM:
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
{
|
||||
const x86_op_mem & mem = op.mem;
|
||||
const auto & mem = op.mem;
|
||||
if(instrText)
|
||||
strcpy_s(basicinfo->memory.mnemonic, cp->OperandText(i).c_str());
|
||||
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;
|
||||
}
|
||||
else if(mem.disp)
|
||||
else if(mem.disp.value)
|
||||
{
|
||||
basicinfo->type |= TYPE_MEMORY;
|
||||
basicinfo->memory.value = ULONG_PTR(mem.disp);
|
||||
basicinfo->memory.value = ULONG_PTR(mem.disp.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define _DISASM_FAST_H
|
||||
|
||||
#include "_global.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
|
||||
void fillbasicinfo(Capstone* disasm, BASIC_INSTRUCTION_INFO* basicinfo, bool instrText = true);
|
||||
bool disasmfast(duint addr, BASIC_INSTRUCTION_INFO* basicinfo, bool cache = false);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "debugger.h"
|
||||
#include "value.h"
|
||||
#include "encodemap.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
#include "datainst_helper.h"
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
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());
|
||||
switch(op.type)
|
||||
{
|
||||
case X86_OP_REG:
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
{
|
||||
arg->type = arg_normal;
|
||||
arg->value = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case X86_OP_IMM:
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
{
|
||||
arg->type = arg_normal;
|
||||
arg->constant = arg->value = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case X86_OP_MEM:
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
{
|
||||
arg->type = arg_memory;
|
||||
const x86_op_mem & mem = op.mem;
|
||||
if(mem.base == X86_REG_RIP) //rip-relative
|
||||
arg->constant = cp.Address() + duint(mem.disp) + cp.Size();
|
||||
const auto & mem = op.mem;
|
||||
if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative
|
||||
arg->constant = cp.Address() + duint(mem.disp.value) + cp.Size();
|
||||
else
|
||||
arg->constant = duint(mem.disp);
|
||||
arg->constant = duint(mem.disp.value);
|
||||
#ifdef _WIN64
|
||||
if(mem.segment == X86_REG_GS)
|
||||
if(mem.segment == ZYDIS_REGISTER_GS)
|
||||
{
|
||||
arg->segment = SEG_GS;
|
||||
#else //x86
|
||||
if(mem.segment == X86_REG_FS)
|
||||
if(mem.segment == ZYDIS_REGISTER_FS)
|
||||
{
|
||||
arg->segment = SEG_FS;
|
||||
#endif
|
||||
|
@ -199,16 +199,16 @@ void disasmget(Capstone & cp, unsigned char* buffer, duint addr, DISASM_INSTR* i
|
|||
instr->argcount = 0;
|
||||
return;
|
||||
}
|
||||
const cs_insn* cpInstr = cp.GetInstr();
|
||||
sprintf_s(instr->instruction, "%s %s", cpInstr->mnemonic, cpInstr->op_str);
|
||||
instr->instr_size = cpInstr->size;
|
||||
if(cp.InGroup(CS_GRP_JUMP) || cp.IsLoop() || cp.InGroup(CS_GRP_RET) || cp.InGroup(CS_GRP_CALL))
|
||||
auto cpInstr = cp.GetInstr();
|
||||
strcpy_s(instr->instruction, cp.InstructionText().c_str());
|
||||
instr->instr_size = cpInstr->length;
|
||||
if(cp.IsBranchType(Capstone::BT_Jmp | Capstone::BT_Loop | Capstone::BT_Ret | Capstone::BT_Call))
|
||||
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;
|
||||
else
|
||||
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++)
|
||||
HandleCapstoneOperand(cp, i, &instr->arg[i], getregs);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define _DISASM_HELPER_H
|
||||
|
||||
#include "_global.h"
|
||||
#include "capstone_wrapper.h"
|
||||
#include "zydis_wrapper.h"
|
||||
|
||||
//functions
|
||||
duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "encodemap.h"
|
||||
#include <unordered_map>
|
||||
#include "addrinfo.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
|
||||
struct ENCODEMAP : AddrInfo
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "watch.h"
|
||||
#include "plugin_loader.h"
|
||||
#include "_dbgfunctions.h"
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
#include "_scriptapi_gui.h"
|
||||
#include "filehelper.h"
|
||||
#include "database.h"
|
||||
|
|
|
@ -389,13 +389,13 @@
|
|||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)..\..\bin\x64\</OutDir>
|
||||
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)..\..\bin\x64d\</OutDir>
|
||||
<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>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -467,7 +467,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<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>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -491,7 +491,7 @@
|
|||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>false</EnableCOMDATFolding>
|
||||
<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>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
@ -200,23 +200,15 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
|
|||
|
||||
auto branchType = Instruction_t::None;
|
||||
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);
|
||||
switch(cp.GetId())
|
||||
{
|
||||
case X86_INS_JMP:
|
||||
case X86_INS_LJMP:
|
||||
if(cp.IsBranchType(Capstone::BT_UncondJmp))
|
||||
branchType = Instruction_t::Unconditional;
|
||||
break;
|
||||
case X86_INS_CALL:
|
||||
case X86_INS_LCALL:
|
||||
else if(cp.IsBranchType(Capstone::BT_Call))
|
||||
branchType = Instruction_t::Call;
|
||||
break;
|
||||
default:
|
||||
branchType = cp.InGroup(CS_GRP_RET) ? Instruction_t::None : Instruction_t::Conditional;
|
||||
break;
|
||||
}
|
||||
else if(cp.IsBranchType(Capstone::BT_CondJmp))
|
||||
branchType = Instruction_t::Conditional;
|
||||
}
|
||||
else
|
||||
wInst.branchDestination = 0;
|
||||
|
@ -233,8 +225,9 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
|
|||
|
||||
if(success)
|
||||
{
|
||||
/* TODO
|
||||
auto instr = cp.GetInstr();
|
||||
cp.RegInfo(reginfo);
|
||||
cp.FlagInfo(flaginfo);
|
||||
|
||||
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++)
|
||||
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])});
|
||||
}
|
||||
|
||||
reginfo[ArchValue(X86_REG_EIP, X86_REG_RIP)] = Capstone::None;
|
||||
for(uint8_t i = X86_REG_INVALID; i < X86_REG_ENDING; i++)
|
||||
reginfo[ArchValue(ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_RIP)] = Capstone::None;
|
||||
for(uint8_t i = ZYDIS_REGISTER_NONE; i < ZYDIS_REGISTER_ENUM_COUNT; i++)
|
||||
if(reginfo[i])
|
||||
wInst.regsReferenced.push_back({cp.RegName(x86_reg(i)), reginfo[i]});
|
||||
*/
|
||||
}
|
||||
|
||||
return wInst;
|
||||
|
|
|
@ -67,8 +67,8 @@ private:
|
|||
bool _bLongDataInst;
|
||||
EncodeMap* mEncodeMap;
|
||||
CodeFoldingHelper* mCodeFoldingManager;
|
||||
uint8_t reginfo[X86_REG_ENDING];
|
||||
uint8_t flaginfo[Capstone::FLAG_ENDING];
|
||||
uint8_t reginfo[ZYDIS_REGISTER_ENUM_COUNT];
|
||||
uint8_t flaginfo[ZYDIS_CPUFLAG_ENUM_COUNT];
|
||||
};
|
||||
|
||||
#endif // QBEAENGINE_H
|
||||
|
|
|
@ -362,21 +362,26 @@ bool CapstoneTokenizer::tokenizePrefix()
|
|||
{
|
||||
bool hasPrefix = true;
|
||||
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])
|
||||
{
|
||||
case X86_PREFIX_LOCK:
|
||||
|
||||
//TODO: look at multiple prefixes on one instruction
|
||||
auto attr = _cp.GetInstr()->attributes;
|
||||
|
||||
if(attr & ZYDIS_ATTRIB_HAS_LOCK)
|
||||
prefixText = "lock";
|
||||
break;
|
||||
case X86_PREFIX_REP:
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_REP)
|
||||
prefixText = "rep";
|
||||
break;
|
||||
case X86_PREFIX_REPNE:
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_REPNE)
|
||||
prefixText = "repe";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_REPNE)
|
||||
prefixText = "repne";
|
||||
break;
|
||||
default:
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_BOUND)
|
||||
prefixText = "bnd";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_XACQUIRE)
|
||||
prefixText = "xacquire";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_XRELEASE)
|
||||
prefixText = "xrelease";
|
||||
else
|
||||
hasPrefix = false;
|
||||
}
|
||||
|
||||
if(hasPrefix)
|
||||
{
|
||||
|
@ -391,52 +396,25 @@ bool CapstoneTokenizer::tokenizeMnemonic()
|
|||
{
|
||||
QString mnemonic = QString(_cp.Mnemonic().c_str());
|
||||
_mnemonicType = TokenType::MnemonicNormal;
|
||||
|
||||
auto id = _cp.GetId();
|
||||
if(isNop)
|
||||
_mnemonicType = TokenType::MnemonicNop;
|
||||
else if(_cp.InGroup(CS_GRP_CALL))
|
||||
else if(_cp.IsCall())
|
||||
_mnemonicType = TokenType::MnemonicCall;
|
||||
else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop())
|
||||
else if(_cp.IsJump() || _cp.IsLoop())
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case X86_INS_JMP:
|
||||
case X86_INS_LJMP:
|
||||
_mnemonicType = TokenType::MnemonicUncondJump;
|
||||
break;
|
||||
default:
|
||||
_mnemonicType = TokenType::MnemonicCondJump;
|
||||
break;
|
||||
}
|
||||
_mnemonicType = (id == ZYDIS_MNEMONIC_JMP) ?
|
||||
TokenType::MnemonicUncondJump : TokenType::MnemonicCondJump;
|
||||
}
|
||||
else if(_cp.IsInt3())
|
||||
_mnemonicType = TokenType::MnemonicInt3;
|
||||
else if(_cp.IsUnusual())
|
||||
_mnemonicType = TokenType::MnemonicUnusual;
|
||||
else if(_cp.InGroup(CS_GRP_RET))
|
||||
else if(_cp.IsRet())
|
||||
_mnemonicType = TokenType::MnemonicRet;
|
||||
else
|
||||
{
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(_cp.IsPushPop())
|
||||
_mnemonicType = TokenType::MnemonicPushPop;
|
||||
|
||||
tokenizeMnemonic(_mnemonicType, mnemonic);
|
||||
|
||||
|
@ -459,57 +437,65 @@ bool CapstoneTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemoni
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CapstoneTokenizer::tokenizeOperand(const cs_x86_op & op)
|
||||
bool CapstoneTokenizer::tokenizeOperand(const ZydisDecodedOperand & op)
|
||||
{
|
||||
switch(op.type)
|
||||
{
|
||||
case X86_OP_REG:
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
return tokenizeRegOperand(op);
|
||||
case X86_OP_IMM:
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
return tokenizeImmOperand(op);
|
||||
case X86_OP_MEM:
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
return tokenizeMemOperand(op);
|
||||
case X86_OP_INVALID:
|
||||
case ZYDIS_OPERAND_TYPE_UNUSED:
|
||||
return tokenizeInvalidOperand(op);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CapstoneTokenizer::tokenizeRegOperand(const cs_x86_op & op)
|
||||
bool CapstoneTokenizer::tokenizeRegOperand(const ZydisDecodedOperand & op)
|
||||
{
|
||||
auto registerType = TokenType::GeneralRegister;
|
||||
auto reg = op.reg;
|
||||
if(reg >= X86_REG_FP0 && reg <= X86_REG_FP7)
|
||||
registerType = TokenType::FpuRegister;
|
||||
else if(reg >= X86_REG_ST0 && reg <= X86_REG_ST7)
|
||||
registerType = TokenType::FpuRegister;
|
||||
else if(reg >= X86_REG_MM0 && reg <= X86_REG_MM7)
|
||||
registerType = TokenType::MmxRegister;
|
||||
else if(reg >= X86_REG_XMM0 && reg <= X86_REG_XMM31)
|
||||
registerType = TokenType::XmmRegister;
|
||||
else if(reg >= X86_REG_YMM0 && reg <= X86_REG_YMM31)
|
||||
registerType = TokenType::YmmRegister;
|
||||
else if(reg >= X86_REG_ZMM0 && reg <= X86_REG_ZMM31)
|
||||
registerType = TokenType::ZmmRegister;
|
||||
else if(reg == ArchValue(X86_REG_FS, X86_REG_GS))
|
||||
auto regClass = ZydisRegisterGetClass(reg);
|
||||
|
||||
switch(regClass)
|
||||
{
|
||||
case ZYDIS_REGCLASS_X87: registerType = TokenType::FpuRegister; break;
|
||||
case ZYDIS_REGCLASS_MMX: registerType = TokenType::MmxRegister; break;
|
||||
case ZYDIS_REGCLASS_XMM: registerType = TokenType::XmmRegister; break;
|
||||
case ZYDIS_REGCLASS_YMM: registerType = TokenType::YmmRegister; break;
|
||||
case ZYDIS_REGCLASS_ZMM: registerType = TokenType::ZmmRegister; break;
|
||||
}
|
||||
|
||||
if(reg == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS))
|
||||
registerType = TokenType::MnemonicUnusual;
|
||||
|
||||
addToken(registerType, _cp.RegName(reg));
|
||||
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));
|
||||
auto valueType = TokenType::Value;
|
||||
if(_cp.InGroup(CS_GRP_JUMP) || _cp.InGroup(CS_GRP_CALL) || _cp.IsLoop())
|
||||
duint value;
|
||||
TokenType valueType;
|
||||
if(_cp.IsBranchType(Capstone::BT_Jmp | Capstone::BT_Call | Capstone::BT_Loop))
|
||||
{
|
||||
value = _cp.BranchDestination();
|
||||
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);
|
||||
addToken(valueType, printValue(tokenValue, true, _maxModuleLength), tokenValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
||||
bool CapstoneTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
|
||||
{
|
||||
//memory size
|
||||
const char* sizeText = _cp.MemSizeName(op.size);
|
||||
|
@ -520,37 +506,19 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
|
||||
//memory segment
|
||||
const auto & mem = op.mem;
|
||||
const char* segmentText = _cp.RegName(mem.segment);
|
||||
if(mem.segment == X86_REG_INVALID) //segment not set
|
||||
{
|
||||
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);
|
||||
auto segmentType = op.reg == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS)
|
||||
? TokenType::MnemonicUnusual : TokenType::MemorySegment;
|
||||
addToken(segmentType, _cp.RegName(mem.segment));
|
||||
addToken(TokenType::Uncategorized, ":");
|
||||
|
||||
//memory opening bracket
|
||||
auto bracketsType = TokenType::MemoryBrackets;
|
||||
switch(mem.base)
|
||||
{
|
||||
case X86_REG_ESP:
|
||||
case X86_REG_RSP:
|
||||
case X86_REG_EBP:
|
||||
case X86_REG_RBP:
|
||||
case ZYDIS_REGISTER_ESP:
|
||||
case ZYDIS_REGISTER_RSP:
|
||||
case ZYDIS_REGISTER_EBP:
|
||||
case ZYDIS_REGISTER_RBP:
|
||||
bracketsType = TokenType::MemoryStackBrackets;
|
||||
default:
|
||||
break;
|
||||
|
@ -558,9 +526,9 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
addToken(bracketsType, "[");
|
||||
|
||||
//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);
|
||||
auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::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
|
||||
{
|
||||
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));
|
||||
prependPlus = true;
|
||||
}
|
||||
if(mem.index != X86_REG_INVALID) //index register
|
||||
if(mem.index != ZYDIS_REGISTER_NONE) //index register
|
||||
{
|
||||
if(prependPlus)
|
||||
addMemoryOperator('+');
|
||||
|
@ -585,16 +553,16 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
}
|
||||
prependPlus = true;
|
||||
}
|
||||
if(mem.disp)
|
||||
if(mem.disp.value)
|
||||
{
|
||||
char operatorText = '+';
|
||||
TokenValue value(op.size, duint(mem.disp));
|
||||
auto displacementType = DbgMemIsValidReadPtr(duint(mem.disp)) ? TokenType::Address : TokenType::Value;
|
||||
TokenValue value(op.size, duint(mem.disp.value));
|
||||
auto displacementType = DbgMemIsValidReadPtr(duint(mem.disp.value)) ? TokenType::Address : TokenType::Value;
|
||||
QString valueText;
|
||||
if(mem.disp < 0)
|
||||
if(mem.disp.value < 0)
|
||||
{
|
||||
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
|
||||
valueText = printValue(value, false, _maxModuleLength);
|
||||
|
@ -611,7 +579,7 @@ bool CapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CapstoneTokenizer::tokenizeInvalidOperand(const cs_x86_op & op)
|
||||
bool CapstoneTokenizer::tokenizeInvalidOperand(const ZydisDecodedOperand & op)
|
||||
{
|
||||
addToken(TokenType::MnemonicUnusual, "???");
|
||||
return true;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _CAPSTONE_GUI_H
|
||||
#define _CAPSTONE_GUI_H
|
||||
|
||||
#include <capstone_wrapper.h>
|
||||
#include <zydis_wrapper.h>
|
||||
#include "RichTextPainter.h"
|
||||
#include "Configuration.h"
|
||||
#include <map>
|
||||
|
@ -187,11 +187,11 @@ private:
|
|||
bool tokenizePrefix();
|
||||
bool tokenizeMnemonic();
|
||||
bool tokenizeMnemonic(TokenType type, const QString & mnemonic);
|
||||
bool tokenizeOperand(const cs_x86_op & op);
|
||||
bool tokenizeRegOperand(const cs_x86_op & op);
|
||||
bool tokenizeImmOperand(const cs_x86_op & op);
|
||||
bool tokenizeMemOperand(const cs_x86_op & op);
|
||||
bool tokenizeInvalidOperand(const cs_x86_op & op);
|
||||
bool tokenizeOperand(const ZydisDecodedOperand & op);
|
||||
bool tokenizeRegOperand(const ZydisDecodedOperand & op);
|
||||
bool tokenizeImmOperand(const ZydisDecodedOperand & op);
|
||||
bool tokenizeMemOperand(const ZydisDecodedOperand & op);
|
||||
bool tokenizeInvalidOperand(const ZydisDecodedOperand & op);
|
||||
};
|
||||
|
||||
#endif //_CAPSTONE_GUI_H
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "LocalVarsView.h"
|
||||
#include "capstone_wrapper.h"
|
||||
#include "zydis_wrapper.h"
|
||||
#include "CPUMultiDump.h"
|
||||
#include "MiscUtil.h"
|
||||
#include "WordEditDialog.h"
|
||||
|
@ -210,18 +210,22 @@ void LocalVarsView::updateSlot()
|
|||
}
|
||||
for(int i = 0; i < dis.OpCount(); i++)
|
||||
{
|
||||
if(dis[i].type != X86_OP_MEM)
|
||||
if(dis[i].type != ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
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;
|
||||
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;
|
||||
const x86_reg registers[] =
|
||||
const ZydisRegister registers[] =
|
||||
{
|
||||
#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
|
||||
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
|
||||
};
|
||||
for(char j = 0; j < ArchValue(8, 16); j++)
|
||||
|
@ -229,7 +233,7 @@ void LocalVarsView::updateSlot()
|
|||
if(!baseRegisters[j]->isChecked())
|
||||
continue;
|
||||
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();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "main.h"
|
||||
#include "capstone_wrapper.h"
|
||||
#include "zydis_wrapper.h"
|
||||
#include "MainWindow.h"
|
||||
#include "Configuration.h"
|
||||
#include <QTextCodec>
|
||||
|
|
|
@ -67,7 +67,8 @@ INCLUDEPATH += \
|
|||
Src/Utils \
|
||||
Src/ThirdPartyLibs/snowman \
|
||||
Src/ThirdPartyLibs/ldconvert \
|
||||
../capstone_wrapper
|
||||
../capstone_wrapper \
|
||||
../zydis_wrapper
|
||||
|
||||
# Resources, sources, headers, and forms
|
||||
RESOURCES += \
|
||||
|
@ -347,15 +348,15 @@ LIBS += -luser32 -ladvapi32 -lwinmm -lshell32
|
|||
|
||||
!contains(QMAKE_HOST.arch, x86_64) {
|
||||
# Windows x86 (32bit) specific build
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/capstone" -lcapstone_x86
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/bin/x32$${DIR_SUFFIX}" -lcapstone_wrapper
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/Zydis" -lZydis_x86
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/bin/x32$${DIR_SUFFIX}" -lzydis_wrapper
|
||||
LIBS += -L"$$PWD/Src/ThirdPartyLibs/snowman" -lsnowman_x86
|
||||
LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x86
|
||||
LIBS += -L"$${X64_BIN_DIR}" -lx32bridge
|
||||
} else {
|
||||
# Windows x64 (64bit) specific build
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/capstone" -lcapstone_x64
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/bin/x64$${DIR_SUFFIX}" -lcapstone_wrapper
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/Zydis" -lZydis_x64
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/bin/x64$${DIR_SUFFIX}" -lzydis_wrapper
|
||||
LIBS += -L"$$PWD/Src/ThirdPartyLibs/snowman" -lsnowman_x64
|
||||
LIBS += -L"$$PWD/Src/ThirdPartyLibs/ldconvert" -lldconvert_x64
|
||||
LIBS += -L"$${X64_BIN_DIR}" -lx64bridge
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 093fbde4acbe897ecd080ed157b3d4bfb95323f3
|
Loading…
Reference in New Issue