Merge pull request #3192 from x64dbg/cross-platform-preparations
Cross platform preparations
This commit is contained in:
commit
7f2566b6ed
|
@ -1,13 +1,7 @@
|
|||
[submodule "src/gui/Translations"]
|
||||
path = src/gui/Translations
|
||||
url = ../Translations.git
|
||||
[submodule "src/dbg/btparser"]
|
||||
path = src/dbg/btparser
|
||||
url = ../btparser
|
||||
[submodule "deps"]
|
||||
path = deps
|
||||
url = ../deps
|
||||
shallow = true
|
||||
[submodule "src/zydis_wrapper/zydis"]
|
||||
path = src/zydis_wrapper/zydis
|
||||
url = ../zydis.git
|
||||
shallow = true
|
|
@ -176,7 +176,10 @@ extern "C"
|
|||
#define MAX_SECTION_SIZE 10
|
||||
#define MAX_COMMAND_LINE_SIZE 256
|
||||
#define MAX_MNEMONIC_SIZE 64
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE 0x1000
|
||||
#endif // PAGE_SIZE
|
||||
|
||||
//Debugger enums
|
||||
typedef enum
|
||||
|
|
|
@ -205,14 +205,14 @@ void TraceRecordManager::TraceExecute(duint address, duint size)
|
|||
//See https://www.felixcloutier.com/x86/FXSAVE.html, max 512 bytes
|
||||
#define memoryContentSize 512
|
||||
|
||||
static void HandleZydisOperand(const Zydis & cp, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char memoryContent[memoryContentSize], unsigned char* memorySize)
|
||||
static void HandleZydisOperand(const Zydis & zydis, int opindex, DISASM_ARGTYPE* argType, duint* value, unsigned char memoryContent[memoryContentSize], unsigned char* memorySize)
|
||||
{
|
||||
*value = cp.ResolveOpValue(opindex, [&cp](ZydisRegister reg)
|
||||
*value = (duint)zydis.ResolveOpValue(opindex, [&zydis](ZydisRegister reg) -> uint64_t
|
||||
{
|
||||
auto regName = cp.RegName(reg);
|
||||
auto regName = zydis.RegName(reg);
|
||||
return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching
|
||||
});
|
||||
const auto & op = cp[opindex];
|
||||
const auto & op = zydis[opindex];
|
||||
switch(op.type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
|
@ -269,7 +269,7 @@ void TraceRecordManager::TraceExecuteRecord(const Zydis & newInstruction)
|
|||
if(newInstruction.Success() && !newInstruction.IsNop() && newInstruction.GetId() != ZYDIS_MNEMONIC_LEA)
|
||||
{
|
||||
// This can happen when trace execute instruction is used, we need to fix that or something would go wrong with the GUI.
|
||||
newContext.registers.regcontext.cip = newInstruction.Address();
|
||||
newContext.registers.regcontext.cip = (duint)newInstruction.Address();
|
||||
DISASM_ARGTYPE argType;
|
||||
duint value;
|
||||
unsigned char memoryContent[memoryContentSize];
|
||||
|
@ -553,13 +553,13 @@ bool TraceRecordManager::enableTraceRecording(bool enabled, const char* fileName
|
|||
for(size_t i = 0; i < _countof(rtOldContextChanged); i++)
|
||||
rtOldContextChanged[i] = true;
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Started trace recording to file: %s\r\n"), fileName);
|
||||
Zydis cp;
|
||||
Zydis zydis;
|
||||
unsigned char instr[MAX_DISASM_BUFFER];
|
||||
auto cip = GetContextDataEx(hActiveThread, UE_CIP);
|
||||
if(MemRead(cip, instr, MAX_DISASM_BUFFER))
|
||||
{
|
||||
cp.DisassembleSafe(cip, instr, MAX_DISASM_BUFFER);
|
||||
TraceExecuteRecord(cp);
|
||||
zydis.DisassembleSafe(cip, instr, MAX_DISASM_BUFFER);
|
||||
TraceExecuteRecord(zydis);
|
||||
}
|
||||
GuiOpenTraceFile(fileName);
|
||||
return true;
|
||||
|
|
|
@ -102,8 +102,8 @@ extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
|
|||
unsigned char data[16];
|
||||
if(MemRead(addr, data, sizeof(data), nullptr, true))
|
||||
{
|
||||
Zydis cp;
|
||||
if(cp.Disassemble(addr, data))
|
||||
Zydis zydis;
|
||||
if(zydis.Disassemble(addr, data))
|
||||
{
|
||||
CONTEXT ctx;
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
|
@ -116,7 +116,7 @@ extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
|
|||
auto cflags = ctx.EFlags;
|
||||
auto ccx = ctx.Ecx;
|
||||
#endif //_WIN64
|
||||
return cp.IsBranchGoingToExecute(cflags, ccx);
|
||||
return zydis.IsBranchGoingToExecute(cflags, ccx);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -329,11 +329,11 @@ static bool getAutoComment(duint addr, String & comment)
|
|||
BRIDGE_ADDRINFO newinfo;
|
||||
char string_text[MAX_STRING_SIZE] = "";
|
||||
|
||||
Zydis cp;
|
||||
Zydis zydis;
|
||||
auto getregs = !bOnlyCipAutoComments || addr == lastContext.cip;
|
||||
disasmget(cp, addr, &instr, getregs);
|
||||
disasmget(zydis, addr, &instr, getregs);
|
||||
// Some nop variants have 'operands' that should be ignored
|
||||
if(cp.Success() && !cp.IsNop())
|
||||
if(zydis.Success() && !zydis.IsNop())
|
||||
{
|
||||
//Ignore register values when not on CIP and OnlyCipAutoComments is enabled: https://github.com/x64dbg/x64dbg/issues/1383
|
||||
if(!getregs)
|
||||
|
@ -342,7 +342,7 @@ static bool getAutoComment(duint addr, String & comment)
|
|||
instr.arg[i].value = instr.arg[i].constant;
|
||||
}
|
||||
|
||||
if(addr == lastContext.cip && (cp.GetId() == ZYDIS_MNEMONIC_SYSCALL || (cp.GetId() == ZYDIS_MNEMONIC_INT && cp[0].imm.value.u == 0x2e)))
|
||||
if(addr == lastContext.cip && (zydis.GetId() == ZYDIS_MNEMONIC_SYSCALL || (zydis.GetId() == ZYDIS_MNEMONIC_INT && zydis[0].imm.value.u == 0x2e)))
|
||||
{
|
||||
auto syscallName = SyscallToName((unsigned int)lastContext.cax);
|
||||
if(!syscallName.empty())
|
||||
|
@ -367,9 +367,9 @@ static bool getAutoComment(duint addr, String & comment)
|
|||
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.IsCall())
|
||||
if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && zydis.IsCall())
|
||||
temp_string.assign("call $0");
|
||||
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && cp.IsJump())
|
||||
else if(instr.arg[i].type == arg_normal && instr.arg[i].value == addr + instr.instr_size && zydis.IsJump())
|
||||
temp_string.assign("jmp $0");
|
||||
else if(instr.type == instr_branch)
|
||||
continue;
|
||||
|
@ -881,12 +881,12 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
|
|||
unsigned char data[MAX_DISASM_BUFFER];
|
||||
if(!MemIsValidReadPtr(addr, true) || !MemRead(addr, data, sizeof(data)))
|
||||
return 0;
|
||||
Zydis cp;
|
||||
if(!cp.Disassemble(addr, data))
|
||||
Zydis zydis;
|
||||
if(!zydis.Disassemble(addr, data))
|
||||
return 0;
|
||||
if(cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
|
||||
if(zydis.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
|
||||
{
|
||||
auto opValue = cp.ResolveOpValue(0, [](ZydisRegister reg) -> size_t
|
||||
auto opValue = (duint)zydis.ResolveOpValue(0, [](ZydisRegister reg) -> uint64_t
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
|
@ -949,10 +949,10 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
|
|||
return 0;
|
||||
}
|
||||
});
|
||||
if(cp.OpCount() && cp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
if(zydis.OpCount() && zydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
auto const tebseg = ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS);
|
||||
if(cp[0].mem.segment == tebseg)
|
||||
if(zydis[0].mem.segment == tebseg)
|
||||
opValue += duint(GetTEBLocation(hActiveThread));
|
||||
if(MemRead(opValue, &opValue, sizeof(opValue)))
|
||||
return opValue;
|
||||
|
@ -960,7 +960,7 @@ extern "C" DLL_EXPORT duint _dbg_getbranchdestination(duint addr)
|
|||
else
|
||||
return opValue;
|
||||
}
|
||||
if(cp.IsRet())
|
||||
if(zydis.IsRet())
|
||||
{
|
||||
auto csp = lastContext.csp;
|
||||
duint dest = 0;
|
||||
|
|
|
@ -31,9 +31,9 @@ bool CodeFollowPass::Analyse()
|
|||
return false;
|
||||
}
|
||||
|
||||
duint CodeFollowPass::GetReferenceOperand(const ZydisDecodedInstruction & Context)
|
||||
duint CodeFollowPass::GetReferenceOperand(const ZydisDisassembledInstruction & Context)
|
||||
{
|
||||
for(int i = 0; i < Context.operandCount; i++)
|
||||
for(int i = 0; i < Context.info.operand_count; i++)
|
||||
{
|
||||
auto operand = Context.operands[i];
|
||||
|
||||
|
@ -50,9 +50,9 @@ duint CodeFollowPass::GetReferenceOperand(const ZydisDecodedInstruction & Contex
|
|||
return 0;
|
||||
}
|
||||
|
||||
duint CodeFollowPass::GetMemoryOperand(Zydis & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect)
|
||||
duint CodeFollowPass::GetMemoryOperand(Zydis & Disasm, const ZydisDisassembledInstruction & Context, bool* Indirect)
|
||||
{
|
||||
if(Context.operandCount <= 0)
|
||||
if(Context.info.operand_count <= 0)
|
||||
return 0;
|
||||
|
||||
// Only the first operand matters
|
||||
|
|
|
@ -14,6 +14,6 @@ public:
|
|||
virtual bool Analyse() override;
|
||||
|
||||
private:
|
||||
duint GetReferenceOperand(const ZydisDecodedInstruction & Context);
|
||||
duint GetMemoryOperand(Zydis & Disasm, const ZydisDecodedInstruction & Context, bool* Indirect);
|
||||
duint GetReferenceOperand(const ZydisDisassembledInstruction & Context);
|
||||
duint GetMemoryOperand(Zydis & Disasm, const ZydisDisassembledInstruction & Context, bool* Indirect);
|
||||
};
|
|
@ -94,7 +94,7 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
|
|||
while(true)
|
||||
{
|
||||
node.icount++;
|
||||
if(!mCp.Disassemble(node.end, translateAddr(node.end)))
|
||||
if(!mZydis.Disassemble(node.end, translateAddr(node.end)))
|
||||
{
|
||||
if(writedata)
|
||||
mEncMap[node.end - mBase] = (byte)enc_byte;
|
||||
|
@ -109,7 +109,7 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
|
|||
}
|
||||
// If the memory range doesn't fit the entire instruction
|
||||
// mark it as bytes and finish this node
|
||||
if(!inRange(node.end + mCp.Size() - 1))
|
||||
if(!inRange(node.end + mZydis.Size() - 1))
|
||||
{
|
||||
duint remainingSize = mBase + mSize - node.end;
|
||||
memset(&mEncMap[node.end - mBase], (byte)enc_byte, remainingSize);
|
||||
|
@ -119,15 +119,15 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
|
|||
if(writedata)
|
||||
{
|
||||
mEncMap[node.end - mBase] = (byte)enc_code;
|
||||
for(int i = 1; i < mCp.Size(); i++)
|
||||
for(size_t i = 1; i < mZydis.Size(); i++)
|
||||
mEncMap[node.end - mBase + i] = (byte)enc_middle;
|
||||
}
|
||||
if(mCp.IsJump() || mCp.IsLoop()) //jump
|
||||
if(mZydis.IsJump() || mZydis.IsLoop()) //jump
|
||||
{
|
||||
//set the branch destinations
|
||||
node.brtrue = mCp.BranchDestination();
|
||||
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
|
||||
node.brfalse = node.end + mCp.Size();
|
||||
node.brtrue = (duint)mZydis.BranchDestination();
|
||||
if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
|
||||
node.brfalse = node.end + mZydis.Size();
|
||||
|
||||
//add node to the function graph
|
||||
graph.AddNode(node);
|
||||
|
@ -140,26 +140,26 @@ void AdvancedAnalysis::analyzeFunction(duint entryPoint, bool writedata)
|
|||
|
||||
break;
|
||||
}
|
||||
if(mCp.IsCall()) //call
|
||||
if(mZydis.IsCall()) //call
|
||||
{
|
||||
//TODO: handle no return
|
||||
duint target = mCp.BranchDestination();
|
||||
auto target = (duint)mZydis.BranchDestination();
|
||||
if(inRange(target) && mEntryPoints.find(target) == mEntryPoints.end())
|
||||
mCandidateEPs.insert(target);
|
||||
}
|
||||
if(mCp.IsRet()) //return
|
||||
if(mZydis.IsRet()) //return
|
||||
{
|
||||
node.terminal = true;
|
||||
graph.AddNode(node);
|
||||
break;
|
||||
}
|
||||
// If this instruction finishes the memory range, end the loop for this entry point
|
||||
if(!inRange(node.end + mCp.Size()))
|
||||
if(!inRange(node.end + mZydis.Size()))
|
||||
{
|
||||
graph.AddNode(node);
|
||||
break;
|
||||
}
|
||||
node.end += mCp.Size();
|
||||
node.end += mZydis.Size();
|
||||
}
|
||||
}
|
||||
mFunctions.push_back(graph);
|
||||
|
@ -173,20 +173,20 @@ void AdvancedAnalysis::linearXrefPass()
|
|||
|
||||
for(auto addr = mBase; addr < mBase + mSize;)
|
||||
{
|
||||
if(!mCp.Disassemble(addr, translateAddr(addr)))
|
||||
if(!mZydis.Disassemble(addr, translateAddr(addr)))
|
||||
{
|
||||
addr++;
|
||||
continue;
|
||||
}
|
||||
addr += mCp.Size();
|
||||
addr += mZydis.Size();
|
||||
|
||||
XREF xref;
|
||||
xref.valid = true;
|
||||
xref.addr = 0;
|
||||
xref.from = mCp.Address();
|
||||
for(auto i = 0; i < mCp.OpCount(); i++)
|
||||
xref.from = (duint)mZydis.Address();
|
||||
for(auto i = 0; i < mZydis.OpCount(); i++)
|
||||
{
|
||||
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
|
||||
auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
|
||||
{
|
||||
return 0;
|
||||
});
|
||||
|
@ -198,9 +198,9 @@ void AdvancedAnalysis::linearXrefPass()
|
|||
}
|
||||
if(xref.addr)
|
||||
{
|
||||
if(mCp.IsCall())
|
||||
if(mZydis.IsCall())
|
||||
xref.type = XREF_CALL;
|
||||
else if(mCp.IsJump())
|
||||
else if(mZydis.IsJump())
|
||||
xref.type = XREF_JMP;
|
||||
else
|
||||
xref.type = XREF_DATA;
|
||||
|
@ -270,16 +270,16 @@ void AdvancedAnalysis::writeDataXrefs()
|
|||
{
|
||||
if(xref.type == XREF_DATA && xref.valid)
|
||||
{
|
||||
if(!mCp.Disassemble(xref.from, translateAddr(xref.from)))
|
||||
if(!mZydis.Disassemble(xref.from, translateAddr(xref.from)))
|
||||
{
|
||||
xref.valid = false;
|
||||
continue;
|
||||
}
|
||||
auto opcode = mCp.GetId();
|
||||
auto opcode = mZydis.GetId();
|
||||
bool isfloat = isFloatInstruction(opcode);
|
||||
for(auto i = 0; i < mCp.OpCount(); i++)
|
||||
for(auto i = 0; i < mZydis.OpCount(); i++)
|
||||
{
|
||||
auto & op = mCp[i];
|
||||
auto & op = mZydis[i];
|
||||
ENCODETYPE type = enc_unknown;
|
||||
|
||||
//Todo: Analyze op type and set correct type
|
||||
|
|
|
@ -17,7 +17,7 @@ protected:
|
|||
duint mBase;
|
||||
duint mSize;
|
||||
unsigned char* mData;
|
||||
Zydis mCp;
|
||||
Zydis mZydis;
|
||||
|
||||
bool inRange(duint addr) const
|
||||
{
|
||||
|
|
|
@ -140,26 +140,26 @@ void ControlFlowAnalysis::BasicBlockStarts()
|
|||
for(duint i = 0; i < mSize;)
|
||||
{
|
||||
auto addr = mBase + i;
|
||||
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
{
|
||||
if(bSkipFilling) //handle filling skip mode
|
||||
{
|
||||
if(!mCp.IsFilling()) //do nothing until the filling stopped
|
||||
if(!mZydis.IsFilling()) //do nothing until the filling stopped
|
||||
{
|
||||
bSkipFilling = false;
|
||||
mBlockStarts.insert(addr);
|
||||
}
|
||||
}
|
||||
else if(mCp.IsRet()) //RET breaks control flow
|
||||
else if(mZydis.IsRet()) //RET breaks control flow
|
||||
{
|
||||
bSkipFilling = true; //skip INT3/NOP/whatever filling bytes (those are not part of the control flow)
|
||||
}
|
||||
else if(mCp.IsJump() || mCp.IsLoop()) //branches
|
||||
else if(mZydis.IsJump() || mZydis.IsLoop()) //branches
|
||||
{
|
||||
auto dest1 = getReferenceOperand();
|
||||
duint dest2 = 0;
|
||||
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump
|
||||
dest2 = addr + mCp.Size();
|
||||
if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //conditional jump
|
||||
dest2 = addr + mZydis.Size();
|
||||
|
||||
if(!dest1 && !dest2) //TODO: better code for this (make sure absolutely no filling is inserted)
|
||||
bSkipFilling = true;
|
||||
|
@ -168,7 +168,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
|
|||
if(dest2)
|
||||
mBlockStarts.insert(dest2);
|
||||
}
|
||||
else if(mCp.IsCall())
|
||||
else if(mZydis.IsCall())
|
||||
{
|
||||
auto dest1 = getReferenceOperand();
|
||||
if(dest1)
|
||||
|
@ -183,7 +183,7 @@ void ControlFlowAnalysis::BasicBlockStarts()
|
|||
if(dest1)
|
||||
mBlockStarts.insert(dest1);
|
||||
}
|
||||
i += mCp.Size();
|
||||
i += mZydis.Size();
|
||||
}
|
||||
else
|
||||
i++;
|
||||
|
@ -204,23 +204,23 @@ void ControlFlowAnalysis::BasicBlocks()
|
|||
for(duint addr = start, prevaddr; addr < mBase + mSize;)
|
||||
{
|
||||
prevaddr = addr;
|
||||
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
{
|
||||
if(mCp.IsRet())
|
||||
if(mZydis.IsRet())
|
||||
{
|
||||
insertBlock(BasicBlock(start, addr, 0, 0)); //leaf block
|
||||
break;
|
||||
}
|
||||
else if(mCp.IsJump() || mCp.IsLoop())
|
||||
else if(mZydis.IsJump() || mZydis.IsLoop())
|
||||
{
|
||||
auto dest1 = getReferenceOperand();
|
||||
auto dest2 = mCp.GetId() != ZYDIS_MNEMONIC_JMP ? addr + mCp.Size() : 0;
|
||||
auto dest2 = mZydis.GetId() != ZYDIS_MNEMONIC_JMP ? addr + mZydis.Size() : 0;
|
||||
insertBlock(BasicBlock(start, addr, dest1, dest2));
|
||||
insertParent(dest1, start);
|
||||
insertParent(dest2, start);
|
||||
break;
|
||||
}
|
||||
addr += mCp.Size();
|
||||
addr += mZydis.Size();
|
||||
}
|
||||
else
|
||||
addr++;
|
||||
|
@ -413,9 +413,9 @@ String ControlFlowAnalysis::blockToString(const BasicBlock* block)
|
|||
|
||||
duint ControlFlowAnalysis::getReferenceOperand() const
|
||||
{
|
||||
for(auto i = 0; i < mCp.OpCount(); i++)
|
||||
for(auto i = 0; i < mZydis.OpCount(); i++)
|
||||
{
|
||||
const auto & op = mCp[i];
|
||||
const auto & op = mZydis[i];
|
||||
if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
|
||||
{
|
||||
auto dest = duint(op.imm.value.u);
|
||||
|
@ -426,7 +426,7 @@ duint ControlFlowAnalysis::getReferenceOperand() const
|
|||
{
|
||||
auto dest = duint(op.mem.disp.value);
|
||||
if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative
|
||||
dest += mCp.Address() + mCp.Size();
|
||||
dest += (duint)mZydis.Address() + mZydis.Size();
|
||||
if(inRange(dest))
|
||||
return dest;
|
||||
}
|
||||
|
|
|
@ -45,12 +45,12 @@ void LinearAnalysis::populateReferences()
|
|||
for(duint i = 0; i < mSize;)
|
||||
{
|
||||
auto addr = mBase + i;
|
||||
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
{
|
||||
auto ref = getReferenceOperand();
|
||||
if(ref)
|
||||
mFunctions.push_back({ ref, 0 });
|
||||
i += mCp.Size();
|
||||
i += mZydis.Size();
|
||||
}
|
||||
else
|
||||
i++;
|
||||
|
@ -72,8 +72,8 @@ void LinearAnalysis::analyseFunctions()
|
|||
auto end = findFunctionEnd(function.start, maxaddr);
|
||||
if(end)
|
||||
{
|
||||
if(mCp.Disassemble(end, translateAddr(end), MAX_DISASM_BUFFER))
|
||||
function.end = end + mCp.Size() - 1;
|
||||
if(mZydis.Disassemble(end, translateAddr(end), MAX_DISASM_BUFFER))
|
||||
function.end = end + mZydis.Size() - 1;
|
||||
else
|
||||
function.end = end;
|
||||
}
|
||||
|
@ -83,10 +83,10 @@ void LinearAnalysis::analyseFunctions()
|
|||
duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
|
||||
{
|
||||
//disassemble first instruction for some heuristics
|
||||
if(mCp.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
|
||||
if(mZydis.Disassemble(start, translateAddr(start), MAX_DISASM_BUFFER))
|
||||
{
|
||||
//JMP [123456] ; import
|
||||
if(mCp.IsJump() && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
if(mZydis.IsJump() && mZydis.OpCount() && mZydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -95,14 +95,14 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
|
|||
duint jumpback = 0;
|
||||
for(duint addr = start, fardest = 0; addr < maxaddr;)
|
||||
{
|
||||
if(mCp.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
if(mZydis.Disassemble(addr, translateAddr(addr), MAX_DISASM_BUFFER))
|
||||
{
|
||||
if(addr + mCp.Size() > maxaddr) //we went past the maximum allowed address
|
||||
if(addr + mZydis.Size() > maxaddr) //we went past the maximum allowed address
|
||||
break;
|
||||
|
||||
if((mCp.IsJump() || mCp.IsLoop()) && mCp.OpCount() && mCp[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
|
||||
if((mZydis.IsJump() || mZydis.IsLoop()) && mZydis.OpCount() && mZydis[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
|
||||
{
|
||||
auto dest = duint(mCp[0].imm.value.u);
|
||||
auto dest = duint(mZydis[0].imm.value.u);
|
||||
|
||||
if(dest >= maxaddr) //jump across function boundaries
|
||||
{
|
||||
|
@ -112,19 +112,19 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
|
|||
{
|
||||
fardest = dest;
|
||||
}
|
||||
else if(end && dest < end && (mCp.GetId() == ZYDIS_MNEMONIC_JMP || mCp.GetId() == ZYDIS_MNEMONIC_LOOP)) //save the last JMP backwards
|
||||
else if(end && dest < end && (mZydis.GetId() == ZYDIS_MNEMONIC_JMP || mZydis.GetId() == ZYDIS_MNEMONIC_LOOP)) //save the last JMP backwards
|
||||
{
|
||||
jumpback = addr;
|
||||
}
|
||||
}
|
||||
else if(mCp.IsRet()) //possible function end?
|
||||
else if(mZydis.IsRet()) //possible function end?
|
||||
{
|
||||
end = addr;
|
||||
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
|
||||
break;
|
||||
}
|
||||
|
||||
addr += mCp.Size();
|
||||
addr += mZydis.Size();
|
||||
}
|
||||
else
|
||||
addr++;
|
||||
|
@ -134,10 +134,10 @@ duint LinearAnalysis::findFunctionEnd(duint start, duint maxaddr)
|
|||
|
||||
duint LinearAnalysis::getReferenceOperand() const
|
||||
{
|
||||
for(auto i = 0; i < mCp.OpCount(); i++)
|
||||
for(auto i = 0; i < mZydis.OpCount(); i++)
|
||||
{
|
||||
const auto & op = mCp[i];
|
||||
if(mCp.IsJump() || mCp.IsLoop()) //skip jumps/loops
|
||||
const auto & op = mZydis[i];
|
||||
if(mZydis.IsJump() || mZydis.IsLoop()) //skip jumps/loops
|
||||
continue;
|
||||
if(op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //we are looking for immediate references
|
||||
{
|
||||
|
|
|
@ -59,11 +59,11 @@ void RecursiveAnalysis::SetMarkers()
|
|||
duint rangeStart = 0, rangeEnd = 0, rangeInstructionCount = 0;
|
||||
for(auto rangeItr = blockRanges.begin(); rangeItr != blockRanges.end(); ++rangeItr)
|
||||
{
|
||||
auto disasmLen = [this](duint addr)
|
||||
auto disasmLen = [this](duint addr) -> size_t
|
||||
{
|
||||
if(!mCp.Disassemble(addr, translateAddr(addr)))
|
||||
if(!mZydis.Disassemble(addr, translateAddr(addr)))
|
||||
return 1;
|
||||
return mCp.Size();
|
||||
return mZydis.Size();
|
||||
};
|
||||
const auto & node = *rangeItr->second;
|
||||
if(!rangeStart)
|
||||
|
@ -171,14 +171,14 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
{
|
||||
if(!inRange(node.end))
|
||||
{
|
||||
node.end = mCp.Address();
|
||||
node.end = (duint)mZydis.Address();
|
||||
node.terminal = true;
|
||||
graph.AddNode(node);
|
||||
break;
|
||||
}
|
||||
|
||||
node.icount++;
|
||||
if(!mCp.Disassemble(node.end, translateAddr(node.end)))
|
||||
if(!mZydis.Disassemble(node.end, translateAddr(node.end)))
|
||||
{
|
||||
node.end++;
|
||||
continue;
|
||||
|
@ -187,10 +187,10 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
//do xref analysis on the instruction
|
||||
XREF xref;
|
||||
xref.addr = 0;
|
||||
xref.from = mCp.Address();
|
||||
for(auto i = 0; i < mCp.OpCount(); i++)
|
||||
xref.from = (duint)mZydis.Address();
|
||||
for(auto i = 0; i < mZydis.OpCount(); i++)
|
||||
{
|
||||
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
|
||||
auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
|
||||
{
|
||||
return 0;
|
||||
});
|
||||
|
@ -203,23 +203,23 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
if(xref.addr)
|
||||
mXrefs.push_back(xref);
|
||||
|
||||
if(!mCp.IsNop() && (mCp.IsJump() || mCp.IsLoop())) //non-nop jump
|
||||
if(!mZydis.IsNop() && (mZydis.IsJump() || mZydis.IsLoop())) //non-nop jump
|
||||
{
|
||||
//set the branch destinations
|
||||
node.brtrue = mCp.BranchDestination();
|
||||
if(mCp.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
|
||||
node.brfalse = node.end + mCp.Size();
|
||||
node.brtrue = (duint)mZydis.BranchDestination();
|
||||
if(mZydis.GetId() != ZYDIS_MNEMONIC_JMP) //unconditional jumps dont have a brfalse
|
||||
node.brfalse = node.end + mZydis.Size();
|
||||
|
||||
//consider register/memory branches as terminal nodes
|
||||
if(mCp.OpCount() && mCp[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
|
||||
if(mZydis.OpCount() && mZydis[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE)
|
||||
{
|
||||
//jmp ptr [index * sizeof(duint) + switchTable]
|
||||
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)))
|
||||
if(mZydis[0].type == ZYDIS_OPERAND_TYPE_MEMORY && mZydis[0].mem.base == ZYDIS_REGISTER_NONE && mZydis[0].mem.index != ZYDIS_REGISTER_NONE
|
||||
&& mZydis[0].mem.scale == sizeof(duint) && MemIsValidReadPtr(duint(mZydis[0].mem.disp.value)))
|
||||
{
|
||||
Memory<duint*> switchTable(512 * sizeof(duint));
|
||||
duint actualSize, index;
|
||||
MemRead(duint(mCp[0].mem.disp.value), switchTable(), 512 * sizeof(duint), &actualSize);
|
||||
MemRead(duint(mZydis[0].mem.disp.value), switchTable(), 512 * sizeof(duint), &actualSize);
|
||||
actualSize /= sizeof(duint);
|
||||
for(index = 0; index < actualSize; index++)
|
||||
if(MemIsCodePage(switchTable()[index], false) == false)
|
||||
|
@ -257,17 +257,17 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
|
||||
break;
|
||||
}
|
||||
if(mCp.IsCall())
|
||||
if(mZydis.IsCall())
|
||||
{
|
||||
//TODO: add this to a queue to be analyzed later
|
||||
}
|
||||
if(mCp.IsRet())
|
||||
if(mZydis.IsRet())
|
||||
{
|
||||
node.terminal = true;
|
||||
graph.AddNode(node);
|
||||
break;
|
||||
}
|
||||
node.end += mCp.Size();
|
||||
node.end += mZydis.Size();
|
||||
}
|
||||
}
|
||||
//second pass: split overlapping blocks introduced by backedges
|
||||
|
@ -279,7 +279,7 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
while(addr < node.end)
|
||||
{
|
||||
icount++;
|
||||
auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1;
|
||||
auto size = mZydis.Disassemble(addr, translateAddr(addr)) ? mZydis.Size() : 1;
|
||||
if(graph.nodes.count(addr + size))
|
||||
{
|
||||
node.end = addr;
|
||||
|
@ -312,10 +312,10 @@ void RecursiveAnalysis::analyzeFunction(duint entryPoint)
|
|||
auto addr = node.start;
|
||||
while(addr <= node.end) //disassemble all instructions
|
||||
{
|
||||
auto size = mCp.Disassemble(addr, translateAddr(addr)) ? mCp.Size() : 1;
|
||||
if(mCp.IsCall() && mCp.OpCount()) //call reg / call [reg+X]
|
||||
auto size = mZydis.Disassemble(addr, translateAddr(addr)) ? mZydis.Size() : 1;
|
||||
if(mZydis.IsCall() && mZydis.OpCount()) //call reg / call [reg+X]
|
||||
{
|
||||
auto & op = mCp[0];
|
||||
auto & op = mZydis[0];
|
||||
switch(op.type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
|
|
|
@ -17,19 +17,19 @@ void XrefsAnalysis::Analyse()
|
|||
|
||||
for(auto addr = mBase; addr < mBase + mSize;)
|
||||
{
|
||||
if(!mCp.Disassemble(addr, translateAddr(addr)))
|
||||
if(!mZydis.Disassemble(addr, translateAddr(addr)))
|
||||
{
|
||||
addr++;
|
||||
continue;
|
||||
}
|
||||
addr += mCp.Size();
|
||||
addr += mZydis.Size();
|
||||
|
||||
XREF xref;
|
||||
xref.addr = 0;
|
||||
xref.from = mCp.Address();
|
||||
for(auto i = 0; i < mCp.OpCount(); i++)
|
||||
xref.from = (duint)mZydis.Address();
|
||||
for(auto i = 0; i < mZydis.OpCount(); i++)
|
||||
{
|
||||
duint dest = mCp.ResolveOpValue(i, [](ZydisRegister)->size_t
|
||||
auto dest = (duint)mZydis.ResolveOpValue(i, [](ZydisRegister) -> uint64_t
|
||||
{
|
||||
return 0;
|
||||
});
|
||||
|
|
|
@ -504,7 +504,7 @@ static bool IsRepeated(const Zydis & zydis)
|
|||
case ZYDIS_MNEMONIC_SCASW:
|
||||
case ZYDIS_MNEMONIC_SCASD:
|
||||
case ZYDIS_MNEMONIC_SCASQ:
|
||||
return (zydis.GetInstr()->attributes & (ZYDIS_ATTRIB_HAS_REP | ZYDIS_ATTRIB_HAS_REPZ | ZYDIS_ATTRIB_HAS_REPNZ)) != 0;
|
||||
return (zydis.GetInstr()->info.attributes & (ZYDIS_ATTRIB_HAS_REP | ZYDIS_ATTRIB_HAS_REPZ | ZYDIS_ATTRIB_HAS_REPNZ)) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -710,9 +710,9 @@ static bool cbModCallFind(Zydis* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFI
|
|||
duint foundaddr = 0;
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
duint base = ModBaseFromAddr(disasm->Address()), size = 0;
|
||||
duint base = ModBaseFromAddr((duint)disasm->Address()), size = 0;
|
||||
if(!base)
|
||||
base = MemFindBaseAddr(disasm->Address(), &size);
|
||||
base = MemFindBaseAddr((duint)disasm->Address(), &size);
|
||||
else
|
||||
size = ModSizeFromAddr(base);
|
||||
if(!base || !size)
|
||||
|
|
|
@ -243,23 +243,26 @@ bool cbInstrZydis(int argc, char* argv[])
|
|||
if(!valfromstring(argv[2], &addr, false))
|
||||
return false;
|
||||
|
||||
Zydis cp;
|
||||
if(!cp.Disassemble(addr, data))
|
||||
Zydis zydis;
|
||||
if(!zydis.Disassemble(addr, data))
|
||||
{
|
||||
dputs_untranslated("Failed to disassemble!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto instr = cp.GetInstr();
|
||||
int argcount = instr->operandCount;
|
||||
dputs_untranslated(cp.InstructionText(true).c_str());
|
||||
dprintf_untranslated("prefix size: %d\n", instr->raw.prefixes.count);
|
||||
if(instr->attributes & ZYDIS_ATTRIB_HAS_REX)
|
||||
dprintf_untranslated("rex.W: %d, rex.R: %d, rex.X: %d, rex.B: %d, rex.data: %02x\n", instr->raw.rex.W, instr->raw.rex.R, instr->raw.rex.X, instr->raw.rex.B, instr->raw.rex.data[0]);
|
||||
dprintf_untranslated("disp.offset: %d, disp.size: %d\n", instr->raw.disp.offset, instr->raw.disp.size);
|
||||
dprintf_untranslated("imm[0].offset: %d, imm[0].size: %d\n", instr->raw.imm[0].offset, instr->raw.imm[0].size);
|
||||
dprintf_untranslated("imm[1].offset: %d, imm[1].size: %d\n", instr->raw.imm[1].offset, instr->raw.imm[1].size);
|
||||
dprintf_untranslated("size: %d, id: %d, opcount: %d\n", cp.Size(), cp.GetId(), instr->operandCount);
|
||||
auto instr = zydis.GetInstr();
|
||||
int argcount = zydis.OpCount();
|
||||
dputs_untranslated(zydis.InstructionText(true).c_str());
|
||||
dprintf_untranslated("prefix size: %d\n", instr->info.raw.prefix_count);
|
||||
if(instr->info.attributes & ZYDIS_ATTRIB_HAS_REX)
|
||||
{
|
||||
auto rexdata = data[instr->info.raw.rex.offset];
|
||||
dprintf_untranslated("rex.W: %d, rex.R: %d, rex.X: %d, rex.B: %d, rex.data: %02x\n", instr->info.raw.rex.W, instr->info.raw.rex.R, instr->info.raw.rex.X, instr->info.raw.rex.B, rexdata);
|
||||
}
|
||||
dprintf_untranslated("disp.offset: %d, disp.size: %d\n", instr->info.raw.disp.offset, instr->info.raw.disp.size);
|
||||
dprintf_untranslated("imm[0].offset: %d, imm[0].size: %d\n", instr->info.raw.imm[0].offset, instr->info.raw.imm[0].size);
|
||||
dprintf_untranslated("imm[1].offset: %d, imm[1].size: %d\n", instr->info.raw.imm[1].offset, instr->info.raw.imm[1].size);
|
||||
dprintf_untranslated("size: %d, id: %d, opcount: %d\n", zydis.Size(), zydis.GetId(), instr->info.operand_count);
|
||||
auto rwstr = [](uint8_t action)
|
||||
{
|
||||
switch(action)
|
||||
|
@ -297,11 +300,11 @@ bool cbInstrZydis(int argc, char* argv[])
|
|||
for(int i = 0; i < argcount; i++)
|
||||
{
|
||||
const auto & op = instr->operands[i];
|
||||
dprintf("operand %d (size: %d, access: %s, visibility: %s) \"%s\", ", i + 1, op.size, rwstr(op.action), vis(op.visibility), cp.OperandText(i).c_str());
|
||||
dprintf("operand %d (size: %d, access: %s, visibility: %s) \"%s\", ", i + 1, op.size, rwstr(op.actions), vis(op.visibility), zydis.OperandText(i).c_str());
|
||||
switch(op.type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
dprintf_untranslated("register: %s\n", cp.RegName(op.reg.value));
|
||||
dprintf_untranslated("register: %s\n", zydis.RegName(op.reg.value));
|
||||
break;
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
dprintf_untranslated("immediate: 0x%p\n", op.imm.value.u);
|
||||
|
@ -311,9 +314,9 @@ bool cbInstrZydis(int argc, char* argv[])
|
|||
//[base + index * scale +/- disp]
|
||||
const auto & mem = op.mem;
|
||||
dprintf_untranslated("memory segment: %s, base: %s, index: %s, scale: %d, displacement: 0x%p\n",
|
||||
cp.RegName(mem.segment),
|
||||
cp.RegName(mem.base),
|
||||
cp.RegName(mem.index),
|
||||
zydis.RegName(mem.segment),
|
||||
zydis.RegName(mem.base),
|
||||
zydis.RegName(mem.index),
|
||||
mem.scale,
|
||||
mem.disp.value);
|
||||
}
|
||||
|
@ -348,7 +351,7 @@ bool cbInstrVisualize(int argc, char* argv[])
|
|||
//DisassemblyBreakpointColor = #000000
|
||||
{
|
||||
//initialize
|
||||
Zydis _cp;
|
||||
Zydis zydis;
|
||||
duint _base = start;
|
||||
duint _size = maxaddr - start;
|
||||
Memory<unsigned char*> _data(_size);
|
||||
|
@ -376,14 +379,14 @@ bool cbInstrVisualize(int argc, char* argv[])
|
|||
|
||||
//continue algorithm
|
||||
const unsigned char* curData = (addr >= _base && addr < _base + _size) ? _data() + (addr - _base) : nullptr;
|
||||
if(_cp.Disassemble(addr, curData, MAX_DISASM_BUFFER))
|
||||
if(zydis.Disassemble(addr, curData, MAX_DISASM_BUFFER))
|
||||
{
|
||||
if(addr + _cp.Size() > maxaddr) //we went past the maximum allowed address
|
||||
if(addr + zydis.Size() > maxaddr) //we went past the maximum allowed address
|
||||
break;
|
||||
|
||||
if((_cp.IsJump() || _cp.IsLoop()) && _cp.OpCount() && _cp[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
|
||||
if((zydis.IsJump() || zydis.IsLoop()) && zydis.OpCount() && zydis[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) //jump
|
||||
{
|
||||
duint dest = (duint)_cp[0].imm.value.u;
|
||||
duint dest = (duint)zydis[0].imm.value.u;
|
||||
|
||||
if(dest >= maxaddr) //jump across function boundaries
|
||||
{
|
||||
|
@ -393,19 +396,19 @@ bool cbInstrVisualize(int argc, char* argv[])
|
|||
{
|
||||
fardest = dest;
|
||||
}
|
||||
else if(end && dest < end && _cp.GetId() == ZYDIS_MNEMONIC_JMP) //save the last JMP backwards
|
||||
else if(end && dest < end && zydis.GetId() == ZYDIS_MNEMONIC_JMP) //save the last JMP backwards
|
||||
{
|
||||
jumpback = addr;
|
||||
}
|
||||
}
|
||||
else if(_cp.IsRet()) //possible function end?
|
||||
else if(zydis.IsRet()) //possible function end?
|
||||
{
|
||||
end = addr;
|
||||
if(fardest < addr) //we stop if the farthest JXX destination forward is before this RET
|
||||
break;
|
||||
}
|
||||
|
||||
addr += _cp.Size();
|
||||
addr += zydis.Size();
|
||||
}
|
||||
else
|
||||
addr++;
|
||||
|
@ -471,22 +474,22 @@ bool cbInstrBriefcheck(int argc, char* argv[])
|
|||
return false;
|
||||
Memory<unsigned char*> buffer(size + 16);
|
||||
DbgMemRead(base, buffer(), size);
|
||||
Zydis cp;
|
||||
Zydis zydis;
|
||||
std::unordered_set<String> reported;
|
||||
for(duint i = 0; i < size;)
|
||||
{
|
||||
if(!cp.Disassemble(base + i, buffer() + i, 16))
|
||||
if(!zydis.Disassemble(base + i, buffer() + i, 16))
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
i += cp.Size();
|
||||
auto mnem = StringUtils::ToLower(cp.Mnemonic());
|
||||
i += zydis.Size();
|
||||
auto mnem = StringUtils::ToLower(zydis.Mnemonic());
|
||||
auto brief = MnemonicHelp::getBriefDescription(mnem.c_str());
|
||||
if(brief.length() || reported.count(mnem))
|
||||
continue;
|
||||
reported.insert(mnem);
|
||||
dprintf_untranslated("%p: %s\n", cp.Address(), mnem.c_str());
|
||||
dprintf_untranslated("%p: %s\n", zydis.Address(), mnem.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1263,8 +1263,8 @@ void cbRtrStep()
|
|||
#endif //_WIN64
|
||||
)
|
||||
{
|
||||
Zydis cp;
|
||||
if(cp.Disassemble(cip, data) && cp.IsRet())
|
||||
Zydis zydis;
|
||||
if(zydis.Disassemble(cip, data) && zydis.IsRet())
|
||||
reachedReturn = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,17 +83,17 @@ bool disasmfast(const unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* b
|
|||
{
|
||||
if(!data || !basicinfo)
|
||||
return false;
|
||||
Zydis cp;
|
||||
cp.Disassemble(addr, data, MAX_DISASM_BUFFER);
|
||||
if(trydisasmfast(data, addr, basicinfo, cp.Success() ? cp.Size() : 1))
|
||||
Zydis zydis;
|
||||
zydis.Disassemble(addr, data, MAX_DISASM_BUFFER);
|
||||
if(trydisasmfast(data, addr, basicinfo, zydis.Success() ? zydis.Size() : 1))
|
||||
return true;
|
||||
if(!cp.Success())
|
||||
if(!zydis.Success())
|
||||
{
|
||||
strcpy_s(basicinfo->instruction, "???");
|
||||
basicinfo->size = 1;
|
||||
return false;
|
||||
}
|
||||
fillbasicinfo(&cp, basicinfo);
|
||||
fillbasicinfo(&zydis, basicinfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n)
|
|||
unsigned char* pdata;
|
||||
|
||||
// Reset Disasm Structure
|
||||
Zydis cp;
|
||||
Zydis zydis;
|
||||
|
||||
// Check if the pointer is not null
|
||||
if(data == NULL)
|
||||
|
@ -58,10 +58,10 @@ duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n)
|
|||
{
|
||||
abuf[i % 128] = addr;
|
||||
|
||||
if(!cp.Disassemble(0, pdata, (int)size))
|
||||
if(!zydis.Disassemble(0, pdata, (int)size))
|
||||
cmdsize = 1;
|
||||
else
|
||||
cmdsize = cp.Size();
|
||||
cmdsize = zydis.Size();
|
||||
|
||||
pdata += cmdsize;
|
||||
addr += cmdsize;
|
||||
|
@ -82,7 +82,7 @@ duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n)
|
|||
unsigned char* pdata;
|
||||
|
||||
// Reset Disasm Structure
|
||||
Zydis cp;
|
||||
Zydis zydis;
|
||||
|
||||
if(data == NULL)
|
||||
return 0;
|
||||
|
@ -98,10 +98,10 @@ duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n)
|
|||
|
||||
for(i = 0; i < n && size > 0; i++)
|
||||
{
|
||||
if(!cp.Disassemble(0, pdata, (int)size))
|
||||
if(!zydis.Disassemble(0, pdata, (int)size))
|
||||
cmdsize = 1;
|
||||
else
|
||||
cmdsize = cp.Size();
|
||||
cmdsize = zydis.Size();
|
||||
|
||||
pdata += cmdsize;
|
||||
ip += cmdsize;
|
||||
|
@ -111,16 +111,16 @@ duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n)
|
|||
return ip;
|
||||
}
|
||||
|
||||
static void HandleZydisOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool getregs)
|
||||
static void HandleZydisOperand(Zydis & zydis, int opindex, DISASM_ARG* arg, bool getregs)
|
||||
{
|
||||
auto value = cp.ResolveOpValue(opindex, [&cp, getregs](ZydisRegister reg)
|
||||
auto value = (duint)zydis.ResolveOpValue(opindex, [&zydis, getregs](ZydisRegister reg)
|
||||
{
|
||||
auto regName = getregs ? cp.RegName(reg) : nullptr;
|
||||
auto regName = getregs ? zydis.RegName(reg) : nullptr;
|
||||
return regName ? getregister(nullptr, regName) : 0; //TODO: temporary needs enums + caching
|
||||
});
|
||||
const auto & op = cp[opindex];
|
||||
const auto & op = zydis[opindex];
|
||||
arg->segment = SEG_DEFAULT;
|
||||
auto opText = cp.OperandText(opindex);
|
||||
auto opText = zydis.OperandText(opindex);
|
||||
StringUtils::ReplaceAll(opText, "0x", "");
|
||||
strcpy_s(arg->mnemonic, opText.c_str());
|
||||
switch(op.type)
|
||||
|
@ -144,7 +144,7 @@ static void HandleZydisOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool ge
|
|||
arg->type = arg_memory;
|
||||
const auto & mem = op.mem;
|
||||
if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative
|
||||
arg->constant = cp.Address() + duint(mem.disp.value) + cp.Size();
|
||||
arg->constant = (duint)zydis.Address() + duint(mem.disp.value) + zydis.Size();
|
||||
else
|
||||
arg->constant = duint(mem.disp.value);
|
||||
if(mem.segment == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS))
|
||||
|
@ -216,13 +216,13 @@ static void HandleZydisOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool ge
|
|||
}
|
||||
}
|
||||
|
||||
void disasmget(Zydis & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
|
||||
void disasmget(Zydis & zydis, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
|
||||
{
|
||||
memset(instr, 0, sizeof(DISASM_INSTR));
|
||||
cp.Disassemble(addr, buffer, MAX_DISASM_BUFFER);
|
||||
if(trydisasm(buffer, addr, instr, cp.Success() ? cp.Size() : 1))
|
||||
zydis.Disassemble(addr, buffer, MAX_DISASM_BUFFER);
|
||||
if(trydisasm(buffer, addr, instr, zydis.Success() ? zydis.Size() : 1))
|
||||
return;
|
||||
if(!cp.Success())
|
||||
if(!zydis.Success())
|
||||
{
|
||||
strcpy_s(instr->instruction, "???");
|
||||
instr->instr_size = 1;
|
||||
|
@ -230,21 +230,21 @@ void disasmget(Zydis & cp, unsigned char* buffer, duint addr, DISASM_INSTR* inst
|
|||
instr->argcount = 0;
|
||||
return;
|
||||
}
|
||||
auto cpInstr = cp.GetInstr();
|
||||
strncpy_s(instr->instruction, cp.InstructionText().c_str(), _TRUNCATE);
|
||||
instr->instr_size = cpInstr->length;
|
||||
if(cp.IsBranchType(Zydis::BTJmp | Zydis::BTLoop | Zydis::BTRet | Zydis::BTCall))
|
||||
auto zyInstr = zydis.GetInstr();
|
||||
strncpy_s(instr->instruction, zydis.InstructionText().c_str(), _TRUNCATE);
|
||||
instr->instr_size = zyInstr->info.length;
|
||||
if(zydis.IsBranchType(Zydis::BTJmp | Zydis::BTLoop | Zydis::BTRet | Zydis::BTCall))
|
||||
instr->type = instr_branch;
|
||||
else if(strstr(instr->instruction, "sp") || strstr(instr->instruction, "bp"))
|
||||
instr->type = instr_stack;
|
||||
else
|
||||
instr->type = instr_normal;
|
||||
instr->argcount = cp.OpCount() <= 3 ? cp.OpCount() : 3;
|
||||
instr->argcount = zydis.OpCount() <= 3 ? zydis.OpCount() : 3;
|
||||
for(int i = 0; i < instr->argcount; i++)
|
||||
HandleZydisOperand(cp, i, &instr->arg[i], getregs);
|
||||
HandleZydisOperand(zydis, i, &instr->arg[i], getregs);
|
||||
}
|
||||
|
||||
void disasmget(Zydis & cp, duint addr, DISASM_INSTR* instr, bool getregs)
|
||||
void disasmget(Zydis & zydis, duint addr, DISASM_INSTR* instr, bool getregs)
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
{
|
||||
|
@ -254,15 +254,15 @@ void disasmget(Zydis & cp, duint addr, DISASM_INSTR* instr, bool getregs)
|
|||
}
|
||||
unsigned char buffer[MAX_DISASM_BUFFER] = "";
|
||||
if(MemRead(addr, buffer, sizeof(buffer)))
|
||||
disasmget(cp, buffer, addr, instr, getregs);
|
||||
disasmget(zydis, buffer, addr, instr, getregs);
|
||||
else
|
||||
memset(instr, 0, sizeof(DISASM_INSTR)); // Buffer overflow
|
||||
}
|
||||
|
||||
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
|
||||
{
|
||||
Zydis cp;
|
||||
disasmget(cp, buffer, addr, instr, getregs);
|
||||
Zydis zydis;
|
||||
disasmget(zydis, buffer, addr, instr, getregs);
|
||||
}
|
||||
|
||||
void disasmget(duint addr, DISASM_INSTR* instr, bool getregs)
|
||||
|
@ -532,10 +532,10 @@ bool disasmgetstringatwrapper(duint addr, char* dest, bool cache)
|
|||
|
||||
int disasmgetsize(duint addr, unsigned char* data)
|
||||
{
|
||||
Zydis cp;
|
||||
if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER))
|
||||
Zydis zydis;
|
||||
if(!zydis.Disassemble(addr, data, MAX_DISASM_BUFFER))
|
||||
return 1;
|
||||
return int(EncodeMapGetSize(addr, cp.Size()));
|
||||
return int(EncodeMapGetSize(addr, zydis.Size()));
|
||||
}
|
||||
|
||||
int disasmgetsize(duint addr)
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
//functions
|
||||
duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n);
|
||||
duint disasmnext(unsigned char* data, duint base, duint size, duint ip, int n);
|
||||
void disasmget(Zydis & cp, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true);
|
||||
void disasmget(Zydis & cp, duint addr, DISASM_INSTR* instr, bool getregs = true);
|
||||
void disasmget(Zydis & zydis, unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true);
|
||||
void disasmget(Zydis & zydis, duint addr, DISASM_INSTR* instr, bool getregs = true);
|
||||
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs = true);
|
||||
void disasmget(duint addr, DISASM_INSTR* instr, bool getregs = true);
|
||||
bool disasmispossiblestring(duint addr, STRING_TYPE* type = nullptr);
|
||||
|
|
|
@ -287,7 +287,7 @@ bool EncodeMapSetType(duint addr, duint size, ENCODETYPE type, bool* created)
|
|||
memset(map.data + offset, (byte)enc_middle, size);
|
||||
if(IsCodeType(type) && size > 1)
|
||||
{
|
||||
Zydis cp;
|
||||
Zydis zydis;
|
||||
Memory<unsigned char*> buffer(size);
|
||||
if(!MemRead(addr, buffer(), size))
|
||||
return false;
|
||||
|
@ -296,8 +296,8 @@ bool EncodeMapSetType(duint addr, duint size, ENCODETYPE type, bool* created)
|
|||
for(auto i = offset; i < offset + size;)
|
||||
{
|
||||
map.data[i] = (byte)type;
|
||||
cp.Disassemble(base + i, buffer() + bufferoffset, int(buffersize - bufferoffset));
|
||||
cmdsize = cp.Success() ? cp.Size() : 1;
|
||||
zydis.Disassemble(base + i, buffer() + bufferoffset, int(buffersize - bufferoffset));
|
||||
cmdsize = zydis.Success() ? zydis.Size() : 1;
|
||||
i += cmdsize;
|
||||
bufferoffset += cmdsize;
|
||||
buffersize -= cmdsize;
|
||||
|
|
|
@ -282,9 +282,9 @@ namespace Exprfunc
|
|||
unsigned char data[16];
|
||||
if(MemRead(addr, data, sizeof(data), nullptr, true))
|
||||
{
|
||||
Zydis cp;
|
||||
if(cp.Disassemble(addr, data))
|
||||
return cp.IsNop();
|
||||
Zydis zydis;
|
||||
if(zydis.Disassemble(addr, data))
|
||||
return zydis.IsNop();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|