From 6f7af9b8daeef3228993c2bbd62327646a9a9493 Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Sat, 14 Oct 2017 00:32:34 +0200 Subject: [PATCH] DBG: fixed various small issues with Zydis ping @athre0z --- src/dbg/analysis/advancedanalysis.cpp | 22 ++++++------ src/dbg/disasm_fast.cpp | 4 +-- src/dbg/disasm_helper.cpp | 20 +++++------ src/zydis_wrapper/zydis_wrapper.cpp | 50 ++++++++++++++++++++++++++- 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/dbg/analysis/advancedanalysis.cpp b/src/dbg/analysis/advancedanalysis.cpp index a88a481c..a7d7c020 100644 --- a/src/dbg/analysis/advancedanalysis.cpp +++ b/src/dbg/analysis/advancedanalysis.cpp @@ -263,36 +263,38 @@ void AdvancedAnalysis::writeDataXrefs() //Todo: Analyze op type and set correct type if(op.type == ZYDIS_OPERAND_TYPE_MEMORY) { - duint datasize = op.size; + duint datasize = op.size / 8; duint size = datasize; duint offset = xref.addr - mBase; switch(op.size) { - case 1: + case 8: type = enc_byte; break; - case 2: + case 16: type = enc_word; break; - case 4: + case 32: type = isfloat ? enc_real4 : enc_dword; break; - case 6: + case 48: type = enc_fword; break; - case 8: + case 64: type = isfloat ? enc_real8 : enc_qword; break; - case 10: + case 80: type = isfloat ? enc_real10 : enc_tbyte; break; - case 16: + case 128: type = enc_oword; break; - case 32: + case 256: type = enc_ymmword; break; - //case 64: type = enc_zmmword; break; + //case 64: type = enc_zmmword; break; + default: + __debugbreak(); } if(datasize == 1) { diff --git a/src/dbg/disasm_fast.cpp b/src/dbg/disasm_fast.cpp index 5a1a34c4..552c3fa4 100644 --- a/src/dbg/disasm_fast.cpp +++ b/src/dbg/disasm_fast.cpp @@ -60,7 +60,7 @@ void fillbasicinfo(Zydis* cp, BASIC_INSTRUCTION_INFO* basicinfo, bool instrText) else { basicinfo->type |= TYPE_VALUE; - basicinfo->value.size = VALUE_SIZE(op.size); + basicinfo->value.size = VALUE_SIZE(op.size / 8); basicinfo->value.value = duint(op.imm.value.u); } } @@ -71,7 +71,7 @@ void fillbasicinfo(Zydis* cp, BASIC_INSTRUCTION_INFO* basicinfo, bool instrText) const auto & mem = op.mem; if(instrText) strcpy_s(basicinfo->memory.mnemonic, cp->OperandText(i).c_str()); - basicinfo->memory.size = MEMORY_SIZE(op.size); + basicinfo->memory.size = MEMORY_SIZE(op.size / 8); if(op.mem.base == ZYDIS_REGISTER_RIP) //rip-relative { basicinfo->memory.value = ULONG_PTR(cp->Address() + op.mem.disp.value + basicinfo->size); diff --git a/src/dbg/disasm_helper.cpp b/src/dbg/disasm_helper.cpp index ea391bc1..a5d66e89 100644 --- a/src/dbg/disasm_helper.cpp +++ b/src/dbg/disasm_helper.cpp @@ -145,15 +145,9 @@ static void HandleCapstoneOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool arg->constant = cp.Address() + duint(mem.disp.value) + cp.Size(); else arg->constant = duint(mem.disp.value); -#ifdef _WIN64 - if(mem.segment == ZYDIS_REGISTER_GS) + if(mem.segment == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS)) { - arg->segment = SEG_GS; -#else //x86 - if(mem.segment == ZYDIS_REGISTER_FS) - { - arg->segment = SEG_FS; -#endif + arg->segment = ArchValue(SEG_FS, SEG_GS); value += ThreadGetLocalBase(ThreadGetId(hActiveThread)); } arg->value = value; @@ -161,20 +155,22 @@ static void HandleCapstoneOperand(Zydis & cp, int opindex, DISASM_ARG* arg, bool { switch(op.size) { - case 1: + case 8: MemRead(value, (unsigned char*)&arg->memvalue, 1); break; - case 2: + case 16: MemRead(value, (unsigned char*)&arg->memvalue, 2); break; - case 4: + case 32: MemRead(value, (unsigned char*)&arg->memvalue, 4); break; #ifdef _WIN64 - case 8: + case 64: MemRead(value, (unsigned char*)&arg->memvalue, 8); break; #endif //_WIN64 + default: + __debugbreak(); } } } diff --git a/src/zydis_wrapper/zydis_wrapper.cpp b/src/zydis_wrapper/zydis_wrapper.cpp index 8e4ec8dd..2577f775 100644 --- a/src/zydis_wrapper/zydis_wrapper.cpp +++ b/src/zydis_wrapper/zydis_wrapper.cpp @@ -1,10 +1,45 @@ #include "zydis_wrapper.h" +#include #include bool Zydis::mInitialized = false; ZydisDecoder Zydis::mDecoder; ZydisFormatter Zydis::mFormatter; +static ZydisStatus ZydisFormatterPrintDisplacementIntelCustom(const ZydisFormatter* formatter, + char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, + ZydisDecodedOperand* operand) +{ + if(!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + if(operand->mem.disp.hasDisplacement && ((operand->mem.disp.value) || + ((operand->mem.base == ZYDIS_REGISTER_NONE) && + (operand->mem.index == ZYDIS_REGISTER_NONE)))) + { + ZydisBool printSignedHEX = + (formatter->displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED); + if(printSignedHEX && (operand->mem.disp.value < 0) && ( + (operand->mem.base != ZYDIS_REGISTER_NONE) || + (operand->mem.index != ZYDIS_REGISTER_NONE))) + { + return ZydisPrintHexS( + buffer, bufferLen, operand->mem.disp.value, 0, ZYDIS_TRUE, ZYDIS_FALSE); + } + char* bufEnd = *buffer + bufferLen; + if((operand->mem.base != ZYDIS_REGISTER_NONE) || + (operand->mem.index != ZYDIS_REGISTER_NONE)) + { + ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "+", ZYDIS_LETTER_CASE_DEFAULT)); + } + return ZydisPrintHexU( + buffer, bufEnd - *buffer, (uint64_t)operand->mem.disp.value, 0, ZYDIS_TRUE, ZYDIS_FALSE); + } + return ZYDIS_STATUS_SUCCESS; +} + void Zydis::GlobalInitialize() { if(!mInitialized) @@ -16,6 +51,7 @@ void Zydis::GlobalInitialize() ZydisDecoderInit(&mDecoder, ZYDIS_MACHINE_MODE_LEGACY_32, ZYDIS_ADDRESS_WIDTH_32); #endif //_WIN64 ZydisFormatterInit(&mFormatter, ZYDIS_FORMATTER_STYLE_INTEL); + mFormatter.funcPrintDisplacement = &ZydisFormatterPrintDisplacementIntelCustom; } } @@ -158,10 +194,12 @@ std::string Zydis::OperandText(int opindex) const return ""; } + //Get the operand format function. ZydisFormatterFormatOperandFunc fmtFunc = nullptr; if(!ZYDIS_SUCCESS(ZydisFormatterSetHook(&mFormatter, type, (const void**)&fmtFunc))) return ""; + //Format the operand. char buf[200] = ""; auto bufPtr = buf; fmtFunc( @@ -172,7 +210,17 @@ std::string Zydis::OperandText(int opindex) const const_cast(&op) ); - return buf; + //Remove [] from memory operands + std::string result; + if(op.type == ZYDIS_OPERAND_TYPE_MEMORY) + { + result = buf + 1; + result.pop_back(); + } + else + result = buf; + + return std::move(result); } int Zydis::Size() const