Moved “zydis_wrapper” into root repo
- Instead, we directly use Zydis as a submodule now
This commit is contained in:
parent
da0d4415e3
commit
ca9401fdb7
|
|
@ -10,6 +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
|
||||
[submodule "src/zydis_wrapper/zydis"]
|
||||
path = src/zydis_wrapper/zydis
|
||||
url = https://github.com/zyantific/zydis.git
|
||||
|
|
|
|||
|
|
@ -389,13 +389,13 @@
|
|||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(ProjectDir)..\..\bin\x64\</OutDir>
|
||||
<TargetName>x64dbg</TargetName>
|
||||
<IncludePath>$(ProjectDir)..\zydis_wrapper;$(ProjectDir)..\capstone_wrapper;$(ProjectDir);$(ProjectDir)analysis;$(ProjectDir)commands;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(ProjectDir)..\zydis_wrapper;$(ProjectDir)..\zydis_wrapper\zydis\include;$(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)..\zydis_wrapper;$(ProjectDir)..\capstone_wrapper;$(ProjectDir);$(ProjectDir)analysis;$(ProjectDir)commands;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(ProjectDir)..\zydis_wrapper;$(ProjectDir)..\zydis_wrapper\zydis\include;$(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>$(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>
|
||||
<AdditionalDependencies>$(ProjectDir)..\zydis_wrapper\bin\x64\zydis_wrapper.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>$(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>
|
||||
<AdditionalDependencies>$(ProjectDir)..\zydis_wrapper\bin\x64d\zydis_wrapper.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" />
|
||||
|
|
|
|||
|
|
@ -1549,6 +1549,8 @@ Instruction_t Disassembly::DisassembleAt(dsint rva)
|
|||
goto _exit;
|
||||
if (cs_instr.instStr.startsWith("fstp")) // CS reports 3 operands but only prints 2 ... wat.
|
||||
goto _exit;
|
||||
if (cs_instr.instStr.startsWith("fnstsw")) // CS reports wrong 32 bit operand size (is 16)
|
||||
goto _exit;
|
||||
|
||||
auto insn_hex = cs_instr.dump.toHex().toStdString();
|
||||
auto cs = cs_instr.instStr.toStdString();
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ Instruction_t CsQBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBa
|
|||
return DecodeDataAt(data, size, origBase, origInstRVA, type);
|
||||
}
|
||||
//tokenize
|
||||
CsCapstoneTokenizer::InstructionToken cap;
|
||||
CapstoneTokenizer::InstructionToken cap;
|
||||
_tokenizer.Tokenize(origBase + origInstRVA, data, size, cap);
|
||||
int len = _tokenizer.Size();
|
||||
|
||||
|
|
@ -269,7 +269,7 @@ Instruction_t CsQBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBa
|
|||
Instruction_t CsQBeaEngine::DecodeDataAt(byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type)
|
||||
{
|
||||
//tokenize
|
||||
CsCapstoneTokenizer::InstructionToken cap;
|
||||
CapstoneTokenizer::InstructionToken cap;
|
||||
|
||||
auto & infoIter = dataInstMap.find(type);
|
||||
if(infoIter == dataInstMap.end())
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <QString>
|
||||
#include <vector>
|
||||
#include "cs_capstone_gui.h"
|
||||
#include "QBeaEngine.h" // for instruction_t
|
||||
|
||||
class EncodeMap;
|
||||
class CodeFoldingHelper;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ CapstoneTokenizer::CapstoneTokenizer(int maxModuleLength)
|
|||
SetConfig(false, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
CapstoneTokenizer::TokenColor colorNamesMap[CapstoneTokenizer::TokenType::Last];
|
||||
static CapstoneTokenizer::TokenColor colorNamesMap[CapstoneTokenizer::TokenType::Last];
|
||||
QHash<QString, int> CapstoneTokenizer::stringPoolMap;
|
||||
int CapstoneTokenizer::poolId = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@ CsCapstoneTokenizer::CsCapstoneTokenizer(int maxModuleLength)
|
|||
: _maxModuleLength(maxModuleLength),
|
||||
_success(false),
|
||||
isNop(false),
|
||||
_mnemonicType(TokenType::Uncategorized)
|
||||
_mnemonicType(CapstoneTokenizer::TokenType::Uncategorized)
|
||||
{
|
||||
SetConfig(false, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
CsCapstoneTokenizer::TokenColor colorNamesMap[CsCapstoneTokenizer::TokenType::Last];
|
||||
static CapstoneTokenizer::TokenColor colorNamesMap[CapstoneTokenizer::TokenType::Last];
|
||||
QHash<QString, int> CsCapstoneTokenizer::stringPoolMap;
|
||||
int CsCapstoneTokenizer::poolId = 0;
|
||||
|
||||
void CsCapstoneTokenizer::addColorName(TokenType type, QString color, QString backgroundColor)
|
||||
void CsCapstoneTokenizer::addColorName(CapstoneTokenizer::TokenType type, QString color, QString backgroundColor)
|
||||
{
|
||||
colorNamesMap[int(type)] = TokenColor(color, backgroundColor);
|
||||
colorNamesMap[int(type)] = CapstoneTokenizer::TokenColor(color, backgroundColor);
|
||||
}
|
||||
|
||||
void CsCapstoneTokenizer::addStringsToPool(const QString & strings)
|
||||
|
|
@ -32,42 +32,42 @@ void CsCapstoneTokenizer::addStringsToPool(const QString & strings)
|
|||
void CsCapstoneTokenizer::UpdateColors()
|
||||
{
|
||||
//filling
|
||||
addColorName(TokenType::Comma, "InstructionCommaColor", "InstructionCommaBackgroundColor");
|
||||
addColorName(TokenType::Space, "", "");
|
||||
addColorName(TokenType::ArgumentSpace, "", "");
|
||||
addColorName(TokenType::MemoryOperatorSpace, "", "");
|
||||
addColorName(CapstoneTokenizer::TokenType::Comma, "InstructionCommaColor", "InstructionCommaBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::Space, "", "");
|
||||
addColorName(CapstoneTokenizer::TokenType::ArgumentSpace, "", "");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemoryOperatorSpace, "", "");
|
||||
//general instruction parts
|
||||
addColorName(TokenType::Prefix, "InstructionPrefixColor", "InstructionPrefixBackgroundColor");
|
||||
addColorName(TokenType::Uncategorized, "InstructionUncategorizedColor", "InstructionUncategorizedBackgroundColor");
|
||||
addColorName(TokenType::Address, "InstructionAddressColor", "InstructionAddressBackgroundColor"); //jump/call destinations
|
||||
addColorName(TokenType::Value, "InstructionValueColor", "InstructionValueBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::Prefix, "InstructionPrefixColor", "InstructionPrefixBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::Uncategorized, "InstructionUncategorizedColor", "InstructionUncategorizedBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::Address, "InstructionAddressColor", "InstructionAddressBackgroundColor"); //jump/call destinations
|
||||
addColorName(CapstoneTokenizer::TokenType::Value, "InstructionValueColor", "InstructionValueBackgroundColor");
|
||||
//mnemonics
|
||||
addColorName(TokenType::MnemonicNormal, "InstructionMnemonicColor", "InstructionMnemonicBackgroundColor");
|
||||
addColorName(TokenType::MnemonicPushPop, "InstructionPushPopColor", "InstructionPushPopBackgroundColor");
|
||||
addColorName(TokenType::MnemonicCall, "InstructionCallColor", "InstructionCallBackgroundColor");
|
||||
addColorName(TokenType::MnemonicRet, "InstructionRetColor", "InstructionRetBackgroundColor");
|
||||
addColorName(TokenType::MnemonicCondJump, "InstructionConditionalJumpColor", "InstructionConditionalJumpBackgroundColor");
|
||||
addColorName(TokenType::MnemonicUncondJump, "InstructionUnconditionalJumpColor", "InstructionUnconditionalJumpBackgroundColor");
|
||||
addColorName(TokenType::MnemonicNop, "InstructionNopColor", "InstructionNopBackgroundColor");
|
||||
addColorName(TokenType::MnemonicFar, "InstructionFarColor", "InstructionFarBackgroundColor");
|
||||
addColorName(TokenType::MnemonicInt3, "InstructionInt3Color", "InstructionInt3BackgroundColor");
|
||||
addColorName(TokenType::MnemonicUnusual, "InstructionUnusualColor", "InstructionUnusualBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicNormal, "InstructionMnemonicColor", "InstructionMnemonicBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicPushPop, "InstructionPushPopColor", "InstructionPushPopBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicCall, "InstructionCallColor", "InstructionCallBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicRet, "InstructionRetColor", "InstructionRetBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicCondJump, "InstructionConditionalJumpColor", "InstructionConditionalJumpBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicUncondJump, "InstructionUnconditionalJumpColor", "InstructionUnconditionalJumpBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicNop, "InstructionNopColor", "InstructionNopBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicFar, "InstructionFarColor", "InstructionFarBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicInt3, "InstructionInt3Color", "InstructionInt3BackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MnemonicUnusual, "InstructionUnusualColor", "InstructionUnusualBackgroundColor");
|
||||
//memory
|
||||
addColorName(TokenType::MemorySize, "InstructionMemorySizeColor", "InstructionMemorySizeBackgroundColor");
|
||||
addColorName(TokenType::MemorySegment, "InstructionMemorySegmentColor", "InstructionMemorySegmentBackgroundColor");
|
||||
addColorName(TokenType::MemoryBrackets, "InstructionMemoryBracketsColor", "InstructionMemoryBracketsBackgroundColor");
|
||||
addColorName(TokenType::MemoryStackBrackets, "InstructionMemoryStackBracketsColor", "InstructionMemoryStackBracketsBackgroundColor");
|
||||
addColorName(TokenType::MemoryBaseRegister, "InstructionMemoryBaseRegisterColor", "InstructionMemoryBaseRegisterBackgroundColor");
|
||||
addColorName(TokenType::MemoryIndexRegister, "InstructionMemoryIndexRegisterColor", "InstructionMemoryIndexRegisterBackgroundColor");
|
||||
addColorName(TokenType::MemoryScale, "InstructionMemoryScaleColor", "InstructionMemoryScaleBackgroundColor");
|
||||
addColorName(TokenType::MemoryOperator, "InstructionMemoryOperatorColor", "InstructionMemoryOperatorBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemorySize, "InstructionMemorySizeColor", "InstructionMemorySizeBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemorySegment, "InstructionMemorySegmentColor", "InstructionMemorySegmentBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemoryBrackets, "InstructionMemoryBracketsColor", "InstructionMemoryBracketsBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemoryStackBrackets, "InstructionMemoryStackBracketsColor", "InstructionMemoryStackBracketsBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemoryBaseRegister, "InstructionMemoryBaseRegisterColor", "InstructionMemoryBaseRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemoryIndexRegister, "InstructionMemoryIndexRegisterColor", "InstructionMemoryIndexRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemoryScale, "InstructionMemoryScaleColor", "InstructionMemoryScaleBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MemoryOperator, "InstructionMemoryOperatorColor", "InstructionMemoryOperatorBackgroundColor");
|
||||
//registers
|
||||
addColorName(TokenType::GeneralRegister, "InstructionGeneralRegisterColor", "InstructionGeneralRegisterBackgroundColor");
|
||||
addColorName(TokenType::FpuRegister, "InstructionFpuRegisterColor", "InstructionFpuRegisterBackgroundColor");
|
||||
addColorName(TokenType::MmxRegister, "InstructionMmxRegisterColor", "InstructionMmxRegisterBackgroundColor");
|
||||
addColorName(TokenType::XmmRegister, "InstructionXmmRegisterColor", "InstructionXmmRegisterBackgroundColor");
|
||||
addColorName(TokenType::YmmRegister, "InstructionYmmRegisterColor", "InstructionYmmRegisterBackgroundColor");
|
||||
addColorName(TokenType::ZmmRegister, "InstructionZmmRegisterColor", "InstructionZmmRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::GeneralRegister, "InstructionGeneralRegisterColor", "InstructionGeneralRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::FpuRegister, "InstructionFpuRegisterColor", "InstructionFpuRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::MmxRegister, "InstructionMmxRegisterColor", "InstructionMmxRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::XmmRegister, "InstructionXmmRegisterColor", "InstructionXmmRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::YmmRegister, "InstructionYmmRegisterColor", "InstructionYmmRegisterBackgroundColor");
|
||||
addColorName(CapstoneTokenizer::TokenType::ZmmRegister, "InstructionZmmRegisterColor", "InstructionZmmRegisterBackgroundColor");
|
||||
}
|
||||
|
||||
void CsCapstoneTokenizer::UpdateStringPool()
|
||||
|
|
@ -109,9 +109,9 @@ void CsCapstoneTokenizer::UpdateStringPool()
|
|||
addStringsToPool("xmm15 ymm15");
|
||||
}
|
||||
|
||||
bool CsCapstoneTokenizer::Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction)
|
||||
bool CsCapstoneTokenizer::Tokenize(duint addr, const unsigned char* data, int datasize, CapstoneTokenizer::InstructionToken & instruction)
|
||||
{
|
||||
_inst = InstructionToken();
|
||||
_inst = CapstoneTokenizer::InstructionToken();
|
||||
|
||||
_success = _cp.DisassembleSafe(addr, data, datasize);
|
||||
if(_success)
|
||||
|
|
@ -124,9 +124,9 @@ bool CsCapstoneTokenizer::Tokenize(duint addr, const unsigned char* data, int da
|
|||
{
|
||||
if(i)
|
||||
{
|
||||
addToken(TokenType::Comma, ",");
|
||||
addToken(CapstoneTokenizer::TokenType::Comma, ",");
|
||||
if(_bArgumentSpaces)
|
||||
addToken(TokenType::ArgumentSpace, " ");
|
||||
addToken(CapstoneTokenizer::TokenType::ArgumentSpace, " ");
|
||||
}
|
||||
if(!tokenizeOperand(_cp[i]))
|
||||
return false;
|
||||
|
|
@ -135,14 +135,14 @@ bool CsCapstoneTokenizer::Tokenize(duint addr, const unsigned char* data, int da
|
|||
else
|
||||
{
|
||||
isNop = false;
|
||||
addToken(TokenType::MnemonicUnusual, "???");
|
||||
addToken(CapstoneTokenizer::TokenType::MnemonicUnusual, "???");
|
||||
}
|
||||
|
||||
if(_bNoHighlightOperands)
|
||||
{
|
||||
while(_inst.tokens.size() && _inst.tokens[_inst.tokens.size() - 1].type == TokenType::Space)
|
||||
while(_inst.tokens.size() && _inst.tokens[_inst.tokens.size() - 1].type == CapstoneTokenizer::TokenType::Space)
|
||||
_inst.tokens.pop_back();
|
||||
for(SingleToken & token : _inst.tokens)
|
||||
for(CapstoneTokenizer::SingleToken & token : _inst.tokens)
|
||||
token.type = _mnemonicType;
|
||||
}
|
||||
|
||||
|
|
@ -151,15 +151,15 @@ bool CsCapstoneTokenizer::Tokenize(duint addr, const unsigned char* data, int da
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CsCapstoneTokenizer::TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction)
|
||||
bool CsCapstoneTokenizer::TokenizeData(const QString & datatype, const QString & data, CapstoneTokenizer::InstructionToken & instruction)
|
||||
{
|
||||
_inst = InstructionToken();
|
||||
_inst = CapstoneTokenizer::InstructionToken();
|
||||
isNop = false;
|
||||
|
||||
if(!tokenizeMnemonic(TokenType::MnemonicNormal, datatype))
|
||||
if(!tokenizeMnemonic(CapstoneTokenizer::TokenType::MnemonicNormal, datatype))
|
||||
return false;
|
||||
|
||||
addToken(TokenType::Value, data);
|
||||
addToken(CapstoneTokenizer::TokenType::Value, data);
|
||||
|
||||
instruction = _inst;
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ const Capstone & CsCapstoneTokenizer::GetCapstone() const
|
|||
return _cp;
|
||||
}
|
||||
|
||||
void CsCapstoneTokenizer::TokenToRichText(const InstructionToken & instr, RichTextPainter::List & richTextList, const SingleToken* highlightToken)
|
||||
void CsCapstoneTokenizer::TokenToRichText(const CapstoneTokenizer::InstructionToken & instr, RichTextPainter::List & richTextList, const CapstoneTokenizer::SingleToken* highlightToken)
|
||||
{
|
||||
QColor highlightColor = ConfigColor("InstructionHighlightColor");
|
||||
for(const auto & token : instr.tokens)
|
||||
|
|
@ -210,7 +210,7 @@ void CsCapstoneTokenizer::TokenToRichText(const InstructionToken & instr, RichTe
|
|||
richText.highlightColor = highlightColor;
|
||||
richText.flags = RichTextPainter::FlagNone;
|
||||
richText.text = token.text;
|
||||
if(token.type < TokenType::Last)
|
||||
if(token.type < CapstoneTokenizer::TokenType::Last)
|
||||
{
|
||||
const auto & tokenColor = colorNamesMap[int(token.type)];
|
||||
richText.flags = tokenColor.flags;
|
||||
|
|
@ -221,7 +221,7 @@ void CsCapstoneTokenizer::TokenToRichText(const InstructionToken & instr, RichTe
|
|||
}
|
||||
}
|
||||
|
||||
bool CsCapstoneTokenizer::TokenFromX(const InstructionToken & instr, SingleToken & token, int x, CachedFontMetrics* fontMetrics)
|
||||
bool CsCapstoneTokenizer::TokenFromX(const CapstoneTokenizer::InstructionToken & instr, CapstoneTokenizer::SingleToken & token, int x, CachedFontMetrics* fontMetrics)
|
||||
{
|
||||
if(x < instr.x) //before the first token
|
||||
return false;
|
||||
|
|
@ -241,18 +241,18 @@ bool CsCapstoneTokenizer::TokenFromX(const InstructionToken & instr, SingleToken
|
|||
return false; //not found
|
||||
}
|
||||
|
||||
bool CsCapstoneTokenizer::IsHighlightableToken(const SingleToken & token)
|
||||
bool CsCapstoneTokenizer::IsHighlightableToken(const CapstoneTokenizer::SingleToken & token)
|
||||
{
|
||||
switch(token.type)
|
||||
{
|
||||
case TokenType::Comma:
|
||||
case TokenType::Space:
|
||||
case TokenType::ArgumentSpace:
|
||||
case TokenType::Uncategorized:
|
||||
case TokenType::MemoryOperatorSpace:
|
||||
case TokenType::MemoryBrackets:
|
||||
case TokenType::MemoryStackBrackets:
|
||||
case TokenType::MemoryOperator:
|
||||
case CapstoneTokenizer::TokenType::Comma:
|
||||
case CapstoneTokenizer::TokenType::Space:
|
||||
case CapstoneTokenizer::TokenType::ArgumentSpace:
|
||||
case CapstoneTokenizer::TokenType::Uncategorized:
|
||||
case CapstoneTokenizer::TokenType::MemoryOperatorSpace:
|
||||
case CapstoneTokenizer::TokenType::MemoryBrackets:
|
||||
case CapstoneTokenizer::TokenType::MemoryStackBrackets:
|
||||
case CapstoneTokenizer::TokenType::MemoryOperator:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -270,7 +270,7 @@ bool CsCapstoneTokenizer::tokenTextPoolEquals(const QString & a, const QString &
|
|||
return found1.value() == found2.value();
|
||||
}
|
||||
|
||||
bool CsCapstoneTokenizer::TokenEquals(const SingleToken* a, const SingleToken* b, bool ignoreSize)
|
||||
bool CsCapstoneTokenizer::TokenEquals(const CapstoneTokenizer::SingleToken* a, const CapstoneTokenizer::SingleToken* b, bool ignoreSize)
|
||||
{
|
||||
if(!a || !b)
|
||||
return false;
|
||||
|
|
@ -284,13 +284,13 @@ bool CsCapstoneTokenizer::TokenEquals(const SingleToken* a, const SingleToken* b
|
|||
return tokenTextPoolEquals(a->text, b->text);
|
||||
}
|
||||
|
||||
void CsCapstoneTokenizer::addToken(TokenType type, QString text, const TokenValue & value)
|
||||
void CsCapstoneTokenizer::addToken(CapstoneTokenizer::TokenType type, QString text, const CapstoneTokenizer::TokenValue & value)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TokenType::Space:
|
||||
case TokenType::ArgumentSpace:
|
||||
case TokenType::MemoryOperatorSpace:
|
||||
case CapstoneTokenizer::TokenType::Space:
|
||||
case CapstoneTokenizer::TokenType::ArgumentSpace:
|
||||
case CapstoneTokenizer::TokenType::MemoryOperatorSpace:
|
||||
break;
|
||||
default:
|
||||
text = text.trimmed();
|
||||
|
|
@ -298,26 +298,26 @@ void CsCapstoneTokenizer::addToken(TokenType type, QString text, const TokenValu
|
|||
}
|
||||
if(_bUppercase && !value.size)
|
||||
text = text.toUpper();
|
||||
_inst.tokens.push_back(SingleToken(isNop ? TokenType::MnemonicNop : type, text, value));
|
||||
_inst.tokens.push_back(CapstoneTokenizer::SingleToken(isNop ? CapstoneTokenizer::TokenType::MnemonicNop : type, text, value));
|
||||
}
|
||||
|
||||
void CsCapstoneTokenizer::addToken(TokenType type, const QString & text)
|
||||
void CsCapstoneTokenizer::addToken(CapstoneTokenizer::TokenType type, const QString & text)
|
||||
{
|
||||
addToken(type, text, TokenValue());
|
||||
addToken(type, text, CapstoneTokenizer::TokenValue());
|
||||
}
|
||||
|
||||
void CsCapstoneTokenizer::addMemoryOperator(char operatorText)
|
||||
{
|
||||
if(_bMemorySpaces)
|
||||
addToken(TokenType::MemoryOperatorSpace, " ");
|
||||
addToken(CapstoneTokenizer::TokenType::MemoryOperatorSpace, " ");
|
||||
QString text;
|
||||
text += operatorText;
|
||||
addToken(TokenType::MemoryOperator, text);
|
||||
addToken(CapstoneTokenizer::TokenType::MemoryOperator, text);
|
||||
if(_bMemorySpaces)
|
||||
addToken(TokenType::MemoryOperatorSpace, " ");
|
||||
addToken(CapstoneTokenizer::TokenType::MemoryOperatorSpace, " ");
|
||||
}
|
||||
|
||||
QString CsCapstoneTokenizer::printValue(const TokenValue & value, bool expandModule, int maxModuleLength) const
|
||||
QString CsCapstoneTokenizer::printValue(const CapstoneTokenizer::TokenValue & value, bool expandModule, int maxModuleLength) const
|
||||
{
|
||||
QString labelText;
|
||||
char label_[MAX_LABEL_SIZE] = "";
|
||||
|
|
@ -380,8 +380,8 @@ bool CsCapstoneTokenizer::tokenizePrefix()
|
|||
|
||||
if(hasPrefix)
|
||||
{
|
||||
addToken(TokenType::Prefix, prefixText);
|
||||
addToken(TokenType::Space, " ");
|
||||
addToken(CapstoneTokenizer::TokenType::Prefix, prefixText);
|
||||
addToken(CapstoneTokenizer::TokenType::Space, " ");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -390,31 +390,31 @@ bool CsCapstoneTokenizer::tokenizePrefix()
|
|||
bool CsCapstoneTokenizer::tokenizeMnemonic()
|
||||
{
|
||||
QString mnemonic = QString(_cp.Mnemonic().c_str());
|
||||
_mnemonicType = TokenType::MnemonicNormal;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicNormal;
|
||||
auto id = _cp.GetId();
|
||||
if(isNop)
|
||||
_mnemonicType = TokenType::MnemonicNop;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicNop;
|
||||
else if(_cp.InGroup(CS_GRP_CALL))
|
||||
_mnemonicType = TokenType::MnemonicCall;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicCall;
|
||||
else if(_cp.InGroup(CS_GRP_JUMP) || _cp.IsLoop())
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case X86_INS_JMP:
|
||||
case X86_INS_LJMP:
|
||||
_mnemonicType = TokenType::MnemonicUncondJump;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicUncondJump;
|
||||
break;
|
||||
default:
|
||||
_mnemonicType = TokenType::MnemonicCondJump;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicCondJump;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(_cp.IsInt3())
|
||||
_mnemonicType = TokenType::MnemonicInt3;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicInt3;
|
||||
else if(_cp.IsUnusual())
|
||||
_mnemonicType = TokenType::MnemonicUnusual;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicUnusual;
|
||||
else if(_cp.InGroup(CS_GRP_RET))
|
||||
_mnemonicType = TokenType::MnemonicRet;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicRet;
|
||||
else
|
||||
{
|
||||
switch(id)
|
||||
|
|
@ -431,7 +431,7 @@ bool CsCapstoneTokenizer::tokenizeMnemonic()
|
|||
case X86_INS_POPFQ:
|
||||
case X86_INS_POPAL:
|
||||
case X86_INS_POPAW:
|
||||
_mnemonicType = TokenType::MnemonicPushPop;
|
||||
_mnemonicType = CapstoneTokenizer::TokenType::MnemonicPushPop;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -443,7 +443,7 @@ bool CsCapstoneTokenizer::tokenizeMnemonic()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CsCapstoneTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemonic)
|
||||
bool CsCapstoneTokenizer::tokenizeMnemonic(CapstoneTokenizer::TokenType type, const QString & mnemonic)
|
||||
{
|
||||
addToken(type, mnemonic);
|
||||
if(_bTabbedMnemonic)
|
||||
|
|
@ -452,10 +452,10 @@ bool CsCapstoneTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemo
|
|||
if(spaceCount > 0)
|
||||
{
|
||||
for(int i = 0; i < spaceCount; i++)
|
||||
addToken(TokenType::Space, " ");
|
||||
addToken(CapstoneTokenizer::TokenType::Space, " ");
|
||||
}
|
||||
}
|
||||
addToken(TokenType::Space, " ");
|
||||
addToken(CapstoneTokenizer::TokenType::Space, " ");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -478,22 +478,22 @@ bool CsCapstoneTokenizer::tokenizeOperand(const cs_x86_op & op)
|
|||
|
||||
bool CsCapstoneTokenizer::tokenizeRegOperand(const cs_x86_op & op)
|
||||
{
|
||||
auto registerType = TokenType::GeneralRegister;
|
||||
auto registerType = CapstoneTokenizer::TokenType::GeneralRegister;
|
||||
auto reg = op.reg;
|
||||
if(reg >= X86_REG_FP0 && reg <= X86_REG_FP7)
|
||||
registerType = TokenType::FpuRegister;
|
||||
registerType = CapstoneTokenizer::TokenType::FpuRegister;
|
||||
else if(reg >= X86_REG_ST0 && reg <= X86_REG_ST7)
|
||||
registerType = TokenType::FpuRegister;
|
||||
registerType = CapstoneTokenizer::TokenType::FpuRegister;
|
||||
else if(reg >= X86_REG_MM0 && reg <= X86_REG_MM7)
|
||||
registerType = TokenType::MmxRegister;
|
||||
registerType = CapstoneTokenizer::TokenType::MmxRegister;
|
||||
else if(reg >= X86_REG_XMM0 && reg <= X86_REG_XMM31)
|
||||
registerType = TokenType::XmmRegister;
|
||||
registerType = CapstoneTokenizer::TokenType::XmmRegister;
|
||||
else if(reg >= X86_REG_YMM0 && reg <= X86_REG_YMM31)
|
||||
registerType = TokenType::YmmRegister;
|
||||
registerType = CapstoneTokenizer::TokenType::YmmRegister;
|
||||
else if(reg >= X86_REG_ZMM0 && reg <= X86_REG_ZMM31)
|
||||
registerType = TokenType::ZmmRegister;
|
||||
registerType = CapstoneTokenizer::TokenType::ZmmRegister;
|
||||
else if(reg == ArchValue(X86_REG_FS, X86_REG_GS))
|
||||
registerType = TokenType::MnemonicUnusual;
|
||||
registerType = CapstoneTokenizer::TokenType::MnemonicUnusual;
|
||||
addToken(registerType, _cp.RegName(reg));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -501,10 +501,10 @@ bool CsCapstoneTokenizer::tokenizeRegOperand(const cs_x86_op & op)
|
|||
bool CsCapstoneTokenizer::tokenizeImmOperand(const cs_x86_op & op)
|
||||
{
|
||||
auto value = duint(op.imm) & (duint(-1) >> (op.size ? 8 * (sizeof(duint) - op.size) : 0));
|
||||
auto valueType = TokenType::Value;
|
||||
auto valueType = CapstoneTokenizer::TokenType::Value;
|
||||
if(_cp.InGroup(CS_GRP_JUMP) || _cp.InGroup(CS_GRP_CALL) || _cp.IsLoop())
|
||||
valueType = TokenType::Address;
|
||||
auto tokenValue = TokenValue(op.size, value);
|
||||
valueType = CapstoneTokenizer::TokenType::Address;
|
||||
auto tokenValue = CapstoneTokenizer::TokenValue(op.size, value);
|
||||
addToken(valueType, printValue(tokenValue, true, _maxModuleLength), tokenValue);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -515,8 +515,8 @@ bool CsCapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
const char* sizeText = _cp.MemSizeName(op.size);
|
||||
if(!sizeText)
|
||||
return false;
|
||||
addToken(TokenType::MemorySize, QString(sizeText) + " ptr");
|
||||
addToken(TokenType::Space, " ");
|
||||
addToken(CapstoneTokenizer::TokenType::MemorySize, QString(sizeText) + " ptr");
|
||||
addToken(CapstoneTokenizer::TokenType::Space, " ");
|
||||
|
||||
//memory segment
|
||||
const auto & mem = op.mem;
|
||||
|
|
@ -539,19 +539,19 @@ bool CsCapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
break;
|
||||
}
|
||||
}
|
||||
auto segmentType = op.reg == ArchValue(X86_REG_FS, X86_REG_GS) ? TokenType::MnemonicUnusual : TokenType::MemorySegment;
|
||||
auto segmentType = op.reg == ArchValue(X86_REG_FS, X86_REG_GS) ? CapstoneTokenizer::TokenType::MnemonicUnusual : CapstoneTokenizer::TokenType::MemorySegment;
|
||||
addToken(segmentType, segmentText);
|
||||
addToken(TokenType::Uncategorized, ":");
|
||||
addToken(CapstoneTokenizer::TokenType::Uncategorized, ":");
|
||||
|
||||
//memory opening bracket
|
||||
auto bracketsType = TokenType::MemoryBrackets;
|
||||
auto bracketsType = CapstoneTokenizer::TokenType::MemoryBrackets;
|
||||
switch(mem.base)
|
||||
{
|
||||
case X86_REG_ESP:
|
||||
case X86_REG_RSP:
|
||||
case X86_REG_EBP:
|
||||
case X86_REG_RBP:
|
||||
bracketsType = TokenType::MemoryStackBrackets;
|
||||
bracketsType = CapstoneTokenizer::TokenType::MemoryStackBrackets;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -561,8 +561,8 @@ bool CsCapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
if(mem.base == X86_REG_RIP) //rip-relative (#replacement)
|
||||
{
|
||||
duint addr = _cp.Address() + duint(mem.disp) + _cp.Size();
|
||||
TokenValue value = TokenValue(op.size, addr);
|
||||
auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::Value;
|
||||
CapstoneTokenizer::TokenValue value = CapstoneTokenizer::TokenValue(op.size, addr);
|
||||
auto displacementType = DbgMemIsValidReadPtr(addr) ? CapstoneTokenizer::TokenType::Address : CapstoneTokenizer::TokenType::Value;
|
||||
addToken(displacementType, printValue(value, false, _maxModuleLength), value);
|
||||
}
|
||||
else //#base + #index * #scale + #displacement
|
||||
|
|
@ -570,31 +570,31 @@ bool CsCapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
bool prependPlus = false;
|
||||
if(mem.base != X86_REG_INVALID) //base register
|
||||
{
|
||||
addToken(TokenType::MemoryBaseRegister, _cp.RegName(mem.base));
|
||||
addToken(CapstoneTokenizer::TokenType::MemoryBaseRegister, _cp.RegName(mem.base));
|
||||
prependPlus = true;
|
||||
}
|
||||
if(mem.index != X86_REG_INVALID) //index register
|
||||
{
|
||||
if(prependPlus)
|
||||
addMemoryOperator('+');
|
||||
addToken(TokenType::MemoryIndexRegister, _cp.RegName(mem.index));
|
||||
addToken(CapstoneTokenizer::TokenType::MemoryIndexRegister, _cp.RegName(mem.index));
|
||||
if(mem.scale > 1)
|
||||
{
|
||||
addMemoryOperator('*');
|
||||
addToken(TokenType::MemoryScale, QString().sprintf("%d", mem.scale));
|
||||
addToken(CapstoneTokenizer::TokenType::MemoryScale, QString().sprintf("%d", mem.scale));
|
||||
}
|
||||
prependPlus = true;
|
||||
}
|
||||
if(mem.disp)
|
||||
{
|
||||
char operatorText = '+';
|
||||
TokenValue value(op.size, duint(mem.disp));
|
||||
auto displacementType = DbgMemIsValidReadPtr(duint(mem.disp)) ? TokenType::Address : TokenType::Value;
|
||||
CapstoneTokenizer::TokenValue value(op.size, duint(mem.disp));
|
||||
auto displacementType = DbgMemIsValidReadPtr(duint(mem.disp)) ? CapstoneTokenizer::TokenType::Address : CapstoneTokenizer::TokenType::Value;
|
||||
QString valueText;
|
||||
if(mem.disp < 0)
|
||||
{
|
||||
operatorText = '-';
|
||||
valueText = printValue(TokenValue(op.size, duint(mem.disp * -1)), false, _maxModuleLength);
|
||||
valueText = printValue(CapstoneTokenizer::TokenValue(op.size, duint(mem.disp * -1)), false, _maxModuleLength);
|
||||
}
|
||||
else
|
||||
valueText = printValue(value, false, _maxModuleLength);
|
||||
|
|
@ -603,7 +603,7 @@ bool CsCapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
addToken(displacementType, valueText, value);
|
||||
}
|
||||
else if(!prependPlus)
|
||||
addToken(TokenType::Value, "0");
|
||||
addToken(CapstoneTokenizer::TokenType::Value, "0");
|
||||
}
|
||||
|
||||
//closing bracket
|
||||
|
|
@ -613,6 +613,6 @@ bool CsCapstoneTokenizer::tokenizeMemOperand(const cs_x86_op & op)
|
|||
|
||||
bool CsCapstoneTokenizer::tokenizeInvalidOperand(const cs_x86_op & op)
|
||||
{
|
||||
addToken(TokenType::MnemonicUnusual, "???");
|
||||
addToken(CapstoneTokenizer::TokenType::MnemonicUnusual, "???");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,144 +8,14 @@
|
|||
#include <QHash>
|
||||
#include <QtCore>
|
||||
|
||||
#include "capstone_gui.h"
|
||||
|
||||
class CsCapstoneTokenizer
|
||||
{
|
||||
public:
|
||||
enum class TokenType
|
||||
{
|
||||
//filling
|
||||
Comma = 0,
|
||||
Space,
|
||||
ArgumentSpace,
|
||||
MemoryOperatorSpace,
|
||||
//general instruction parts
|
||||
Prefix,
|
||||
Uncategorized,
|
||||
//mnemonics
|
||||
MnemonicNormal,
|
||||
MnemonicPushPop,
|
||||
MnemonicCall,
|
||||
MnemonicRet,
|
||||
MnemonicCondJump,
|
||||
MnemonicUncondJump,
|
||||
MnemonicNop,
|
||||
MnemonicFar,
|
||||
MnemonicInt3,
|
||||
MnemonicUnusual,
|
||||
//values
|
||||
Address, //jump/call destinations or displacements inside memory
|
||||
Value,
|
||||
//memory
|
||||
MemorySize,
|
||||
MemorySegment,
|
||||
MemoryBrackets,
|
||||
MemoryStackBrackets,
|
||||
MemoryBaseRegister,
|
||||
MemoryIndexRegister,
|
||||
MemoryScale,
|
||||
MemoryOperator, //'+', '-' and '*'
|
||||
//registers
|
||||
GeneralRegister,
|
||||
FpuRegister,
|
||||
MmxRegister,
|
||||
XmmRegister,
|
||||
YmmRegister,
|
||||
ZmmRegister,
|
||||
//last
|
||||
Last
|
||||
};
|
||||
|
||||
struct TokenValue
|
||||
{
|
||||
int size; //value size (in bytes), zero means no value
|
||||
duint value; //actual value
|
||||
|
||||
TokenValue(int size, duint value) :
|
||||
size(size),
|
||||
value(value)
|
||||
{
|
||||
}
|
||||
|
||||
TokenValue() :
|
||||
size(0),
|
||||
value(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct SingleToken
|
||||
{
|
||||
TokenType type; //token type
|
||||
QString text; //token text
|
||||
TokenValue value; //token value (if applicable)
|
||||
|
||||
SingleToken() :
|
||||
type(TokenType::Uncategorized)
|
||||
{
|
||||
}
|
||||
|
||||
SingleToken(TokenType type, const QString & text, const TokenValue & value) :
|
||||
type(type),
|
||||
text(text),
|
||||
value(value)
|
||||
{
|
||||
}
|
||||
|
||||
SingleToken(TokenType type, const QString & text) :
|
||||
SingleToken(type, text, TokenValue())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct InstructionToken
|
||||
{
|
||||
std::vector<SingleToken> tokens; //list of tokens that form the instruction
|
||||
int x; //x of the first character
|
||||
|
||||
InstructionToken()
|
||||
{
|
||||
tokens.clear();
|
||||
x = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct TokenColor
|
||||
{
|
||||
RichTextPainter::CustomRichTextFlags flags;
|
||||
QColor color;
|
||||
QColor backgroundColor;
|
||||
|
||||
TokenColor(QString color, QString backgroundColor)
|
||||
{
|
||||
if(color.length() && backgroundColor.length())
|
||||
{
|
||||
this->flags = RichTextPainter::FlagAll;
|
||||
this->color = ConfigColor(color);
|
||||
this->backgroundColor = ConfigColor(backgroundColor);
|
||||
}
|
||||
else if(color.length())
|
||||
{
|
||||
this->flags = RichTextPainter::FlagColor;
|
||||
this->color = ConfigColor(color);
|
||||
}
|
||||
else if(backgroundColor.length())
|
||||
{
|
||||
this->flags = RichTextPainter::FlagBackground;
|
||||
this->backgroundColor = ConfigColor(backgroundColor);
|
||||
}
|
||||
else
|
||||
this->flags = RichTextPainter::FlagNone;
|
||||
}
|
||||
|
||||
TokenColor()
|
||||
: TokenColor("", "")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
CsCapstoneTokenizer(int maxModuleLength);
|
||||
bool Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction);
|
||||
bool TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction);
|
||||
bool Tokenize(duint addr, const unsigned char* data, int datasize, CapstoneTokenizer::InstructionToken & instruction);
|
||||
bool TokenizeData(const QString & datatype, const QString & data, CapstoneTokenizer::InstructionToken & instruction);
|
||||
void UpdateConfig();
|
||||
void SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bMemorySpaces, bool bNoHighlightOperands, bool bNoCurrentModuleText, bool b0xPrefixValues);
|
||||
int Size() const;
|
||||
|
|
@ -153,18 +23,18 @@ public:
|
|||
|
||||
static void UpdateColors();
|
||||
static void UpdateStringPool();
|
||||
static void TokenToRichText(const InstructionToken & instr, RichTextPainter::List & richTextList, const SingleToken* highlightToken);
|
||||
static bool TokenFromX(const InstructionToken & instr, SingleToken & token, int x, CachedFontMetrics* fontMetrics);
|
||||
static bool IsHighlightableToken(const SingleToken & token);
|
||||
static bool TokenEquals(const SingleToken* a, const SingleToken* b, bool ignoreSize = true);
|
||||
static void addColorName(TokenType type, QString color, QString backgroundColor);
|
||||
static void TokenToRichText(const CapstoneTokenizer::InstructionToken & instr, RichTextPainter::List & richTextList, const CapstoneTokenizer::SingleToken* highlightToken);
|
||||
static bool TokenFromX(const CapstoneTokenizer::InstructionToken & instr, CapstoneTokenizer::SingleToken & token, int x, CachedFontMetrics* fontMetrics);
|
||||
static bool IsHighlightableToken(const CapstoneTokenizer::SingleToken & token);
|
||||
static bool TokenEquals(const CapstoneTokenizer::SingleToken* a, const CapstoneTokenizer::SingleToken* b, bool ignoreSize = true);
|
||||
static void addColorName(CapstoneTokenizer::TokenType type, QString color, QString backgroundColor);
|
||||
static void addStringsToPool(const QString & regs);
|
||||
static bool tokenTextPoolEquals(const QString & a, const QString & b);
|
||||
|
||||
private:
|
||||
Capstone _cp;
|
||||
bool isNop;
|
||||
InstructionToken _inst;
|
||||
CapstoneTokenizer::InstructionToken _inst;
|
||||
bool _success;
|
||||
int _maxModuleLength;
|
||||
bool _bUppercase;
|
||||
|
|
@ -174,19 +44,19 @@ private:
|
|||
bool _bNoHighlightOperands;
|
||||
bool _bNoCurrentModuleText;
|
||||
bool _b0xPrefixValues;
|
||||
TokenType _mnemonicType;
|
||||
CapstoneTokenizer::TokenType _mnemonicType;
|
||||
|
||||
void addToken(TokenType type, QString text, const TokenValue & value);
|
||||
void addToken(TokenType type, const QString & text);
|
||||
void addToken(CapstoneTokenizer::TokenType type, QString text, const CapstoneTokenizer::TokenValue & value);
|
||||
void addToken(CapstoneTokenizer::TokenType type, const QString & text);
|
||||
void addMemoryOperator(char operatorText);
|
||||
QString printValue(const TokenValue & value, bool expandModule, int maxModuleLength) const;
|
||||
QString printValue(const CapstoneTokenizer::TokenValue & value, bool expandModule, int maxModuleLength) const;
|
||||
|
||||
static QHash<QString, int> stringPoolMap;
|
||||
static int poolId;
|
||||
|
||||
bool tokenizePrefix();
|
||||
bool tokenizeMnemonic();
|
||||
bool tokenizeMnemonic(TokenType type, const QString & mnemonic);
|
||||
bool tokenizeMnemonic(CapstoneTokenizer::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);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ INCLUDEPATH += \
|
|||
Src/ThirdPartyLibs/snowman \
|
||||
Src/ThirdPartyLibs/ldconvert \
|
||||
../capstone_wrapper \
|
||||
../zydis_wrapper
|
||||
../zydis_wrapper \
|
||||
../zydis_wrapper/zydis/include
|
||||
|
||||
# Resources, sources, headers, and forms
|
||||
RESOURCES += \
|
||||
|
|
@ -352,7 +353,6 @@ LIBS += -luser32 -ladvapi32 -lwinmm -lshell32
|
|||
|
||||
!contains(QMAKE_HOST.arch, x86_64) {
|
||||
# Windows x86 (32bit) specific build
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/Zydis" -lZydis_x86
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/bin/x32$${DIR_SUFFIX}" -lzydis_wrapper
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/capstone" -lcapstone_x86
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/bin/x32$${DIR_SUFFIX}" -lcapstone_wrapper
|
||||
|
|
@ -361,7 +361,6 @@ LIBS += -luser32 -ladvapi32 -lwinmm -lshell32
|
|||
LIBS += -L"$${X64_BIN_DIR}" -lx32bridge
|
||||
} else {
|
||||
# Windows x64 (64bit) specific build
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/Zydis" -lZydis_x64
|
||||
LIBS += -L"$$PWD/../zydis_wrapper/bin/x64$${DIR_SUFFIX}" -lzydis_wrapper
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/capstone" -lcapstone_x64
|
||||
LIBS += -L"$$PWD/../capstone_wrapper/bin/x64$${DIR_SUFFIX}" -lcapstone_wrapper
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit a9298c2f45d0bf1f482142aa15cde9e498de84f6
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
bin/
|
||||
Release/
|
||||
Debug/
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.suo
|
||||
.DS_Store
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 x64dbg
|
||||
Copyright (c) 2017 Joel Höner <athre0z@zyantific.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
zydis x64dbg module
|
||||
===================
|
||||
|
||||
A "capstone_wrapper" implementation with Zydis.
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
#ifndef ZYDIS_EXPORT_H
|
||||
#define ZYDIS_EXPORT_H
|
||||
|
||||
#ifdef ZYDIS_STATIC_DEFINE
|
||||
# define ZYDIS_EXPORT
|
||||
# define ZYDIS_NO_EXPORT
|
||||
#else
|
||||
# ifndef ZYDIS_EXPORT
|
||||
# ifdef Zydis_EXPORTS
|
||||
/* We are building this library */
|
||||
# define ZYDIS_EXPORT
|
||||
# else
|
||||
/* We are using this library */
|
||||
# define ZYDIS_EXPORT
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef ZYDIS_NO_EXPORT
|
||||
# define ZYDIS_NO_EXPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZYDIS_DEPRECATED
|
||||
# define ZYDIS_DEPRECATED __attribute__ ((__deprecated__))
|
||||
#endif
|
||||
|
||||
#ifndef ZYDIS_DEPRECATED_EXPORT
|
||||
# define ZYDIS_DEPRECATED_EXPORT ZYDIS_EXPORT ZYDIS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifndef ZYDIS_DEPRECATED_NO_EXPORT
|
||||
# define ZYDIS_DEPRECATED_NO_EXPORT ZYDIS_NO_EXPORT ZYDIS_DEPRECATED
|
||||
#endif
|
||||
|
||||
#define DEFINE_NO_DEPRECATED 0
|
||||
#if DEFINE_NO_DEPRECATED
|
||||
# define ZYDIS_NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 38975c8d3d55e82cfda5f7e2bbe217ca59252866
|
||||
|
|
@ -0,0 +1,866 @@
|
|||
#include "zydis_wrapper.h"
|
||||
#include <windows.h>
|
||||
|
||||
bool Zydis::mInitialized = false;
|
||||
ZydisDecoder Zydis::mZyDecoder;
|
||||
ZydisFormatter Zydis::mZyFormatter;
|
||||
|
||||
void Zydis::GlobalInitialize()
|
||||
{
|
||||
if(!mInitialized)
|
||||
{
|
||||
mInitialized = true;
|
||||
#ifdef _WIN64
|
||||
ZydisDecoderInit(&mZyDecoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
|
||||
#else //x86
|
||||
ZydisDecoderInit(&mZyDecoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32);
|
||||
#endif //_WIN64
|
||||
ZydisFormatterInit(&mZyFormatter, ZYDIS_FORMATTER_STYLE_INTEL);
|
||||
}
|
||||
}
|
||||
|
||||
void Zydis::GlobalFinalize()
|
||||
{
|
||||
mInitialized = false;
|
||||
}
|
||||
|
||||
Zydis::Zydis()
|
||||
: mSuccess(false),
|
||||
mExplicitOpCount(0)
|
||||
{
|
||||
GlobalInitialize();
|
||||
}
|
||||
|
||||
Zydis::~Zydis()
|
||||
{
|
||||
}
|
||||
|
||||
bool Zydis::Disassemble(size_t addr, const unsigned char data[MAX_DISASM_BUFFER])
|
||||
{
|
||||
return Disassemble(addr, data, MAX_DISASM_BUFFER);
|
||||
}
|
||||
|
||||
bool Zydis::Disassemble(size_t addr, const unsigned char* data, int size)
|
||||
{
|
||||
if(!data || !size)
|
||||
return false;
|
||||
|
||||
mSuccess = false;
|
||||
|
||||
// Decode instruction.
|
||||
if(!ZYDIS_SUCCESS(ZydisDecoderDecodeBuffer(
|
||||
&mZyDecoder, data, size, addr, &mZyInstr
|
||||
)))
|
||||
return false;
|
||||
|
||||
// Format it to human readable representation.
|
||||
if(!ZYDIS_SUCCESS(ZydisFormatterFormatInstruction(
|
||||
&mZyFormatter,
|
||||
const_cast<ZydisDecodedInstruction*>(&mZyInstr),
|
||||
mInstrText,
|
||||
sizeof(mInstrText)
|
||||
)))
|
||||
return false;
|
||||
|
||||
// Count explicit operands.
|
||||
mExplicitOpCount = 0;
|
||||
for(size_t i = 0; i < ZYDIS_MAX_OPERAND_COUNT; ++i)
|
||||
{
|
||||
auto & op = mZyInstr.operands[i];
|
||||
|
||||
// HACK (ath): Rebase IMM if relative (codebase expects it this way)
|
||||
if (op.type == ZYDIS_OPERAND_TYPE_IMMEDIATE && op.imm.isRelative)
|
||||
ZydisUtilsCalcAbsoluteTargetAddress(&mZyInstr, &op, &op.imm.value.u);
|
||||
|
||||
if (op.visibility != ZYDIS_OPERAND_VISIBILITY_EXPLICIT)
|
||||
break;
|
||||
|
||||
++mExplicitOpCount;
|
||||
}
|
||||
|
||||
mSuccess = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Zydis::DisassembleSafe(size_t addr, const unsigned char* data, int size)
|
||||
{
|
||||
unsigned char dataSafe[MAX_DISASM_BUFFER];
|
||||
memset(dataSafe, 0, sizeof(dataSafe));
|
||||
memcpy(dataSafe, data, min(MAX_DISASM_BUFFER, size_t(size)));
|
||||
return Disassemble(addr, dataSafe);
|
||||
}
|
||||
|
||||
const ZydisDecodedInstruction* Zydis::GetInstr() const
|
||||
{
|
||||
if(!Success())
|
||||
return nullptr;
|
||||
return &mZyInstr;
|
||||
}
|
||||
|
||||
bool Zydis::Success() const
|
||||
{
|
||||
return mSuccess;
|
||||
}
|
||||
|
||||
const char* Zydis::RegName(ZydisRegister reg) const
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case ZYDIS_REGISTER_ST0:
|
||||
return "st(0)";
|
||||
case ZYDIS_REGISTER_ST1:
|
||||
return "st(1)";
|
||||
case ZYDIS_REGISTER_ST2:
|
||||
return "st(2)";
|
||||
case ZYDIS_REGISTER_ST3:
|
||||
return "st(3)";
|
||||
case ZYDIS_REGISTER_ST4:
|
||||
return "st(4)";
|
||||
case ZYDIS_REGISTER_ST5:
|
||||
return "st(5)";
|
||||
case ZYDIS_REGISTER_ST6:
|
||||
return "st(6)";
|
||||
case ZYDIS_REGISTER_ST7:
|
||||
return "st(7)";
|
||||
default:
|
||||
return ZydisRegisterGetString(reg);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Zydis::OperandText(int opindex) const
|
||||
{
|
||||
if(!Success() || opindex >= mZyInstr.operandCount)
|
||||
return "";
|
||||
|
||||
auto& op = mZyInstr.operands[opindex];
|
||||
|
||||
ZydisFormatterHookType type;
|
||||
switch (op.type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
type = ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM; break;
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
type = ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM; break;
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
type = ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG; break;
|
||||
case ZYDIS_OPERAND_TYPE_POINTER:
|
||||
type = ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR; break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
ZydisFormatterFormatOperandFunc fmtFunc = nullptr;
|
||||
if (!ZYDIS_SUCCESS(ZydisFormatterSetHook(&mZyFormatter, type, (const void**)&fmtFunc)))
|
||||
return "";
|
||||
|
||||
char buf[200] = "";
|
||||
auto bufPtr = buf;
|
||||
fmtFunc(
|
||||
&mZyFormatter,
|
||||
&bufPtr,
|
||||
sizeof(buf),
|
||||
(ZydisDecodedInstruction*)&mZyInstr,
|
||||
(ZydisDecodedOperand*)&op
|
||||
);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int Zydis::Size() const
|
||||
{
|
||||
if(!Success())
|
||||
return 1;
|
||||
return GetInstr()->length;
|
||||
}
|
||||
|
||||
size_t Zydis::Address() const
|
||||
{
|
||||
if(!Success())
|
||||
return 0;
|
||||
|
||||
return size_t(GetInstr()->instrAddress);
|
||||
}
|
||||
|
||||
bool Zydis::IsFilling() const
|
||||
{
|
||||
if(!Success())
|
||||
return false;
|
||||
|
||||
switch(mZyInstr.mnemonic)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_NOP:
|
||||
case ZYDIS_MNEMONIC_INT3:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Zydis::IsBranchType(std::underlying_type_t<BranchType> bt) const
|
||||
{
|
||||
if(!Success())
|
||||
return false;
|
||||
|
||||
std::underlying_type_t<BranchType> ref = 0;
|
||||
const auto & op0 = mZyInstr.operands[0];
|
||||
|
||||
switch(mZyInstr.mnemonic)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_RET:
|
||||
ref = BT_Ret;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_CALL:
|
||||
ref = (op0.elementType == ZYDIS_ELEMENT_TYPE_STRUCT ||
|
||||
op0.type == ZYDIS_OPERAND_TYPE_POINTER) ? BT_FarCall : BT_Call;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_JMP:
|
||||
ref = (op0.elementType == ZYDIS_ELEMENT_TYPE_STRUCT ||
|
||||
op0.type == ZYDIS_OPERAND_TYPE_POINTER) ? BT_FarJmp : BT_UncondJmp;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_JB:
|
||||
case ZYDIS_MNEMONIC_JBE:
|
||||
case ZYDIS_MNEMONIC_JCXZ:
|
||||
case ZYDIS_MNEMONIC_JECXZ:
|
||||
case ZYDIS_MNEMONIC_JKNZD:
|
||||
case ZYDIS_MNEMONIC_JKZD:
|
||||
case ZYDIS_MNEMONIC_JL:
|
||||
case ZYDIS_MNEMONIC_JLE:
|
||||
case ZYDIS_MNEMONIC_JNB:
|
||||
case ZYDIS_MNEMONIC_JNBE:
|
||||
case ZYDIS_MNEMONIC_JNL:
|
||||
case ZYDIS_MNEMONIC_JNLE:
|
||||
case ZYDIS_MNEMONIC_JNO:
|
||||
case ZYDIS_MNEMONIC_JNP:
|
||||
case ZYDIS_MNEMONIC_JNS:
|
||||
case ZYDIS_MNEMONIC_JNZ:
|
||||
case ZYDIS_MNEMONIC_JO:
|
||||
case ZYDIS_MNEMONIC_JP:
|
||||
case ZYDIS_MNEMONIC_JRCXZ:
|
||||
case ZYDIS_MNEMONIC_JS:
|
||||
case ZYDIS_MNEMONIC_JZ:
|
||||
ref = BT_CondJmp;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_SYSCALL:
|
||||
case ZYDIS_MNEMONIC_SYSENTER:
|
||||
ref = BT_Syscall;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_SYSRET:
|
||||
case ZYDIS_MNEMONIC_SYSEXIT:
|
||||
ref = BT_Sysret;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_INT:
|
||||
ref = BT_Int;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_INT3:
|
||||
ref = BT_Int3;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_INT1:
|
||||
ref = BT_Int1;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_XBEGIN:
|
||||
ref = BT_Xbegin;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_XABORT:
|
||||
ref = BT_Xabort;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_RSM:
|
||||
ref = BT_Rsm;
|
||||
break;
|
||||
case ZYDIS_MNEMONIC_LOOP:
|
||||
case ZYDIS_MNEMONIC_LOOPE:
|
||||
case ZYDIS_MNEMONIC_LOOPNE:
|
||||
ref = BT_Loop;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
return (bt & ref) != 0;
|
||||
}
|
||||
|
||||
|
||||
ZydisMnemonic Zydis::GetId() const
|
||||
{
|
||||
if(!Success())
|
||||
DebugBreak();
|
||||
return mZyInstr.mnemonic;
|
||||
}
|
||||
|
||||
std::string Zydis::InstructionText(bool replaceRipRelative) const
|
||||
{
|
||||
if(!Success())
|
||||
return "???";
|
||||
|
||||
std::string result = mInstrText;
|
||||
#ifdef _WIN64
|
||||
// TODO (ath): We can do that a whole lot sexier using formatter hooks
|
||||
if(replaceRipRelative)
|
||||
{
|
||||
//replace [rip +/- 0x?] with the actual address
|
||||
bool ripPlus = true;
|
||||
auto found = result.find("[rip + ");
|
||||
if(found == std::string::npos)
|
||||
{
|
||||
ripPlus = false;
|
||||
found = result.find("[rip - ");
|
||||
}
|
||||
if(found != std::string::npos)
|
||||
{
|
||||
auto wVA = Address();
|
||||
auto end = result.find("]", found);
|
||||
auto ripStr = result.substr(found + 1, end - found - 1);
|
||||
uint64_t offset;
|
||||
sscanf_s(ripStr.substr(ripStr.rfind(' ') + 1).c_str(), "%llX", &offset);
|
||||
auto dest = ripPlus ? (wVA + offset + Size()) : (wVA - offset + Size());
|
||||
char buf[20];
|
||||
sprintf_s(buf, "0x%llx", dest);
|
||||
result.replace(found + 1, ripStr.length(), buf);
|
||||
}
|
||||
}
|
||||
#endif //_WIN64
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Zydis::OpCount() const
|
||||
{
|
||||
if(!Success())
|
||||
return 0;
|
||||
return mExplicitOpCount;
|
||||
}
|
||||
|
||||
const ZydisDecodedOperand & Zydis::operator[](int index) const
|
||||
{
|
||||
if(!Success() || index < 0 || index >= OpCount())
|
||||
DebugBreak();
|
||||
return mZyInstr.operands[index];
|
||||
}
|
||||
|
||||
static bool isSafe64NopRegOp(const ZydisDecodedOperand & op)
|
||||
{
|
||||
if(op.type != ZYDIS_OPERAND_TYPE_REGISTER)
|
||||
return true; //a non-register is safe
|
||||
#ifdef _WIN64
|
||||
switch(op.reg.value)
|
||||
{
|
||||
case ZYDIS_REGISTER_EAX:
|
||||
case ZYDIS_REGISTER_EBX:
|
||||
case ZYDIS_REGISTER_ECX:
|
||||
case ZYDIS_REGISTER_EDX:
|
||||
case ZYDIS_REGISTER_EBP:
|
||||
case ZYDIS_REGISTER_ESP:
|
||||
case ZYDIS_REGISTER_ESI:
|
||||
case ZYDIS_REGISTER_EDI:
|
||||
return false; //32 bit register modifications clear the high part of the 64 bit register
|
||||
default:
|
||||
return true; //all other registers are safe
|
||||
}
|
||||
#else
|
||||
return true;
|
||||
#endif //_WIN64
|
||||
}
|
||||
|
||||
bool Zydis::IsNop() const
|
||||
{
|
||||
if(!Success())
|
||||
return false;
|
||||
|
||||
const auto & ops = mZyInstr.operands;
|
||||
|
||||
switch(mZyInstr.mnemonic)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_NOP:
|
||||
case ZYDIS_MNEMONIC_PAUSE:
|
||||
case ZYDIS_MNEMONIC_FNOP:
|
||||
// nop
|
||||
return true;
|
||||
case ZYDIS_MNEMONIC_MOV:
|
||||
case ZYDIS_MNEMONIC_CMOVB:
|
||||
case ZYDIS_MNEMONIC_CMOVBE:
|
||||
case ZYDIS_MNEMONIC_CMOVL:
|
||||
case ZYDIS_MNEMONIC_CMOVLE:
|
||||
case ZYDIS_MNEMONIC_CMOVNB:
|
||||
case ZYDIS_MNEMONIC_CMOVNBE:
|
||||
case ZYDIS_MNEMONIC_CMOVNL:
|
||||
case ZYDIS_MNEMONIC_CMOVNLE:
|
||||
case ZYDIS_MNEMONIC_CMOVNO:
|
||||
case ZYDIS_MNEMONIC_CMOVNP:
|
||||
case ZYDIS_MNEMONIC_CMOVNS:
|
||||
case ZYDIS_MNEMONIC_CMOVNZ:
|
||||
case ZYDIS_MNEMONIC_CMOVO:
|
||||
case ZYDIS_MNEMONIC_CMOVP:
|
||||
case ZYDIS_MNEMONIC_CMOVS:
|
||||
case ZYDIS_MNEMONIC_CMOVZ:
|
||||
case ZYDIS_MNEMONIC_MOVAPS:
|
||||
case ZYDIS_MNEMONIC_MOVAPD:
|
||||
case ZYDIS_MNEMONIC_MOVUPS:
|
||||
case ZYDIS_MNEMONIC_MOVUPD:
|
||||
case ZYDIS_MNEMONIC_XCHG:
|
||||
// mov edi, edi
|
||||
return ops[0].type == ZYDIS_OPERAND_TYPE_REGISTER
|
||||
&& ops[1].type == ZYDIS_OPERAND_TYPE_REGISTER
|
||||
&& ops[0].reg.value == ops[1].reg.value
|
||||
&& isSafe64NopRegOp(ops[0]);
|
||||
case ZYDIS_MNEMONIC_LEA:
|
||||
{
|
||||
// lea eax, [eax + 0]
|
||||
auto reg = ops[0].reg.value;
|
||||
auto mem = ops[1].mem;
|
||||
return ops[0].type == ZYDIS_OPERAND_TYPE_REGISTER
|
||||
&& ops[1].type == ZYDIS_OPERAND_TYPE_REGISTER
|
||||
&& mem.disp.value == 0
|
||||
&& ((mem.index == ZYDIS_REGISTER_NONE && mem.base == reg) ||
|
||||
(mem.index == reg && mem.base == ZYDIS_REGISTER_NONE && mem.scale == 1))
|
||||
&& isSafe64NopRegOp(ops[0]);
|
||||
}
|
||||
case ZYDIS_MNEMONIC_JB:
|
||||
case ZYDIS_MNEMONIC_JBE:
|
||||
case ZYDIS_MNEMONIC_JCXZ:
|
||||
case ZYDIS_MNEMONIC_JECXZ:
|
||||
case ZYDIS_MNEMONIC_JKNZD:
|
||||
case ZYDIS_MNEMONIC_JKZD:
|
||||
case ZYDIS_MNEMONIC_JL:
|
||||
case ZYDIS_MNEMONIC_JLE:
|
||||
case ZYDIS_MNEMONIC_JMP:
|
||||
case ZYDIS_MNEMONIC_JNB:
|
||||
case ZYDIS_MNEMONIC_JNBE:
|
||||
case ZYDIS_MNEMONIC_JNL:
|
||||
case ZYDIS_MNEMONIC_JNLE:
|
||||
case ZYDIS_MNEMONIC_JNO:
|
||||
case ZYDIS_MNEMONIC_JNP:
|
||||
case ZYDIS_MNEMONIC_JNS:
|
||||
case ZYDIS_MNEMONIC_JNZ:
|
||||
case ZYDIS_MNEMONIC_JO:
|
||||
case ZYDIS_MNEMONIC_JP:
|
||||
case ZYDIS_MNEMONIC_JRCXZ:
|
||||
case ZYDIS_MNEMONIC_JS:
|
||||
case ZYDIS_MNEMONIC_JZ:
|
||||
// jmp 0
|
||||
return ops[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE
|
||||
&& ops[0].imm.value.u == this->Address() + this->Size();
|
||||
case ZYDIS_MNEMONIC_SHL:
|
||||
case ZYDIS_MNEMONIC_SHR:
|
||||
case ZYDIS_MNEMONIC_ROL:
|
||||
case ZYDIS_MNEMONIC_ROR:
|
||||
case ZYDIS_MNEMONIC_SAR:
|
||||
// shl eax, 0
|
||||
return ops[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE
|
||||
&& ops[1].imm.value.u == 0
|
||||
&& isSafe64NopRegOp(ops[0]);
|
||||
case ZYDIS_MNEMONIC_SHLD:
|
||||
case ZYDIS_MNEMONIC_SHRD:
|
||||
// shld eax, ebx, 0
|
||||
return ops[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE
|
||||
&& ops[2].imm.value.u == 0
|
||||
&& isSafe64NopRegOp(ops[0])
|
||||
&& isSafe64NopRegOp(ops[1]);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Zydis::IsPushPop() const
|
||||
{
|
||||
if(!Success())
|
||||
return false;
|
||||
|
||||
switch(mZyInstr.meta.category)
|
||||
{
|
||||
case ZYDIS_CATEGORY_PUSH:
|
||||
case ZYDIS_CATEGORY_POP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Zydis::IsUnusual() const
|
||||
{
|
||||
if(!Success())
|
||||
return false;
|
||||
|
||||
auto id = mZyInstr.mnemonic;
|
||||
return mZyInstr.attributes & ZYDIS_ATTRIB_IS_PRIVILEGED
|
||||
|| id == ZYDIS_MNEMONIC_RDTSC
|
||||
|| id == ZYDIS_MNEMONIC_SYSCALL
|
||||
|| id == ZYDIS_MNEMONIC_SYSENTER
|
||||
|| id == ZYDIS_MNEMONIC_CPUID
|
||||
|| id == ZYDIS_MNEMONIC_RDTSCP
|
||||
|| id == ZYDIS_MNEMONIC_RDRAND
|
||||
|| id == ZYDIS_MNEMONIC_RDSEED
|
||||
|| id == ZYDIS_MNEMONIC_UD1
|
||||
|| id == ZYDIS_MNEMONIC_UD2;
|
||||
}
|
||||
|
||||
std::string Zydis::Mnemonic() const
|
||||
{
|
||||
if(!Success())
|
||||
return "???";
|
||||
|
||||
switch(mZyInstr.mnemonic)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_JZ:
|
||||
return "je";
|
||||
case ZYDIS_MNEMONIC_JNZ:
|
||||
return "jne";
|
||||
case ZYDIS_MNEMONIC_JNBE:
|
||||
return "ja";
|
||||
case ZYDIS_MNEMONIC_JNB:
|
||||
return "jae";
|
||||
case ZYDIS_MNEMONIC_JNLE:
|
||||
return "jg";
|
||||
case ZYDIS_MNEMONIC_JNL:
|
||||
return "jge";
|
||||
case ZYDIS_MNEMONIC_CMOVNBE:
|
||||
return "cmova";
|
||||
case ZYDIS_MNEMONIC_CMOVNB:
|
||||
return "cmovae";
|
||||
case ZYDIS_MNEMONIC_CMOVZ:
|
||||
return "cmove";
|
||||
case ZYDIS_MNEMONIC_CMOVNLE:
|
||||
return "cmovg";
|
||||
case ZYDIS_MNEMONIC_CMOVNL:
|
||||
return "cmovge";
|
||||
case ZYDIS_MNEMONIC_CMOVNZ:
|
||||
return "cmovne";
|
||||
case ZYDIS_MNEMONIC_SETNBE:
|
||||
return "seta";
|
||||
case ZYDIS_MNEMONIC_SETNB:
|
||||
return "setae";
|
||||
case ZYDIS_MNEMONIC_SETZ:
|
||||
return "sete";
|
||||
case ZYDIS_MNEMONIC_SETNLE:
|
||||
return "setg";
|
||||
case ZYDIS_MNEMONIC_SETNL:
|
||||
return "setge";
|
||||
case ZYDIS_MNEMONIC_SETNZ:
|
||||
return "setne";
|
||||
default:
|
||||
return ZydisMnemonicGetString(mZyInstr.mnemonic);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Zydis::MnemonicId() const
|
||||
{
|
||||
// hax
|
||||
return Mnemonic();
|
||||
}
|
||||
|
||||
const char* Zydis::MemSizeName(int size) const
|
||||
{
|
||||
switch(size)
|
||||
{
|
||||
case 1:
|
||||
return "byte";
|
||||
case 2:
|
||||
return "word";
|
||||
case 4:
|
||||
return "dword";
|
||||
case 6:
|
||||
return "fword";
|
||||
case 8:
|
||||
return "qword";
|
||||
case 10:
|
||||
return "tword";
|
||||
case 14:
|
||||
return "m14";
|
||||
case 16:
|
||||
return "xmmword";
|
||||
case 28:
|
||||
return "m28";
|
||||
case 32:
|
||||
return "yword";
|
||||
case 64:
|
||||
return "zword";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
size_t Zydis::BranchDestination() const
|
||||
{
|
||||
if(!Success()
|
||||
|| mZyInstr.operands[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE
|
||||
|| !mZyInstr.operands[0].imm.isRelative)
|
||||
return 0;
|
||||
|
||||
return mZyInstr.operands[0].imm.value.u;
|
||||
}
|
||||
|
||||
size_t Zydis::ResolveOpValue(int opindex, const std::function<size_t(ZydisRegister)> & resolveReg) const
|
||||
{
|
||||
size_t dest = 0;
|
||||
const auto & op = mZyInstr.operands[opindex];
|
||||
switch(op.type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
dest = size_t(op.imm.value.u);
|
||||
break;
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
dest = resolveReg(op.reg.value);
|
||||
break;
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
dest = size_t(op.mem.disp.value);
|
||||
if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative
|
||||
dest += Address() + Size();
|
||||
else
|
||||
dest += resolveReg(op.mem.base) + resolveReg(op.mem.index) * op.mem.scale;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
bool Zydis::IsBranchGoingToExecute(size_t cflags, size_t ccx) const
|
||||
{
|
||||
if(!Success())
|
||||
return false;
|
||||
return IsBranchGoingToExecute(mZyInstr.mnemonic, cflags, ccx);
|
||||
}
|
||||
|
||||
bool Zydis::IsBranchGoingToExecute(ZydisMnemonic id, size_t cflags, size_t ccx)
|
||||
{
|
||||
auto bCF = (cflags & (1 << 0)) != 0;
|
||||
auto bPF = (cflags & (1 << 2)) != 0;
|
||||
auto bZF = (cflags & (1 << 6)) != 0;
|
||||
auto bSF = (cflags & (1 << 7)) != 0;
|
||||
auto bOF = (cflags & (1 << 11)) != 0;
|
||||
switch(id)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_CALL:
|
||||
case ZYDIS_MNEMONIC_JMP:
|
||||
case ZYDIS_MNEMONIC_RET:
|
||||
return true;
|
||||
case ZYDIS_MNEMONIC_JNB: //jump short if above or equal
|
||||
return !bCF;
|
||||
case ZYDIS_MNEMONIC_JNBE: //jump short if above
|
||||
return !bCF && !bZF;
|
||||
case ZYDIS_MNEMONIC_JBE: //jump short if below or equal/not above
|
||||
return bCF || bZF;
|
||||
case ZYDIS_MNEMONIC_JB: //jump short if below/not above nor equal/carry
|
||||
return bCF;
|
||||
case ZYDIS_MNEMONIC_JCXZ: //jump short if ecx register is zero
|
||||
case ZYDIS_MNEMONIC_JECXZ: //jump short if ecx register is zero
|
||||
case ZYDIS_MNEMONIC_JRCXZ: //jump short if rcx register is zero
|
||||
return ccx == 0;
|
||||
case ZYDIS_MNEMONIC_JZ: //jump short if equal
|
||||
return bZF;
|
||||
case ZYDIS_MNEMONIC_JNL: //jump short if greater or equal
|
||||
return bSF == bOF;
|
||||
case ZYDIS_MNEMONIC_JNLE: //jump short if greater
|
||||
return !bZF && bSF == bOF;
|
||||
case ZYDIS_MNEMONIC_JLE: //jump short if less or equal/not greater
|
||||
return bZF || bSF != bOF;
|
||||
case ZYDIS_MNEMONIC_JL: //jump short if less/not greater
|
||||
return bSF != bOF;
|
||||
case ZYDIS_MNEMONIC_JNZ: //jump short if not equal/not zero
|
||||
return !bZF;
|
||||
case ZYDIS_MNEMONIC_JNO: //jump short if not overflow
|
||||
return !bOF;
|
||||
case ZYDIS_MNEMONIC_JNP: //jump short if not parity/parity odd
|
||||
return !bPF;
|
||||
case ZYDIS_MNEMONIC_JNS: //jump short if not sign
|
||||
return !bSF;
|
||||
case ZYDIS_MNEMONIC_JO: //jump short if overflow
|
||||
return bOF;
|
||||
case ZYDIS_MNEMONIC_JP: //jump short if parity/parity even
|
||||
return bPF;
|
||||
case ZYDIS_MNEMONIC_JS: //jump short if sign
|
||||
return bSF;
|
||||
case ZYDIS_MNEMONIC_LOOP: //decrement count; jump short if ecx!=0
|
||||
return ccx != 0;
|
||||
case ZYDIS_MNEMONIC_LOOPE: //decrement count; jump short if ecx!=0 and zf=1
|
||||
return ccx != 0 && bZF;
|
||||
case ZYDIS_MNEMONIC_LOOPNE: //decrement count; jump short if ecx!=0 and zf=0
|
||||
return ccx != 0 && !bZF;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Zydis::IsConditionalGoingToExecute(size_t cflags, size_t ccx) const
|
||||
{
|
||||
if(!Success())
|
||||
return false;
|
||||
return IsConditionalGoingToExecute(mZyInstr.mnemonic, cflags, ccx);
|
||||
}
|
||||
|
||||
bool Zydis::IsConditionalGoingToExecute(ZydisMnemonic id, size_t cflags, size_t ccx)
|
||||
{
|
||||
auto bCF = (cflags & (1 << 0)) != 0;
|
||||
auto bPF = (cflags & (1 << 2)) != 0;
|
||||
auto bZF = (cflags & (1 << 6)) != 0;
|
||||
auto bSF = (cflags & (1 << 7)) != 0;
|
||||
auto bOF = (cflags & (1 << 11)) != 0;
|
||||
switch(id)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_CMOVNBE: //conditional move - above/not below nor equal
|
||||
return !bCF && !bZF;
|
||||
case ZYDIS_MNEMONIC_CMOVNB: //conditional move - above or equal/not below/not carry
|
||||
return !bCF;
|
||||
case ZYDIS_MNEMONIC_CMOVB: //conditional move - below/not above nor equal/carry
|
||||
return bCF;
|
||||
case ZYDIS_MNEMONIC_CMOVBE: //conditional move - below or equal/not above
|
||||
return bCF || bZF;
|
||||
case ZYDIS_MNEMONIC_CMOVZ: //conditional move - equal/zero
|
||||
return bZF;
|
||||
case ZYDIS_MNEMONIC_CMOVNLE: //conditional move - greater/not less nor equal
|
||||
return !bZF && bSF == bOF;
|
||||
case ZYDIS_MNEMONIC_CMOVNL: //conditional move - greater or equal/not less
|
||||
return bSF == bOF;
|
||||
case ZYDIS_MNEMONIC_CMOVL: //conditional move - less/not greater nor equal
|
||||
return bSF != bOF;
|
||||
case ZYDIS_MNEMONIC_CMOVLE: //conditional move - less or equal/not greater
|
||||
return bZF || bSF != bOF;
|
||||
case ZYDIS_MNEMONIC_CMOVNZ: //conditional move - not equal/not zero
|
||||
return !bZF;
|
||||
case ZYDIS_MNEMONIC_CMOVNO: //conditional move - not overflow
|
||||
return !bOF;
|
||||
case ZYDIS_MNEMONIC_CMOVNP: //conditional move - not parity/parity odd
|
||||
return !bPF;
|
||||
case ZYDIS_MNEMONIC_CMOVNS: //conditional move - not sign
|
||||
return !bSF;
|
||||
case ZYDIS_MNEMONIC_CMOVO: //conditional move - overflow
|
||||
return bOF;
|
||||
case ZYDIS_MNEMONIC_CMOVP: //conditional move - parity/parity even
|
||||
return bPF;
|
||||
case ZYDIS_MNEMONIC_CMOVS: //conditional move - sign
|
||||
return bSF;
|
||||
case ZYDIS_MNEMONIC_FCMOVBE: //fp conditional move - below or equal
|
||||
return bCF || bZF;
|
||||
case ZYDIS_MNEMONIC_FCMOVB: //fp conditional move - below
|
||||
return bCF;
|
||||
case ZYDIS_MNEMONIC_FCMOVE: //fp conditional move - equal
|
||||
return bZF;
|
||||
case ZYDIS_MNEMONIC_FCMOVNBE: //fp conditional move - not below or equal
|
||||
return !bCF && !bZF;
|
||||
case ZYDIS_MNEMONIC_FCMOVNB: //fp conditional move - not below
|
||||
return !bCF;
|
||||
case ZYDIS_MNEMONIC_FCMOVNE: //fp conditional move - not equal
|
||||
return !bZF;
|
||||
case ZYDIS_MNEMONIC_FCMOVNU: //fp conditional move - not unordered
|
||||
return !bPF;
|
||||
case ZYDIS_MNEMONIC_FCMOVU: //fp conditional move - unordered
|
||||
return bPF;
|
||||
case ZYDIS_MNEMONIC_SETNBE: //set byte on condition - above/not below nor equal
|
||||
return !bCF && !bZF;
|
||||
case ZYDIS_MNEMONIC_SETNB: //set byte on condition - above or equal/not below/not carry
|
||||
return !bCF;
|
||||
case ZYDIS_MNEMONIC_SETB: //set byte on condition - below/not above nor equal/carry
|
||||
return bCF;
|
||||
case ZYDIS_MNEMONIC_SETBE: //set byte on condition - below or equal/not above
|
||||
return bCF || bZF;
|
||||
case ZYDIS_MNEMONIC_SETZ: //set byte on condition - equal/zero
|
||||
return bZF;
|
||||
case ZYDIS_MNEMONIC_SETNLE: //set byte on condition - greater/not less nor equal
|
||||
return !bZF && bSF == bOF;
|
||||
case ZYDIS_MNEMONIC_SETNL: //set byte on condition - greater or equal/not less
|
||||
return bSF == bOF;
|
||||
case ZYDIS_MNEMONIC_SETL: //set byte on condition - less/not greater nor equal
|
||||
return bSF != bOF;
|
||||
case ZYDIS_MNEMONIC_SETLE: //set byte on condition - less or equal/not greater
|
||||
return bZF || bSF != bOF;
|
||||
case ZYDIS_MNEMONIC_SETNZ: //set byte on condition - not equal/not zero
|
||||
return !bZF;
|
||||
case ZYDIS_MNEMONIC_SETNO: //set byte on condition - not overflow
|
||||
return !bOF;
|
||||
case ZYDIS_MNEMONIC_SETNP: //set byte on condition - not parity/parity odd
|
||||
return !bPF;
|
||||
case ZYDIS_MNEMONIC_SETNS: //set byte on condition - not sign
|
||||
return !bSF;
|
||||
case ZYDIS_MNEMONIC_SETO: //set byte on condition - overflow
|
||||
return bOF;
|
||||
case ZYDIS_MNEMONIC_SETP: //set byte on condition - parity/parity even
|
||||
return bPF;
|
||||
case ZYDIS_MNEMONIC_SETS: //set byte on condition - sign
|
||||
return bSF;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Zydis::RegInfo(uint8_t regs[ZYDIS_REGISTER_MAX_VALUE + 1]) const
|
||||
{
|
||||
memset(regs, 0, sizeof(uint8_t) * (ZYDIS_REGISTER_MAX_VALUE + 1));
|
||||
if(!Success() || IsNop())
|
||||
return;
|
||||
for(int i = 0; i < OpCount(); i++)
|
||||
{
|
||||
const auto & op = mZyInstr.operands[i];
|
||||
switch(op.type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
{
|
||||
if(op.action & ZYDIS_OPERAND_ACTION_MASK_READ)
|
||||
regs[op.reg.value] |= Read;
|
||||
if(op.action & ZYDIS_OPERAND_ACTION_MASK_WRITE)
|
||||
regs[op.reg.value] |= Write;
|
||||
regs[op.reg.value] |= op.visibility == ZYDIS_OPERAND_VISIBILITY_EXPLICIT ?
|
||||
Explicit : Implicit;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
{
|
||||
if(op.mem.segment == ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
switch(op.mem.base)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
case ZYDIS_REGISTER_RSP:
|
||||
case ZYDIS_REGISTER_RBP:
|
||||
#else //x86
|
||||
case ZYDIS_REGISTER_ESP:
|
||||
case ZYDIS_REGISTER_EBP:
|
||||
#endif //_WIN64
|
||||
regs[ZYDIS_REGISTER_SS] |= Read | Explicit;
|
||||
break;
|
||||
default:
|
||||
regs[ZYDIS_REGISTER_DS] |= Read | Explicit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
regs[op.mem.segment] |= Read | Explicit;
|
||||
regs[op.mem.base] |= Read | Explicit;
|
||||
regs[op.mem.index] |= Read | Explicit;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* Zydis::FlagName(ZydisCPUFlag flag) const
|
||||
{
|
||||
switch(flag)
|
||||
{
|
||||
case ZYDIS_CPUFLAG_AF:
|
||||
return "AF";
|
||||
case ZYDIS_CPUFLAG_CF:
|
||||
return "CF";
|
||||
case ZYDIS_CPUFLAG_SF:
|
||||
return "SF";
|
||||
case ZYDIS_CPUFLAG_ZF:
|
||||
return "ZF";
|
||||
case ZYDIS_CPUFLAG_PF:
|
||||
return "PF";
|
||||
case ZYDIS_CPUFLAG_OF:
|
||||
return "OF";
|
||||
case ZYDIS_CPUFLAG_TF:
|
||||
return "TF";
|
||||
case ZYDIS_CPUFLAG_IF:
|
||||
return "IF";
|
||||
case ZYDIS_CPUFLAG_DF:
|
||||
return "DF";
|
||||
case ZYDIS_CPUFLAG_NT:
|
||||
return "NT";
|
||||
case ZYDIS_CPUFLAG_RF:
|
||||
return "RF";
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
#ifndef ZYDIS_WRAPPER_H
|
||||
#define ZYDIS_WRAPPER_H
|
||||
|
||||
#include "Zydis/Zydis.h"
|
||||
#include <functional>
|
||||
|
||||
#define MAX_DISASM_BUFFER 16
|
||||
|
||||
class Zydis
|
||||
{
|
||||
public:
|
||||
static void GlobalInitialize();
|
||||
static void GlobalFinalize();
|
||||
Zydis();
|
||||
Zydis(const Zydis & capstone) = delete;
|
||||
~Zydis();
|
||||
bool Disassemble(size_t addr, const unsigned char data[MAX_DISASM_BUFFER]);
|
||||
bool Disassemble(size_t addr, const unsigned char* data, int size);
|
||||
bool DisassembleSafe(size_t addr, const unsigned char* data, int size);
|
||||
const ZydisDecodedInstruction* GetInstr() const;
|
||||
bool Success() const;
|
||||
const char* RegName(ZydisRegister reg) const;
|
||||
std::string OperandText(int opindex) const;
|
||||
int Size() const;
|
||||
size_t Address() const;
|
||||
bool IsFilling() const;
|
||||
bool IsUnusual() const;
|
||||
bool IsNop() const;
|
||||
bool IsPushPop() const;
|
||||
ZydisMnemonic GetId() const;
|
||||
std::string InstructionText(bool replaceRipRelative = true) const;
|
||||
int OpCount() const;
|
||||
const ZydisDecodedOperand & operator[](int index) const;
|
||||
std::string Mnemonic() const;
|
||||
std::string MnemonicId() const;
|
||||
const char* MemSizeName(int size) const;
|
||||
size_t BranchDestination() const;
|
||||
size_t ResolveOpValue(int opindex, const std::function<size_t(ZydisRegister)> & resolveReg) const;
|
||||
bool IsBranchGoingToExecute(size_t cflags, size_t ccx) const;
|
||||
static bool IsBranchGoingToExecute(ZydisMnemonic id, size_t cflags, size_t ccx);
|
||||
bool IsConditionalGoingToExecute(size_t cflags, size_t ccx) const;
|
||||
static bool IsConditionalGoingToExecute(ZydisMnemonic id, size_t cflags, size_t ccx);
|
||||
|
||||
enum RegInfoAccess : uint8_t
|
||||
{
|
||||
None = 1 << 0,
|
||||
Read = 1 << 0,
|
||||
Write = 1 << 1,
|
||||
Implicit = 1 << 2,
|
||||
Explicit = 1 << 3
|
||||
};
|
||||
|
||||
void RegInfo(uint8_t info[ZYDIS_REGISTER_MAX_VALUE + 1]) const;
|
||||
const char* FlagName(ZydisCPUFlag flag) const;
|
||||
|
||||
enum BranchType : uint16_t
|
||||
{
|
||||
// Basic types.
|
||||
BT_Ret = 1 << 0,
|
||||
BT_Call = 1 << 1,
|
||||
BT_FarCall = 1 << 2,
|
||||
BT_Syscall = 1 << 3, // Also sysenter
|
||||
BT_Sysret = 1 << 4, // Also sysexit
|
||||
BT_Int = 1 << 5,
|
||||
BT_Int3 = 1 << 6,
|
||||
BT_Int1 = 1 << 7,
|
||||
BT_Iret = 1 << 8,
|
||||
BT_CondJmp = 1 << 9,
|
||||
BT_UncondJmp = 1 << 10,
|
||||
BT_FarJmp = 1 << 11,
|
||||
BT_Xbegin = 1 << 12,
|
||||
BT_Xabort = 1 << 13,
|
||||
BT_Rsm = 1 << 14,
|
||||
BT_Loop = 1 << 15,
|
||||
|
||||
BT_Jmp = BT_CondJmp | BT_UncondJmp,
|
||||
|
||||
// Semantic groups (behaves like XX).
|
||||
BT_CallSem = BT_Call | BT_Syscall | BT_Int,
|
||||
BT_RetSem = BT_Ret | BT_Sysret | BT_Iret | BT_Rsm | BT_Xabort,
|
||||
BT_IntSem = BT_Int | BT_Int1 | BT_Int3 | BT_Syscall,
|
||||
BT_IretSem = BT_Iret | BT_Sysret,
|
||||
BT_JmpSem = BT_Jmp | BT_Loop,
|
||||
|
||||
BT_Rtm = BT_Xabort | BT_Xbegin,
|
||||
BT_CtxSwitch = BT_IntSem | BT_IretSem | BT_Rsm | BT_FarCall | BT_FarJmp,
|
||||
|
||||
BT_Any = std::underlying_type_t<BranchType>(-1)
|
||||
};
|
||||
|
||||
bool IsBranchType(std::underlying_type_t<BranchType> bt) const;
|
||||
|
||||
// Shortcuts.
|
||||
bool IsRet () const { return IsBranchType(BT_Ret); }
|
||||
bool IsCall () const { return IsBranchType(BT_Call); }
|
||||
bool IsJump () const { return IsBranchType(BT_Jmp); }
|
||||
bool IsLoop () const { return IsBranchType(BT_Loop); }
|
||||
bool IsInt3 () const { return IsBranchType(BT_Int3); }
|
||||
private:
|
||||
static ZydisDecoder mZyDecoder;
|
||||
static ZydisFormatter mZyFormatter;
|
||||
static bool mInitialized;
|
||||
ZydisDecodedInstruction mZyInstr;
|
||||
char mInstrText[200];
|
||||
bool mSuccess;
|
||||
uint8_t mExplicitOpCount;
|
||||
};
|
||||
|
||||
#endif //ZYDIS_WRAPPER_H
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.40629.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zydis_wrapper", "zydis_wrapper.vcxproj", "{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Debug|x64.Build.0 = Debug|x64
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|Win32.Build.0 = Release|Win32
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|x64.ActiveCfg = Release|x64
|
||||
{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{3B2C1EE1-FDEC-4D85-BE46-3C6A5EA69883}</ProjectGuid>
|
||||
<RootNamespace>zydis_wrapper</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetExt>.lib</TargetExt>
|
||||
<OutDir>$(ProjectDir)bin\x32\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetExt>.lib</TargetExt>
|
||||
<OutDir>$(ProjectDir)bin\x64\</OutDir>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath);$(ProjectDir)\zydis\include;$(ProjectDir)\zydis\src</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetExt>.lib</TargetExt>
|
||||
<OutDir>$(ProjectDir)bin\x32d\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetExt>.lib</TargetExt>
|
||||
<OutDir>$(ProjectDir)bin\x64d\</OutDir>
|
||||
<IncludePath>$(ProjectDir);$(IncludePath);$(ProjectDir)\zydis\include;$(ProjectDir)\zydis\src</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="zydis\src\Decoder.c" />
|
||||
<ClCompile Include="zydis\src\DecoderData.c" />
|
||||
<ClCompile Include="zydis\src\FormatHelper.c" />
|
||||
<ClCompile Include="zydis\src\Formatter.c" />
|
||||
<ClCompile Include="zydis\src\MetaInfo.c" />
|
||||
<ClCompile Include="zydis\src\Mnemonic.c" />
|
||||
<ClCompile Include="zydis\src\Register.c" />
|
||||
<ClCompile Include="zydis\src\SharedData.c" />
|
||||
<ClCompile Include="zydis\src\Utils.c" />
|
||||
<ClCompile Include="zydis\src\Zydis.c" />
|
||||
<ClCompile Include="zydis_wrapper.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="zydis\include\Zydis\CommonTypes.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Decoder.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\DecoderTypes.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Defines.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Encoder.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Formatter.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\MetaInfo.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Mnemonic.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Register.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\SharedTypes.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Status.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Utils.h" />
|
||||
<ClInclude Include="zydis\include\Zydis\Zydis.h" />
|
||||
<ClInclude Include="zydis\src\DecoderData.h" />
|
||||
<ClInclude Include="zydis\src\FormatHelper.h" />
|
||||
<ClInclude Include="zydis\src\SharedData.h" />
|
||||
<ClInclude Include="zydis_wrapper.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files\Zydis">
|
||||
<UniqueIdentifier>{0f43347f-70ba-4bf2-b8bc-ae1df066b27a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Zydis">
|
||||
<UniqueIdentifier>{9b6d6e4c-4e1e-48b2-b8ba-1b926c7c7302}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="zydis_wrapper.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\Decoder.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\DecoderData.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\FormatHelper.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\Formatter.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\MetaInfo.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\Mnemonic.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\Register.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\SharedData.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\Utils.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="zydis\src\Zydis.c">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="zydis_wrapper.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\CommonTypes.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Decoder.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\DecoderTypes.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Defines.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Encoder.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Formatter.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\MetaInfo.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Mnemonic.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Register.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\SharedTypes.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Status.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Utils.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\include\Zydis\Zydis.h">
|
||||
<Filter>Header Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\src\DecoderData.h">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\src\FormatHelper.h">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="zydis\src\SharedData.h">
|
||||
<Filter>Source Files\Zydis</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
Loading…
Reference in New Issue