1
0
Fork 0

zydis_wrapper: Better compliance with style-guide

- Removed underscores
- Removed redundant “zy” prefix
- Executed `AStyleWhore` (sorreh, I use git on my macOS host, can’t put it into pre-commit-hook)
This commit is contained in:
Joel Höner 2017-09-24 00:05:46 +02:00 committed by Duncan Ogilvie
parent ca9401fdb7
commit af0ff55df3
17 changed files with 343 additions and 309 deletions

View File

@ -374,7 +374,7 @@ void _dbg_dbgtraceexecute(duint CIP)
if(MemRead(CIP, buffer, MAX_DISASM_BUFFER))
{
TraceRecord.increaseInstructionCounter();
Zydis instruction;
Zydis instruction;
instruction.Disassemble(CIP, buffer, MAX_DISASM_BUFFER);
TraceRecord.TraceExecute(CIP, instruction.Size());
}

View File

@ -98,7 +98,7 @@ extern "C" DLL_EXPORT bool _dbg_isjumpgoingtoexecute(duint addr)
unsigned char data[16];
if(MemRead(addr, data, sizeof(data), nullptr, true))
{
Zydis cp;
Zydis cp;
if(cp.Disassemble(addr, data))
{
CONTEXT ctx;
@ -334,7 +334,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, BRID
BRIDGE_ADDRINFO newinfo;
char string_text[MAX_STRING_SIZE] = "";
Zydis cp;
Zydis cp;
auto getregs = !bOnlyCipAutoComments || addr == titcontext.cip;
disasmget(cp, addr, &instr, getregs);
@ -735,14 +735,14 @@ 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;
Zydis cp;
if(!cp.Disassemble(addr, data))
return 0;
if(cp.IsBranchType(Zydis::BT_Jmp | Zydis::BT_Call | Zydis::BT_Loop))
if(cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop))
{
auto opValue = cp.ResolveOpValue(0, [](ZydisRegister reg) -> size_t
{
switch(reg)
switch(reg)
{
#ifndef _WIN64 //x32
case ZYDIS_REGISTER_EAX:

View File

@ -142,7 +142,7 @@ void LinearPass::AnalyseOverlaps()
void LinearPass::AnalysisWorker(duint Start, duint End, BBlockArray* Blocks)
{
Zydis disasm;
Zydis disasm;
duint blockBegin = Start; // BBlock starting virtual address
duint blockEnd = 0; // BBlock ending virtual address

View File

@ -326,7 +326,7 @@ bool cbInstrVisualize(int argc, char* argv[])
//DisassemblyBreakpointColor = #000000
{
//initialize
Zydis _cp;
Zydis _cp;
duint _base = start;
duint _size = maxaddr - start;
Memory<unsigned char*> _data(_size);
@ -444,7 +444,7 @@ bool cbInstrBriefcheck(int argc, char* argv[])
return false;
Memory<unsigned char*> buffer(size + 16);
DbgMemRead(base, buffer(), size);
Zydis cp;
Zydis cp;
std::unordered_set<String> reported;
for(duint i = 0; i < size;)
{

View File

@ -1160,7 +1160,7 @@ void cbRtrStep()
#endif //_WIN64
)
{
Zydis cp;
Zydis cp;
unsigned char data[MAX_DISASM_BUFFER];
memset(data, 0, sizeof(data));
MemRead(cip, data, MAX_DISASM_BUFFER);

View File

@ -95,7 +95,7 @@ bool disasmfast(const unsigned char* data, duint addr, BASIC_INSTRUCTION_INFO* b
{
if(!data || !basicinfo)
return false;
Zydis cp;
Zydis cp;
cp.Disassemble(addr, data, MAX_DISASM_BUFFER);
if(trydisasmfast(data, addr, basicinfo, cp.Success() ? cp.Size() : 1))
return true;

View File

@ -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 cp;
// Check if the pointer is not null
if(data == NULL)
@ -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 cp;
if(data == NULL)
return 0;
@ -202,13 +202,13 @@ void disasmget(Zydis & cp, unsigned char* buffer, duint addr, DISASM_INSTR* inst
auto cpInstr = cp.GetInstr();
strcpy_s(instr->instruction, cp.InstructionText().c_str());
instr->instr_size = cpInstr->length;
if(cp.IsBranchType(Zydis::BT_Jmp | Zydis::BT_Loop | Zydis::BT_Ret | Zydis::BT_Call))
if(cp.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 = cp.OpCount() <= 3 ? cp.OpCount() : 3;
for(int i = 0; i < instr->argcount; i++)
HandleCapstoneOperand(cp, i, &instr->arg[i], getregs);
}
@ -230,7 +230,7 @@ void disasmget(Zydis & cp, duint addr, DISASM_INSTR* instr, bool getregs)
void disasmget(unsigned char* buffer, duint addr, DISASM_INSTR* instr, bool getregs)
{
Zydis cp;
Zydis cp;
disasmget(cp, buffer, addr, instr, getregs);
}
@ -404,7 +404,7 @@ bool disasmgetstringatwrapper(duint addr, char* dest, bool cache)
int disasmgetsize(duint addr, unsigned char* data)
{
Zydis cp;
Zydis cp;
if(!cp.Disassemble(addr, data, MAX_DISASM_BUFFER))
return 1;
return int(EncodeMapGetSize(addr, cp.Size()));

View File

@ -248,7 +248,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 cp;
Memory<unsigned char*> buffer(size);
if(!MemRead(addr, buffer(), size))
return false;

View File

@ -178,7 +178,7 @@ namespace Exprfunc
unsigned char data[16];
if(MemRead(addr, data, sizeof(data), nullptr, true))
{
Zydis cp;
Zydis cp;
if(cp.Disassemble(addr, data))
return cp.IsNop();
}
@ -190,7 +190,7 @@ namespace Exprfunc
unsigned char data[16];
if(MemRead(addr, data, sizeof(data), nullptr, true))
{
Zydis cp;
Zydis cp;
if(cp.Disassemble(addr, data))
return cp.IsUnusual();
}

View File

@ -643,7 +643,7 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit()
json_set_alloc_funcs(json_malloc, json_free);
//#endif //ENABLE_MEM_TRACE
dputs(QT_TRANSLATE_NOOP("DBG", "Initializing capstone..."));
Zydis::GlobalInitialize();
Zydis::GlobalInitialize();
dputs(QT_TRANSLATE_NOOP("DBG", "Initializing Yara..."));
if(yr_initialize() != ERROR_SUCCESS)
return "Failed to initialize Yara!";
@ -780,7 +780,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
cmdfree();
varfree();
yr_finalize();
Zydis::GlobalFinalize();
Zydis::GlobalFinalize();
dputs(QT_TRANSLATE_NOOP("DBG", "Cleaning up wait objects..."));
waitdeinitialize();
SafeDbghelpDeinitialize();

View File

@ -1499,76 +1499,76 @@ Instruction_t Disassembly::DisassembleAt(dsint rva)
auto zy_instr = mDisasm->DisassembleAt((byte_t*)wBuffer.data(), wBuffer.size(), base, rva);
auto cs_instr = mCsDisasm->DisassembleAt((byte_t*)wBuffer.data(), wBuffer.size(), base, rva);
if (zy_instr.tokens.tokens != cs_instr.tokens.tokens)
if(zy_instr.tokens.tokens != cs_instr.tokens.tokens)
{
if (zy_instr.instStr.startsWith("lea")) // cs scales lea mem op incorrectly
if(zy_instr.instStr.startsWith("lea")) // cs scales lea mem op incorrectly
goto _exit;
if (cs_instr.instStr.startsWith("movabs")) // cs uses non-standard movabs mnem
if(cs_instr.instStr.startsWith("movabs")) // cs uses non-standard movabs mnem
goto _exit;
if (cs_instr.instStr.startsWith("lock") || cs_instr.instStr.startsWith("rep")) // cs includes prefix in mnem
if(cs_instr.instStr.startsWith("lock") || cs_instr.instStr.startsWith("rep")) // cs includes prefix in mnem
goto _exit;
if (cs_instr.instStr.startsWith('j') && cs_instr.length == 4) // cs has AMD style handling of 66 branches
if(cs_instr.instStr.startsWith('j') && cs_instr.length == 4) // cs has AMD style handling of 66 branches
goto _exit;
if (cs_instr.instStr.startsWith("prefetchw")) // cs uses m8 (AMD/intel doc), zy m512
if(cs_instr.instStr.startsWith("prefetchw")) // cs uses m8 (AMD/intel doc), zy m512
goto _exit; // (doesn't matter, prefetch doesn't really have a size)
if (cs_instr.instStr.startsWith("xchg")) // cs/zy print operands in different order (doesn't make any diff)
if(cs_instr.instStr.startsWith("xchg")) // cs/zy print operands in different order (doesn't make any diff)
goto _exit;
if (cs_instr.instStr.startsWith("rdpmc") ||
cs_instr.instStr.startsWith("in") ||
cs_instr.instStr.startsWith("out") ||
cs_instr.instStr.startsWith("sti") ||
cs_instr.instStr.startsWith("cli") ||
cs_instr.instStr.startsWith("iret")) // cs assumes priviliged, zydis doesn't (CPL is configurable for those)
if(cs_instr.instStr.startsWith("rdpmc") ||
cs_instr.instStr.startsWith("in") ||
cs_instr.instStr.startsWith("out") ||
cs_instr.instStr.startsWith("sti") ||
cs_instr.instStr.startsWith("cli") ||
cs_instr.instStr.startsWith("iret")) // cs assumes priviliged, zydis doesn't (CPL is configurable for those)
goto _exit;
if (cs_instr.instStr.startsWith("sal")) // cs says sal, zydis say shl (both correct)
if(cs_instr.instStr.startsWith("sal")) // cs says sal, zydis say shl (both correct)
goto _exit;
if (cs_instr.instStr.startsWith("xlat")) // cs uses xlatb form, zydis xlat m8 form (both correct)
if(cs_instr.instStr.startsWith("xlat")) // cs uses xlatb form, zydis xlat m8 form (both correct)
goto _exit;
if (cs_instr.instStr.startsWith("lcall") ||
cs_instr.instStr.startsWith("ljmp") ||
cs_instr.instStr.startsWith("retf")) // cs uses "f" mnem-suffic, zydis has seperate "far" token
if(cs_instr.instStr.startsWith("lcall") ||
cs_instr.instStr.startsWith("ljmp") ||
cs_instr.instStr.startsWith("retf")) // cs uses "f" mnem-suffic, zydis has seperate "far" token
goto _exit;
if (cs_instr.instStr.startsWith("movsxd")) // cs has wrong operand size (32) for 0x63 variant (e.g. "63646566")
if(cs_instr.instStr.startsWith("movsxd")) // cs has wrong operand size (32) for 0x63 variant (e.g. "63646566")
goto _exit;
if (cs_instr.instStr.startsWith('j') && (cs_instr.dump[0] & 0x40) == 0x40) // cs honors rex.w on jumps, truncating the
if(cs_instr.instStr.startsWith('j') && (cs_instr.dump[0] & 0x40) == 0x40) // cs honors rex.w on jumps, truncating the
goto _exit; // target address to 32 bit (must be ignored)
if (cs_instr.instStr.startsWith("enter")) // cs has wrong operand size (32)
if(cs_instr.instStr.startsWith("enter")) // cs has wrong operand size (32)
goto _exit;
if (cs_instr.instStr.startsWith("wait")) // cs says wait, zy says fwait (both ok)
if(cs_instr.instStr.startsWith("wait")) // cs says wait, zy says fwait (both ok)
goto _exit;
if (cs_instr.dump.length() > 2 && // cs ignores segment prefixes if followed by branch hints
(cs_instr.dump[1] == '\x2e' ||
cs_instr.dump[2] == '\x3e'))
if(cs_instr.dump.length() > 2 && // cs ignores segment prefixes if followed by branch hints
(cs_instr.dump[1] == '\x2e' ||
cs_instr.dump[2] == '\x3e'))
goto _exit;
if (QRegExp("mov .s,.*").exactMatch(cs_instr.instStr) ||
cs_instr.instStr.startsWith("str")) // cs claims it's priviliged (it's not)
if(QRegExp("mov .s,.*").exactMatch(cs_instr.instStr) ||
cs_instr.instStr.startsWith("str")) // cs claims it's priviliged (it's not)
goto _exit;
if (QRegExp("l[defgs]s.*").exactMatch(cs_instr.instStr)) // cs allows LES (and friends) in 64 bit mode (invalid)
if(QRegExp("l[defgs]s.*").exactMatch(cs_instr.instStr)) // cs allows LES (and friends) in 64 bit mode (invalid)
goto _exit;
if (QRegExp("f[^ ]+ st0.*").exactMatch(zy_instr.instStr)) // zy prints excplitic st0, cs omits (both ok)
if(QRegExp("f[^ ]+ st0.*").exactMatch(zy_instr.instStr)) // zy prints excplitic st0, cs omits (both ok)
goto _exit;
if (cs_instr.instStr.startsWith("fstp")) // CS reports 3 operands but only prints 2 ... wat.
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)
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();
auto zy = zy_instr.instStr.toStdString();
for (auto zy_it = zy_instr.tokens.tokens.begin(), cs_it = cs_instr.tokens.tokens.begin()
; zy_it != zy_instr.tokens.tokens.end() && cs_it != cs_instr.tokens.tokens.end()
; ++zy_it, ++cs_it)
for(auto zy_it = zy_instr.tokens.tokens.begin(), cs_it = cs_instr.tokens.tokens.begin()
; zy_it != zy_instr.tokens.tokens.end() && cs_it != cs_instr.tokens.tokens.end()
; ++zy_it, ++cs_it)
{
auto zy_tok_text = zy_it->text.toStdString();
auto cs_tok_text = cs_it->text.toStdString();
if (zy_tok_text == "bnd") // cs doesn't support BND prefix
if(zy_tok_text == "bnd") // cs doesn't support BND prefix
goto _exit;
if (zy_it->value.size != cs_it->value.size) // imm sizes in CS are completely broken
if(zy_it->value.size != cs_it->value.size) // imm sizes in CS are completely broken
goto _exit;
if (!(*zy_it == *cs_it))
if(!(*zy_it == *cs_it))
__debugbreak();
}

View File

@ -200,14 +200,14 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
auto branchType = Instruction_t::None;
Instruction_t wInst;
if(success && (cp.IsBranchType(Zydis::BT_Jmp | Zydis::BT_Call | Zydis::BT_Ret | Zydis::BT_Loop)))
if(success && (cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTRet | Zydis::BTLoop)))
{
wInst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA);
if(cp.IsBranchType(Zydis::BT_UncondJmp))
if(cp.IsBranchType(Zydis::BTUncondJmp))
branchType = Instruction_t::Unconditional;
else if(cp.IsBranchType(Zydis::BT_Call))
else if(cp.IsBranchType(Zydis::BTCall))
branchType = Instruction_t::Call;
else if(cp.IsBranchType(Zydis::BT_CondJmp))
else if(cp.IsBranchType(Zydis::BTCondJmp))
branchType = Instruction_t::Conditional;
}
else
@ -232,14 +232,14 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
auto flaginfo2reginfo = [](uint8_t info)
{
auto result = 0;
#define checkFlag(test, reg) result |= (info & test) == test ? reg : 0
#define checkFlag(test, reg) result |= (info & test) == test ? reg : 0
checkFlag(Capstone::Modify, Capstone::Write);
checkFlag(Capstone::Prior, Capstone::None);
checkFlag(Capstone::Reset, Capstone::Write);
checkFlag(Capstone::Set, Capstone::Write);
checkFlag(Capstone::Test, Capstone::Read);
checkFlag(Capstone::Undefined, Capstone::None);
#undef checkFlag
#undef checkFlag
return result;
};

View File

@ -116,7 +116,7 @@ bool CapstoneTokenizer::Tokenize(duint addr, const unsigned char* data, int data
_success = _cp.DisassembleSafe(addr, data, datasize);
if(_success)
{
if (!tokenizePrefix())
if(!tokenizePrefix())
return false;
isNop = _cp.IsNop();
@ -399,7 +399,7 @@ bool CapstoneTokenizer::tokenizeMnemonic()
QString mnemonic = QString(_cp.Mnemonic().c_str());
_mnemonicType = TokenType::MnemonicNormal;
if (_cp.IsBranchType(Zydis::BT_FarCall | Zydis::BT_FarJmp))
if(_cp.IsBranchType(Zydis::BTFarCall | Zydis::BTFarJmp))
{
mnemonic += " far";
}
@ -408,9 +408,9 @@ bool CapstoneTokenizer::tokenizeMnemonic()
_mnemonicType = TokenType::MnemonicNop;
else if(_cp.IsCall())
_mnemonicType = TokenType::MnemonicCall;
else if(_cp.IsBranchType(Zydis::BT_CondJmp | Zydis::BT_Loop | Zydis::BT_Xbegin))
else if(_cp.IsBranchType(Zydis::BTCondJmp | Zydis::BTLoop | Zydis::BTXbegin))
_mnemonicType = TokenType::MnemonicCondJump;
else if (_cp.IsBranchType(Zydis::BT_UncondJmp | Zydis::BT_Xabort))
else if(_cp.IsBranchType(Zydis::BTUncondJmp | Zydis::BTXabort))
_mnemonicType = TokenType::MnemonicUncondJump;
else if(_cp.IsInt3())
_mnemonicType = TokenType::MnemonicInt3;
@ -465,11 +465,21 @@ bool CapstoneTokenizer::tokenizeRegOperand(const ZydisDecodedOperand & op)
switch(regClass)
{
case ZYDIS_REGCLASS_X87: registerType = TokenType::FpuRegister; break;
case ZYDIS_REGCLASS_MMX: registerType = TokenType::MmxRegister; break;
case ZYDIS_REGCLASS_XMM: registerType = TokenType::XmmRegister; break;
case ZYDIS_REGCLASS_YMM: registerType = TokenType::YmmRegister; break;
case ZYDIS_REGCLASS_ZMM: registerType = TokenType::ZmmRegister; break;
case ZYDIS_REGCLASS_X87:
registerType = TokenType::FpuRegister;
break;
case ZYDIS_REGCLASS_MMX:
registerType = TokenType::MmxRegister;
break;
case ZYDIS_REGCLASS_XMM:
registerType = TokenType::XmmRegister;
break;
case ZYDIS_REGCLASS_YMM:
registerType = TokenType::YmmRegister;
break;
case ZYDIS_REGCLASS_ZMM:
registerType = TokenType::ZmmRegister;
break;
}
if(reg.value == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS))
@ -483,7 +493,7 @@ bool CapstoneTokenizer::tokenizeImmOperand(const ZydisDecodedOperand & op)
{
duint value;
TokenType valueType;
if(_cp.IsBranchType(Zydis::BT_Jmp | Zydis::BT_Call | Zydis::BT_Loop))
if(_cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop))
{
valueType = TokenType::Address;
value = op.imm.value.u;
@ -513,7 +523,7 @@ bool CapstoneTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
//memory segment
const auto & mem = op.mem;
auto segmentType = mem.segment == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS)
? TokenType::MnemonicUnusual : TokenType::MemorySegment;
? TokenType::MnemonicUnusual : TokenType::MemorySegment;
addToken(segmentType, _cp.RegName(mem.segment));
addToken(TokenType::Uncategorized, ":");

View File

@ -2342,15 +2342,15 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value)
if(highlight)
{
const char* name = "";
switch(highlight & ~(Zydis::Implicit | Zydis::Explicit))
switch(highlight & ~(Zydis::RAIImplicit | Zydis::RAIExplicit))
{
case Zydis::Read:
case Zydis::RAIRead:
name = "RegistersHighlightReadColor";
break;
case Zydis::Write:
case Zydis::RAIWrite:
name = "RegistersHighlightWriteColor";
break;
case Zydis::Read | Zydis::Write:
case Zydis::RAIRead | Zydis::RAIWrite:
name = "RegistersHighlightReadWriteColor";
break;
}

View File

@ -8,16 +8,16 @@
#else
# ifndef ZYDIS_EXPORT
# ifdef Zydis_EXPORTS
/* We are building this library */
# define ZYDIS_EXPORT
/* We are building this library */
# define ZYDIS_EXPORT
# else
/* We are using this library */
# define ZYDIS_EXPORT
/* We are using this library */
# define ZYDIS_EXPORT
# endif
# endif
# ifndef ZYDIS_NO_EXPORT
# define ZYDIS_NO_EXPORT
# define ZYDIS_NO_EXPORT
# endif
#endif

View File

@ -2,8 +2,8 @@
#include <windows.h>
bool Zydis::mInitialized = false;
ZydisDecoder Zydis::mZyDecoder;
ZydisFormatter Zydis::mZyFormatter;
ZydisDecoder Zydis::mDecoder;
ZydisFormatter Zydis::mFormatter;
void Zydis::GlobalInitialize()
{
@ -11,11 +11,11 @@ void Zydis::GlobalInitialize()
{
mInitialized = true;
#ifdef _WIN64
ZydisDecoderInit(&mZyDecoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
ZydisDecoderInit(&mDecoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
#else //x86
ZydisDecoderInit(&mZyDecoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32);
ZydisDecoderInit(&mDecoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32);
#endif //_WIN64
ZydisFormatterInit(&mZyFormatter, ZYDIS_FORMATTER_STYLE_INTEL);
ZydisFormatterInit(&mFormatter, ZYDIS_FORMATTER_STYLE_INTEL);
}
}
@ -26,13 +26,13 @@ void Zydis::GlobalFinalize()
Zydis::Zydis()
: mSuccess(false),
mExplicitOpCount(0)
mVisibleOpCount(0)
{
GlobalInitialize();
}
Zydis::~Zydis()
{
{
}
bool Zydis::Disassemble(size_t addr, const unsigned char data[MAX_DISASM_BUFFER])
@ -48,34 +48,34 @@ bool Zydis::Disassemble(size_t addr, const unsigned char* data, int size)
mSuccess = false;
// Decode instruction.
if(!ZYDIS_SUCCESS(ZydisDecoderDecodeBuffer(
&mZyDecoder, data, size, addr, &mZyInstr
)))
if(!ZYDIS_SUCCESS(ZydisDecoderDecodeBuffer(
&mDecoder, data, size, addr, &mInstr
)))
return false;
// Format it to human readable representation.
if(!ZYDIS_SUCCESS(ZydisFormatterFormatInstruction(
&mZyFormatter,
const_cast<ZydisDecodedInstruction*>(&mZyInstr),
mInstrText,
sizeof(mInstrText)
)))
&mFormatter,
const_cast<ZydisDecodedInstruction*>(&mInstr),
mInstrText,
sizeof(mInstrText)
)))
return false;
// Count explicit operands.
mExplicitOpCount = 0;
for(size_t i = 0; i < ZYDIS_MAX_OPERAND_COUNT; ++i)
mVisibleOpCount = 0;
for(size_t i = 0; i < mInstr.operandCount; ++i)
{
auto & op = mZyInstr.operands[i];
auto & op = mInstr.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.type == ZYDIS_OPERAND_TYPE_IMMEDIATE && op.imm.isRelative)
ZydisUtilsCalcAbsoluteTargetAddress(&mInstr, &op, &op.imm.value.u);
if (op.visibility != ZYDIS_OPERAND_VISIBILITY_EXPLICIT)
if(op.visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN)
break;
++mExplicitOpCount;
++mVisibleOpCount;
}
mSuccess = true;
@ -94,7 +94,7 @@ const ZydisDecodedInstruction* Zydis::GetInstr() const
{
if(!Success())
return nullptr;
return &mZyInstr;
return &mInstr;
}
bool Zydis::Success() const
@ -123,46 +123,50 @@ const char* Zydis::RegName(ZydisRegister reg) const
case ZYDIS_REGISTER_ST7:
return "st(7)";
default:
return ZydisRegisterGetString(reg);
return ZydisRegisterGetString(reg);
}
}
std::string Zydis::OperandText(int opindex) const
{
if(!Success() || opindex >= mZyInstr.operandCount)
if(!Success() || opindex >= mInstr.operandCount)
return "";
auto& op = mZyInstr.operands[opindex];
auto & op = mInstr.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 "";
}
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)))
ZydisFormatterFormatOperandFunc fmtFunc = nullptr;
if(!ZYDIS_SUCCESS(ZydisFormatterSetHook(&mFormatter, type, (const void**)&fmtFunc)))
return "";
char buf[200] = "";
auto bufPtr = buf;
fmtFunc(
&mZyFormatter,
&bufPtr,
sizeof(buf),
(ZydisDecodedInstruction*)&mZyInstr,
(ZydisDecodedOperand*)&op
);
char buf[200] = "";
auto bufPtr = buf;
fmtFunc(
&mFormatter,
&bufPtr,
sizeof(buf),
(ZydisDecodedInstruction*)&mInstr,
(ZydisDecodedOperand*)&op
);
return buf;
}
@ -186,7 +190,7 @@ bool Zydis::IsFilling() const
if(!Success())
return false;
switch(mZyInstr.mnemonic)
switch(mInstr.mnemonic)
{
case ZYDIS_MNEMONIC_NOP:
case ZYDIS_MNEMONIC_INT3:
@ -202,20 +206,20 @@ bool Zydis::IsBranchType(std::underlying_type_t<BranchType> bt) const
return false;
std::underlying_type_t<BranchType> ref = 0;
const auto & op0 = mZyInstr.operands[0];
const auto & op0 = mInstr.operands[0];
switch(mZyInstr.mnemonic)
switch(mInstr.mnemonic)
{
case ZYDIS_MNEMONIC_RET:
ref = BT_Ret;
case ZYDIS_MNEMONIC_RET:
ref = BTRet;
break;
case ZYDIS_MNEMONIC_CALL:
ref = (op0.elementType == ZYDIS_ELEMENT_TYPE_STRUCT ||
op0.type == ZYDIS_OPERAND_TYPE_POINTER) ? BT_FarCall : BT_Call;
op0.type == ZYDIS_OPERAND_TYPE_POINTER) ? BTFarCall : BTCall;
break;
case ZYDIS_MNEMONIC_JMP:
ref = (op0.elementType == ZYDIS_ELEMENT_TYPE_STRUCT ||
op0.type == ZYDIS_OPERAND_TYPE_POINTER) ? BT_FarJmp : BT_UncondJmp;
op0.type == ZYDIS_OPERAND_TYPE_POINTER) ? BTFarJmp : BTUncondJmp;
break;
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
@ -238,38 +242,38 @@ bool Zydis::IsBranchType(std::underlying_type_t<BranchType> bt) const
case ZYDIS_MNEMONIC_JRCXZ:
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
ref = BT_CondJmp;
ref = BTCondJmp;
break;
case ZYDIS_MNEMONIC_SYSCALL:
case ZYDIS_MNEMONIC_SYSENTER:
ref = BT_Syscall;
ref = BTSyscall;
break;
case ZYDIS_MNEMONIC_SYSRET:
case ZYDIS_MNEMONIC_SYSEXIT:
ref = BT_Sysret;
ref = BTSysret;
break;
case ZYDIS_MNEMONIC_INT:
ref = BT_Int;
ref = BTInt;
break;
case ZYDIS_MNEMONIC_INT3:
ref = BT_Int3;
ref = BTInt3;
break;
case ZYDIS_MNEMONIC_INT1:
ref = BT_Int1;
ref = BTInt1;
break;
case ZYDIS_MNEMONIC_XBEGIN:
ref = BT_Xbegin;
ref = BTXbegin;
break;
case ZYDIS_MNEMONIC_XABORT:
ref = BT_Xabort;
ref = BTXabort;
break;
case ZYDIS_MNEMONIC_RSM:
ref = BT_Rsm;
ref = BTRsm;
break;
case ZYDIS_MNEMONIC_LOOP:
case ZYDIS_MNEMONIC_LOOPE:
case ZYDIS_MNEMONIC_LOOPNE:
ref = BT_Loop;
ref = BTLoop;
default:
;
}
@ -282,7 +286,7 @@ ZydisMnemonic Zydis::GetId() const
{
if(!Success())
DebugBreak();
return mZyInstr.mnemonic;
return mInstr.mnemonic;
}
std::string Zydis::InstructionText(bool replaceRipRelative) const
@ -325,14 +329,14 @@ int Zydis::OpCount() const
{
if(!Success())
return 0;
return mExplicitOpCount;
return mVisibleOpCount;
}
const ZydisDecodedOperand & Zydis::operator[](int index) const
{
if(!Success() || index < 0 || index >= OpCount())
DebugBreak();
return mZyInstr.operands[index];
return mInstr.operands[index];
}
static bool isSafe64NopRegOp(const ZydisDecodedOperand & op)
@ -364,9 +368,9 @@ bool Zydis::IsNop() const
if(!Success())
return false;
const auto & ops = mZyInstr.operands;
const auto & ops = mInstr.operands;
switch(mZyInstr.mnemonic)
switch(mInstr.mnemonic)
{
case ZYDIS_MNEMONIC_NOP:
case ZYDIS_MNEMONIC_PAUSE:
@ -374,85 +378,85 @@ bool Zydis::IsNop() const
// 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_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]);
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]);
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:
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();
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]);
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]);
return ops[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE
&& ops[2].imm.value.u == 0
&& isSafe64NopRegOp(ops[0])
&& isSafe64NopRegOp(ops[1]);
default:
return false;
}
@ -463,7 +467,7 @@ bool Zydis::IsPushPop() const
if(!Success())
return false;
switch(mZyInstr.meta.category)
switch(mInstr.meta.category)
{
case ZYDIS_CATEGORY_PUSH:
case ZYDIS_CATEGORY_POP:
@ -479,17 +483,17 @@ 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;
auto id = mInstr.mnemonic;
return mInstr.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
@ -497,8 +501,8 @@ std::string Zydis::Mnemonic() const
if(!Success())
return "???";
switch(mZyInstr.mnemonic)
{
switch(mInstr.mnemonic)
{
case ZYDIS_MNEMONIC_JZ:
return "je";
case ZYDIS_MNEMONIC_JNZ:
@ -536,8 +540,8 @@ std::string Zydis::Mnemonic() const
case ZYDIS_MNEMONIC_SETNZ:
return "setne";
default:
return ZydisMnemonicGetString(mZyInstr.mnemonic);
}
return ZydisMnemonicGetString(mInstr.mnemonic);
}
}
std::string Zydis::MnemonicId() const
@ -579,18 +583,18 @@ const char* Zydis::MemSizeName(int size) const
size_t Zydis::BranchDestination() const
{
if(!Success()
|| mZyInstr.operands[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE
|| !mZyInstr.operands[0].imm.isRelative)
if(!Success()
|| mInstr.operands[0].type != ZYDIS_OPERAND_TYPE_IMMEDIATE
|| !mInstr.operands[0].imm.isRelative)
return 0;
return mZyInstr.operands[0].imm.value.u;
return mInstr.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];
const auto & op = mInstr.operands[opindex];
switch(op.type)
{
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
@ -616,7 +620,7 @@ bool Zydis::IsBranchGoingToExecute(size_t cflags, size_t ccx) const
{
if(!Success())
return false;
return IsBranchGoingToExecute(mZyInstr.mnemonic, cflags, ccx);
return IsBranchGoingToExecute(mInstr.mnemonic, cflags, ccx);
}
bool Zydis::IsBranchGoingToExecute(ZydisMnemonic id, size_t cflags, size_t ccx)
@ -634,7 +638,7 @@ bool Zydis::IsBranchGoingToExecute(ZydisMnemonic id, size_t cflags, size_t ccx)
return true;
case ZYDIS_MNEMONIC_JNB: //jump short if above or equal
return !bCF;
case ZYDIS_MNEMONIC_JNBE: //jump short if above
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;
@ -683,7 +687,7 @@ bool Zydis::IsConditionalGoingToExecute(size_t cflags, size_t ccx) const
{
if(!Success())
return false;
return IsConditionalGoingToExecute(mZyInstr.mnemonic, cflags, ccx);
return IsConditionalGoingToExecute(mInstr.mnemonic, cflags, ccx);
}
bool Zydis::IsConditionalGoingToExecute(ZydisMnemonic id, size_t cflags, size_t ccx)
@ -787,17 +791,17 @@ void Zydis::RegInfo(uint8_t regs[ZYDIS_REGISTER_MAX_VALUE + 1]) const
return;
for(int i = 0; i < OpCount(); i++)
{
const auto & op = mZyInstr.operands[i];
const auto & op = mInstr.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;
if(op.action & ZYDIS_OPERAND_ACTION_MASK_READ)
regs[op.reg.value] |= RAIRead;
if(op.action & ZYDIS_OPERAND_ACTION_MASK_WRITE)
regs[op.reg.value] |= RAIWrite;
regs[op.reg.value] |= op.visibility != ZYDIS_OPERAND_VISIBILITY_HIDDEN ?
RAIExplicit : RAIImplicit;
}
break;
@ -814,17 +818,17 @@ void Zydis::RegInfo(uint8_t regs[ZYDIS_REGISTER_MAX_VALUE + 1]) const
case ZYDIS_REGISTER_ESP:
case ZYDIS_REGISTER_EBP:
#endif //_WIN64
regs[ZYDIS_REGISTER_SS] |= Read | Explicit;
regs[ZYDIS_REGISTER_SS] |= RAIRead | RAIExplicit;
break;
default:
regs[ZYDIS_REGISTER_DS] |= Read | Explicit;
regs[ZYDIS_REGISTER_DS] |= RAIRead | RAIExplicit;
break;
}
}
else
regs[op.mem.segment] |= Read | Explicit;
regs[op.mem.base] |= Read | Explicit;
regs[op.mem.index] |= Read | Explicit;
regs[op.mem.segment] |= RAIRead | RAIExplicit;
regs[op.mem.base] |= RAIRead | RAIExplicit;
regs[op.mem.index] |= RAIRead | RAIExplicit;
}
break;
@ -838,29 +842,49 @@ 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_AF:
return "AF";
case ZYDIS_CPUFLAG_ZF:
return "ZF";
case ZYDIS_CPUFLAG_SF:
return "SF";
case ZYDIS_CPUFLAG_TF:
return "TF";
case ZYDIS_CPUFLAG_IF:
return "IF";
case ZYDIS_CPUFLAG_DF:
return "DF";
case ZYDIS_CPUFLAG_OF:
return "OF";
case ZYDIS_CPUFLAG_IOPL:
return "IOPL";
case ZYDIS_CPUFLAG_NT:
return "NT";
case ZYDIS_CPUFLAG_RF:
return "RF";
case ZYDIS_CPUFLAG_VM:
return "VM";
case ZYDIS_CPUFLAG_AC:
return "AC";
case ZYDIS_CPUFLAG_VIF:
return "VIF";
case ZYDIS_CPUFLAG_VIP:
return "VIP";
case ZYDIS_CPUFLAG_ID:
return "ID";
case ZYDIS_CPUFLAG_C0:
return "C0";
case ZYDIS_CPUFLAG_C1:
return "C1";
case ZYDIS_CPUFLAG_C2:
return "C2";
case ZYDIS_CPUFLAG_C3:
return "C3";
default:
return nullptr;
}
}
}

