Major changes to the instruction decoder

- Decoupled semantic operand decoding (optional) from physical instruction decoding
- Several optimizations of the internal structures
- Further preparations for MVEX-support
This commit is contained in:
flobernd 2017-06-12 19:16:01 +02:00
parent e5e5899f72
commit 8740b1e50f
20 changed files with 48043 additions and 39538 deletions

View File

@ -37,7 +37,6 @@
#include <Zydis/Zydis.h> #include <Zydis/Zydis.h>
#include "FormatHelper.h" #include "FormatHelper.h"
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
/* ============================================================================================== */ /* ============================================================================================== */
/* Static data */ /* Static data */
@ -173,7 +172,8 @@ static ZydisStatus ZydisFormatterFormatOperandImm(ZydisInstructionFormatter* for
/* Helper functions */ /* Helper functions */
/* ============================================================================================== */ /* ============================================================================================== */
void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks) void disassembleBuffer(ZydisInstructionDecoder* decoder, uint8_t* data, size_t length,
ZydisBool installHooks)
{ {
ZydisInstructionFormatter formatter; ZydisInstructionFormatter formatter;
ZydisFormatterInitInstructionFormatterEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, ZydisFormatterInitInstructionFormatterEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL,
@ -195,7 +195,7 @@ void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks)
ZydisInstructionInfo info; ZydisInstructionInfo info;
char buffer[256]; char buffer[256];
while (ZYDIS_SUCCESS( while (ZYDIS_SUCCESS(
ZydisDecode(ZYDIS_OPERATING_MODE_64BIT, data, length, instructionPointer, &info))) ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &info)))
{ {
data += info.length; data += info.length;
length -= info.length; length -= info.length;
@ -210,6 +210,8 @@ void disassembleBuffer(uint8_t* data, size_t length, ZydisBool installHooks)
/* Entry point */ /* Entry point */
/* ============================================================================================== */ /* ============================================================================================== */
#include <Zydis/Internal/InstructionTable.h>
int main() int main()
{ {
@ -218,16 +220,20 @@ int main()
// cmpps xmm1, xmm4, 0x03 // cmpps xmm1, xmm4, 0x03
0x0F, 0xC2, 0xCC, 0x03, 0x0F, 0xC2, 0xCC, 0x03,
// vcmpord_spd xmm1, xmm2, xmm3 // vcmppd xmm1, xmm2, xmm3, 0x17
0xC5, 0xE9, 0xC2, 0xCB, 0x17, 0xC5, 0xE9, 0xC2, 0xCB, 0x17,
// vcmpps k2 {k7}, zmm2, dword ptr ds:[rax + rbx*4 + 0x100] {1to16}, 0x0F // vcmpps k2 {k7}, zmm2, dword ptr ds:[rax + rbx*4 + 0x100] {1to16}, 0x0F
0x62, 0xF1, 0x6C, 0x5F, 0xC2, 0x54, 0x98, 0x40, 0x0F 0x62, 0xF1, 0x6C, 0x5F, 0xC2, 0x54, 0x98, 0x40, 0x0F
}; };
disassembleBuffer(&data[0], sizeof(data), ZYDIS_FALSE); ZydisInstructionDecoder decoder;
ZydisDecoderInitInstructionDecoder(
&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_INVALID);
disassembleBuffer(&decoder, &data[0], sizeof(data), ZYDIS_FALSE);
puts(""); puts("");
disassembleBuffer(&data[0], sizeof(data), ZYDIS_TRUE); disassembleBuffer(&decoder, &data[0], sizeof(data), ZYDIS_TRUE);
getchar(); getchar();
return 0; return 0;

View File

@ -51,10 +51,23 @@ typedef uint32_t ZydisDecodeGranularity;
enum ZydisDecodeGranularities enum ZydisDecodeGranularities
{ {
ZYDIS_DECODE_GRANULARITY_DEFAULT, ZYDIS_DECODE_GRANULARITY_DEFAULT,
/**
* @brief Minimal instruction decoding without semantic operand analysis.
*/
ZYDIS_DECODE_GRANULARITY_MINIMAL, ZYDIS_DECODE_GRANULARITY_MINIMAL,
ZYDIS_DECODE_GRANULARITY_FULL ZYDIS_DECODE_GRANULARITY_FULL
}; };
/**
* @brief Defines the @c ZydisInstructionDecoder datatype.
*/
typedef struct ZydisInstructionDecoder_
{
ZydisMachineMode machineMode;
ZydisAddressWidth addressWidth;
ZydisDecodeGranularity decodeGranularity;
} ZydisInstructionDecoder;
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */ /* ============================================================================================== */
@ -62,36 +75,45 @@ enum ZydisDecodeGranularities
/* ============================================================================================== */ /* ============================================================================================== */
/** /**
* @brief Decodes the instruction in the given input @c buffer. * @brief Initializes the given @c ZydisInstructionDecoder instance.
* *
* @param operatingMode The desired operating mode. * @param decoder A pointer to the @c ZydisInstructionDecoder instance.
* @param buffer A pointer to the input buffer. * @param machineMode The machine mode.
* @param bufferLen The length of the input buffer. * @param addressWidth The address width.
* @param instructionPointer The instruction-pointer.
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the
* details about the decoded instruction.
* *
* @return A zydis status code. * @return A zydis status code.
*/ */
ZYDIS_EXPORT ZydisStatus ZydisDecode(ZydisOperatingMode operatingMode, const void* buffer, ZYDIS_EXPORT ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder,
size_t bufferLen, uint64_t instructionPointer, ZydisInstructionInfo* info); ZydisMachineMode machineMode, ZydisAddressWidth addressWidth);
/**
* @brief Initializes the given @c ZydisInstructionDecoder instance.
*
* @param decoder A pointer to the @c ZydisInstructionDecoder 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);
/** /**
* @brief Decodes the instruction in the given input @c buffer. * @brief Decodes the instruction in the given input @c buffer.
* *
* @param operatingMode The desired operating mode. * @param decoder A pointer to the @c ZydisInstructionDecoder instance.
* @param buffer A pointer to the input buffer. * @param buffer A pointer to the input buffer.
* @param bufferLen The length of the input buffer. * @param bufferLen The length of the input buffer.
* @param instructionPointer The instruction-pointer. * @param instructionPointer The instruction-pointer.
* @param granularity The granularity to decode with.
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the * @param info A pointer to the @c ZydisInstructionInfo struct, that receives the
* details about the decoded instruction. * details about the decoded instruction.
* *
* @return A zydis status code. * @return A zydis status code.
*/ */
ZYDIS_EXPORT ZydisStatus ZydisDecodeEx(ZydisOperatingMode operatingMode, const void* buffer, ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeBuffer(ZydisInstructionDecoder* decoder,
size_t bufferLen, uint64_t instructionPointer, ZydisDecodeGranularity granularity, const void* buffer, size_t bufferLen, uint64_t instructionPointer, ZydisInstructionInfo* info);
ZydisInstructionInfo* info);
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -119,11 +119,13 @@
#define ZYDIS_ASSERT(condition) assert(condition) #define ZYDIS_ASSERT(condition) assert(condition)
#if defined(ZYDIS_MSVC) && defined(ZYDIS_RELEASE) #if defined(ZYDIS_RELEASE)
# define ZYDIS_UNREACHABLE # if defined(ZYDIS_GNUC)
#elif defined(ZYDIS_GNUC) && defined(ZYDIS_RELEASE) # if __has_builtin(__builtin_unreachable)
# if __has_builtin(__builtin_unreachable) # define ZYDIS_UNREACHABLE __builtin_unreachable()
# define ZYDIS_UNREACHABLE __builtin_unreachable() # else
# define ZYDIS_UNREACHABLE
# endif
# else # else
# define ZYDIS_UNREACHABLE # define ZYDIS_UNREACHABLE
# endif # endif

View File

@ -392,22 +392,64 @@ typedef struct ZydisOperandInfo_
/* ============================================================================================== */ /* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Disassembler mode */ /* Machine mode */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Defines the @c ZydisOperatingMode datatype. * @brief Defines the @c ZydisMachineMode datatype.
*/ */
typedef uint8_t ZydisOperatingMode; typedef uint8_t ZydisMachineMode;
/** /**
* @brief Values that represent operating modes. * @brief Values that represent machine modes.
*/ */
enum ZydisOperatingModes enum ZydisMachineModes
{ {
ZYDIS_OPERATING_MODE_16BIT = 16, ZYDIS_MACHINE_MODE_INVALID = 0,
ZYDIS_OPERATING_MODE_32BIT = 32, /**
ZYDIS_OPERATING_MODE_64BIT = 64 * @brief 64 bit mode.
*/
ZYDIS_MACHINE_MODE_LONG_64 = 64,
/**
* @brief 32 bit protected mode.
*/
ZYDIS_MACHINE_MODE_LONG_COMPAT_32 = 32,
/**
* @brief 16 bit protected mode.
*/
ZYDIS_MACHINE_MODE_LONG_COMPAT_16 = 16,
/**
* @brief 32 bit protected mode.
*/
ZYDIS_MACHINE_MODE_LEGACY_32 = 32,
/**
* @brief 16 bit protected mode.
*/
ZYDIS_MACHINE_MODE_LEGACY_16 = 16,
/**
* @brief 16 bit real mode.
*/
ZYDIS_MACHINE_MODE_REAL_16 = 16
};
/* ---------------------------------------------------------------------------------------------- */
/* Address width */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisAddressWidth datatype.
*/
typedef uint8_t ZydisAddressWidth;
/**
* @brief Values that represent address widths.
*/
enum ZydisAddressWidths
{
ZYDIS_ADDRESS_WIDTH_INVALID = 0,
ZYDIS_ADDRESS_WIDTH_16 = 16,
ZYDIS_ADDRESS_WIDTH_32 = 32,
ZYDIS_ADDRESS_WIDTH_64 = 64
}; };
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -425,25 +467,29 @@ typedef uint8_t ZydisInstructionEncoding;
enum ZydisInstructionEncodings enum ZydisInstructionEncodings
{ {
/** /**
* @brief The instruction uses the default operand-encoding. * @brief The instruction uses the default encoding.
*/ */
ZYDIS_INSTRUCTION_ENCODING_DEFAULT = 0x00, ZYDIS_INSTRUCTION_ENCODING_DEFAULT = 0x00,
/** /**
* @brief The instruction uses the AMD 3DNow operand-encoding. * @brief The instruction uses the AMD 3DNow-encoding.
*/ */
ZYDIS_INSTRUCTION_ENCODING_3DNOW = 0x01, ZYDIS_INSTRUCTION_ENCODING_3DNOW = 0x01,
/** /**
* @brief The instruction uses the AMD XOP operand-encoding. * @brief The instruction uses the AMD XOP-encoding.
*/ */
ZYDIS_INSTRUCTION_ENCODING_XOP = 0x02, ZYDIS_INSTRUCTION_ENCODING_XOP = 0x02,
/** /**
* @brief The instruction uses the VEX operand-encoding. * @brief The instruction uses the VEX-encoding.
*/ */
ZYDIS_INSTRUCTION_ENCODING_VEX = 0x03, ZYDIS_INSTRUCTION_ENCODING_VEX = 0x03,
/** /**
* @brief The instruction uses the EVEX operand-encoding. * @brief The instruction uses the EVEX-encoding.
*/ */
ZYDIS_INSTRUCTION_ENCODING_EVEX = 0x04 ZYDIS_INSTRUCTION_ENCODING_EVEX = 0x04,
/**
* @brief The instruction uses the MVEX-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_MVEX = 0x05
}; };
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -461,12 +507,13 @@ typedef uint8_t ZydisOpcodeMap;
enum ZydisOpcodeMaps enum ZydisOpcodeMaps
{ {
ZYDIS_OPCODE_MAP_DEFAULT = 0x00, ZYDIS_OPCODE_MAP_DEFAULT = 0x00,
ZYDIS_OPCODE_MAP_0F = 0x01, ZYDIS_OPCODE_MAP_EX0 = 0x01,
ZYDIS_OPCODE_MAP_0F38 = 0x02, ZYDIS_OPCODE_MAP_0F = 0x02,
ZYDIS_OPCODE_MAP_0F3A = 0x03, ZYDIS_OPCODE_MAP_0F38 = 0x03,
ZYDIS_OPCODE_MAP_XOP8 = 0x04, ZYDIS_OPCODE_MAP_0F3A = 0x04,
ZYDIS_OPCODE_MAP_XOP9 = 0x05, ZYDIS_OPCODE_MAP_XOP8 = 0x05,
ZYDIS_OPCODE_MAP_XOPA = 0x06 ZYDIS_OPCODE_MAP_XOP9 = 0x06,
ZYDIS_OPCODE_MAP_XOPA = 0x07
}; };
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -565,11 +612,11 @@ typedef uint64_t ZydisInstructionAttributes;
/** /**
* @brief The instruction accepts the operand-size prefix (0x66). * @brief The instruction accepts the operand-size prefix (0x66).
*/ */
#define ZYDIS_ATTRIB_ACCEPTS_OPERANDSIZE 0x0000000000040000 #define ZYDIS_ATTRIB_ACCEPTS_OPERANDSIZE 0x0000000000040000 // TODO: Remove
/** /**
* @brief The instruction accepts the address-size prefix (0x67). * @brief The instruction accepts the address-size prefix (0x67).
*/ */
#define ZYDIS_ATTRIB_ACCEPTS_ADDRESSSIZE 0x0000000000080000 #define ZYDIS_ATTRIB_ACCEPTS_ADDRESSSIZE 0x0000000000080000 // TODO: Remove
/** /**
* @brief The instruction has the lock prefix (0xF0). * @brief The instruction has the lock prefix (0xF0).
*/ */
@ -783,9 +830,9 @@ enum ZydisAVXRoundingModes
typedef struct ZydisInstructionInfo_ typedef struct ZydisInstructionInfo_
{ {
/** /**
* @brief The operating mode used to decode this instruction. * @brief The machine mode used to decode this instruction.
*/ */
ZydisOperatingMode mode; ZydisMachineMode machineMode;
/** /**
* @brief The instruction-mnemonic. * @brief The instruction-mnemonic.
*/ */
@ -810,6 +857,14 @@ typedef struct ZydisInstructionInfo_
* @brief The instruction-opcode. * @brief The instruction-opcode.
*/ */
uint8_t opcode; uint8_t opcode;
/**
* @brief The effective operand size.
*/
uint8_t operandSize;
/**
* @brief The effective address width.
*/
uint8_t addressWidth;
/** /**
* @brief The number of instruction-operands. * @brief The number of instruction-operands.
*/ */
@ -875,7 +930,8 @@ typedef struct ZydisInstructionInfo_
*/ */
struct struct
{ {
uint8_t data[ZYDIS_MAX_INSTRUCTION_LENGTH - 1]; // TODO: uint8_t data[ZYDIS_MAX_INSTRUCTION_LENGTH - 1];
uint8_t count;
uint8_t hasF0; uint8_t hasF0;
uint8_t hasF3; uint8_t hasF3;
uint8_t hasF2; uint8_t hasF2;
@ -1140,7 +1196,7 @@ typedef struct ZydisInstructionInfo_
/** /**
* @brief Embedded opmask register specifier. * @brief Embedded opmask register specifier.
*/ */
uint8_t aaa; uint8_t kkk;
} mvex; } mvex;
/** /**
* @brief Detailed info about the ModRM-byte. * @brief Detailed info about the ModRM-byte.
@ -1198,6 +1254,12 @@ typedef struct ZydisInstructionInfo_
* @brief Signals, if the immediate value is signed. * @brief Signals, if the immediate value is signed.
*/ */
ZydisBool isSigned; ZydisBool isSigned;
/**
* @brief Signals, if the immediate value contains a relative offset. You can use
* @c ZydisUtilsCalcAbsoluteTargetAddress to determine the absolute address
* value.
*/
ZydisBool isRelative;
/** /**
* @brief The immediate value. * @brief The immediate value.
*/ */

View File

@ -1,25 +0,0 @@
typedef struct ZydisInstructionDefinition_
{
uint32_t mnemonic : 11;
uint32_t operandsId : 9;
uint32_t evexContext : 2;
uint32_t evexMaskPolicy : 2;
uint32_t evexZeroMaskAccepted : 1;
uint32_t acceptsLock : 1;
uint32_t acceptsREP : 1;
uint32_t acceptsREPEREPNE : 1;
uint32_t acceptsBOUND : 1;
uint32_t acceptsXACQUIRE : 1;
uint32_t acceptsXRELEASE : 1;
uint32_t acceptsHLEWithoutLock : 1;
uint32_t acceptsBranchHints : 1;
#ifdef ZYDIS_ENABLE_FEATURE_IMPLICITLY_USED_REGISTERS
uint8_t implicitRegistersId : 8;
#endif
#ifdef ZYDIS_ENABLE_FEATURE_AFFECTED_FLAGS
uint8_t affectedFlagsId : 8;
#endif
#ifdef ZYDIS_ENABLE_FEATURE_CPUID
uint8_t cpuidId : 8;
#endif
} ZydisInstructionDefinition;

View File

@ -0,0 +1,20 @@
static const ZydisInstructionParts instructionClassMap[] =
{
/*00*/ { 0, { { 0, 0, 0 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*01*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*02*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM, { { 0, 0, 0 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*03*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*04*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*05*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*06*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*07*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0 | ZYDIS_INSTRPART_FLAG_HAS_IMM1, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 16, 16, 16 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*08*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*09*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 32, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0A*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0 | ZYDIS_INSTRPART_FLAG_HAS_IMM1, { { 0, 0, 0 } }, { { { 16, 16, 16 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 8, 8, 8 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0B*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0C*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0D*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_DISP, { { 16, 32, 64 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0E*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 64 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0F*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 16, 16 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*10*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 32, 32, 32 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } }
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -39,10 +39,6 @@ extern "C" {
/* Enums and types */ /* Enums and types */
/* ============================================================================================== */ /* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Generated types */
/* ---------------------------------------------------------------------------------------------- */
// MSVC does not like types other than (un-)signed int for bitfields // MSVC does not like types other than (un-)signed int for bitfields
#ifdef ZYDIS_MSVC #ifdef ZYDIS_MSVC
# pragma warning(push) # pragma warning(push)
@ -51,47 +47,188 @@ extern "C" {
#pragma pack(push, 1) #pragma pack(push, 1)
/** /* ---------------------------------------------------------------------------------------------- */
* @brief Defines the @c ZydisInstructionTableNodeType datatype. /* Instruction tree */
*/ /* ---------------------------------------------------------------------------------------------- */
typedef uint8_t ZydisInstructionTableNodeType;
/** /**
* @brief Defines the @c ZydisInstructionTableNodeValue datatype. * @brief Defines the @c ZydisInstructionTreeNodeType datatype.
*/ */
typedef uint16_t ZydisInstructionTableNodeValue; typedef uint8_t ZydisInstructionTreeNodeType;
/** /**
* @brief Defines the @c ZydisInstructionTableNode struct. * @brief Defines the @c ZydisInstructionTreeNodeValue datatype.
*/
typedef uint16_t ZydisInstructionTreeNodeValue;
/**
* @brief Defines the @c ZydisInstructionTreeNode struct.
* *
* This struct is static for now, because its size is sufficient to encode up to 65535 * This struct is static for now, because its size is sufficient to encode up to 65535
* instruction filters (what is about 10 times more than we currently need). * instruction filters (what is about 10 times more than we currently need).
*/ */
typedef struct ZydisInstructionTableNode_ typedef struct ZydisInstructionTreeNode_
{ {
ZydisInstructionTableNodeType type; ZydisInstructionTreeNodeType type;
ZydisInstructionTableNodeValue value; ZydisInstructionTreeNodeValue value;
} ZydisInstructionTableNode; } ZydisInstructionTreeNode;
/** /**
* @brief Defines the @c ZydisSemanticOperandType datatype. * @brief Values that represent zydis instruction tree node types.
*/ */
typedef uint8_t ZydisSemanticOperandType; enum ZydisInstructionTreeNodeTypes
{
ZYDIS_NODETYPE_INVALID = 0x00,
/**
* @brief Reference to an instruction-definition.
*/
ZYDIS_NODETYPE_DEFINITION_MASK = 0x80,
/**
* @brief Reference to an XOP-map filter.
*/
ZYDIS_NODETYPE_FILTER_XOP = 0x01,
/**
* @brief Reference to an VEX-map filter.
*/
ZYDIS_NODETYPE_FILTER_VEX = 0x02,
/**
* @brief Reference to an EVEX/MVEX-map filter.
*/
ZYDIS_NODETYPE_FILTER_EMVEX = 0x03,
/**
* @brief Reference to an opcode filter.
*/
ZYDIS_NODETYPE_FILTER_OPCODE = 0x04,
/**
* @brief Reference to an instruction-mode filter.
*/
ZYDIS_NODETYPE_FILTER_MODE = 0x05,
/**
* @brief Reference to an compacted instruction-mode filter.
*/
ZYDIS_NODETYPE_FILTER_MODE_COMPACT = 0x06,
/**
* @brief Reference to a ModRM.mod filter.
*/
ZYDIS_NODETYPE_FILTER_MODRM_MOD = 0x07,
/**
* @brief Reference to a compacted ModRM.mod filter.
*/
ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT = 0x08,
/**
* @brief Reference to a ModRM.reg filter.
*/
ZYDIS_NODETYPE_FILTER_MODRM_REG = 0x09,
/**
* @brief Reference to a ModRM.rm filter.
*/
ZYDIS_NODETYPE_FILTER_MODRM_RM = 0x0A,
/**
* @brief Reference to a mandatory-prefix filter.
*/
ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX = 0x0B,
/**
* @brief Reference to an operand-size filter.
*/
ZYDIS_NODETYPE_FILTER_OPERAND_SIZE = 0x0C,
/**
* @brief Reference to an address-size filter.
*/
ZYDIS_NODETYPE_FILTER_ADDRESS_SIZE = 0x0D,
/**
* @brief Reference to a vector-length filter.
*/
ZYDIS_NODETYPE_FILTER_VECTOR_LENGTH = 0x0E,
/**
* @brief Reference to an REX/VEX/EVEX.W filter.
*/
ZYDIS_NODETYPE_FILTER_REX_W = 0x0F,
/**
* @brief Reference to an REX/VEX/EVEX.B filter.
*/
ZYDIS_NODETYPE_FILTER_REX_B = 0x10,
/**
* @brief Reference to an EVEX.b filter.
*/
ZYDIS_NODETYPE_FILTER_EVEX_B = 0x11,
/**
* @brief Reference to an MVEX.E filter.
*/
ZYDIS_NODETYPE_FILTER_MVEX_E = 0x12,
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand definition */
/* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Defines the @c ZydisOperandDefinition struct. * @brief Defines the @c ZydisOperandDefinition struct.
*
* This struct is static for now, because adding more operand-types oder encodings requires
* code changes anyways.
*/ */
typedef struct ZydisOperandDefinition_ typedef struct ZydisOperandDefinition_
{ {
ZydisSemanticOperandType type : 7; int dummy;
ZydisOperandEncoding encoding : 5;
ZydisOperandAction action : 3;
} ZydisOperandDefinition; } ZydisOperandDefinition;
#include <Zydis/Internal/GeneratedTypes.inc> /* ---------------------------------------------------------------------------------------------- */
/* Instruction definition */
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_INSTRUCTION_DEFINITION_BASE \
ZydisInstructionMnemonic mnemonic : 11; \
uint8_t operandCount : 4; \
uint16_t operandReference : 15; \
uint8_t operandSizeMap : 3
/**
* @brief Defines the @c ZydisInstructionDefinition struct.
*/
typedef struct ZydisInstructionDefinition_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE;
} ZydisInstructionDefinition;
typedef struct ZydisInstructionDefinitionDEFAULT_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE;
ZydisBool acceptsLock : 1;
ZydisBool acceptsREP : 1;
ZydisBool acceptsREPEREPZ : 1;
ZydisBool acceptsREPNEREPNZ : 1;
ZydisBool acceptsBOUND : 1;
ZydisBool acceptsXACQUIRE : 1;
ZydisBool acceptsXRELEASE : 1;
ZydisBool acceptsHLEWithoutLock : 1;
ZydisBool acceptsBranchHints : 1;
ZydisBool acceptsSegment : 1;
} ZydisInstructionDefinitionDEFAULT;
typedef struct ZydisInstructionDefinition3DNOW_
{
ZydisInstructionDefinition base;
} ZydisInstructionDefinition3DNOW;
typedef struct ZydisInstructionDefinitionXOP_
{
ZydisInstructionDefinition base;
} ZydisInstructionDefinitionXOP;
typedef struct ZydisInstructionDefinitionVEX_
{
ZydisInstructionDefinition base;
} ZydisInstructionDefinitionVEX;
typedef struct ZydisInstructionDefinitionEVEX_
{
ZydisInstructionDefinition base;
} ZydisInstructionDefinitionEVEX;
typedef struct ZydisInstructionDefinitionMVEX_
{
ZydisInstructionDefinition base;
} ZydisInstructionDefinitionMVEX;
/* ---------------------------------------------------------------------------------------------- */
#pragma pack(pop) #pragma pack(pop)
@ -100,217 +237,80 @@ typedef struct ZydisOperandDefinition_
#endif #endif
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Instruction Table */ /* Physical instruction info */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Values that represent zydis instruction table node types. * @brief Defines the @c ZydisInstructionPartFlags datatype.
*/ */
enum ZydisInstructionTableNodeTypes typedef uint8_t ZydisInstructionPartFlags;
{
ZYDIS_NODETYPE_INVALID = 0x00,
/**
* @brief Reference to an instruction-definition with 0 operands.
*/
ZYDIS_NODETYPE_DEFINITION_0OP = 0x01,
/**
* @brief Reference to an instruction-definition with 1 operands.
*/
ZYDIS_NODETYPE_DEFINITION_1OP = 0x02,
/**
* @brief Reference to an instruction-definition with 2 operands.
*/
ZYDIS_NODETYPE_DEFINITION_2OP = 0x03,
/**
* @brief Reference to an instruction-definition with 3 operands.
*/
ZYDIS_NODETYPE_DEFINITION_3OP = 0x04,
/**
* @brief Reference to an instruction-definition with 4 operands.
*/
ZYDIS_NODETYPE_DEFINITION_4OP = 0x05,
/**
* @brief Reference to an instruction-definition with 5 operands.
*/
ZYDIS_NODETYPE_DEFINITION_5OP = 0x06,
/**
* @brief Reference to an opcode filter.
*/
ZYDIS_NODETYPE_FILTER_OPCODE = 0x07,
/**
* @brief Reference to an VEX/EVEX-map filter.
*/
ZYDIS_NODETYPE_FILTER_VEX = 0x08,
/**
* @brief Reference to an XOP-map filter.
*/
ZYDIS_NODETYPE_FILTER_XOP = 0x09,
/**
* @brief Reference to an instruction-mode filter.
*/
ZYDIS_NODETYPE_FILTER_MODE = 0x0A,
/**
* @brief Reference to a mandatory-prefix filter.
*/
ZYDIS_NODETYPE_FILTER_MANDATORYPREFIX = 0x0B,
/**
* @brief Reference to a ModRM.mod filter.
*/
ZYDIS_NODETYPE_FILTER_MODRMMOD = 0x0C,
/**
* @brief Reference to a ModRM.reg filter.
*/
ZYDIS_NODETYPE_FILTER_MODRMREG = 0x0D,
/**
* @brief Reference to a ModRM.rm filter.
*/
ZYDIS_NODETYPE_FILTER_MODRMRM = 0x0E,
/**
* @brief Reference to an operand-size filter.
*/
ZYDIS_NODETYPE_FILTER_OPERANDSIZE = 0x0F,
/**
* @brief Reference to an address-size filter.
*/
ZYDIS_NODETYPE_FILTER_ADDRESSSIZE = 0x10,
/**
* @brief Reference to an REX/VEX/EVEX.w filter.
*/
ZYDIS_NODETYPE_FILTER_REXW = 0x11,
/**
* @brief Reference to an VEX/EVEX.l filter.
*/
ZYDIS_NODETYPE_FILTER_VEXL = 0x12,
/**
* @brief Reference to an EVEX.l' filter.
*/
ZYDIS_NODETYPE_FILTER_EVEXL2 = 0x13,
/**
* @brief Reference to an EVEX.b filter.
*/
ZYDIS_NODETYPE_FILTER_EVEXB = 0x14
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand definition */
/* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Values that represent semantic operand types. * @brief The instruction has an optional modrm byte.
*/ */
enum ZydisSemanticOperandTypes #define ZYDIS_INSTRPART_FLAG_HAS_MODRM 0x01
{
ZYDIS_SEM_OPERAND_TYPE_UNUSED,
ZYDIS_SEM_OPERAND_TYPE_GPR8,
ZYDIS_SEM_OPERAND_TYPE_GPR16,
ZYDIS_SEM_OPERAND_TYPE_GPR32,
ZYDIS_SEM_OPERAND_TYPE_GPR64,
ZYDIS_SEM_OPERAND_TYPE_FPR,
ZYDIS_SEM_OPERAND_TYPE_VR64,
ZYDIS_SEM_OPERAND_TYPE_VR128,
ZYDIS_SEM_OPERAND_TYPE_VR256,
ZYDIS_SEM_OPERAND_TYPE_VR512,
ZYDIS_SEM_OPERAND_TYPE_TR,
ZYDIS_SEM_OPERAND_TYPE_CR,
ZYDIS_SEM_OPERAND_TYPE_DR,
ZYDIS_SEM_OPERAND_TYPE_SREG,
ZYDIS_SEM_OPERAND_TYPE_MSKR,
ZYDIS_SEM_OPERAND_TYPE_BNDR,
ZYDIS_SEM_OPERAND_TYPE_MEM,
ZYDIS_SEM_OPERAND_TYPE_MEM8,
ZYDIS_SEM_OPERAND_TYPE_MEM16,
ZYDIS_SEM_OPERAND_TYPE_MEM32,
ZYDIS_SEM_OPERAND_TYPE_MEM64,
ZYDIS_SEM_OPERAND_TYPE_MEM80,
ZYDIS_SEM_OPERAND_TYPE_MEM128,
ZYDIS_SEM_OPERAND_TYPE_MEM256,
ZYDIS_SEM_OPERAND_TYPE_MEM512,
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST2,
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST4,
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST8,
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST16,
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST2,
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST4,
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST8,
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST16,
ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBX,
ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBY,
ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBZ,
ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBX,
ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBY,
ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBZ,
ZYDIS_SEM_OPERAND_TYPE_M1616,
ZYDIS_SEM_OPERAND_TYPE_M1632,
ZYDIS_SEM_OPERAND_TYPE_M1664,
ZYDIS_SEM_OPERAND_TYPE_MEM112,
ZYDIS_SEM_OPERAND_TYPE_MEM224,
ZYDIS_SEM_OPERAND_TYPE_IMM8,
ZYDIS_SEM_OPERAND_TYPE_IMM16,
ZYDIS_SEM_OPERAND_TYPE_IMM32,
ZYDIS_SEM_OPERAND_TYPE_IMM64,
ZYDIS_SEM_OPERAND_TYPE_IMM8U,
ZYDIS_SEM_OPERAND_TYPE_REL8,
ZYDIS_SEM_OPERAND_TYPE_REL16,
ZYDIS_SEM_OPERAND_TYPE_REL32,
ZYDIS_SEM_OPERAND_TYPE_REL64,
ZYDIS_SEM_OPERAND_TYPE_PTR1616,
ZYDIS_SEM_OPERAND_TYPE_PTR1632,
ZYDIS_SEM_OPERAND_TYPE_PTR1664,
ZYDIS_SEM_OPERAND_TYPE_MOFFS16,
ZYDIS_SEM_OPERAND_TYPE_MOFFS32,
ZYDIS_SEM_OPERAND_TYPE_MOFFS64,
ZYDIS_SEM_OPERAND_TYPE_SRCIDX8,
ZYDIS_SEM_OPERAND_TYPE_SRCIDX16,
ZYDIS_SEM_OPERAND_TYPE_SRCIDX32,
ZYDIS_SEM_OPERAND_TYPE_SRCIDX64,
ZYDIS_SEM_OPERAND_TYPE_DSTIDX8,
ZYDIS_SEM_OPERAND_TYPE_DSTIDX16,
ZYDIS_SEM_OPERAND_TYPE_DSTIDX32,
ZYDIS_SEM_OPERAND_TYPE_DSTIDX64,
ZYDIS_SEM_OPERAND_TYPE_FIXED1,
ZYDIS_SEM_OPERAND_TYPE_AL,
ZYDIS_SEM_OPERAND_TYPE_CL,
ZYDIS_SEM_OPERAND_TYPE_AX,
ZYDIS_SEM_OPERAND_TYPE_DX,
ZYDIS_SEM_OPERAND_TYPE_EAX,
ZYDIS_SEM_OPERAND_TYPE_ECX,
ZYDIS_SEM_OPERAND_TYPE_RAX,
ZYDIS_SEM_OPERAND_TYPE_ES,
ZYDIS_SEM_OPERAND_TYPE_CS,
ZYDIS_SEM_OPERAND_TYPE_SS,
ZYDIS_SEM_OPERAND_TYPE_DS,
ZYDIS_SEM_OPERAND_TYPE_GS,
ZYDIS_SEM_OPERAND_TYPE_FS,
ZYDIS_SEM_OPERAND_TYPE_ST0
};
/* ---------------------------------------------------------------------------------------------- */
/* Instruction definition */
/* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Values that represent zydis EVEX.b-contexts. * @brief The instruction has an optional displacement value.
*/ */
enum ZydisEvexBFunctionalities #define ZYDIS_INSTRPART_FLAG_HAS_DISP 0x02
{
ZYDIS_EVEX_CONTEXT_INVALID,
ZYDIS_EVEX_CONTEXT_BC,
ZYDIS_EVEX_CONTEXT_RC,
ZYDIS_EVEX_CONTEXT_SAE
};
/* ---------------------------------------------------------------------------------------------- */ /**
* @brief The instruction has an optional immediate value.
*/
#define ZYDIS_INSTRPART_FLAG_HAS_IMM0 0x04
/**
* @brief The instruction has a second optional immediate value.
*/
#define ZYDIS_INSTRPART_FLAG_HAS_IMM1 0x08
typedef struct ZydisInstructionParts_
{
/**
* @brief
*/
ZydisInstructionPartFlags flags;
/**
* @brief Displacement info.
*/
struct
{
/**
* @brief The size of the displacement value.
*/
uint8_t size[3];
} disp;
/**
* @brief Immediate info.
*/
struct
{
/**
* @brief The size of the immediate value.
*/
uint8_t size[3];
/**
* @brief Signals, if the value is signed.
*/
ZydisBool isSigned;
/**
* @brief Signals, if the value is a relative offset.
*/
ZydisBool isRelative;
} imm[2];
} ZydisInstructionParts;
/* ============================================================================================== */ /* ============================================================================================== */
/* Functions */ /* Functions */
/* ============================================================================================== */ /* ============================================================================================== */
/** /**
* @brief Returns the root node of the instruction table. * @brief Returns the root node of the instruction tree.
* *
* @return The root node of the instruction table. * @return The root node of the instruction tree.
*/ */
ZYDIS_NO_EXPORT const ZydisInstructionTableNode* ZydisInstructionTableGetRootNode(); ZYDIS_NO_EXPORT const ZydisInstructionTreeNode* ZydisInstructionTreeGetRootNode();
/** /**
* @brief Returns the child node of @c parent specified by @c index. * @brief Returns the child node of @c parent specified by @c index.
@ -320,25 +320,39 @@ ZYDIS_NO_EXPORT const ZydisInstructionTableNode* ZydisInstructionTableGetRootNod
* *
* @return The specified child node. * @return The specified child node.
*/ */
ZYDIS_NO_EXPORT const ZydisInstructionTableNode* ZydisInstructionTableGetChildNode( ZYDIS_NO_EXPORT const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode(
const ZydisInstructionTableNode* parent, uint16_t index); const ZydisInstructionTreeNode* parent, uint16_t index);
/** /**
* @brief Returns the instruction- and operand-definition that is linked to the given @c node. * @brief Returns the instruction- and operand-definition that is linked to the given @c node.
* *
* @param node The instruction definition node. * @param node The instruction definition node.
* @param definition A pointer to a variable that receives a pointer to the * @param definition A pointer to a variable that receives a pointer to the
* instruction-definition. */
ZYDIS_NO_EXPORT void ZydisGetInstructionDefinition(const ZydisInstructionTreeNode* node,
const ZydisInstructionDefinition** definition);
/**
* @brief Returns information about optional instruction parts for the instruction that is linked
* to the given @c node.
*
* @param node The instruction definition node.
* @param info A pointer to the @c ZydisInstructionParts struct.
*/
ZYDIS_NO_EXPORT void ZydisGetOptionalInstructionParts(const ZydisInstructionTreeNode* node,
const ZydisInstructionParts** info);
/**
* @brief Returns the instruction- and operand-definition that is linked to the given @c node.
*
* @param definition A pointer to the instruction-definition.
* @param operands A pointer to a variable that receives a pointer to the first * @param operands A pointer to a variable that receives a pointer to the first
* operand-definition of the instruction. * operand-definition of the instruction.
* @param operandCount A pointer to a variable that receives the number of operand-definitions *
* for the instruction. * @return The number of operands for the given instruction-definition.
*
* @return @c TRUE, if @c node contained a valid instruction-definition, @c FALSE if not.
*/ */
ZYDIS_NO_EXPORT ZydisBool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node, ZYDIS_NO_EXPORT uint8_t ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition,
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands, const ZydisOperandDefinition** operands);
uint8_t* operandCount);
/* ============================================================================================== */ /* ============================================================================================== */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,6 @@
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h> #include <Zydis/Types.h>
#include <Zydis/Status.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -113,7 +113,7 @@ enum ZydisRegisters
// Instruction-pointer registers // Instruction-pointer registers
ZYDIS_REGISTER_RIP, ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP, ZYDIS_REGISTER_RIP, ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP,
// Special registers // Special registers
ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU, ZYDIS_REGISTER_XCR0, ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU, ZYDIS_REGISTER_XCR0,
// Segment registers // Segment registers
ZYDIS_REGISTER_ES, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_DS, ZYDIS_REGISTER_ES, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_DS,
ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS, ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS,

View File

@ -92,21 +92,27 @@ enum ZydisStatusCode
*/ */
ZYDIS_STATUS_ILLEGAL_LOCK, ZYDIS_STATUS_ILLEGAL_LOCK,
/** /**
* @brief A legacy-prefix (F2, F3, 66) was found while decoding a XOP/VEX/EVEX instruction. * @brief A legacy-prefix (F2, F3, 66) was found while decoding a XOP/VEX/EVEX/MVEX
* instruction.
*/ */
ZYDIS_STATUS_ILLEGAL_LEGACY_PFX, ZYDIS_STATUS_ILLEGAL_LEGACY_PFX,
/** /**
* @brief A rex-prefix was found while decoding a XOP/VEX/EVEX instruction. * @brief A rex-prefix was found while decoding a XOP/VEX/EVEX/MVEX instruction.
*/ */
ZYDIS_STATUS_ILLEGAL_REX, ZYDIS_STATUS_ILLEGAL_REX,
/** /**
* @brief An invalid opcode-map value was found while decoding a XOP/VEX/EVEX-prefix. * @brief An invalid opcode-map value was found while decoding a XOP/VEX/EVEX/MVEX-prefix.
*/ */
ZYDIS_STATUS_INVALID_MAP, ZYDIS_STATUS_INVALID_MAP,
/** /**
* @brief An error occured while decoding the EVEX-prefix. * @brief An error occured while decoding the EVEX-prefix.
*/ */
ZYDIS_STATUS_MALFORMED_EVEX, ZYDIS_STATUS_MALFORMED_EVEX,
/**
* @brief An error occured while decoding the MVEX-prefix.
*/
ZYDIS_STATUS_MALFORMED_MVEX, // TODO: Do we need this?
// TODO: // TODO:
ZYDIS_STATUS_INVALID_MASK, ZYDIS_STATUS_INVALID_MASK,
ZYDIS_STATUS_INVALID_VSIB, ZYDIS_STATUS_INVALID_VSIB,

File diff suppressed because it is too large Load Diff

View File

@ -391,13 +391,13 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(ZydisInstructionFormatter* fo
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
switch (info->mode) switch (info->machineMode)
{ {
case ZYDIS_OPERATING_MODE_16BIT: case 16:
case ZYDIS_OPERATING_MODE_32BIT: case 32:
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"0x%08"PRIX64, address); "0x%08"PRIX64, address);
case ZYDIS_OPERATING_MODE_64BIT: case 64:
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
"0x%016"PRIX64, address); "0x%016"PRIX64, address);
default: default:

View File

@ -35,36 +35,6 @@
/* Forward declarations */ /* Forward declarations */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/**
* @brief Contains all opcode filters.
*
* Indexed by the numeric value of the opcode.
*/
extern const ZydisInstructionTableNode filterOpcode[][256];
/**
* @brief Contains all VEX-map filters.
*
* Index values:
* 0 = LES, LDS or BOUND instruction (default encoding)
* 1 = 0F
* 2 = 0F38
* 3 = 0F3A
* 4 = 66
* 5 = 66_0F
* 6 = 66_0F38
* 7 = 66_0F3A
* 8 = F3
* 9 = F3_0F
* A = F3_0F38
* B = F3_0F3A
* C = F2
* D = F2_0F
* E = F2_0F38
* F = F2_0F3A
*/
extern const ZydisInstructionTableNode filterVEX[][16];
/** /**
* @brief Contains all XOP-map filters. * @brief Contains all XOP-map filters.
* *
@ -74,264 +44,267 @@ extern const ZydisInstructionTableNode filterVEX[][16];
* 2 = xop9 * 2 = xop9
* 3 = xopA * 3 = xopA
*/ */
extern const ZydisInstructionTableNode filterXOP[][4]; extern const ZydisInstructionTreeNode filtersXOP[][4];
/**
* @brief Contains all VEX-map filters.
*
* Index values:
* 00 = LES or LDS instruction (default encoding)
* 01 = VEX MAP0
* 02 = 0F
* 03 = 0F38
* 04 = 0F3A
* 05 = 66
* 06 = 66_0F
* 07 = 66_0F38
* 08 = 66_0F3A
* 09 = F3
* 0A = F3_0F
* 0B = F3_0F38
* 0C = F3_0F3A
* 0D = F2
* 0E = F2_0F
* 0F = F2_0F38
* 10 = F2_0F3A
*/
extern const ZydisInstructionTreeNode filtersVEX[][17];
/**
* @brief Contains all EVEX/MVEX-map filters.
*
* Index values:
* 00 = BOUND instruction (default encoding)
* 01 = EVEX MAP0
* 02 = EVEX 0F
* 03 = EVEX 0F38
* 04 = EVEX 0F3A
* 05 = EVEX 66
* 06 = EVEX 66_0F
* 07 = EVEX 66_0F38
* 08 = EVEX 66_0F3A
* 09 = EVEX F3
* 0A = EVEX F3_0F
* 0B = EVEX F3_0F38
* 0C = EVEX F3_0F3A
* 0D = EVEX EVEX F2
* 0E = EVEX F2_0F
* 0F = EVEX
* 10 = EVEX F2_0F3A
* 11 = MVEX MAP0
* 12 = MVEX 0F
* 13 = MVEX 0F38
* 14 = MVEX 0F3A
* 15 = MVEX 66
* 16 = MVEX 66_0F
* 17 = MVEX 66_0F38
* 18 = MVEX 66_0F3A
* 19 = MVEX F3
* 1A = MVEX F3_0F
* 1B = MVEX F3_0F38
* 1C = MVEX F3_0F3A
* 1D = MVEX EVEX F2
* 1E = MVEX F2_0F
* 1F = MVEX F2_0F38
* 20 = MVEX F2_0F3A
*/
extern const ZydisInstructionTreeNode filtersEMVEX[][33];
/**
* @brief Contains all opcode filters.
*
* Indexed by the numeric value of the opcode.
*/
extern const ZydisInstructionTreeNode filtersOpcode[][256];
/** /**
* @brief Contains all instruction-mode filters. * @brief Contains all instruction-mode filters.
* *
* Index values: * Index values:
* 0 = 64 bit mode required * 0 = 16 bit mode
* 1 = 64 bit mode excluded * 1 = 32 bit mode
* 2 = 64 bit mode
*/ */
extern const ZydisInstructionTableNode filterMode[][2]; extern const ZydisInstructionTreeNode filtersMode[][3];
/**
* @brief Contains all compacted instruction-mode filters.
*
* Index values:
* 0 = 64 bit mode
* 1 = not 64 bit mode
*/
extern const ZydisInstructionTreeNode filtersModeCompact[][2];
/**
* @brief Contains all ModRM.mod filters.
*
* Indexed by the ordinal value of the ModRM.mod field.
*/
extern const ZydisInstructionTreeNode filtersModrmMod[][4];
/**
* @brief Contains all compacted ModRM.mod filters.
*
* Index values:
* 0 = [ModRM.mod == 11] = register
* 1 = [ModRM.mod == !11] = memory
*/
extern const ZydisInstructionTreeNode filtersModrmModCompact[][2];
/**
* @brief Contains all ModRM.reg filters.
*
* Indexed by the numeric value of the ModRM.reg field.
*/
extern const ZydisInstructionTreeNode filtersModrmReg[][8];
/**
* @brief Contains all ModRM.rm filters.
*
* Indexed by the numeric value of the ModRM.rm field.
*/
extern const ZydisInstructionTreeNode filtersModrmRm[][8];
/** /**
* @brief Contains all mandatory-prefix switch tables. * @brief Contains all mandatory-prefix switch tables.
* *
* Index values: * Index values:
* 0 = none * 0 = ignored (prefixes are not interpreted as mandatory-prefix)
* 1 = 66 * 1 = none
* 2 = F3 * 2 = 66
* 3 = F2 * 3 = F3
* 4 = F2
*/ */
extern const ZydisInstructionTableNode filterMandatoryPrefix[][4]; extern const ZydisInstructionTreeNode filtersMandatoryPrefix[][5];
/**
* @brief Contains all ModRM.mod filters.
*
* Index values:
* 0 = [modrm_mod == !11] = memory
* 1 = [modrm_mod == 11] = register
*/
extern const ZydisInstructionTableNode filterModrmMod[][2];
/**
* @brief Contains all ModRM.reg filters.
*
* Indexed by the numeric value of the modrm_reg field.
*/
extern const ZydisInstructionTableNode filterModrmReg[][8];
/**
* @brief Contains all ModRM.rm filters.
*
* Indexed by the numeric value of the modrm_rm field.
*/
extern const ZydisInstructionTableNode filterModrmRm[][8];
/** /**
* @brief Contains all operand-size filters. * @brief Contains all operand-size filters.
* *
* Index values: * Index values:
* 0 = 16bit = 0x66 prefix in 32 bit mode * 0 = 16 bit
* 1 = 32bit = 0x66 prefix in 16 bit mode * 1 = 32 bit
* 2 = 64 bit
*/ */
extern const ZydisInstructionTableNode filterOperandSize[][2]; extern const ZydisInstructionTreeNode filtersOperandSize[][3];
/** /**
* @brief Contains all address-size filters. * @brief Contains all address-size filters.
* *
* Index values: * Index values:
* 0 = 16 * 0 = 16 bit
* 1 = 32 * 1 = 32 bit
* 2 = 64 * 2 = 64 bit
*/ */
extern const ZydisInstructionTableNode filterAddressSize[][3]; extern const ZydisInstructionTreeNode filtersAddressSize[][3];
/**
* @brief Contains all vector-length filters.
*
* Index values:
* 0 = 128 bit
* 1 = 256 bit
* 2 = 512 bit
*/
extern const ZydisInstructionTreeNode filtersVectorLength[][3];
/** /**
* @brief Contains all REX/VEX/EVEX.w filters. * @brief Contains all REX/VEX/EVEX.w filters.
* *
* Indexed by the numeric value of the REX/VEX/EVEX.w field. * Indexed by the numeric value of the REX/VEX/EVEX.w field.
*/ */
extern const ZydisInstructionTableNode filterREXW[][2]; extern const ZydisInstructionTreeNode filtersREXW[][2];
/** /**
* @brief Contains all VEX.l filters. * @brief Contains all REX/VEX/EVEX.B filters.
* *
* Indexed by the numeric value of the VEX/EVEX.l field. * Indexed by the numeric value of the REX/VEX/EVEX.B field.
*/ */
extern const ZydisInstructionTableNode filterVEXL[][2]; extern const ZydisInstructionTreeNode filtersREXB[][2];
/**
* @brief Contains all EVEX.l' filters.
*
* Indexed by the numeric value of the EVEX.l' field.
*/
extern const ZydisInstructionTableNode filterEVEXL2[][2];
/** /**
* @brief Contains all EVEX.b filters. * @brief Contains all EVEX.b filters.
* *
* Indexed by the numeric value of the EVEX.b field. * Indexed by the numeric value of the EVEX.b field.
*/ */
extern const ZydisInstructionTableNode filterEVEXB[][2]; extern const ZydisInstructionTreeNode filtersEVEXB[][2];
/**
* @brief Contains all MVEX.E filters.
*
* Indexed by the numeric value of the MVEX.E field.
*/
extern const ZydisInstructionTreeNode filtersMVEXE[][2];
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Contains all operand-definitions with 1 operands. * @brief Contains all operand-definitions.
*/ */
extern const ZydisOperandDefinition operandDefinitions1[][1]; extern const ZydisOperandDefinition operandDefinitions[];
/**
* @brief Contains all operand-definitions with 2 operands.
*/
extern const ZydisOperandDefinition operandDefinitions2[][2];
/**
* @brief Contains all operand-definitions with 3 operands.
*/
extern const ZydisOperandDefinition operandDefinitions3[][3];
/**
* @brief Contains all operand-definitions with 4 operands.
*/
extern const ZydisOperandDefinition operandDefinitions4[][4];
/**
* @brief Contains all operand-definitions with 5 operands.
*/
extern const ZydisOperandDefinition operandDefinitions5[][5];
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Contains all instruction-definitions. * @brief Contains all instruction-definitions with @c DEFAULT encoding.
*/ */
extern const ZydisInstructionDefinition instructionDefinitions[]; extern const ZydisInstructionDefinitionDEFAULT instructionDefinitionsDEFAULT[];
/**
* @brief Contains all instruction-definitions with @c 3DNOW encoding.
*/
extern const ZydisInstructionDefinition3DNOW instructionDefinitions3DNOW[];
/**
* @brief Contains all instruction-definitions with @c XOP encoding.
*/
extern const ZydisInstructionDefinitionXOP instructionDefinitionsXOP[];
/**
* @brief Contains all instruction-definitions with @c VEX encoding.
*/
extern const ZydisInstructionDefinitionVEX instructionDefinitionsVEX[];
/**
* @brief Contains all instruction-definitions with @c EVEX encoding.
*/
extern const ZydisInstructionDefinitionEVEX instructionDefinitionsEVEX[];
/**
* @brief Contains all instruction-definitions with @c MVEX encoding.
*/
extern const ZydisInstructionDefinitionMVEX instructionDefinitionsMVEX[];
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Functions */ /* Physical instruction encodings */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
const ZydisInstructionTableNode* ZydisInstructionTableGetRootNode() #include <Zydis/Internal/InstructionClassMap.inc>
{
static const ZydisInstructionTableNode root = { ZYDIS_NODETYPE_FILTER_OPCODE, 0x00000000 };
return &root;
}
const ZydisInstructionTableNode* ZydisInstructionTableGetChildNode(
const ZydisInstructionTableNode* parent, uint16_t index)
{
switch (parent->type)
{
case ZYDIS_NODETYPE_FILTER_OPCODE:
ZYDIS_ASSERT(index < 256);
return &filterOpcode[parent->value][index];
case ZYDIS_NODETYPE_FILTER_VEX:
ZYDIS_ASSERT(index < 16);
return &filterVEX[parent->value][index];
case ZYDIS_NODETYPE_FILTER_XOP:
ZYDIS_ASSERT(index < 4);
return &filterXOP[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODE:
ZYDIS_ASSERT(index < 3);
return &filterMode[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MANDATORYPREFIX:
ZYDIS_ASSERT(index < 4);
return &filterMandatoryPrefix[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODRMMOD:
ZYDIS_ASSERT(index < 2);
return &filterModrmMod[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODRMREG:
ZYDIS_ASSERT(index < 8);
return &filterModrmReg[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODRMRM:
ZYDIS_ASSERT(index < 8);
return &filterModrmRm[parent->value][index];
case ZYDIS_NODETYPE_FILTER_OPERANDSIZE:
ZYDIS_ASSERT(index < 2);
return &filterOperandSize[parent->value][index];
case ZYDIS_NODETYPE_FILTER_ADDRESSSIZE:
ZYDIS_ASSERT(index < 3);
return &filterAddressSize[parent->value][index];
case ZYDIS_NODETYPE_FILTER_REXW:
ZYDIS_ASSERT(index < 2);
return &filterREXW[parent->value][index];
case ZYDIS_NODETYPE_FILTER_VEXL:
ZYDIS_ASSERT(index < 2);
return &filterVEXL[parent->value][index];
case ZYDIS_NODETYPE_FILTER_EVEXL2:
ZYDIS_ASSERT(index < 2);
return &filterEVEXL2[parent->value][index];
case ZYDIS_NODETYPE_FILTER_EVEXB:
ZYDIS_ASSERT(index < 2);
return &filterEVEXB[parent->value][index];
default:
ZYDIS_UNREACHABLE;
}
static const ZydisInstructionTableNode invalid = { ZYDIS_NODETYPE_INVALID, 0x00000000 };
return &invalid;
}
ZydisBool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* node,
const ZydisInstructionDefinition** definition, const ZydisOperandDefinition** operands,
uint8_t* operandCount)
{
*definition = &instructionDefinitions[node->value];
switch (node->type)
{
case ZYDIS_NODETYPE_DEFINITION_0OP:
*operandCount = 0;
break;
case ZYDIS_NODETYPE_DEFINITION_1OP:
*operandCount = 1;
*operands = operandDefinitions1[(*definition)->operandsId];
break;
case ZYDIS_NODETYPE_DEFINITION_2OP:
*operandCount = 2;
*operands = operandDefinitions2[(*definition)->operandsId];
break;
case ZYDIS_NODETYPE_DEFINITION_3OP:
*operandCount = 3;
*operands = operandDefinitions3[(*definition)->operandsId];
break;
case ZYDIS_NODETYPE_DEFINITION_4OP:
*operandCount = 4;
*operands = operandDefinitions4[(*definition)->operandsId];
break;
case ZYDIS_NODETYPE_DEFINITION_5OP:
*operandCount = 5;
*operands = operandDefinitions5[(*definition)->operandsId];
break;
default:
ZYDIS_UNREACHABLE;
//return ZYDIS_FALSE;
}
return ZYDIS_TRUE;
}
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Main instruction-table */ /* Instruction tree */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_INVALID \ #define ZYDIS_INVALID \
{ ZYDIS_NODETYPE_INVALID, 0x00000000 } { ZYDIS_NODETYPE_INVALID, 0x00000000 }
#define ZYDIS_FILTER(type, id) \ #define ZYDIS_FILTER(type, id) \
{ type, id } { type, id }
#define ZYDIS_DEFINITION_0OP(id) \ #define ZYDIS_DEFINITION(encoding, instrclass, id) \
{ ZYDIS_NODETYPE_DEFINITION_0OP, id } { ZYDIS_NODETYPE_DEFINITION_MASK | instrclass, (encoding << 13) | id }
#define ZYDIS_DEFINITION_1OP(id) \
{ ZYDIS_NODETYPE_DEFINITION_1OP, id }
#define ZYDIS_DEFINITION_2OP(id) \
{ ZYDIS_NODETYPE_DEFINITION_2OP, id }
#define ZYDIS_DEFINITION_3OP(id) \
{ ZYDIS_NODETYPE_DEFINITION_3OP, id }
#define ZYDIS_DEFINITION_4OP(id) \
{ ZYDIS_NODETYPE_DEFINITION_4OP, id }
#define ZYDIS_DEFINITION_5OP(id) \
{ ZYDIS_NODETYPE_DEFINITION_5OP, id }
#include <Zydis/Internal/InstructionFilters.inc> #include <Zydis/Internal/InstructionFilters.inc>
#undef ZYDIS_INVALID #undef ZYDIS_INVALID
#undef ZYDIS_FILTER #undef ZYDIS_FILTER
#undef ZYDIS_DEFINITION_0OP #undef ZYDIS_DEFINITION
#undef ZYDIS_DEFINITION_1OP
#undef ZYDIS_DEFINITION_2OP /* ---------------------------------------------------------------------------------------------- */
#undef ZYDIS_DEFINITION_3OP /* Instruction definitions */
#undef ZYDIS_DEFINITION_4OP /* ---------------------------------------------------------------------------------------------- */
#undef ZYDIS_DEFINITION_5OP
#include <Zydis/Internal/InstructionDefinitions.inc>
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Operand definitions */ /* Operand definitions */
@ -344,10 +317,137 @@ ZydisBool ZydisInstructionTableGetDefinition(const ZydisInstructionTableNode* no
#undef ZYDIS_OPERAND_DEFINITION #undef ZYDIS_OPERAND_DEFINITION
/* ---------------------------------------------------------------------------------------------- */ /* ============================================================================================== */
/* Instruction definitions */ /* Functions */
/* ---------------------------------------------------------------------------------------------- */ /* ============================================================================================== */
#include <Zydis/Internal/InstructionDefinitions.inc> const ZydisInstructionTreeNode* ZydisInstructionTreeGetRootNode()
{
static const ZydisInstructionTreeNode root = { ZYDIS_NODETYPE_FILTER_OPCODE, 0x00000000 };
return &root;
}
const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode(
const ZydisInstructionTreeNode* parent, uint16_t index)
{
switch (parent->type)
{
case ZYDIS_NODETYPE_FILTER_XOP:
ZYDIS_ASSERT(index < 4);
return &filtersXOP[parent->value][index];
case ZYDIS_NODETYPE_FILTER_VEX:
ZYDIS_ASSERT(index < 17);
return &filtersVEX[parent->value][index];
case ZYDIS_NODETYPE_FILTER_EMVEX:
ZYDIS_ASSERT(index < 33);
return &filtersEMVEX[parent->value][index];
case ZYDIS_NODETYPE_FILTER_OPCODE:
ZYDIS_ASSERT(index < 256);
return &filtersOpcode[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODE:
ZYDIS_ASSERT(index < 4);
return &filtersMode[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODE_COMPACT:
ZYDIS_ASSERT(index < 3);
return &filtersModeCompact[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODRM_MOD:
ZYDIS_ASSERT(index < 4);
return &filtersModrmMod[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT:
ZYDIS_ASSERT(index < 2);
return &filtersModrmModCompact[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODRM_REG:
ZYDIS_ASSERT(index < 8);
return &filtersModrmReg[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MODRM_RM:
ZYDIS_ASSERT(index < 8);
return &filtersModrmRm[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX:
ZYDIS_ASSERT(index < 5);
return &filtersMandatoryPrefix[parent->value][index];
case ZYDIS_NODETYPE_FILTER_OPERAND_SIZE:
ZYDIS_ASSERT(index < 3);
return &filtersOperandSize[parent->value][index];
case ZYDIS_NODETYPE_FILTER_ADDRESS_SIZE:
ZYDIS_ASSERT(index < 3);
return &filtersAddressSize[parent->value][index];
case ZYDIS_NODETYPE_FILTER_VECTOR_LENGTH:
ZYDIS_ASSERT(index < 3);
return &filtersVectorLength[parent->value][index];
case ZYDIS_NODETYPE_FILTER_REX_W:
ZYDIS_ASSERT(index < 2);
return &filtersREXW[parent->value][index];
case ZYDIS_NODETYPE_FILTER_REX_B:
ZYDIS_ASSERT(index < 2);
return &filtersREXB[parent->value][index];
case ZYDIS_NODETYPE_FILTER_EVEX_B:
ZYDIS_ASSERT(index < 2);
return &filtersEVEXB[parent->value][index];
case ZYDIS_NODETYPE_FILTER_MVEX_E:
ZYDIS_ASSERT(index < 2);
return &filtersMVEXE[parent->value][index];
default:
ZYDIS_UNREACHABLE;
}
static const ZydisInstructionTreeNode invalid = { ZYDIS_NODETYPE_INVALID, 0x00000000 };
return &invalid;
}
void ZydisGetInstructionDefinition(const ZydisInstructionTreeNode* node,
const ZydisInstructionDefinition** definition)
{
ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK);
switch ((node->value >> 13) & 0x07)
{
case ZYDIS_INSTRUCTION_ENCODING_DEFAULT:
*definition =
(ZydisInstructionDefinition*)&instructionDefinitionsDEFAULT[node->value & 0x1FFF];
break;
case ZYDIS_INSTRUCTION_ENCODING_3DNOW:
*definition =
(ZydisInstructionDefinition*)&instructionDefinitions3DNOW[node->value & 0x1FFF];
break;
case ZYDIS_INSTRUCTION_ENCODING_XOP:
*definition =
(ZydisInstructionDefinition*)&instructionDefinitionsXOP[node->value & 0x1FFF];
break;
case ZYDIS_INSTRUCTION_ENCODING_VEX:
*definition =
(ZydisInstructionDefinition*)&instructionDefinitionsVEX[node->value & 0x1FFF];
break;
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
*definition =
(ZydisInstructionDefinition*)&instructionDefinitionsEVEX[node->value & 0x1FFF];
break;
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
*definition =
(ZydisInstructionDefinition*)&instructionDefinitionsMVEX[node->value & 0x1FFF];
break;
default:
ZYDIS_UNREACHABLE;
}
}
void ZydisGetOptionalInstructionParts(const ZydisInstructionTreeNode* node,
const ZydisInstructionParts** info)
{
ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK);
uint8_t class = (node->type) & 0x7F;
ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(instructionClassMap));
*info = &instructionClassMap[class];
}
uint8_t ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition,
const ZydisOperandDefinition** operands)
{
if (definition->operandCount == 0)
{
*operands = NULL;
return 0;
}
ZYDIS_ASSERT(definition->operandReference != 0xFFFF);
*operands = &operandDefinitions[definition->operandReference];
return definition->operandCount;
}
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -30,10 +30,7 @@
/* Mnemonic strings */ /* Mnemonic strings */
/* ============================================================================================== */ /* ============================================================================================== */
static const char* mnemonicStrings[] =
{
#include <Zydis/Internal/MnemonicStrings.inc> #include <Zydis/Internal/MnemonicStrings.inc>
};
/* ============================================================================================== */ /* ============================================================================================== */
/* Exported functions */ /* Exported functions */
@ -41,7 +38,7 @@ static const char* mnemonicStrings[] =
const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic) const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic)
{ {
if (mnemonic > (sizeof(mnemonicStrings) / sizeof(mnemonicStrings[0])) - 1) if (mnemonic > ZYDIS_ARRAY_SIZE(mnemonicStrings) - 1)
{ {
return NULL; return NULL;
} }

View File

@ -66,16 +66,16 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
{ {
*address = *address =
(uint64_t)((int64_t)info->instrPointer + info->length + operand->imm.value.sqword); (uint64_t)((int64_t)info->instrPointer + info->length + operand->imm.value.sqword);
switch (info->mode) switch (info->machineMode)
{ {
case ZYDIS_OPERATING_MODE_16BIT: case 16:
case ZYDIS_OPERATING_MODE_32BIT: case 32:
if (operand->size == 16) if (operand->size == 16)
{ {
*address &= 0xFFFF; *address &= 0xFFFF;
} }
break; break;
case ZYDIS_OPERATING_MODE_64BIT: case 64:
break; break;
default: default:
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;