From 0ba5c95dac0058860a5f7f10b343d22131128557 Mon Sep 17 00:00:00 2001 From: flobernd Date: Thu, 2 Nov 2017 17:03:12 +0100 Subject: [PATCH] Minor interface changes - Removed `ZydisDecoderEnableMode` - Added `ZydisDecoderInitEx` with an additional `flags` parameter that can be used to specify a mask of decoder-modes --- examples/ZydisFuzzIn.c | 15 +---- examples/ZydisPerfTest.c | 14 ++-- include/Zydis/Decoder.h | 140 +++++++++++++++++++-------------------- src/Decoder.c | 47 +++++-------- 4 files changed, 94 insertions(+), 122 deletions(-) diff --git a/examples/ZydisFuzzIn.c b/examples/ZydisFuzzIn.c index 3a68a2c..0b49bf2 100644 --- a/examples/ZydisFuzzIn.c +++ b/examples/ZydisFuzzIn.c @@ -43,7 +43,7 @@ typedef struct ZydisFuzzControlBlock_ { ZydisMachineMode machineMode; ZydisAddressWidth addressWidth; - ZydisBool decoderMode[ZYDIS_DECODER_MODE_MAX_VALUE + 1]; + ZydisDecoderFlags decoderFlags; ZydisFormatterStyle formatterStyle; ZydisFormatterFlags formatterFlags; ZydisFormatterAddressFormat formatterAddrFormat; @@ -71,21 +71,12 @@ int main() } ZydisDecoder decoder; - if (!ZYDIS_SUCCESS( - ZydisDecoderInit(&decoder, controlBlock.machineMode, controlBlock.addressWidth))) + if (!ZYDIS_SUCCESS(ZydisDecoderInitEx(&decoder, controlBlock.machineMode, + controlBlock.addressWidth, controlBlock.decoderFlags))) { fputs("Failed to initialize decoder\n", stderr); return EXIT_FAILURE; } - for (ZydisDecoderMode mode = 1; mode <= ZYDIS_DECODER_MODE_MAX_VALUE; ++mode) - { - if (!ZYDIS_SUCCESS( - ZydisDecoderEnableMode(&decoder, mode, controlBlock.decoderMode[mode] ? 1 : 0))) - { - fputs("Failed to adjust decoder-mode\n", stderr); - return EXIT_FAILURE; - } - } ZydisFormatter formatter; if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, controlBlock.formatterStyle, diff --git a/examples/ZydisPerfTest.c b/examples/ZydisPerfTest.c index 4b47ec7..074ed1a 100644 --- a/examples/ZydisPerfTest.c +++ b/examples/ZydisPerfTest.c @@ -154,19 +154,19 @@ void adjustProcessAndThreadPriority() uint64_t processBuffer(const char* buffer, size_t length, ZydisBool minimalMode, ZydisBool format) { + ZydisDecoderFlags flags = ZYDIS_DECODER_FLAG_DEFAULT_MASK; + if (minimalMode) + { + flags |= ZYDIS_DECODER_FLAG_MINIMAL; + } + ZydisDecoder decoder; if (!ZYDIS_SUCCESS( - ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64))) + ZydisDecoderInitEx(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64, flags))) { fputs("Failed to initialize decoder\n", stderr); exit(EXIT_FAILURE); } - if (!ZYDIS_SUCCESS( - ZydisDecoderEnableMode(&decoder, ZYDIS_DECODER_MODE_MINIMAL, minimalMode))) - { - fputs("Failed to adjust decoder-mode\n", stderr); - exit(EXIT_FAILURE); - } ZydisFormatter formatter; if (format) diff --git a/include/Zydis/Decoder.h b/include/Zydis/Decoder.h index 4ed2eef..fdee76b 100644 --- a/include/Zydis/Decoder.h +++ b/include/Zydis/Decoder.h @@ -46,77 +46,74 @@ extern "C" { /* ============================================================================================== */ /* ---------------------------------------------------------------------------------------------- */ -/* Decoder mode */ +/* Decoder flags */ /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the @c ZydisDecoderMode datatype. + * @brief Defines the @c ZydisDecoderFlags datatype. */ -typedef uint8_t ZydisDecoderMode; +typedef uint8_t ZydisDecoderFlags; /** - * @brief Values that represent decoder-modes. + * @brief Enables minimal instruction decoding without semantic analysis. + * + * This mode provides access to the mnemonic, the instruction-length, the effective + * operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`) + * and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct. + * + * Operands, most attributes and other specific information (like AVX info) are not + * accessible in this mode. */ -enum ZydisDecoderModes -{ - ZYDIS_DECODER_MODE_INVALID, - /** - * @brief Enables minimal instruction decoding without semantic analysis. - * - * This mode provides access to the mnemonic, the instruction-length, the effective - * operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`) - * and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct. - * - * Operands, most attributes and other specific information (like AVX info) are not - * accessible in this mode. - */ - ZYDIS_DECODER_MODE_MINIMAL, - /** - * @brief Enables the AMD-branch mode. - * - * Intel ignores the operand-size override-prefix (`0x66`) for all branches with 32-bit - * immediates and forces the operand-size of the instruction to 64-bit in 64-bit mode. - * In AMD-branch mode `0x66` is not ignored and changes the operand-size and the size of the - * immediate to 16-bit. - */ - ZYDIS_DECODER_MODE_AMD_BRANCHES, - /** - * @brief Enables the MPX mode. - * - * The MPX isa-extension reuses (overrides) some of the widenop instruction opcodes. - * - * This mode is enabled by default. - */ - ZYDIS_DECODER_MODE_MPX, - /** - * @brief Enables the CET mode. - * - * The CET isa-extension reuses (overrides) some of the widenop instruction opcodes. - * - * This mode is enabled by default. - */ - ZYDIS_DECODER_MODE_CET, - /** - * @brief Enables the LZCNT mode. - * - * The LZCNT isa-extension reuses (overrides) some of the widenop instruction opcodes. - * - * This mode is enabled by default. - */ - ZYDIS_DECODER_MODE_LZCNT, - /** - * @brief Enables the TZCNT mode. - * - * The TZCNT isa-extension reuses (overrides) some of the widenop instruction opcodes. - * - * This mode is enabled by default. - */ - ZYDIS_DECODER_MODE_TZCNT, - /** - * @brief Maximum value of this enum. - */ - ZYDIS_DECODER_MODE_MAX_VALUE = ZYDIS_DECODER_MODE_TZCNT -}; +#define ZYDIS_DECODER_FLAG_MINIMAL 0x01 // (1 << 0) +/** + * @brief Enables the AMD-branch mode. + * + * Intel ignores the operand-size override-prefix (`0x66`) for all branches with 32-bit + * immediates and forces the operand-size of the instruction to 64-bit in 64-bit mode. + * In AMD-branch mode `0x66` is not ignored and changes the operand-size and the size of the + * immediate to 16-bit. + */ +#define ZYDIS_DECODER_FLAG_AMD_BRANCHES 0x02 // (1 << 1) +/** + * @brief Enables the MPX mode. + * + * The MPX ISA-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ +#define ZYDIS_DECODER_FLAG_MPX 0x04 // (1 << 2) +/** + * @brief Enables the CET mode. + * + * The CET ISA-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ +#define ZYDIS_DECODER_FLAG_CET 0x08 // (1 << 3) +/** + * @brief Enables the LZCNT mode. + * + * The LZCNT ISA-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ +#define ZYDIS_DECODER_FLAG_LZCNT 0x10 // (1 << 4) +/** + * @brief Enables the TZCNT mode. + * + * The TZCNT ISA-extension reuses (overrides) some of the widenop instruction opcodes. + * + * This mode is enabled by default. + */ +#define ZYDIS_DECODER_FLAG_TZCNT 0x20 // (1 << 5) + +/** + * @brief The default set of decoder-flags. + */ +#define ZYDIS_DECODER_FLAG_DEFAULT_MASK ZYDIS_DECODER_FLAG_MPX | \ + ZYDIS_DECODER_FLAG_CET | \ + ZYDIS_DECODER_FLAG_LZCNT | \ + ZYDIS_DECODER_FLAG_TZCNT /* ---------------------------------------------------------------------------------------------- */ /* Decoder struct */ @@ -129,7 +126,7 @@ typedef struct ZydisDecoder_ { ZydisMachineMode machineMode; ZydisAddressWidth addressWidth; - ZydisBool decoderMode[ZYDIS_DECODER_MODE_MAX_VALUE + 1]; + ZydisDecoderFlags flags; } ZydisDecoder; /* ---------------------------------------------------------------------------------------------- */ @@ -151,16 +148,17 @@ ZYDIS_EXPORT ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMod ZydisAddressWidth addressWidth); /** - * @brief Enables or disables the specified decoder-mode. + * @brief Initializes the given @c ZydisDecoder instance. * - * @param decoder A pointer to the @c ZydisDecoder instance. - * @param mode The decoder mode. - * @param enabled `ZYDIS_TRUE` to enable, or `ZYDIS_FALSE` to disable the specified decoder-mode. + * @param decoder A pointer to the @c ZydisDecoder instance. + * @param machineMode The machine mode. + * @param addressWidth The address width. + * @param flags Additional decoder flags. * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisDecoderEnableMode(ZydisDecoder* decoder, ZydisDecoderMode mode, - ZydisBool enabled); +ZYDIS_EXPORT ZydisStatus ZydisDecoderInitEx(ZydisDecoder* decoder, ZydisMachineMode machineMode, + ZydisAddressWidth addressWidth, ZydisDecoderFlags flags); /** * @brief Decodes the instruction in the given input @c buffer. diff --git a/src/Decoder.c b/src/Decoder.c index a560435..e8d9de8 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -2107,8 +2107,8 @@ static void ZydisSetAttributes(ZydisDecoderContext* context, ZydisDecodedInstruc break; } } - if (context->decoder->decoderMode[ZYDIS_DECODER_MODE_MPX] && - instruction->attributes & ZYDIS_ATTRIB_ACCEPTS_BOUND) + if ((context->decoder->flags & ZYDIS_DECODER_FLAG_MPX) && + (instruction->attributes & ZYDIS_ATTRIB_ACCEPTS_BOUND)) { instruction->attributes |= ZYDIS_ATTRIB_HAS_BOUND; break; @@ -4300,19 +4300,19 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, status = ZydisNodeHandlerMvexE(instruction, &index); break; case ZYDIS_NODETYPE_FILTER_MODE_AMD: - index = context->decoder->decoderMode[ZYDIS_DECODER_MODE_AMD_BRANCHES] ? 1 : 0; + index = context->decoder->flags & ZYDIS_DECODER_FLAG_AMD_BRANCHES ? 1 : 0; break; case ZYDIS_NODETYPE_FILTER_MODE_MPX: - index = context->decoder->decoderMode[ZYDIS_DECODER_MODE_MPX] ? 1 : 0; + index = context->decoder->flags & ZYDIS_DECODER_FLAG_MPX ? 1 : 0; break; case ZYDIS_NODETYPE_FILTER_MODE_CET: - index = context->decoder->decoderMode[ZYDIS_DECODER_MODE_CET] ? 1 : 0; + index = context->decoder->flags & ZYDIS_DECODER_FLAG_CET ? 1 : 0; break; case ZYDIS_NODETYPE_FILTER_MODE_LZCNT: - index = context->decoder->decoderMode[ZYDIS_DECODER_MODE_LZCNT] ? 1 : 0; + index = context->decoder->flags & ZYDIS_DECODER_FLAG_LZCNT ? 1 : 0; break; case ZYDIS_NODETYPE_FILTER_MODE_TZCNT: - index = context->decoder->decoderMode[ZYDIS_DECODER_MODE_TZCNT] ? 1 : 0; + index = context->decoder->flags & ZYDIS_DECODER_FLAG_TZCNT ? 1 : 0; break; default: if (nodeType & ZYDIS_NODETYPE_DEFINITION_MASK) @@ -4353,7 +4353,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, instruction->meta.isaExt = definition->isaExt; instruction->meta.exceptionClass = definition->exceptionClass; - if (!context->decoder->decoderMode[ZYDIS_DECODER_MODE_MINIMAL]) + if (!(context->decoder->flags & ZYDIS_DECODER_FLAG_MINIMAL)) { ZydisSetAttributes(context, instruction, definition); switch (instruction->encoding) @@ -4396,17 +4396,12 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context, ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode, ZydisAddressWidth addressWidth) { - static const ZydisBool decoderModes[ZYDIS_DECODER_MODE_MAX_VALUE + 1] = - { - ZYDIS_FALSE, // ZYDIS_DECODER_MODE_INVALID - ZYDIS_FALSE, // ZYDIS_DECODER_MODE_MINIMAL - ZYDIS_FALSE, // ZYDIS_DECODER_MODE_AMD_BRANCHES - ZYDIS_TRUE , // ZYDIS_DECODER_MODE_MPX - ZYDIS_TRUE , // ZYDIS_DECODER_MODE_CET - ZYDIS_TRUE , // ZYDIS_DECODER_MODE_LZCNT - ZYDIS_TRUE // ZYDIS_DECODER_MODE_TZCNT - }; + return ZydisDecoderInitEx(decoder, machineMode, addressWidth, ZYDIS_DECODER_FLAG_DEFAULT_MASK); +} +ZydisStatus ZydisDecoderInitEx(ZydisDecoder* decoder, ZydisMachineMode machineMode, + ZydisAddressWidth addressWidth, ZydisDecoderFlags flags) +{ if (!decoder || ((machineMode != 16) && (machineMode != 32) && (machineMode != 64))) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -4427,21 +4422,9 @@ ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode decoder->machineMode = machineMode; decoder->addressWidth = addressWidth; - memcpy(&decoder->decoderMode, &decoderModes, sizeof(decoderModes)); + decoder->flags = flags; - return ZYDIS_STATUS_SUCCESS; -} - -ZydisStatus ZydisDecoderEnableMode(ZydisDecoder* decoder, ZydisDecoderMode mode, ZydisBool enabled) -{ - if (!decoder || !mode || (mode > ZYDIS_DECODER_MODE_MAX_VALUE)) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - - decoder->decoderMode[mode] = enabled; - - return ZYDIS_STATUS_SUCCESS; + return ZYDIS_STATUS_SUCCESS; } ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* buffer,