View File

@ -11,15 +11,15 @@ class Zydis
public:
static void GlobalInitialize();
static void GlobalFinalize();
Zydis();
Zydis(const Zydis & capstone) = delete;
~Zydis();
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;
const ZydisDecodedInstruction* GetInstr() const;
bool Success() const;
const char* RegName(ZydisRegister reg) const;
const char* RegName(ZydisRegister reg) const;
std::string OperandText(int opindex) const;
int Size() const;
size_t Address() const;
@ -30,24 +30,24 @@ public:
ZydisMnemonic GetId() const;
std::string InstructionText(bool replaceRipRelative = true) const;
int OpCount() const;
const ZydisDecodedOperand & operator[](int index) 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;
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
enum RegAccessInfo : uint8_t
{
None = 1 << 0,
Read = 1 << 0,
Write = 1 << 1,
Implicit = 1 << 2,
Explicit = 1 << 3
RAINone = 0,
RAIRead = 1 << 0,
RAIWrite = 1 << 1,
RAIImplicit = 1 << 2,
RAIExplicit = 1 << 3
};
void RegInfo(uint8_t info[ZYDIS_REGISTER_MAX_VALUE + 1]) const;
@ -56,54 +56,54 @@ public:
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,
BTRet = 1 << 0,
BTCall = 1 << 1,
BTFarCall = 1 << 2,
BTSyscall = 1 << 3, // Also sysenter
BTSysret = 1 << 4, // Also sysexit
BTInt = 1 << 5,
BTInt3 = 1 << 6,
BTInt1 = 1 << 7,
BTIret = 1 << 8,
BTCondJmp = 1 << 9,
BTUncondJmp = 1 << 10,
BTFarJmp = 1 << 11,
BTXbegin = 1 << 12,
BTXabort = 1 << 13,
BTRsm = 1 << 14,
BTLoop = 1 << 15,
BT_Jmp = BT_CondJmp | BT_UncondJmp,
BTJmp = BTCondJmp | BTUncondJmp,
// 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,
BTCallSem = BTCall | BTSyscall | BTInt,
BTRetSem = BTRet | BTSysret | BTIret | BTRsm | BTXabort,
BTIntSem = BTInt | BTInt1 | BTInt3 | BTSyscall,
BTIretSem = BTIret | BTSysret,
BTJmpSem = BTJmp | BTLoop,
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)
BTRtm = BTXabort | BTXbegin,
BTCtxSwitch = BTIntSem | BTIretSem | BTRsm | BTFarCall | BTFarJmp,
BTAny = 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); }
bool IsRet() const { return IsBranchType(BTRet); }
bool IsCall() const { return IsBranchType(BTCall); }
bool IsJump() const { return IsBranchType(BTJmp); }
bool IsLoop() const { return IsBranchType(BTLoop); }
bool IsInt3() const { return IsBranchType(BTInt3); }
private:
static ZydisDecoder mZyDecoder;
static ZydisFormatter mZyFormatter;
static ZydisDecoder mDecoder;
static ZydisFormatter mFormatter;
static bool mInitialized;
ZydisDecodedInstruction mZyInstr;
ZydisDecodedInstruction mInstr;
char mInstrText[200];
bool mSuccess;
uint8_t mExplicitOpCount;
uint8_t mVisibleOpCount;
};
#endif //ZYDIS_WRAPPER_H