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:
parent
ca9401fdb7
commit
af0ff55df3
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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, ":");
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue