diff --git a/CMakeLists.txt b/CMakeLists.txt index 9116845..f8c01ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,4 +145,9 @@ if (ZYDIS_BUILD_TOOLS) target_link_libraries("ZydisFuzzIn" "Zydis") set_target_properties("ZydisFuzzIn" PROPERTIES FOLDER "Tools") target_compile_definitions("ZydisFuzzIn" PRIVATE "_CRT_SECURE_NO_WARNINGS") + + add_executable("PerfTest" "tools/PerfTest.c") + target_link_libraries("PerfTest" "Zydis") + set_target_properties("PerfTest" PROPERTIES FOLDER "Tools") + target_compile_definitions("PerfTest" PRIVATE "_CRT_SECURE_NO_WARNINGS") endif () diff --git a/README.md b/README.md index e18b1ed..000e5e2 100644 --- a/README.md +++ b/README.md @@ -37,29 +37,26 @@ int main() 0x88, 0xFC, 0xDA, 0x02, 0x00 }; - ZydisMemoryInput input; - ZydisInputInitMemoryInput(&input, &data, sizeof(data)); + ZydisDecoder decoder; + ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); - ZydisInstructionDecoder decoder; - ZydisDecoderInitInstructionDecoderEx(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT, - (ZydisCustomInput*)&input, ZYDIS_DECODER_FLAG_SKIP_DATA); - ZydisDecoderSetInstructionPointer(&decoder, 0x007FFFFFFF400000); - - ZydisInstructionFormatter formatter; - ZydisFormatterInitInstructionFormatterEx(&formatter, - ZYDIS_FORMATTER_STYLE_INTEL, ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT); + ZydisFormatter formatter; + ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, + ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, + ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); - ZydisInstructionInfo info; + uint64_t instructionPointer = 0x007FFFFFFF400000; + + ZydisDecodedInstruction instruction; char buffer[256]; - while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info))) + while (ZYDIS_SUCCESS( + ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction))) { - printf("%016llX ", info.instrAddress); - if (info.flags & ZYDIS_IFLAG_ERROR_MASK) - { - printf(" db %02x\n", info.data[0]); - continue; - } - ZydisFormatterFormatInstruction(&formatter, &info, &buffer[0], sizeof(buffer)); + data += instruction.length; + length -= instruction.length; + instructionPointer += instruction.length; + printf("%016" PRIX64 " ", instruction.instrAddress); + ZydisFormatterFormatInstruction(&formatter, &instruction, &buffer[0], sizeof(buffer)); printf(" %s\n", &buffer[0]); } } diff --git a/examples/FormatterHooks.c b/examples/FormatterHooks.c index 4f8803f..b31b6c3 100644 --- a/examples/FormatterHooks.c +++ b/examples/FormatterHooks.c @@ -26,9 +26,9 @@ /** * @file - * @brief Demonstrates the hooking functionality of the @c ZydisInstructionFormatter class. + * @brief Demonstrates the hooking functionality of the @c ZydisFormatter class. * - * This example demonstrates the hooking functionality of the @c ZydisInstructionFormatter class by + * This example demonstrates the hooking functionality of the @c ZydisFormatter class by * rewriting the mnemonics of (V)CMPPS and (V)CMPPD to their corresponding alias-forms (based on * the condition encoded in the immediate operand). */ @@ -87,7 +87,7 @@ static const char* conditionCodeStrings[0x20] = ZydisFormatterFormatFunc defaultPrintMnemonic; -static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) { // We use the user-data field of the instruction-info to pass data to the @@ -152,7 +152,7 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisInstructionFormatter* ZydisFormatterFormatOperandFunc defaultFormatOperandImm; -static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -175,11 +175,10 @@ static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisInstructionFormatte /* Helper functions */ /* ============================================================================================== */ -void disassembleBuffer(ZydisInstructionDecoder* decoder, uint8_t* data, size_t length, - ZydisBool installHooks) +void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, ZydisBool installHooks) { - ZydisInstructionFormatter formatter; - ZydisFormatterInitInstructionFormatterEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, + ZydisFormatter formatter; + ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); @@ -215,6 +214,7 @@ void disassembleBuffer(ZydisInstructionDecoder* decoder, uint8_t* data, size_t l int main() { + uint8_t data[] = { // cmpps xmm1, xmm4, 0x03 @@ -227,10 +227,8 @@ int main() 0x62, 0xF1, 0x6C, 0x5F, 0xC2, 0x54, 0x98, 0x40, 0x0F }; - - ZydisInstructionDecoder decoder; - ZydisDecoderInitInstructionDecoder( - &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); + ZydisDecoder decoder; + ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); disassembleBuffer(&decoder, &data[0], sizeof(data), ZYDIS_FALSE); puts(""); diff --git a/include/Zydis/Decoder.h b/include/Zydis/Decoder.h index b2b6697..723d2f1 100644 --- a/include/Zydis/Decoder.h +++ b/include/Zydis/Decoder.h @@ -46,27 +46,37 @@ extern "C" { typedef uint32_t ZydisDecodeGranularity; /** - * @brief Decoders modes defining how granular the instruction should be decoded. + * @brief Decoder modes defining how granular the instruction should be decoded. */ enum ZydisDecodeGranularities { ZYDIS_DECODE_GRANULARITY_DEFAULT, /** - * @brief Minimal instruction decoding without semantic operand analysis. + * @brief Minimal instruction decoding without semantic analysis. + * + * This mode should be sufficient, if you plan to analyse code for pure relocation purposes, + * as it gives you access to the mnemonic, the instruction-length, displacements, immediates + * and the `ZYDIS_ATTRIB_IS_RELATIVE` attribute. + * + * Operands, most attributes and other specific information (like AVX info) are not + * accessible in this mode. */ ZYDIS_DECODE_GRANULARITY_MINIMAL, + /** + * @brief Full physical and semantical instruction-decoding. + */ ZYDIS_DECODE_GRANULARITY_FULL }; /** - * @brief Defines the @c ZydisInstructionDecoder datatype. + * @brief Defines the @c ZydisDecoder datatype. */ -typedef struct ZydisInstructionDecoder_ +typedef struct ZydisDecoder_ { ZydisMachineMode machineMode; ZydisAddressWidth addressWidth; ZydisDecodeGranularity decodeGranularity; -} ZydisInstructionDecoder; +} ZydisDecoder; /* ---------------------------------------------------------------------------------------------- */ @@ -75,35 +85,34 @@ typedef struct ZydisInstructionDecoder_ /* ============================================================================================== */ /** - * @brief Initializes the given @c ZydisInstructionDecoder instance. + * @brief Initializes the given @c ZydisDecoder instance. * - * @param decoder A pointer to the @c ZydisInstructionDecoder instance. - * @param machineMode The machine mode. - * @param addressWidth The address width. + * @param decoder A pointer to the @c ZydisDecoder instance. + * @param machineMode The machine mode. + * @param addressWidth The address width. * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder, - ZydisMachineMode machineMode, ZydisAddressWidth addressWidth); +ZYDIS_EXPORT ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode, + ZydisAddressWidth addressWidth); /** - * @brief Initializes the given @c ZydisInstructionDecoder instance. + * @brief Initializes the given @c ZydisDecoder instance. * - * @param decoder A pointer to the @c ZydisInstructionDecoder instance. + * @param decoder A pointer to the @c ZydisDecoder instance. * @param machineMode The machine mode. * @param addressWidth The address width. * @param decodeGranularity The decode granularity. * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decoder, - ZydisMachineMode machineMode, ZydisAddressWidth addressWidth, - ZydisDecodeGranularity decodeGranularity); +ZYDIS_EXPORT ZydisStatus ZydisDecoderInitEx(ZydisDecoder* decoder, ZydisMachineMode machineMode, + ZydisAddressWidth addressWidth, ZydisDecodeGranularity decodeGranularity); /** * @brief Decodes the instruction in the given input @c buffer. * - * @param decoder A pointer to the @c ZydisInstructionDecoder instance. + * @param decoder A pointer to the @c ZydisDecoder instance. * @param buffer A pointer to the input buffer. * @param bufferLen The length of the input buffer. * @param instructionPointer The instruction-pointer. @@ -112,7 +121,7 @@ ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDe * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeBuffer(const ZydisInstructionDecoder* decoder, +ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* buffer, size_t bufferLen, uint64_t instructionPointer, ZydisDecodedInstruction* instruction); diff --git a/include/Zydis/DecoderTypes.h b/include/Zydis/DecoderTypes.h index a0e1e48..a6e2ddb 100644 --- a/include/Zydis/DecoderTypes.h +++ b/include/Zydis/DecoderTypes.h @@ -1346,7 +1346,7 @@ typedef struct ZydisDecodedInstruction_ */ uint8_t offset; } imm[2]; - } details; + } raw; /** * @brief This field is intended for custom data and may be freely set by the user. */ diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index 98db0b6..4501089 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -277,12 +277,12 @@ enum ZydisFormatterHookTypes /* ---------------------------------------------------------------------------------------------- */ -typedef struct ZydisInstructionFormatter_ ZydisInstructionFormatter; +typedef struct ZydisFormatter_ ZydisFormatter; /** * @brief Defines the @c ZydisFormatterNotifyFunc function pointer. * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the @@ -291,13 +291,13 @@ typedef struct ZydisInstructionFormatter_ ZydisInstructionFormatter; * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRE and * @c ZYDIS_FORMATTER_HOOK_POST hook-types. */ -typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisInstructionFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, ZydisDecodedInstruction* instruction); /** * @brief Defines the @c ZydisFormatterFormatFunc function pointer. * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param buffer A pointer to the string-buffer. * @param bufferLen The length of the string-buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. @@ -311,13 +311,13 @@ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisInstructionFormatter* * This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION, * @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types. */ -typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisInstructionFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction); /** * @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer. * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param buffer A pointer to the string-buffer. * @param bufferLen The length of the string-buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. @@ -347,14 +347,14 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisInstructionFormatter* * @c ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT and @c ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE * hook-types. */ -typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisInstructionFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand); /** * @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer. * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param buffer A pointer to the string-buffer. * @param bufferLen The length of the string-buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. @@ -369,14 +369,14 @@ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisInstructionFor * * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type. */ -typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisInstructionFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand, uint64_t address); /** - * @brief Defines the @c ZydisInstructionFormatter struct. + * @brief Defines the @c ZydisFormatter struct. */ -struct ZydisInstructionFormatter_ +struct ZydisFormatter_ { ZydisFormatterFlags flags; ZydisFormatterAddressFormat addressFormat; @@ -409,20 +409,19 @@ struct ZydisInstructionFormatter_ /* ============================================================================================== */ /** - * @brief Initializes the given @c ZydisInstructionFormatter instance. + * @brief Initializes the given @c ZydisFormatter instance. * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param style The formatter style. * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisFormatterInitInstructionFormatter( - ZydisInstructionFormatter* formatter, ZydisFormatterStyle style); +ZYDIS_EXPORT ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle style); /** - * @brief Initializes the given @c ZydisInstructionFormatter instance. + * @brief Initializes the given @c ZydisFormatter instance. * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param style The formatter style. * @param addressFormat The address format. * @param displacementFormat The displacement format. @@ -430,34 +429,34 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInitInstructionFormatter( * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisFormatterInitInstructionFormatterEx( - ZydisInstructionFormatter* formatter, ZydisFormatterStyle style, ZydisFormatterFlags flags, - ZydisFormatterAddressFormat addressFormat, ZydisFormatterDisplacementFormat displacementFormat, +ZYDIS_EXPORT ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, ZydisFormatterStyle style, + ZydisFormatterFlags flags, ZydisFormatterAddressFormat addressFormat, + ZydisFormatterDisplacementFormat displacementFormat, ZydisFormatterImmediateFormat immmediateFormat); /** * @brief TODO: * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param hook The formatter hook-type. * @param callback TODO: In Out * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter, +ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookType hook, const void** callback); /** * @brief Formats the given instruction and writes it into the output buffer. * - * @param formatter A pointer to the @c ZydisInstructionFormatter instance. + * @param formatter A pointer to the @c ZydisFormatter instance. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param buffer A pointer to the output buffer. * @param bufferLen The length of the output buffer. * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisInstructionFormatter* formatter, +ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen); /* ============================================================================================== */ diff --git a/src/Decoder.c b/src/Decoder.c index 1857c9e..47ff954 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -45,7 +45,7 @@ typedef struct ZydisDecoderContext_ /** * @brief A pointer to the @c ZydisInstructionDecoder instance. */ - const ZydisInstructionDecoder* decoder; + const ZydisDecoder* decoder; /** * @brief The input buffer. */ @@ -213,9 +213,6 @@ enum ZydisRegisterEncodings * @param value A pointer to the memory that receives the byte from the input data-source. * * @return A zydis status code. - * - * If not empty, the internal buffer of the @c ZydisDecoderContext instance is used as temporary - * data-source, instead of reading the byte from the actual input data-source. * * This function may fail, if the @c ZYDIS_MAX_INSTRUCTION_LENGTH limit got exceeded, or no more * data is available. @@ -249,10 +246,7 @@ static ZydisStatus ZydisInputPeek(ZydisDecoderContext* context, * * This function is supposed to get called ONLY after a successfull call of @c ZydisInputPeek. * - * If not empty, the read-position of the @c ZydisDecoderContext instances internal buffer is - * increased, instead of the actual input data-sources read-position. - * - * This function increases the @c length field of the @c ZydisInstructionInfo struct by one and + * This function increases the @c length field of the @c ZydisDecodedInstruction struct by one and * adds the current byte to the @c data array. */ static void ZydisInputSkip(ZydisDecoderContext* context, ZydisDecodedInstruction* instruction) @@ -359,18 +353,18 @@ static void ZydisDecodeREX(ZydisDecoderContext* context, ZydisDecodedInstruction ZYDIS_ASSERT((data & 0xF0) == 0x40); instruction->attributes |= ZYDIS_ATTRIB_HAS_REX; - instruction->details.rex.isDecoded = ZYDIS_TRUE; - instruction->details.rex.data[0] = data; - instruction->details.rex.W = (data >> 3) & 0x01; - instruction->details.rex.R = (data >> 2) & 0x01; - instruction->details.rex.X = (data >> 1) & 0x01; - instruction->details.rex.B = (data >> 0) & 0x01; + instruction->raw.rex.isDecoded = ZYDIS_TRUE; + instruction->raw.rex.data[0] = data; + instruction->raw.rex.W = (data >> 3) & 0x01; + instruction->raw.rex.R = (data >> 2) & 0x01; + instruction->raw.rex.X = (data >> 1) & 0x01; + instruction->raw.rex.B = (data >> 0) & 0x01; // Update internal fields - context->cache.W = instruction->details.rex.W; - context->cache.R = instruction->details.rex.R; - context->cache.X = instruction->details.rex.X; - context->cache.B = instruction->details.rex.B; + context->cache.W = instruction->raw.rex.W; + context->cache.R = instruction->raw.rex.R; + context->cache.X = instruction->raw.rex.X; + context->cache.B = instruction->raw.rex.B; } /** @@ -390,34 +384,34 @@ static ZydisStatus ZydisDecodeXOP(ZydisDecoderContext* context, ZYDIS_ASSERT(((data[1] >> 0) & 0x1F) >= 8); instruction->attributes |= ZYDIS_ATTRIB_HAS_XOP; - instruction->details.xop.isDecoded = ZYDIS_TRUE; - instruction->details.xop.data[0] = 0x8F; - instruction->details.xop.data[1] = data[1]; - instruction->details.xop.data[2] = data[2]; - instruction->details.xop.R = (data[1] >> 7) & 0x01; - instruction->details.xop.X = (data[1] >> 6) & 0x01; - instruction->details.xop.B = (data[1] >> 5) & 0x01; - instruction->details.xop.m_mmmm = (data[1] >> 0) & 0x1F; + instruction->raw.xop.isDecoded = ZYDIS_TRUE; + instruction->raw.xop.data[0] = 0x8F; + instruction->raw.xop.data[1] = data[1]; + instruction->raw.xop.data[2] = data[2]; + instruction->raw.xop.R = (data[1] >> 7) & 0x01; + instruction->raw.xop.X = (data[1] >> 6) & 0x01; + instruction->raw.xop.B = (data[1] >> 5) & 0x01; + instruction->raw.xop.m_mmmm = (data[1] >> 0) & 0x1F; - if ((instruction->details.xop.m_mmmm < 0x08) || (instruction->details.xop.m_mmmm > 0x0A)) + if ((instruction->raw.xop.m_mmmm < 0x08) || (instruction->raw.xop.m_mmmm > 0x0A)) { // Invalid according to the AMD documentation return ZYDIS_STATUS_INVALID_MAP; } - instruction->details.xop.W = (data[2] >> 7) & 0x01; - instruction->details.xop.vvvv = (data[2] >> 3) & 0x0F; - instruction->details.xop.L = (data[2] >> 2) & 0x01; - instruction->details.xop.pp = (data[2] >> 0) & 0x03; + instruction->raw.xop.W = (data[2] >> 7) & 0x01; + instruction->raw.xop.vvvv = (data[2] >> 3) & 0x0F; + instruction->raw.xop.L = (data[2] >> 2) & 0x01; + instruction->raw.xop.pp = (data[2] >> 0) & 0x03; // Update internal fields - context->cache.W = instruction->details.xop.W; - context->cache.R = 0x01 & ~instruction->details.xop.R; - context->cache.X = 0x01 & ~instruction->details.xop.X; - context->cache.B = 0x01 & ~instruction->details.xop.B; - context->cache.L = instruction->details.xop.L; - context->cache.LL = instruction->details.xop.L; - context->cache.v_vvvv = (0x0F & ~instruction->details.xop.vvvv); + context->cache.W = instruction->raw.xop.W; + context->cache.R = 0x01 & ~instruction->raw.xop.R; + context->cache.X = 0x01 & ~instruction->raw.xop.X; + context->cache.B = 0x01 & ~instruction->raw.xop.B; + context->cache.L = instruction->raw.xop.L; + context->cache.LL = instruction->raw.xop.L; + context->cache.v_vvvv = (0x0F & ~instruction->raw.xop.vvvv); return ZYDIS_STATUS_SUCCESS; } @@ -438,53 +432,57 @@ static ZydisStatus ZydisDecodeVEX(ZydisDecoderContext* context, ZYDIS_ASSERT((data[0] == 0xC4) || (data[0] == 0xC5)); instruction->attributes |= ZYDIS_ATTRIB_HAS_VEX; - instruction->details.vex.isDecoded = ZYDIS_TRUE; - instruction->details.vex.data[0] = data[0]; + instruction->raw.vex.isDecoded = ZYDIS_TRUE; + instruction->raw.vex.data[0] = data[0]; switch (data[0]) { case 0xC4: - instruction->details.vex.data[1] = data[1]; - instruction->details.vex.data[2] = data[2]; - instruction->details.vex.R = (data[1] >> 7) & 0x01; - instruction->details.vex.X = (data[1] >> 6) & 0x01; - instruction->details.vex.B = (data[1] >> 5) & 0x01; - instruction->details.vex.m_mmmm = (data[1] >> 0) & 0x1F; - instruction->details.vex.W = (data[2] >> 7) & 0x01; - instruction->details.vex.vvvv = (data[2] >> 3) & 0x0F; - instruction->details.vex.L = (data[2] >> 2) & 0x01; - instruction->details.vex.pp = (data[2] >> 0) & 0x03; + instruction->raw.vex.data[1] = data[1]; + instruction->raw.vex.data[2] = data[2]; + instruction->raw.vex.R = (data[1] >> 7) & 0x01; + instruction->raw.vex.X = (data[1] >> 6) & 0x01; + instruction->raw.vex.B = (data[1] >> 5) & 0x01; + instruction->raw.vex.m_mmmm = (data[1] >> 0) & 0x1F; + instruction->raw.vex.W = (data[2] >> 7) & 0x01; + instruction->raw.vex.vvvv = (data[2] >> 3) & 0x0F; + instruction->raw.vex.L = (data[2] >> 2) & 0x01; + instruction->raw.vex.pp = (data[2] >> 0) & 0x03; break; case 0xC5: - instruction->details.vex.data[1] = data[1]; - instruction->details.vex.data[2] = 0; - instruction->details.vex.R = (data[1] >> 7) & 0x01; - instruction->details.vex.X = 1; - instruction->details.vex.B = 1; - instruction->details.vex.m_mmmm = 1; - instruction->details.vex.W = 0; - instruction->details.vex.vvvv = (data[1] >> 3) & 0x0F; - instruction->details.vex.L = (data[1] >> 2) & 0x01; - instruction->details.vex.pp = (data[1] >> 0) & 0x03; + instruction->raw.vex.data[1] = data[1]; + instruction->raw.vex.data[2] = 0; + instruction->raw.vex.R = (data[1] >> 7) & 0x01; + instruction->raw.vex.X = 1; + instruction->raw.vex.B = 1; + instruction->raw.vex.m_mmmm = 1; + instruction->raw.vex.W = 0; + instruction->raw.vex.vvvv = (data[1] >> 3) & 0x0F; + instruction->raw.vex.L = (data[1] >> 2) & 0x01; + instruction->raw.vex.pp = (data[1] >> 0) & 0x03; break; default: ZYDIS_UNREACHABLE; } - // TODO: m_mmmm = 0 is only valid for some KNC instructions - if (instruction->details.vex.m_mmmm > 0x03) + // Map 0 is only valid for some KNC instructions +#ifdef ZYDIS_ENABLE_FEATURE_MVEX + if (instruction->raw.vex.m_mmmm > 0x03) +#else + if ((instruction->raw.vex.m_mmmm == 0) || (instruction->raw.vex.m_mmmm > 0x03)) +#endif { // Invalid according to the intel documentation return ZYDIS_STATUS_INVALID_MAP; } // Update internal fields - context->cache.W = instruction->details.vex.W; - context->cache.R = 0x01 & ~instruction->details.vex.R; - context->cache.X = 0x01 & ~instruction->details.vex.X; - context->cache.B = 0x01 & ~instruction->details.vex.B; - context->cache.L = instruction->details.vex.L; - context->cache.LL = instruction->details.vex.L; - context->cache.v_vvvv = (0x0F & ~instruction->details.vex.vvvv); + context->cache.W = instruction->raw.vex.W; + context->cache.R = 0x01 & ~instruction->raw.vex.R; + context->cache.X = 0x01 & ~instruction->raw.vex.X; + context->cache.B = 0x01 & ~instruction->raw.vex.B; + context->cache.L = instruction->raw.vex.L; + context->cache.LL = instruction->raw.vex.L; + context->cache.v_vvvv = (0x0F & ~instruction->raw.vex.vvvv); return ZYDIS_STATUS_SUCCESS; } @@ -505,15 +503,15 @@ static ZydisStatus ZydisDecodeEVEX(ZydisDecoderContext* context, ZYDIS_ASSERT(data[0] == 0x62); instruction->attributes |= ZYDIS_ATTRIB_HAS_EVEX; - instruction->details.evex.isDecoded = ZYDIS_TRUE; - instruction->details.evex.data[0] = 0x62; - instruction->details.evex.data[1] = data[1]; - instruction->details.evex.data[2] = data[2]; - instruction->details.evex.data[3] = data[3]; - instruction->details.evex.R = (data[1] >> 7) & 0x01; - instruction->details.evex.X = (data[1] >> 6) & 0x01; - instruction->details.evex.B = (data[1] >> 5) & 0x01; - instruction->details.evex.R2 = (data[1] >> 4) & 0x01; + instruction->raw.evex.isDecoded = ZYDIS_TRUE; + instruction->raw.evex.data[0] = 0x62; + instruction->raw.evex.data[1] = data[1]; + instruction->raw.evex.data[2] = data[2]; + instruction->raw.evex.data[3] = data[3]; + instruction->raw.evex.R = (data[1] >> 7) & 0x01; + instruction->raw.evex.X = (data[1] >> 6) & 0x01; + instruction->raw.evex.B = (data[1] >> 5) & 0x01; + instruction->raw.evex.R2 = (data[1] >> 4) & 0x01; if (((data[1] >> 2) & 0x03) != 0x00) { @@ -521,51 +519,51 @@ static ZydisStatus ZydisDecodeEVEX(ZydisDecoderContext* context, return ZYDIS_STATUS_MALFORMED_EVEX; } - instruction->details.evex.mm = (data[1] >> 0) & 0x03; + instruction->raw.evex.mm = (data[1] >> 0) & 0x03; - if (instruction->details.evex.mm == 0x00) + if (instruction->raw.evex.mm == 0x00) { // Invalid according to the intel documentation return ZYDIS_STATUS_INVALID_MAP; } - instruction->details.evex.W = (data[2] >> 7) & 0x01; - instruction->details.evex.vvvv = (data[2] >> 3) & 0x0F; + instruction->raw.evex.W = (data[2] >> 7) & 0x01; + instruction->raw.evex.vvvv = (data[2] >> 3) & 0x0F; ZYDIS_ASSERT(((data[2] >> 2) & 0x01) == 0x01); - instruction->details.evex.pp = (data[2] >> 0) & 0x03; - instruction->details.evex.z = (data[3] >> 7) & 0x01; - instruction->details.evex.L2 = (data[3] >> 6) & 0x01; - instruction->details.evex.L = (data[3] >> 5) & 0x01; - instruction->details.evex.b = (data[3] >> 4) & 0x01; - instruction->details.evex.V2 = (data[3] >> 3) & 0x01; + instruction->raw.evex.pp = (data[2] >> 0) & 0x03; + instruction->raw.evex.z = (data[3] >> 7) & 0x01; + instruction->raw.evex.L2 = (data[3] >> 6) & 0x01; + instruction->raw.evex.L = (data[3] >> 5) & 0x01; + instruction->raw.evex.b = (data[3] >> 4) & 0x01; + instruction->raw.evex.V2 = (data[3] >> 3) & 0x01; - if (!instruction->details.evex.V2 && + if (!instruction->raw.evex.V2 && (context->decoder->machineMode != ZYDIS_MACHINE_MODE_LONG_64)) { return ZYDIS_STATUS_MALFORMED_EVEX; } - instruction->details.evex.aaa = (data[3] >> 0) & 0x07; + instruction->raw.evex.aaa = (data[3] >> 0) & 0x07; // Update internal fields - context->cache.W = instruction->details.evex.W; - context->cache.R = 0x01 & ~instruction->details.evex.R; - context->cache.X = 0x01 & ~instruction->details.evex.X; - context->cache.B = 0x01 & ~instruction->details.evex.B; - context->cache.LL = (data[3] >> 5) & 0x03; - context->cache.R2 = 0x01 & ~instruction->details.evex.R2; - context->cache.V2 = 0x01 & ~instruction->details.evex.V2; - context->cache.v_vvvv = - ((0x01 & ~instruction->details.evex.V2) << 4) | (0x0F & ~instruction->details.evex.vvvv); - context->cache.mask = instruction->details.evex.aaa; + context->cache.W = instruction->raw.evex.W; + context->cache.R = 0x01 & ~instruction->raw.evex.R; + context->cache.X = 0x01 & ~instruction->raw.evex.X; + context->cache.B = 0x01 & ~instruction->raw.evex.B; + context->cache.LL = (data[3] >> 5) & 0x03; + context->cache.R2 = 0x01 & ~instruction->raw.evex.R2; + context->cache.V2 = 0x01 & ~instruction->raw.evex.V2; + context->cache.v_vvvv = + ((0x01 & ~instruction->raw.evex.V2) << 4) | (0x0F & ~instruction->raw.evex.vvvv); + context->cache.mask = instruction->raw.evex.aaa; - if (!instruction->details.evex.V2 && (context->decoder->machineMode != 64)) + if (!instruction->raw.evex.V2 && (context->decoder->machineMode != 64)) { return ZYDIS_STATUS_MALFORMED_EVEX; } - if (!instruction->details.evex.b && (context->cache.LL == 3)) + if (!instruction->raw.evex.b && (context->cache.LL == 3)) { // LL = 3 is only valid for instructions with embedded rounding control return ZYDIS_STATUS_MALFORMED_EVEX; @@ -590,45 +588,45 @@ static ZydisStatus ZydisDecodeMVEX(ZydisDecoderContext* context, ZYDIS_ASSERT(data[0] == 0x62); instruction->attributes |= ZYDIS_ATTRIB_HAS_EVEX; - instruction->details.mvex.isDecoded = ZYDIS_TRUE; - instruction->details.mvex.data[0] = 0x62; - instruction->details.mvex.data[1] = data[1]; - instruction->details.mvex.data[2] = data[2]; - instruction->details.mvex.data[3] = data[3]; - instruction->details.mvex.R = (data[1] >> 7) & 0x01; - instruction->details.mvex.X = (data[1] >> 6) & 0x01; - instruction->details.mvex.B = (data[1] >> 5) & 0x01; - instruction->details.mvex.R2 = (data[1] >> 4) & 0x01; - instruction->details.mvex.mmmm = (data[1] >> 0) & 0x0F; + instruction->raw.mvex.isDecoded = ZYDIS_TRUE; + instruction->raw.mvex.data[0] = 0x62; + instruction->raw.mvex.data[1] = data[1]; + instruction->raw.mvex.data[2] = data[2]; + instruction->raw.mvex.data[3] = data[3]; + instruction->raw.mvex.R = (data[1] >> 7) & 0x01; + instruction->raw.mvex.X = (data[1] >> 6) & 0x01; + instruction->raw.mvex.B = (data[1] >> 5) & 0x01; + instruction->raw.mvex.R2 = (data[1] >> 4) & 0x01; + instruction->raw.mvex.mmmm = (data[1] >> 0) & 0x0F; - if (instruction->details.mvex.mmmm > 0x03) + if (instruction->raw.mvex.mmmm > 0x03) { // Invalid according to the intel documentation return ZYDIS_STATUS_INVALID_MAP; } - instruction->details.mvex.W = (data[2] >> 7) & 0x01; - instruction->details.mvex.vvvv = (data[2] >> 3) & 0x0F; + instruction->raw.mvex.W = (data[2] >> 7) & 0x01; + instruction->raw.mvex.vvvv = (data[2] >> 3) & 0x0F; ZYDIS_ASSERT(((data[2] >> 2) & 0x01) == 0x00); - instruction->details.mvex.pp = (data[2] >> 0) & 0x03; - instruction->details.mvex.E = (data[3] >> 7) & 0x01; - instruction->details.mvex.SSS = (data[3] >> 4) & 0x07; - instruction->details.mvex.V2 = (data[3] >> 3) & 0x01; - instruction->details.mvex.kkk = (data[3] >> 0) & 0x07; + instruction->raw.mvex.pp = (data[2] >> 0) & 0x03; + instruction->raw.mvex.E = (data[3] >> 7) & 0x01; + instruction->raw.mvex.SSS = (data[3] >> 4) & 0x07; + instruction->raw.mvex.V2 = (data[3] >> 3) & 0x01; + instruction->raw.mvex.kkk = (data[3] >> 0) & 0x07; // Update internal fields - context->cache.W = instruction->details.mvex.W; - context->cache.R = 0x01 & ~instruction->details.mvex.R; - context->cache.X = 0x01 & ~instruction->details.mvex.X; - context->cache.B = 0x01 & ~instruction->details.mvex.B; - context->cache.R2 = 0x01 & ~instruction->details.mvex.R2; - context->cache.V2 = 0x01 & ~instruction->details.mvex.V2; - context->cache.LL = 2; - context->cache.v_vvvv = - ((0x01 & ~instruction->details.mvex.V2) << 4) | (0x0F & ~instruction->details.mvex.vvvv); - context->cache.mask = instruction->details.mvex.kkk; + context->cache.W = instruction->raw.mvex.W; + context->cache.R = 0x01 & ~instruction->raw.mvex.R; + context->cache.X = 0x01 & ~instruction->raw.mvex.X; + context->cache.B = 0x01 & ~instruction->raw.mvex.B; + context->cache.R2 = 0x01 & ~instruction->raw.mvex.R2; + context->cache.V2 = 0x01 & ~instruction->raw.mvex.V2; + context->cache.LL = 2; + context->cache.v_vvvv = + ((0x01 & ~instruction->raw.mvex.V2) << 4) | (0x0F & ~instruction->raw.mvex.vvvv); + context->cache.mask = instruction->raw.mvex.kkk; return ZYDIS_STATUS_SUCCESS; } @@ -644,11 +642,11 @@ static void ZydisDecodeModRM(ZydisDecodedInstruction* instruction, uint8_t data) ZYDIS_ASSERT(instruction); instruction->attributes |= ZYDIS_ATTRIB_HAS_MODRM; - instruction->details.modrm.isDecoded = ZYDIS_TRUE; - instruction->details.modrm.data[0] = data; - instruction->details.modrm.mod = (data >> 6) & 0x03; - instruction->details.modrm.reg = (data >> 3) & 0x07; - instruction->details.modrm.rm = (data >> 0) & 0x07; + instruction->raw.modrm.isDecoded = ZYDIS_TRUE; + instruction->raw.modrm.data[0] = data; + instruction->raw.modrm.mod = (data >> 6) & 0x03; + instruction->raw.modrm.reg = (data >> 3) & 0x07; + instruction->raw.modrm.rm = (data >> 0) & 0x07; } /** @@ -660,15 +658,15 @@ static void ZydisDecodeModRM(ZydisDecodedInstruction* instruction, uint8_t data) static void ZydisDecodeSIB(ZydisDecodedInstruction* instruction, uint8_t data) { ZYDIS_ASSERT(instruction); - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.rm == 4); + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.rm == 4); instruction->attributes |= ZYDIS_ATTRIB_HAS_SIB; - instruction->details.sib.isDecoded = ZYDIS_TRUE; - instruction->details.sib.data[0] = data; - instruction->details.sib.scale = (data >> 6) & 0x03; - instruction->details.sib.index = (data >> 3) & 0x07; - instruction->details.sib.base = (data >> 0) & 0x07; + instruction->raw.sib.isDecoded = ZYDIS_TRUE; + instruction->raw.sib.data[0] = data; + instruction->raw.sib.scale = (data >> 6) & 0x03; + instruction->raw.sib.index = (data >> 3) & 0x07; + instruction->raw.sib.base = (data >> 0) & 0x07; } /* ---------------------------------------------------------------------------------------------- */ @@ -687,10 +685,10 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, { ZYDIS_ASSERT(context); ZYDIS_ASSERT(instruction); - ZYDIS_ASSERT(instruction->details.disp.size == 0); + ZYDIS_ASSERT(instruction->raw.disp.size == 0); - instruction->details.disp.size = size; - instruction->details.disp.offset = instruction->length; + instruction->raw.disp.size = size; + instruction->raw.disp.offset = instruction->length; switch (size) { @@ -698,28 +696,28 @@ static ZydisStatus ZydisReadDisplacement(ZydisDecoderContext* context, { uint8_t value; ZYDIS_CHECK(ZydisInputNext(context, instruction, &value)); - instruction->details.disp.value = *(int8_t*)&value; + instruction->raw.disp.value = *(int8_t*)&value; break; } case 16: { uint16_t value; ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, (uint8_t*)&value, 2)); - instruction->details.disp.value = *(int16_t*)&value; + instruction->raw.disp.value = *(int16_t*)&value; break; } case 32: { uint32_t value; ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, (uint8_t*)&value, 4)); - instruction->details.disp.value = *(int32_t*)&value; + instruction->raw.disp.value = *(int32_t*)&value; break; } case 64: { uint64_t value; ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, (uint8_t*)&value, 8)); - instruction->details.disp.value = *(int64_t*)&value; + instruction->raw.disp.value = *(int64_t*)&value; break; } default: @@ -751,12 +749,12 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZYDIS_ASSERT(instruction); ZYDIS_ASSERT((id == 0) || (id == 1)); ZYDIS_ASSERT(isSigned || !isRelative); - ZYDIS_ASSERT(instruction->details.imm[id].size == 0); + ZYDIS_ASSERT(instruction->raw.imm[id].size == 0); - instruction->details.imm[id].size = size; - instruction->details.imm[id].offset = instruction->length; - instruction->details.imm[id].isSigned = isSigned; - instruction->details.imm[id].isRelative = isRelative; + instruction->raw.imm[id].size = size; + instruction->raw.imm[id].offset = instruction->length; + instruction->raw.imm[id].isSigned = isSigned; + instruction->raw.imm[id].isRelative = isRelative; switch (size) { case 8: @@ -765,10 +763,10 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZYDIS_CHECK(ZydisInputNext(context, instruction, &value)); if (isSigned) { - instruction->details.imm[id].value.s = (int8_t)value; + instruction->raw.imm[id].value.s = (int8_t)value; } else { - instruction->details.imm[id].value.u = value; + instruction->raw.imm[id].value.u = value; } break; } @@ -778,10 +776,10 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, (uint8_t*)&value, 2)); if (isSigned) { - instruction->details.imm[id].value.s = (int16_t)value; + instruction->raw.imm[id].value.s = (int16_t)value; } else { - instruction->details.imm[id].value.u = value; + instruction->raw.imm[id].value.u = value; } break; } @@ -791,10 +789,10 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, (uint8_t*)&value, 4)); if (isSigned) { - instruction->details.imm[id].value.s = (int32_t)value; + instruction->raw.imm[id].value.s = (int32_t)value; } else { - instruction->details.imm[id].value.u = value; + instruction->raw.imm[id].value.u = value; } break; } @@ -804,10 +802,10 @@ static ZydisStatus ZydisReadImmediate(ZydisDecoderContext* context, ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, (uint8_t*)&value, 8)); if (isSigned) { - instruction->details.imm[id].value.s = (int64_t)value; + instruction->raw.imm[id].value.s = (int64_t)value; } else { - instruction->details.imm[id].value.u = value; + instruction->raw.imm[id].value.u = value; } break; } @@ -861,37 +859,37 @@ static uint8_t ZydisCalcRegisterId(ZydisDecoderContext* context, return value; } case ZYDIS_REG_ENCODING_REG: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - return instruction->details.modrm.reg; + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + return instruction->raw.modrm.reg; case ZYDIS_REG_ENCODING_NDSNDD: return context->cache.v_vvvv & 0x07; case ZYDIS_REG_ENCODING_RM: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - return instruction->details.modrm.rm; + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + return instruction->raw.modrm.rm; case ZYDIS_REG_ENCODING_BASE: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); - if (instruction->details.modrm.rm == 4) + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); + if (instruction->raw.modrm.rm == 4) { - ZYDIS_ASSERT(instruction->details.sib.isDecoded); - return instruction->details.sib.base; + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); + return instruction->raw.sib.base; } - return instruction->details.modrm.rm; + return instruction->raw.modrm.rm; case ZYDIS_REG_ENCODING_INDEX: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); - ZYDIS_ASSERT(instruction->details.sib.isDecoded); - return instruction->details.sib.index; + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); + return instruction->raw.sib.index; case ZYDIS_REG_ENCODING_VIDX: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); - ZYDIS_ASSERT(instruction->details.sib.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); ZYDIS_ASSERT((registerClass == ZYDIS_REGCLASS_XMM) || (registerClass == ZYDIS_REGCLASS_YMM) || (registerClass == ZYDIS_REGCLASS_ZMM)); - return instruction->details.sib.index; + return instruction->raw.sib.index; case ZYDIS_REG_ENCODING_IS4: - return (instruction->details.imm[0].value.u >> 5) & 0x07; + return (instruction->raw.imm[0].value.u >> 5) & 0x07; case ZYDIS_REG_ENCODING_MASK: return context->cache.mask; default: @@ -915,8 +913,8 @@ static uint8_t ZydisCalcRegisterId(ZydisDecoderContext* context, } case ZYDIS_REG_ENCODING_REG: { - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - uint8_t value = instruction->details.modrm.reg; + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + uint8_t value = instruction->raw.modrm.reg; if (registerClass != ZYDIS_REGCLASS_MASK) { value |= (context->cache.R << 3); @@ -949,8 +947,8 @@ static uint8_t ZydisCalcRegisterId(ZydisDecoderContext* context, } case ZYDIS_REG_ENCODING_RM: { - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - uint8_t value = instruction->details.modrm.rm; + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + uint8_t value = instruction->raw.modrm.rm; if (registerClass != ZYDIS_REGCLASS_MASK) { value |= (context->cache.B << 3); @@ -974,32 +972,32 @@ static uint8_t ZydisCalcRegisterId(ZydisDecoderContext* context, return value; } case ZYDIS_REG_ENCODING_BASE: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); - if (instruction->details.modrm.rm == 4) + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); + if (instruction->raw.modrm.rm == 4) { - ZYDIS_ASSERT(instruction->details.sib.isDecoded); - return instruction->details.sib.base | (context->cache.B << 3); + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); + return instruction->raw.sib.base | (context->cache.B << 3); } - return instruction->details.modrm.rm | (context->cache.B << 3); + return instruction->raw.modrm.rm | (context->cache.B << 3); case ZYDIS_REG_ENCODING_INDEX: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); - ZYDIS_ASSERT(instruction->details.sib.isDecoded); - return instruction->details.sib.index | (context->cache.X << 3); + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); + return instruction->raw.sib.index | (context->cache.X << 3); case ZYDIS_REG_ENCODING_VIDX: - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); - ZYDIS_ASSERT(instruction->details.sib.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); ZYDIS_ASSERT((registerClass == ZYDIS_REGCLASS_XMM) || (registerClass == ZYDIS_REGCLASS_YMM) || (registerClass == ZYDIS_REGCLASS_ZMM)); // v' only exists for EVEX and MVEX. No encoding check needed - return instruction->details.sib.index | (context->cache.X << 3) | + return instruction->raw.sib.index | (context->cache.X << 3) | (context->cache.V2 << 4); case ZYDIS_REG_ENCODING_IS4: { - uint8_t value = (instruction->details.imm[0].value.u >> 4) & 0x0F; + uint8_t value = (instruction->raw.imm[0].value.u >> 4) & 0x0F; // We have to check the instruction-encoding, because the extension by bit [3] is only // valid for EVEX and MVEX instructions if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || @@ -1010,7 +1008,7 @@ static uint8_t ZydisCalcRegisterId(ZydisDecoderContext* context, case ZYDIS_REGCLASS_XMM: case ZYDIS_REGCLASS_YMM: case ZYDIS_REGCLASS_ZMM: - value |= ((instruction->details.imm[0].value.u & 0x08) << 1); + value |= ((instruction->raw.imm[0].value.u & 0x08) << 1); default: break; } @@ -1226,10 +1224,10 @@ static void ZydisSetOperandSizeAndElementInfo(ZydisDecoderContext* context, } break; case ZYDIS_OPERAND_TYPE_POINTER: - ZYDIS_ASSERT((instruction->details.imm[0].size == 16) || - (instruction->details.imm[0].size == 32)); - ZYDIS_ASSERT( instruction->details.imm[1].size == 16); - operand->size = instruction->details.imm[0].size + instruction->details.imm[1].size; + ZYDIS_ASSERT((instruction->raw.imm[0].size == 16) || + (instruction->raw.imm[0].size == 32)); + ZYDIS_ASSERT( instruction->raw.imm[1].size == 16); + operand->size = instruction->raw.imm[0].size + instruction->raw.imm[1].size; break; case ZYDIS_OPERAND_TYPE_IMMEDIATE: operand->size = definition->size[context->eoszIndex] * 8; @@ -1330,14 +1328,14 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, ZYDIS_ASSERT(context); ZYDIS_ASSERT(instruction); ZYDIS_ASSERT(operand); - ZYDIS_ASSERT(instruction->details.modrm.isDecoded); - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); - ZYDIS_ASSERT(!vidxRegisterClass || ((instruction->details.modrm.rm == 4) && + ZYDIS_ASSERT(instruction->raw.modrm.isDecoded); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); + ZYDIS_ASSERT(!vidxRegisterClass || ((instruction->raw.modrm.rm == 4) && ((instruction->addressWidth == 32) || (instruction->addressWidth == 64)))); operand->type = ZYDIS_OPERAND_TYPE_MEMORY; - uint8_t modrm_rm = instruction->details.modrm.rm; + uint8_t modrm_rm = instruction->raw.modrm.rm; uint8_t displacementSize = 0; switch (instruction->addressWidth) { @@ -1356,7 +1354,7 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, operand->mem.base = bases[modrm_rm]; operand->mem.index = indices[modrm_rm]; operand->mem.scale = 0; - switch (instruction->details.modrm.mod) + switch (instruction->raw.modrm.mod) { case 0: if (modrm_rm == 6) @@ -1380,7 +1378,7 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, { operand->mem.base = ZYDIS_REGISTER_EAX + ZydisCalcRegisterId(context, instruction, ZYDIS_REG_ENCODING_BASE, ZYDIS_REGCLASS_GPR32); - switch (instruction->details.modrm.mod) + switch (instruction->raw.modrm.mod) { case 0: if (modrm_rm == 5) @@ -1406,13 +1404,13 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, } if (modrm_rm == 4) { - ZYDIS_ASSERT(instruction->details.sib.isDecoded); + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); operand->mem.index = ZydisRegisterEncode(vidxRegisterClass ? vidxRegisterClass : ZYDIS_REGCLASS_GPR32, ZydisCalcRegisterId(context, instruction, vidxRegisterClass ? ZYDIS_REG_ENCODING_VIDX : ZYDIS_REG_ENCODING_INDEX, vidxRegisterClass ? vidxRegisterClass : ZYDIS_REGCLASS_GPR32)); - operand->mem.scale = (1 << instruction->details.sib.scale) & ~1; + operand->mem.scale = (1 << instruction->raw.sib.scale) & ~1; if (operand->mem.index == ZYDIS_REGISTER_ESP) { operand->mem.index = ZYDIS_REGISTER_NONE; @@ -1420,11 +1418,11 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, } if (operand->mem.base == ZYDIS_REGISTER_EBP) { - if (instruction->details.modrm.mod == 0) + if (instruction->raw.modrm.mod == 0) { operand->mem.base = ZYDIS_REGISTER_NONE; } - displacementSize = (instruction->details.modrm.mod == 1) ? 8 : 32; + displacementSize = (instruction->raw.modrm.mod == 1) ? 8 : 32; } } else { @@ -1437,7 +1435,7 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, { operand->mem.base = ZYDIS_REGISTER_RAX + ZydisCalcRegisterId(context, instruction, ZYDIS_REG_ENCODING_BASE, ZYDIS_REGCLASS_GPR64); - switch (instruction->details.modrm.mod) + switch (instruction->raw.modrm.mod) { case 0: if (modrm_rm == 5) @@ -1463,13 +1461,13 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, } if ((modrm_rm & 0x07) == 4) { - ZYDIS_ASSERT(instruction->details.sib.isDecoded); + ZYDIS_ASSERT(instruction->raw.sib.isDecoded); operand->mem.index = ZydisRegisterEncode(vidxRegisterClass ? vidxRegisterClass : ZYDIS_REGCLASS_GPR64, ZydisCalcRegisterId(context, instruction, vidxRegisterClass ? ZYDIS_REG_ENCODING_VIDX : ZYDIS_REG_ENCODING_INDEX, vidxRegisterClass ? vidxRegisterClass : ZYDIS_REGCLASS_GPR64)); - operand->mem.scale = (1 << instruction->details.sib.scale) & ~1; + operand->mem.scale = (1 << instruction->raw.sib.scale) & ~1; if (operand->mem.index == ZYDIS_REGISTER_RSP) { operand->mem.index = ZYDIS_REGISTER_NONE; @@ -1478,11 +1476,11 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, if ((operand->mem.base == ZYDIS_REGISTER_RBP) || (operand->mem.base == ZYDIS_REGISTER_R13)) { - if (instruction->details.modrm.mod == 0) + if (instruction->raw.modrm.mod == 0) { operand->mem.base = ZYDIS_REGISTER_NONE; } - displacementSize = (instruction->details.modrm.mod == 1) ? 8 : 32; + displacementSize = (instruction->raw.modrm.mod == 1) ? 8 : 32; } } else { @@ -1496,9 +1494,9 @@ static ZydisStatus ZydisDecodeOperandMemory(ZydisDecoderContext* context, } if (displacementSize) { - ZYDIS_ASSERT(instruction->details.disp.size == displacementSize); + ZYDIS_ASSERT(instruction->raw.disp.size == displacementSize); operand->mem.disp.hasDisplacement = ZYDIS_TRUE; - operand->mem.disp.value = instruction->details.disp.value; + operand->mem.disp.value = instruction->raw.disp.value; } return ZYDIS_STATUS_SUCCESS; } @@ -1870,12 +1868,12 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, context, instruction, &instruction->operands[i], ZYDIS_REGCLASS_ZMM)); break; case ZYDIS_SEMANTIC_OPTYPE_PTR: - ZYDIS_ASSERT((instruction->details.imm[0].size == 16) || - (instruction->details.imm[0].size == 32)); - ZYDIS_ASSERT( instruction->details.imm[1].size == 16); + ZYDIS_ASSERT((instruction->raw.imm[0].size == 16) || + (instruction->raw.imm[0].size == 32)); + ZYDIS_ASSERT( instruction->raw.imm[1].size == 16); instruction->operands[i].type = ZYDIS_OPERAND_TYPE_POINTER; - instruction->operands[i].ptr.offset = (uint32_t)instruction->details.imm[0].value.u; - instruction->operands[i].ptr.segment = (uint16_t)instruction->details.imm[1].value.u; + instruction->operands[i].ptr.offset = (uint32_t)instruction->raw.imm[0].value.u; + instruction->operands[i].ptr.segment = (uint16_t)instruction->raw.imm[1].value.u; break; case ZYDIS_SEMANTIC_OPTYPE_AGEN: instruction->operands[i].action = ZYDIS_OPERAND_ACTION_INVALID; @@ -1885,10 +1883,10 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, context, instruction, &instruction->operands[i], ZYDIS_REGISTER_NONE)); break; case ZYDIS_SEMANTIC_OPTYPE_MOFFS: - ZYDIS_ASSERT(instruction->details.disp.size); + ZYDIS_ASSERT(instruction->raw.disp.size); instruction->operands[i].type = ZYDIS_OPERAND_TYPE_MEMORY; instruction->operands[i].mem.disp.hasDisplacement = ZYDIS_TRUE; - instruction->operands[i].mem.disp.value = instruction->details.disp.value; + instruction->operands[i].mem.disp.value = instruction->raw.disp.value; break; default: break; @@ -1898,7 +1896,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, // Handle compressed 8-bit displacement if (((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) && - (instruction->details.disp.size == 8)) + (instruction->raw.disp.size == 8)) { instruction->operands[i].mem.disp.value *= instruction->avx.compressedDisp8Scale; } @@ -1910,7 +1908,7 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, switch (operand->type) { case ZYDIS_SEMANTIC_OPTYPE_REL: - ZYDIS_ASSERT(instruction->details.imm[immId].isRelative); + ZYDIS_ASSERT(instruction->raw.imm[immId].isRelative); case ZYDIS_SEMANTIC_OPTYPE_IMM: ZYDIS_ASSERT((immId == 0) || (immId == 1)); instruction->operands[i].type = ZYDIS_OPERAND_TYPE_IMMEDIATE; @@ -1918,15 +1916,15 @@ static ZydisStatus ZydisDecodeOperands(ZydisDecoderContext* context, if (operand->op.encoding == ZYDIS_OPERAND_ENCODING_IS4) { // The upper half of the 8-bit immediate is used to encode a register specifier - ZYDIS_ASSERT(instruction->details.imm[immId].size == 8); + ZYDIS_ASSERT(instruction->raw.imm[immId].size == 8); instruction->operands[i].imm.value.u = - (uint8_t)instruction->details.imm[immId].value.u & 0x0F; + (uint8_t)instruction->raw.imm[immId].value.u & 0x0F; } else { - instruction->operands[i].imm.value.u = instruction->details.imm[immId].value.u; + instruction->operands[i].imm.value.u = instruction->raw.imm[immId].value.u; } - instruction->operands[i].imm.isSigned = instruction->details.imm[immId].isSigned; - instruction->operands[i].imm.isRelative = instruction->details.imm[immId].isRelative; + instruction->operands[i].imm.isSigned = instruction->raw.imm[immId].isSigned; + instruction->operands[i].imm.isRelative = instruction->raw.imm[immId].isRelative; ++immId; break; default: @@ -2047,7 +2045,7 @@ static void ZydisSetPrefixRelatedAttributes(ZydisDecoderContext* context, if (def->acceptsLock) { instruction->attributes |= ZYDIS_ATTRIB_ACCEPTS_LOCK; - if (instruction->details.prefixes.hasF0) + if (instruction->raw.prefixes.hasF0) { instruction->attributes |= ZYDIS_ATTRIB_HAS_LOCK; } @@ -2333,7 +2331,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, context->evex.tupleType = def->tupleType; if (def->tupleType) { - ZYDIS_ASSERT(instruction->details.modrm.mod != 3); + ZYDIS_ASSERT(instruction->raw.modrm.mod != 3); ZYDIS_ASSERT(def->elementSize); // Element size @@ -2359,7 +2357,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, switch (def->tupleType) { case ZYDIS_TUPLETYPE_FV: - switch (instruction->details.evex.b) + switch (instruction->raw.evex.b) { case 0: switch (instruction->avx.vectorLength) @@ -2427,7 +2425,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, break; case ZYDIS_TUPLETYPE_HV: ZYDIS_ASSERT(context->evex.elementSize == 32); - switch (instruction->details.evex.b) + switch (instruction->raw.evex.b) { case 0: switch (instruction->avx.vectorLength) @@ -2628,7 +2626,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, } } else { - ZYDIS_ASSERT(instruction->details.modrm.mod == 3); + ZYDIS_ASSERT(instruction->raw.modrm.mod == 3); } // Static broadcast-factor @@ -2680,7 +2678,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, } // Rounding mode and SAE - if (instruction->details.evex.b) + if (instruction->raw.evex.b) { switch (def->functionality) { @@ -2700,7 +2698,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, } // Mask mode - instruction->avx.maskMode = ZYDIS_MASK_MODE_MERGE + instruction->details.evex.z; + instruction->avx.maskMode = ZYDIS_MASK_MODE_MERGE + instruction->raw.evex.z; break; } @@ -2769,8 +2767,8 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, { 4, 0, 0, 2, 1, 1, 2, 2 }, { 16, 0, 0, 8, 4, 4, 8, 8 } }; - ZYDIS_ASSERT(instruction->details.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); - instruction->avx.compressedDisp8Scale = lookup[index][instruction->details.mvex.SSS]; + ZYDIS_ASSERT(instruction->raw.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); + instruction->avx.compressedDisp8Scale = lookup[index][instruction->raw.mvex.SSS]; break; } case ZYDIS_MVEX_FUNC_SI_32: @@ -2784,8 +2782,8 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, { 4, 0, 0, 0, 1, 1, 2, 2 }, { 16, 0, 0, 0, 4, 4, 8, 8 } }; - ZYDIS_ASSERT(instruction->details.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); - instruction->avx.compressedDisp8Scale = lookup[index][instruction->details.mvex.SSS]; + ZYDIS_ASSERT(instruction->raw.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); + instruction->avx.compressedDisp8Scale = lookup[index][instruction->raw.mvex.SSS]; break; } case ZYDIS_MVEX_FUNC_SF_64: @@ -2799,8 +2797,8 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, { 8, 0, 0 }, { 32, 0, 0 } }; - ZYDIS_ASSERT(instruction->details.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); - instruction->avx.compressedDisp8Scale = lookup[index][instruction->details.mvex.SSS]; + ZYDIS_ASSERT(instruction->raw.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); + instruction->avx.compressedDisp8Scale = lookup[index][instruction->raw.mvex.SSS]; break; } case ZYDIS_MVEX_FUNC_DF_32: @@ -2811,8 +2809,8 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, { 64, 0, 0, 32, 16, 16, 32, 32 }, { 4, 0, 0, 2, 1, 1, 2, 2 } }; - ZYDIS_ASSERT(instruction->details.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); - instruction->avx.compressedDisp8Scale = lookup[index][instruction->details.mvex.SSS]; + ZYDIS_ASSERT(instruction->raw.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); + instruction->avx.compressedDisp8Scale = lookup[index][instruction->raw.mvex.SSS]; break; } case ZYDIS_MVEX_FUNC_DF_64: @@ -2823,8 +2821,8 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, { 64 }, { 8 } }; - ZYDIS_ASSERT(instruction->details.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); - instruction->avx.compressedDisp8Scale = lookup[index][instruction->details.mvex.SSS]; + ZYDIS_ASSERT(instruction->raw.mvex.SSS < ZYDIS_ARRAY_SIZE(lookup[index])); + instruction->avx.compressedDisp8Scale = lookup[index][instruction->raw.mvex.SSS]; break; } default: @@ -2844,22 +2842,22 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, // Nothing to do here break; case ZYDIS_MVEX_FUNC_RC: - instruction->avx.roundingMode = ZYDIS_ROUNDING_MODE_RN + instruction->details.mvex.SSS; + instruction->avx.roundingMode = ZYDIS_ROUNDING_MODE_RN + instruction->raw.mvex.SSS; break; case ZYDIS_MVEX_FUNC_SAE: - if (instruction->details.mvex.SSS >= 4) + if (instruction->raw.mvex.SSS >= 4) { instruction->avx.hasSAE = ZYDIS_TRUE; } break; case ZYDIS_MVEX_FUNC_SWIZZLE_32: case ZYDIS_MVEX_FUNC_SWIZZLE_64: - instruction->avx.swizzleMode = ZYDIS_SWIZZLE_MODE_DCBA + instruction->details.mvex.SSS; + instruction->avx.swizzleMode = ZYDIS_SWIZZLE_MODE_DCBA + instruction->raw.mvex.SSS; break; case ZYDIS_MVEX_FUNC_SF_32: case ZYDIS_MVEX_FUNC_SF_32_BCST: case ZYDIS_MVEX_FUNC_SF_32_BCST_4TO16: - switch (instruction->details.mvex.SSS) + switch (instruction->raw.mvex.SSS) { case 0: break; @@ -2891,7 +2889,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, case ZYDIS_MVEX_FUNC_SI_32: case ZYDIS_MVEX_FUNC_SI_32_BCST: case ZYDIS_MVEX_FUNC_SI_32_BCST_4TO16: - switch (instruction->details.mvex.SSS) + switch (instruction->raw.mvex.SSS) { case 0: break; @@ -2919,7 +2917,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, break; case ZYDIS_MVEX_FUNC_SF_64: case ZYDIS_MVEX_FUNC_SI_64: - switch (instruction->details.mvex.SSS) + switch (instruction->raw.mvex.SSS) { case 0: break; @@ -2935,7 +2933,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, break; case ZYDIS_MVEX_FUNC_UF_32: case ZYDIS_MVEX_FUNC_DF_32: - switch (instruction->details.mvex.SSS) + switch (instruction->raw.mvex.SSS) { case 0: break; @@ -2963,7 +2961,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, break; case ZYDIS_MVEX_FUNC_UI_32: case ZYDIS_MVEX_FUNC_DI_32: - switch (instruction->details.mvex.SSS) + switch (instruction->raw.mvex.SSS) { case 0: break; @@ -2991,7 +2989,7 @@ static void ZydisSetAVXInformation(ZydisDecoderContext* context, } // Eviction hint - if ((instruction->details.modrm.mod != 3) && instruction->details.mvex.E) + if ((instruction->raw.modrm.mod != 3) && instruction->raw.mvex.E) { instruction->avx.hasEvictionHint = ZYDIS_TRUE; } @@ -3027,7 +3025,7 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, { ZYDIS_ASSERT(context); ZYDIS_ASSERT(instruction); - ZYDIS_ASSERT(instruction->details.prefixes.count == 0); + ZYDIS_ASSERT(instruction->raw.prefixes.count == 0); ZydisBool done = ZYDIS_FALSE; do @@ -3037,18 +3035,18 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, switch (prefixByte) { case 0xF0: - ++instruction->details.prefixes.hasF0; + ++instruction->raw.prefixes.hasF0; break; case 0xF2: context->mandatoryCandidate = 0xF2; - ++instruction->details.prefixes.hasF2; + ++instruction->raw.prefixes.hasF2; break; case 0xF3: context->mandatoryCandidate = 0xF3; - ++instruction->details.prefixes.hasF3; + ++instruction->raw.prefixes.hasF3; break; case 0x2E: - ++instruction->details.prefixes.has2E; + ++instruction->raw.prefixes.has2E; if ((context->decoder->machineMode != ZYDIS_MACHINE_MODE_LONG_64) || ((context->lastSegmentPrefix != 0x64) && (context->lastSegmentPrefix != 0x65))) { @@ -3056,7 +3054,7 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, } break; case 0x36: - ++instruction->details.prefixes.has36; + ++instruction->raw.prefixes.has36; if ((context->decoder->machineMode != ZYDIS_MACHINE_MODE_LONG_64) || ((context->lastSegmentPrefix != 0x64) && (context->lastSegmentPrefix != 0x65))) { @@ -3064,7 +3062,7 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, } break; case 0x3E: - ++instruction->details.prefixes.has3E; + ++instruction->raw.prefixes.has3E; if ((context->decoder->machineMode != ZYDIS_MACHINE_MODE_LONG_64) || ((context->lastSegmentPrefix != 0x64) && (context->lastSegmentPrefix != 0x65))) { @@ -3072,7 +3070,7 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, } break; case 0x26: - ++instruction->details.prefixes.has26; + ++instruction->raw.prefixes.has26; if ((context->decoder->machineMode != ZYDIS_MACHINE_MODE_LONG_64) || ((context->lastSegmentPrefix != 0x64) && (context->lastSegmentPrefix != 0x65))) { @@ -3080,11 +3078,11 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, } break; case 0x64: - ++instruction->details.prefixes.has64; + ++instruction->raw.prefixes.has64; context->lastSegmentPrefix = 0x64; break; case 0x65: - ++instruction->details.prefixes.has65; + ++instruction->raw.prefixes.has65; context->lastSegmentPrefix = 0x65; break; case 0x66: @@ -3092,18 +3090,18 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, { context->mandatoryCandidate = 0x66; } - ++instruction->details.prefixes.has66; + ++instruction->raw.prefixes.has66; instruction->attributes |= ZYDIS_ATTRIB_HAS_OPERANDSIZE; break; case 0x67: - ++instruction->details.prefixes.has67; + ++instruction->raw.prefixes.has67; instruction->attributes |= ZYDIS_ATTRIB_HAS_ADDRESSSIZE; break; default: if ((context->decoder->machineMode == ZYDIS_MACHINE_MODE_LONG_64) && (prefixByte & 0xF0) == 0x40) { - instruction->details.rex.data[0] = prefixByte; + instruction->raw.rex.data[0] = prefixByte; } else { done = ZYDIS_TRUE; @@ -3114,17 +3112,17 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, { if ((prefixByte & 0xF0) != 0x40) { - instruction->details.rex.data[0] = 0x00; + instruction->raw.rex.data[0] = 0x00; } - context->prefixes[instruction->details.prefixes.count] = prefixByte; - instruction->details.prefixes.data[instruction->details.prefixes.count++] = prefixByte; + context->prefixes[instruction->raw.prefixes.count] = prefixByte; + instruction->raw.prefixes.data[instruction->raw.prefixes.count++] = prefixByte; ZydisInputSkip(context, instruction); } } while (!done); - if (instruction->details.rex.data[0]) + if (instruction->raw.rex.data[0]) { - ZydisDecodeREX(context, instruction, instruction->details.rex.data[0]); + ZydisDecodeREX(context, instruction, instruction->raw.rex.data[0]); } return ZYDIS_STATUS_SUCCESS; @@ -3140,7 +3138,7 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context, * * @return A zydis status code. */ -static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* context, +static ZydisStatus ZydisDecodeInstructionPhysical(ZydisDecoderContext* context, ZydisDecodedInstruction* instruction, const ZydisInstructionParts* optionalParts) { ZYDIS_ASSERT(context); @@ -3149,7 +3147,7 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_MODRM) { - if (!instruction->details.modrm.isDecoded) + if (!instruction->raw.modrm.isDecoded) { uint8_t modrmByte; ZYDIS_CHECK(ZydisInputNext(context, instruction, &modrmByte)); @@ -3162,10 +3160,10 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont switch (instruction->addressWidth) { case 16: - switch (instruction->details.modrm.mod) + switch (instruction->raw.modrm.mod) { case 0: - if (instruction->details.modrm.rm == 6) + if (instruction->raw.modrm.rm == 6) { displacementSize = 16; } @@ -3184,11 +3182,11 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont case 32: case 64: hasSIB = - (instruction->details.modrm.mod != 3) && (instruction->details.modrm.rm == 4); - switch (instruction->details.modrm.mod) + (instruction->raw.modrm.mod != 3) && (instruction->raw.modrm.rm == 4); + switch (instruction->raw.modrm.mod) { case 0: - if (instruction->details.modrm.rm == 5) + if (instruction->raw.modrm.rm == 5) { if (context->decoder->machineMode == 64) { @@ -3217,9 +3215,9 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont uint8_t sibByte; ZYDIS_CHECK(ZydisInputNext(context, instruction, &sibByte)); ZydisDecodeSIB(instruction, sibByte); - if (instruction->details.sib.base == 5) + if (instruction->raw.sib.base == 5) { - displacementSize = (instruction->details.modrm.mod == 1) ? 8 : 32; + displacementSize = (instruction->raw.modrm.mod == 1) ? 8 : 32; } } if (displacementSize) @@ -3232,7 +3230,7 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_DISP) { ZYDIS_CHECK(ZydisReadDisplacement( - context, instruction, optionalParts->disp.size[context->easzIndex])); + context, instruction, optionalParts->disp.size[context->easzIndex])); } if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_IMM0) @@ -3243,7 +3241,7 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont } ZYDIS_CHECK(ZydisReadImmediate(context, instruction, 0, optionalParts->imm[0].size[context->eoszIndex], - optionalParts->imm[0].isSigned, optionalParts->imm[0].isRelative)); + optionalParts->imm[0].isSigned, optionalParts->imm[0].isRelative)); } if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_IMM1) @@ -3251,7 +3249,7 @@ static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* cont ZYDIS_ASSERT(!(optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_DISP)); ZYDIS_CHECK(ZydisReadImmediate(context, instruction, 1, optionalParts->imm[1].size[context->eoszIndex], - optionalParts->imm[1].isSigned, optionalParts->imm[1].isRelative)); + optionalParts->imm[1].isSigned, optionalParts->imm[1].isRelative)); } return ZYDIS_STATUS_SUCCESS; @@ -3452,8 +3450,8 @@ static ZydisStatus ZydisNodeHandlerXOP(ZydisDecodedInstruction* instruction, uin *index = 0; break; case ZYDIS_INSTRUCTION_ENCODING_XOP: - ZYDIS_ASSERT(instruction->details.xop.isDecoded); - *index = (instruction->details.xop.m_mmmm - 0x08) + 1; + ZYDIS_ASSERT(instruction->raw.xop.isDecoded); + *index = (instruction->raw.xop.m_mmmm - 0x08) + 1; break; default: ZYDIS_UNREACHABLE; @@ -3472,8 +3470,8 @@ static ZydisStatus ZydisNodeHandlerVEX(ZydisDecodedInstruction* instruction, uin *index = 0; break; case ZYDIS_INSTRUCTION_ENCODING_VEX: - ZYDIS_ASSERT(instruction->details.vex.isDecoded); - *index = instruction->details.vex.m_mmmm + (instruction->details.vex.pp << 2) + 1; + ZYDIS_ASSERT(instruction->raw.vex.isDecoded); + *index = instruction->raw.vex.m_mmmm + (instruction->raw.vex.pp << 2) + 1; break; default: ZYDIS_UNREACHABLE; @@ -3492,12 +3490,12 @@ static ZydisStatus ZydisNodeHandlerEMVEX(ZydisDecodedInstruction* instruction, u *index = 0; break; case ZYDIS_INSTRUCTION_ENCODING_EVEX: - ZYDIS_ASSERT(instruction->details.evex.isDecoded); - *index = instruction->details.evex.mm + (instruction->details.evex.pp << 2) + 1; + ZYDIS_ASSERT(instruction->raw.evex.isDecoded); + *index = instruction->raw.evex.mm + (instruction->raw.evex.pp << 2) + 1; break; case ZYDIS_INSTRUCTION_ENCODING_MVEX: - ZYDIS_ASSERT(instruction->details.mvex.isDecoded); - *index = instruction->details.mvex.mmmm + (instruction->details.mvex.pp << 2) + 17; + ZYDIS_ASSERT(instruction->raw.mvex.isDecoded); + *index = instruction->raw.mvex.mmmm + (instruction->raw.mvex.pp << 2) + 17; break; default: ZYDIS_UNREACHABLE; @@ -3548,20 +3546,20 @@ static ZydisStatus ZydisNodeHandlerOpcode(ZydisDecoderContext* context, { case 0xC4: // Read additional 3-byte VEX-prefix data - ZYDIS_ASSERT(!instruction->details.vex.isDecoded); + ZYDIS_ASSERT(!instruction->raw.vex.isDecoded); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[1])); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[2])); //ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, &prefixBytes[1], 2)); break; case 0xC5: // Read additional 2-byte VEX-prefix data - ZYDIS_ASSERT(!instruction->details.vex.isDecoded); + ZYDIS_ASSERT(!instruction->raw.vex.isDecoded); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[1])); break; case 0x62: // Read additional EVEX/MVEX-prefix data - ZYDIS_ASSERT(!instruction->details.evex.isDecoded); - ZYDIS_ASSERT(!instruction->details.mvex.isDecoded); + ZYDIS_ASSERT(!instruction->raw.evex.isDecoded); + ZYDIS_ASSERT(!instruction->raw.mvex.isDecoded); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[1])); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[2])); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[3])); @@ -3578,7 +3576,7 @@ static ZydisStatus ZydisNodeHandlerOpcode(ZydisDecoderContext* context, instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_VEX; ZYDIS_CHECK(ZydisDecodeVEX(context, instruction, prefixBytes)); instruction->opcodeMap = - ZYDIS_OPCODE_MAP_EX0 + instruction->details.vex.m_mmmm; + ZYDIS_OPCODE_MAP_EX0 + instruction->raw.vex.m_mmmm; break; case 0x62: switch ((prefixBytes[2] >> 2) & 0x01) @@ -3588,14 +3586,14 @@ static ZydisStatus ZydisNodeHandlerOpcode(ZydisDecoderContext* context, instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_MVEX; ZYDIS_CHECK(ZydisDecodeMVEX(context, instruction, prefixBytes)); instruction->opcodeMap = - ZYDIS_OPCODE_MAP_EX0 + instruction->details.mvex.mmmm; + ZYDIS_OPCODE_MAP_EX0 + instruction->raw.mvex.mmmm; break; case 1: // Decode EVEX-prefix instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_EVEX; ZYDIS_CHECK(ZydisDecodeEVEX(context, instruction, prefixBytes)); instruction->opcodeMap = - ZYDIS_OPCODE_MAP_EX0 + instruction->details.evex.mm; + ZYDIS_OPCODE_MAP_EX0 + instruction->raw.evex.mm; break; default: ZYDIS_UNREACHABLE; @@ -3623,7 +3621,7 @@ static ZydisStatus ZydisNodeHandlerOpcode(ZydisDecoderContext* context, } uint8_t prefixBytes[3] = { 0x8F, 0x00, 0x00 }; // Read additional xop-prefix data - ZYDIS_ASSERT(!instruction->details.xop.isDecoded); + ZYDIS_ASSERT(!instruction->raw.xop.isDecoded); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[1])); ZYDIS_CHECK(ZydisInputNext(context, instruction, &prefixBytes[2])); //ZYDIS_CHECK(ZydisInputNextBytes(context, instruction, &prefixBytes[1], 2)); @@ -3631,7 +3629,7 @@ static ZydisStatus ZydisNodeHandlerOpcode(ZydisDecoderContext* context, instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_XOP; ZYDIS_CHECK(ZydisDecodeXOP(context, instruction, prefixBytes)); instruction->opcodeMap = - ZYDIS_OPCODE_MAP_XOP8 + instruction->details.xop.m_mmmm - 0x08; + ZYDIS_OPCODE_MAP_XOP8 + instruction->raw.xop.m_mmmm - 0x08; } break; } @@ -3719,13 +3717,13 @@ static ZydisStatus ZydisNodeHandlerModrmMod(ZydisDecoderContext* context, ZYDIS_ASSERT(instruction); ZYDIS_ASSERT(index); - if (!instruction->details.modrm.isDecoded) + if (!instruction->raw.modrm.isDecoded) { uint8_t modrmByte; ZYDIS_CHECK(ZydisInputNext(context, instruction, &modrmByte)); ZydisDecodeModRM(instruction, modrmByte); } - *index = instruction->details.modrm.mod; + *index = instruction->raw.modrm.mod; return ZYDIS_STATUS_SUCCESS; } @@ -3744,13 +3742,13 @@ static ZydisStatus ZydisNodeHandlerModrmReg(ZydisDecoderContext* context, ZYDIS_ASSERT(instruction); ZYDIS_ASSERT(index); - if (!instruction->details.modrm.isDecoded) + if (!instruction->raw.modrm.isDecoded) { uint8_t modrmByte; ZYDIS_CHECK(ZydisInputNext(context, instruction, &modrmByte)); ZydisDecodeModRM(instruction, modrmByte); } - *index = instruction->details.modrm.reg; + *index = instruction->raw.modrm.reg; return ZYDIS_STATUS_SUCCESS; } @@ -3761,13 +3759,13 @@ static ZydisStatus ZydisNodeHandlerModrmRm(ZydisDecoderContext* context, ZYDIS_ASSERT(instruction); ZYDIS_ASSERT(index); - if (!instruction->details.modrm.isDecoded) + if (!instruction->raw.modrm.isDecoded) { uint8_t modrmByte; ZYDIS_CHECK(ZydisInputNext(context, instruction, &modrmByte)); ZydisDecodeModRM(instruction, modrmByte); } - *index = instruction->details.modrm.rm; + *index = instruction->raw.modrm.rm; return ZYDIS_STATUS_SUCCESS; } @@ -3862,16 +3860,16 @@ static ZydisStatus ZydisNodeHandlerVectorLength(ZydisDecoderContext* context, switch (instruction->encoding) { case ZYDIS_INSTRUCTION_ENCODING_XOP: - ZYDIS_ASSERT(instruction->details.xop.isDecoded); + ZYDIS_ASSERT(instruction->raw.xop.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_VEX: - ZYDIS_ASSERT(instruction->details.vex.isDecoded); + ZYDIS_ASSERT(instruction->raw.vex.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_EVEX: - ZYDIS_ASSERT(instruction->details.evex.isDecoded); + ZYDIS_ASSERT(instruction->raw.evex.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_MVEX: - ZYDIS_ASSERT(instruction->details.mvex.isDecoded); + ZYDIS_ASSERT(instruction->raw.mvex.isDecoded); break; default: ZYDIS_UNREACHABLE; @@ -3897,16 +3895,16 @@ static ZydisStatus ZydisNodeHandlerRexW(ZydisDecoderContext* context, // nothing to do here break; case ZYDIS_INSTRUCTION_ENCODING_XOP: - ZYDIS_ASSERT(instruction->details.xop.isDecoded); + ZYDIS_ASSERT(instruction->raw.xop.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_VEX: - ZYDIS_ASSERT(instruction->details.vex.isDecoded); + ZYDIS_ASSERT(instruction->raw.vex.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_EVEX: - ZYDIS_ASSERT(instruction->details.evex.isDecoded); + ZYDIS_ASSERT(instruction->raw.evex.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_MVEX: - ZYDIS_ASSERT(instruction->details.mvex.isDecoded); + ZYDIS_ASSERT(instruction->raw.mvex.isDecoded); break; default: ZYDIS_UNREACHABLE; @@ -3928,16 +3926,16 @@ static ZydisStatus ZydisNodeHandlerRexB(ZydisDecoderContext* context, // nothing to do here break; case ZYDIS_INSTRUCTION_ENCODING_XOP: - ZYDIS_ASSERT(instruction->details.xop.isDecoded); + ZYDIS_ASSERT(instruction->raw.xop.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_VEX: - ZYDIS_ASSERT(instruction->details.vex.isDecoded); + ZYDIS_ASSERT(instruction->raw.vex.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_EVEX: - ZYDIS_ASSERT(instruction->details.evex.isDecoded); + ZYDIS_ASSERT(instruction->raw.evex.isDecoded); break; case ZYDIS_INSTRUCTION_ENCODING_MVEX: - ZYDIS_ASSERT(instruction->details.mvex.isDecoded); + ZYDIS_ASSERT(instruction->raw.mvex.isDecoded); break; default: ZYDIS_UNREACHABLE; @@ -3952,8 +3950,8 @@ static ZydisStatus ZydisNodeHandlerEvexB(ZydisDecodedInstruction* instruction, u ZYDIS_ASSERT(index); ZYDIS_ASSERT(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX); - ZYDIS_ASSERT(instruction->details.evex.isDecoded); - *index = instruction->details.evex.b; + ZYDIS_ASSERT(instruction->raw.evex.isDecoded); + *index = instruction->raw.evex.b; return ZYDIS_STATUS_SUCCESS; } @@ -3963,8 +3961,8 @@ static ZydisStatus ZydisNodeHandlerEvexZ(ZydisDecodedInstruction* instruction, u ZYDIS_ASSERT(index); ZYDIS_ASSERT(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX); - ZYDIS_ASSERT(instruction->details.evex.isDecoded); - *index = instruction->details.evex.z; + ZYDIS_ASSERT(instruction->raw.evex.isDecoded); + *index = instruction->raw.evex.z; return ZYDIS_STATUS_SUCCESS; } @@ -3974,8 +3972,8 @@ static ZydisStatus ZydisNodeHandlerMvexE(ZydisDecodedInstruction* instruction, u ZYDIS_ASSERT(index); ZYDIS_ASSERT(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX); - ZYDIS_ASSERT(instruction->details.mvex.isDecoded); - *index = instruction->details.mvex.E; + ZYDIS_ASSERT(instruction->raw.mvex.isDecoded); + *index = instruction->raw.mvex.E; return ZYDIS_STATUS_SUCCESS; } @@ -4100,8 +4098,8 @@ static ZydisStatus ZydisCheckErrorConditions(ZydisDecoderContext* context, { 1, 0, 0, 0, 0, 0, 0, 0 } }; ZYDIS_ASSERT(def->functionality < ZYDIS_ARRAY_SIZE(lookup)); - ZYDIS_ASSERT(instruction->details.mvex.SSS < 8); - if (!lookup[def->functionality][instruction->details.mvex.SSS]) + ZYDIS_ASSERT(instruction->raw.mvex.SSS < 8); + if (!lookup[def->functionality][instruction->raw.mvex.SSS]) { return ZYDIS_STATUS_DECODING_ERROR; } @@ -4112,7 +4110,7 @@ static ZydisStatus ZydisCheckErrorConditions(ZydisDecoderContext* context, } // Check for illegal LOCK-prefix - if (instruction->details.prefixes.hasF0 && !acceptsLock) + if (instruction->raw.prefixes.hasF0 && !acceptsLock) { return ZYDIS_STATUS_ILLEGAL_LOCK; } @@ -4266,8 +4264,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, const ZydisInstructionParts* optionalParts; ZydisGetOptionalInstructionParts(node, &optionalParts); - ZYDIS_CHECK( - ZydisDecodeOptionalInstructionParts(context, instruction, optionalParts)); + ZYDIS_CHECK(ZydisDecodeInstructionPhysical(context, instruction, optionalParts)); if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW) { @@ -4283,7 +4280,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, } ZYDIS_ASSERT(node->type == ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT); node = ZydisInstructionTreeGetChildNode( - node, (instruction->details.modrm.mod == 0x3) ? 0 : 1); + node, (instruction->raw.modrm.mod == 0x3) ? 0 : 1); ZydisGetInstructionDefinition(node, &definition); } @@ -4324,27 +4321,28 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, /* Exported functions */ /* ============================================================================================== */ -ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder, - ZydisMachineMode machineMode, ZydisAddressWidth addressWidth) +ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode, + ZydisAddressWidth addressWidth) { - return ZydisDecoderInitInstructionDecoderEx( - decoder, machineMode, addressWidth, ZYDIS_DECODE_GRANULARITY_DEFAULT); + return ZydisDecoderInitEx(decoder, machineMode, addressWidth, ZYDIS_DECODE_GRANULARITY_DEFAULT); } -ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decoder, - ZydisMachineMode machineMode, ZydisAddressWidth addressWidth, - ZydisDecodeGranularity decodeGranularity) +ZydisStatus ZydisDecoderInitEx(ZydisDecoder* decoder, ZydisMachineMode machineMode, + ZydisAddressWidth addressWidth, ZydisDecodeGranularity decodeGranularity) { if (!decoder || ((machineMode != 16) && (machineMode != 32) && (machineMode != 64)) || ((decodeGranularity != ZYDIS_DECODE_GRANULARITY_DEFAULT) && - (decodeGranularity != ZYDIS_DECODE_GRANULARITY_FULL) && - (decodeGranularity != ZYDIS_DECODE_GRANULARITY_MINIMAL))) + (decodeGranularity != ZYDIS_DECODE_GRANULARITY_MINIMAL) && + (decodeGranularity != ZYDIS_DECODE_GRANULARITY_FULL))) { return ZYDIS_STATUS_INVALID_PARAMETER; } if (machineMode == 64) { - addressWidth = ZYDIS_ADDRESS_WIDTH_64; + if (addressWidth != 64) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } } else { if ((addressWidth != 16) && (addressWidth != 32)) @@ -4364,7 +4362,7 @@ ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decode return ZYDIS_STATUS_SUCCESS; } -ZydisStatus ZydisDecoderDecodeBuffer(const ZydisInstructionDecoder* decoder, const void* buffer, +ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* buffer, size_t bufferLen, uint64_t instructionPointer, ZydisDecodedInstruction* instruction) { if (!decoder) diff --git a/src/Formatter.c b/src/Formatter.c index 86db4ec..032510f 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -181,7 +181,7 @@ static ZydisStatus ZydisStringBufferAppendFormat(char** buffer, size_t bufferLen /* Intel style */ /* ---------------------------------------------------------------------------------------------- */ -static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) @@ -224,7 +224,7 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisInstructionFormat return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) @@ -242,7 +242,7 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisInstructionFormat /* ---------------------------------------------------------------------------------------------- */ -static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -259,7 +259,7 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisInstructionFor return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, reg); } -static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -327,7 +327,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisInstructionFor return ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "]"); } -static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -340,7 +340,7 @@ static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisInstructionFor "0x%04"PRIX16":0x%08"PRIX32, operand->ptr.segment, operand->ptr.offset); } -static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -386,7 +386,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisInstructionFor /* ---------------------------------------------------------------------------------------------- */ -static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand, uint64_t address) @@ -410,7 +410,7 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisInstructionFormatt } } -static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -441,7 +441,7 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisInstructionFo return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -493,7 +493,7 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisInstructionForma /* ---------------------------------------------------------------------------------------------- */ -static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -586,7 +586,7 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisInstructionFor return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -625,7 +625,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisInstructionFormatt return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, ZydisDecodedOperand* operand) { @@ -828,7 +828,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisInstructionForma return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisInstructionFormatter* formatter, +static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) @@ -916,16 +916,16 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisInstructionFormatte /* Exported functions */ /* ---------------------------------------------------------------------------------------------- */ -ZydisStatus ZydisFormatterInitInstructionFormatter( - ZydisInstructionFormatter* formatter, ZydisFormatterStyle style) +ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, + ZydisFormatterStyle style) { - return ZydisFormatterInitInstructionFormatterEx(formatter, style, 0, - ZYDIS_FORMATTER_ADDR_DEFAULT, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); + return ZydisFormatterInitEx(formatter, style, 0, ZYDIS_FORMATTER_ADDR_DEFAULT, + ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); } -ZydisStatus ZydisFormatterInitInstructionFormatterEx( - ZydisInstructionFormatter* formatter, ZydisFormatterStyle style, ZydisFormatterFlags flags, - ZydisFormatterAddressFormat addressFormat, ZydisFormatterDisplacementFormat displacementFormat, +ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, + ZydisFormatterStyle style, ZydisFormatterFlags flags, ZydisFormatterAddressFormat addressFormat, + ZydisFormatterDisplacementFormat displacementFormat, ZydisFormatterImmediateFormat immmediateFormat) { if (!formatter || @@ -944,7 +944,7 @@ ZydisStatus ZydisFormatterInitInstructionFormatterEx( return ZYDIS_STATUS_INVALID_PARAMETER; } - memset(formatter, 0, sizeof(ZydisInstructionFormatter)); + memset(formatter, 0, sizeof(ZydisFormatter)); formatter->flags = flags; formatter->addressFormat = addressFormat; formatter->displacementFormat = displacementFormat; @@ -974,8 +974,8 @@ ZydisStatus ZydisFormatterInitInstructionFormatterEx( return ZYDIS_STATUS_SUCCESS; } -ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter, - ZydisFormatterHookType hook, const void** callback) +ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookType hook, + const void** callback) { if (!formatter || !callback) { @@ -1097,7 +1097,7 @@ ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter, return ZYDIS_STATUS_INVALID_PARAMETER; } -ZydisStatus ZydisFormatterFormatInstruction(const ZydisInstructionFormatter* formatter, +ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen) { if (!formatter || !instruction || !buffer || (bufferLen == 0)) diff --git a/tools/PerfTest.c b/tools/PerfTest.c new file mode 100644 index 0000000..b2658c1 --- /dev/null +++ b/tools/PerfTest.c @@ -0,0 +1,315 @@ +/*************************************************************************************************** + + Zyan Disassembler Engine (Zydis) + + Original Author : Florian Bernd + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(ZYDIS_WINDOWS) +# include +#elif defined(ZYDIS_APPLE) +# include +#elif defined(ZYDIS_LINUX) +# include +#else +# error "Unsupported platform detected" +#endif + +/* ============================================================================================== */ +/* Helper functions */ +/* ============================================================================================== */ + +#if defined(ZYDIS_WINDOWS) +double CounterFreq = 0.0; +uint64_t CounterStart = 0; + +void StartCounter() +{ + LARGE_INTEGER li; + if (!QueryPerformanceFrequency(&li)) + { + fputs("QueryPerformanceFrequency failed!\n", stderr); + } + CounterFreq = (double)li.QuadPart / 1000.0; + QueryPerformanceCounter(&li); + CounterStart = li.QuadPart; +} + +double GetCounter() +{ + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + return (double)(li.QuadPart - CounterStart) / CounterFreq; +} +#elif defined(ZYDIS_APPLE) +// TODO: +#elif defined(ZYDIS_LINUX) +// TODO: +#endif + +/* ============================================================================================== */ +/* Internal functions */ +/* ============================================================================================== */ + +void processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity granularity, + ZydisBool format) +{ + ZydisDecoder decoder; + if (!ZYDIS_SUCCESS(ZydisDecoderInitEx(&decoder, + ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64, granularity))) + { + fputs("Failed to initialize decoder\n", stderr); + exit(EXIT_FAILURE); + } + + ZydisFormatter formatter; + if (format) + { + if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, + ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, + ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, + ZYDIS_FORMATTER_IMM_DEFAULT))) + { + fputs("Failed to initialized instruction-formatter\n", stderr); + exit(EXIT_FAILURE); + } + } + + size_t offset = 0; + ZydisStatus status; + ZydisDecodedInstruction instruction; + char formatBuffer[256]; + while ((status = ZydisDecoderDecodeBuffer(&decoder, buffer + offset, length - offset, offset, + &instruction)) != ZYDIS_STATUS_NO_MORE_DATA) + { + ZYDIS_ASSERT(ZYDIS_SUCCESS(status)); + if (!ZYDIS_SUCCESS(status)) + { + puts("Unexpected decoding error"); + exit(EXIT_FAILURE); + } + if (format) + { + ZydisFormatterFormatInstruction( + &formatter, &instruction, formatBuffer, sizeof(formatBuffer)); + } + offset += instruction.length; + } +} + +void testPerformance(const char* buffer, size_t length, ZydisDecodeGranularity granularity, + ZydisBool format) +{ + StartCounter(); + for (uint8_t j = 0; j < 100; ++j) + { + processBuffer(buffer, length, granularity, format); + } + printf("Granularity %d, Formatting %d: %8.2f msec\n", granularity, format, GetCounter()); +} + +void generateTestData(FILE* file, uint8_t encoding) +{ + ZydisDecoder decoder; + if (!ZYDIS_SUCCESS( + ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64))) + { + fputs("Failed to initialize decoder\n", stderr); + exit(EXIT_FAILURE); + } + + uint8_t last = 0; + double size = 0; + ZydisDecodedInstruction instruction; + while (size < 1024 * 1024) + { + uint8_t data[ZYDIS_MAX_INSTRUCTION_LENGTH]; + for (int i = 0; i < ZYDIS_MAX_INSTRUCTION_LENGTH; ++i) + { + data[i] = rand() % 256; + } + uint8_t offset = rand() % (ZYDIS_MAX_INSTRUCTION_LENGTH - 2); + switch (encoding) + { + case 0: + break; + case 1: + data[offset ] = 0x0F; + data[offset + 1] = 0x0F; + break; + case 2: + data[offset ] = 0x8F; + break; + case 3: + data[offset ] = 0xC4; + break; + case 4: + data[offset ] = 0xC5; + break; + case 5: + case 6: + data[offset ] = 0x62; + break; + default: + ZYDIS_UNREACHABLE; + } + if (ZYDIS_SUCCESS(ZydisDecoderDecodeBuffer(&decoder, data, sizeof(data), 0, &instruction))) + { + ZydisBool b = ZYDIS_FALSE; + switch (encoding) + { + case 0: + b = (instruction.encoding == ZYDIS_INSTRUCTION_ENCODING_DEFAULT); + break; + case 1: + b = (instruction.encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW); + break; + case 2: + b = (instruction.encoding == ZYDIS_INSTRUCTION_ENCODING_XOP); + break; + case 3: + case 4: + b = (instruction.encoding == ZYDIS_INSTRUCTION_ENCODING_VEX); + break; + case 5: + b = (instruction.encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX); + break; + case 6: + b = (instruction.encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX); + break; + default: + ZYDIS_UNREACHABLE; + } + if (b) + { + fwrite(&instruction.data[0], 1, instruction.length, file); + size += instruction.length; + + double p = (size / (1024 * 1024) * 100); + if (last < (uint8_t)p) + { + last = (uint8_t)p; + printf("%3.0f%%\n", p); + } + + } + } + } +} + +/* ============================================================================================== */ +/* Entry point */ +/* ============================================================================================== */ + +int main(int argc, char** argv) +{ + if (argc < 3 || (!strcmp(argv[1], "-test") && !strcmp(argv[1], "-generate"))) + { + fputs("Usage: PerfTest -[test|generate] [directory]", stderr); + return EXIT_FAILURE; + } + + ZydisBool generate = ZYDIS_FALSE; + if (!strcmp(argv[1], "-generate")) + { + generate = ZYDIS_TRUE; + } + const char* directory = argv[2]; + + static const struct + { + const char* encoding; + const char* filename; + } tests[7] = + { + { "DEFAULT", "enc_default.dat" }, + { "3DNOW" , "enc_3dnow.dat" }, + { "XOP" , "enc_xop.dat" }, + { "VEX_C4" , "enc_vex_c4.dat" }, + { "VEX_C5" , "enc_vex_c5.dat" }, + { "EVEX" , "enc_evex.dat" }, + { "MVEX" , "enc_mvex.dat" } + }; + + if (generate) + { + time_t t; + srand((unsigned) time(&t)); + } + + for (uint8_t i = 0; i < ZYDIS_ARRAY_SIZE(tests); ++i) + { + FILE* file; + + char buf[256]; + strcpy(&buf[0], directory); + if (generate) + { + file = fopen(strcat(buf, tests[i].filename), "wb"); + } else + { + file = fopen(strcat(buf, tests[i].filename), "rb"); + } + if (!file) + { + fprintf(stderr, "Can not open file \"%s\": %s\n", &buf[0], strerror(errno)); + continue; + } + + if (generate) + { + printf("Generating %s ...\n", tests[i].encoding); + generateTestData(file, i); + } else + { + fseek(file, 0L, SEEK_END); + long length = ftell(file); + void* buffer = malloc(length); + rewind(file); + fread(buffer, 1, length, file); + + printf("Testing %s ...\n", tests[i].encoding); + testPerformance(buffer, length, ZYDIS_DECODE_GRANULARITY_PHYSICAL, ZYDIS_FALSE); + testPerformance(buffer, length, ZYDIS_DECODE_GRANULARITY_SEMANTIC, ZYDIS_FALSE); + // testPerformance(buffer, length, ZYDIS_DECODE_GRANULARITY_SEMANTIC, ZYDIS_TRUE ); + + puts(""); + free(buffer); + fclose(file); + } + } + + getchar(); + + return 0; +} + +/* ============================================================================================== */ diff --git a/tools/ZydisDisasm.c b/tools/ZydisDisasm.c index 1f07bff..65a0239 100644 --- a/tools/ZydisDisasm.c +++ b/tools/ZydisDisasm.c @@ -51,17 +51,17 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - ZydisInstructionDecoder decoder; - if (!ZYDIS_SUCCESS(ZydisDecoderInitInstructionDecoder( - &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64))) + ZydisDecoder decoder; + if (!ZYDIS_SUCCESS( + ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64))) { fputs("Failed to initialize decoder\n", stderr); return EXIT_FAILURE; } - ZydisInstructionFormatter formatter; - if (!ZYDIS_SUCCESS(ZydisFormatterInitInstructionFormatterEx(&formatter, - ZYDIS_FORMATTER_STYLE_INTEL, ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, + ZydisFormatter formatter; + if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, + ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT))) { fputs("Failed to initialized instruction-formatter\n", stderr); diff --git a/tools/ZydisFuzzIn.c b/tools/ZydisFuzzIn.c index 3add2fd..22e28d7 100644 --- a/tools/ZydisFuzzIn.c +++ b/tools/ZydisFuzzIn.c @@ -63,17 +63,17 @@ int main() return EXIT_FAILURE; } - ZydisInstructionDecoder decoder; - if (!ZYDIS_SUCCESS(ZydisDecoderInitInstructionDecoderEx( - &decoder, controlBlock.machineMode, controlBlock.addressWidth, controlBlock.granularity))) + ZydisDecoder decoder; + if (!ZYDIS_SUCCESS(ZydisDecoderInitEx(&decoder, controlBlock.machineMode, + controlBlock.addressWidth, controlBlock.granularity))) { fputs("Failed to initialize decoder\n", stderr); return EXIT_FAILURE; } - ZydisInstructionFormatter formatter; - if (!ZYDIS_SUCCESS(ZydisFormatterInitInstructionFormatterEx(&formatter, - controlBlock.formatterStyle, controlBlock.formatterFlags, controlBlock.formatterAddrFormat, + ZydisFormatter formatter; + if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, controlBlock.formatterStyle, + controlBlock.formatterFlags, controlBlock.formatterAddrFormat, controlBlock.formatterDispFormat, controlBlock.formatterImmFormat))) { fputs("failed to initialize instruction-formatter\n", stderr);