Minor interface changes

- Removed `ZydisDecoderEnableMode`
- Added `ZydisDecoderInitEx` with an additional `flags` parameter that can be used to specify a mask of decoder-modes
This commit is contained in:
flobernd 2017-11-02 17:03:12 +01:00
parent 97a3425e31
commit 0ba5c95dac
4 changed files with 94 additions and 122 deletions

View File

@ -43,7 +43,7 @@ typedef struct ZydisFuzzControlBlock_
{ {
ZydisMachineMode machineMode; ZydisMachineMode machineMode;
ZydisAddressWidth addressWidth; ZydisAddressWidth addressWidth;
ZydisBool decoderMode[ZYDIS_DECODER_MODE_MAX_VALUE + 1]; ZydisDecoderFlags decoderFlags;
ZydisFormatterStyle formatterStyle; ZydisFormatterStyle formatterStyle;
ZydisFormatterFlags formatterFlags; ZydisFormatterFlags formatterFlags;
ZydisFormatterAddressFormat formatterAddrFormat; ZydisFormatterAddressFormat formatterAddrFormat;
@ -71,21 +71,12 @@ int main()
} }
ZydisDecoder decoder; ZydisDecoder decoder;
if (!ZYDIS_SUCCESS( if (!ZYDIS_SUCCESS(ZydisDecoderInitEx(&decoder, controlBlock.machineMode,
ZydisDecoderInit(&decoder, controlBlock.machineMode, controlBlock.addressWidth))) controlBlock.addressWidth, controlBlock.decoderFlags)))
{ {
fputs("Failed to initialize decoder\n", stderr); fputs("Failed to initialize decoder\n", stderr);
return EXIT_FAILURE; 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; ZydisFormatter formatter;
if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, controlBlock.formatterStyle, if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, controlBlock.formatterStyle,

View File

@ -154,19 +154,19 @@ void adjustProcessAndThreadPriority()
uint64_t processBuffer(const char* buffer, size_t length, ZydisBool minimalMode, ZydisBool format) 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; ZydisDecoder decoder;
if (!ZYDIS_SUCCESS( 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); fputs("Failed to initialize decoder\n", stderr);
exit(EXIT_FAILURE); 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; ZydisFormatter formatter;
if (format) if (format)

View File

@ -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 #define ZYDIS_DECODER_FLAG_MINIMAL 0x01 // (1 << 0)
{ /**
ZYDIS_DECODER_MODE_INVALID, * @brief Enables the AMD-branch mode.
/** *
* @brief Enables minimal instruction decoding without semantic analysis. * 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.
* This mode provides access to the mnemonic, the instruction-length, the effective * In AMD-branch mode `0x66` is not ignored and changes the operand-size and the size of the
* operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`) * immediate to 16-bit.
* and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct. */
* #define ZYDIS_DECODER_FLAG_AMD_BRANCHES 0x02 // (1 << 1)
* Operands, most attributes and other specific information (like AVX info) are not /**
* accessible in this mode. * @brief Enables the MPX mode.
*/ *
ZYDIS_DECODER_MODE_MINIMAL, * The MPX ISA-extension reuses (overrides) some of the widenop instruction opcodes.
/** *
* @brief Enables the AMD-branch mode. * This mode is enabled by default.
* */
* Intel ignores the operand-size override-prefix (`0x66`) for all branches with 32-bit #define ZYDIS_DECODER_FLAG_MPX 0x04 // (1 << 2)
* 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 * @brief Enables the CET mode.
* immediate to 16-bit. *
*/ * The CET ISA-extension reuses (overrides) some of the widenop instruction opcodes.
ZYDIS_DECODER_MODE_AMD_BRANCHES, *
/** * This mode is enabled by default.
* @brief Enables the MPX mode. */
* #define ZYDIS_DECODER_FLAG_CET 0x08 // (1 << 3)
* The MPX isa-extension reuses (overrides) some of the widenop instruction opcodes. /**
* * @brief Enables the LZCNT mode.
* This mode is enabled by default. *
*/ * The LZCNT ISA-extension reuses (overrides) some of the widenop instruction opcodes.
ZYDIS_DECODER_MODE_MPX, *
/** * This mode is enabled by default.
* @brief Enables the CET mode. */
* #define ZYDIS_DECODER_FLAG_LZCNT 0x10 // (1 << 4)
* The CET isa-extension reuses (overrides) some of the widenop instruction opcodes. /**
* * @brief Enables the TZCNT mode.
* This mode is enabled by default. *
*/ * The TZCNT ISA-extension reuses (overrides) some of the widenop instruction opcodes.
ZYDIS_DECODER_MODE_CET, *
/** * This mode is enabled by default.
* @brief Enables the LZCNT mode. */
* #define ZYDIS_DECODER_FLAG_TZCNT 0x20 // (1 << 5)
* The LZCNT isa-extension reuses (overrides) some of the widenop instruction opcodes.
* /**
* This mode is enabled by default. * @brief The default set of decoder-flags.
*/ */
ZYDIS_DECODER_MODE_LZCNT, #define ZYDIS_DECODER_FLAG_DEFAULT_MASK ZYDIS_DECODER_FLAG_MPX | \
/** ZYDIS_DECODER_FLAG_CET | \
* @brief Enables the TZCNT mode. ZYDIS_DECODER_FLAG_LZCNT | \
* ZYDIS_DECODER_FLAG_TZCNT
* 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
};
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Decoder struct */ /* Decoder struct */
@ -129,7 +126,7 @@ typedef struct ZydisDecoder_
{ {
ZydisMachineMode machineMode; ZydisMachineMode machineMode;
ZydisAddressWidth addressWidth; ZydisAddressWidth addressWidth;
ZydisBool decoderMode[ZYDIS_DECODER_MODE_MAX_VALUE + 1]; ZydisDecoderFlags flags;
} ZydisDecoder; } ZydisDecoder;
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -151,16 +148,17 @@ ZYDIS_EXPORT ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMod
ZydisAddressWidth addressWidth); 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 decoder A pointer to the @c ZydisDecoder instance.
* @param mode The decoder mode. * @param machineMode The machine mode.
* @param enabled `ZYDIS_TRUE` to enable, or `ZYDIS_FALSE` to disable the specified decoder-mode. * @param addressWidth The address width.
* @param flags Additional decoder flags.
* *
* @return A zydis status code. * @return A zydis status code.
*/ */
ZYDIS_EXPORT ZydisStatus ZydisDecoderEnableMode(ZydisDecoder* decoder, ZydisDecoderMode mode, ZYDIS_EXPORT ZydisStatus ZydisDecoderInitEx(ZydisDecoder* decoder, ZydisMachineMode machineMode,
ZydisBool enabled); ZydisAddressWidth addressWidth, ZydisDecoderFlags flags);
/** /**
* @brief Decodes the instruction in the given input @c buffer. * @brief Decodes the instruction in the given input @c buffer.

View File

@ -2107,8 +2107,8 @@ static void ZydisSetAttributes(ZydisDecoderContext* context, ZydisDecodedInstruc
break; break;
} }
} }
if (context->decoder->decoderMode[ZYDIS_DECODER_MODE_MPX] && if ((context->decoder->flags & ZYDIS_DECODER_FLAG_MPX) &&
instruction->attributes & ZYDIS_ATTRIB_ACCEPTS_BOUND) (instruction->attributes & ZYDIS_ATTRIB_ACCEPTS_BOUND))
{ {
instruction->attributes |= ZYDIS_ATTRIB_HAS_BOUND; instruction->attributes |= ZYDIS_ATTRIB_HAS_BOUND;
break; break;
@ -4300,19 +4300,19 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
status = ZydisNodeHandlerMvexE(instruction, &index); status = ZydisNodeHandlerMvexE(instruction, &index);
break; break;
case ZYDIS_NODETYPE_FILTER_MODE_AMD: 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; break;
case ZYDIS_NODETYPE_FILTER_MODE_MPX: 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; break;
case ZYDIS_NODETYPE_FILTER_MODE_CET: 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; break;
case ZYDIS_NODETYPE_FILTER_MODE_LZCNT: 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; break;
case ZYDIS_NODETYPE_FILTER_MODE_TZCNT: 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; break;
default: default:
if (nodeType & ZYDIS_NODETYPE_DEFINITION_MASK) if (nodeType & ZYDIS_NODETYPE_DEFINITION_MASK)
@ -4353,7 +4353,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
instruction->meta.isaExt = definition->isaExt; instruction->meta.isaExt = definition->isaExt;
instruction->meta.exceptionClass = definition->exceptionClass; 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); ZydisSetAttributes(context, instruction, definition);
switch (instruction->encoding) switch (instruction->encoding)
@ -4396,17 +4396,12 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode, ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode,
ZydisAddressWidth addressWidth) ZydisAddressWidth addressWidth)
{ {
static const ZydisBool decoderModes[ZYDIS_DECODER_MODE_MAX_VALUE + 1] = return ZydisDecoderInitEx(decoder, machineMode, addressWidth, ZYDIS_DECODER_FLAG_DEFAULT_MASK);
{ }
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
};
ZydisStatus ZydisDecoderInitEx(ZydisDecoder* decoder, ZydisMachineMode machineMode,
ZydisAddressWidth addressWidth, ZydisDecoderFlags flags)
{
if (!decoder || ((machineMode != 16) && (machineMode != 32) && (machineMode != 64))) if (!decoder || ((machineMode != 16) && (machineMode != 32) && (machineMode != 64)))
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -4427,21 +4422,9 @@ ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode
decoder->machineMode = machineMode; decoder->machineMode = machineMode;
decoder->addressWidth = addressWidth; decoder->addressWidth = addressWidth;
memcpy(&decoder->decoderMode, &decoderModes, sizeof(decoderModes)); decoder->flags = flags;
return ZYDIS_STATUS_SUCCESS; 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;
} }
ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* buffer, ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* buffer,