# Conflicts:
#	CMakeLists.txt
This commit is contained in:
Joel Höner 2017-07-06 08:17:38 +02:00
commit 610d08960b
27 changed files with 26085 additions and 12407 deletions

View File

@ -81,23 +81,26 @@ endif ()
target_sources("Zydis" target_sources("Zydis"
PUBLIC PUBLIC
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/CommonTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Decoder.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Decoder.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/DecoderTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Defines.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Defines.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/DecoderTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Mnemonic.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Mnemonic.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/SharedTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Types.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Utils.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Utils.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h"
PRIVATE PRIVATE
"src/InstructionTable.h" "src/DecoderData.h"
"src/SharedData.h"
"src/Decoder.c" "src/Decoder.c"
"src/DecoderData.c"
"src/Formatter.c" "src/Formatter.c"
"src/InstructionTable.c"
"src/Mnemonic.c" "src/Mnemonic.c"
"src/Register.c" "src/Register.c"
"src/SharedData.c"
"src/Utils.c" "src/Utils.c"
"src/Zydis.c") "src/Zydis.c")
@ -107,8 +110,12 @@ endif ()
if (ZYDIS_FEATURE_ENCODER) if (ZYDIS_FEATURE_ENCODER)
target_sources("Zydis" target_sources("Zydis"
PUBLIC "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Encoder.h" PUBLIC
PRIVATE "src/Encoder.c") "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Encoder.h"
PRIVATE
"src/EncoderData.h"
"src/Encoder.c"
"src/EncoderData.c")
endif () endif ()
# TODO: Install CMake config. # TODO: Install CMake config.

View File

@ -1,5 +1,5 @@
# Zyan Disassembler Engine (Zydis) # Zyan Disassembler Engine (Zydis)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Gitter](https://badges.gitter.im/zyantific/zyan-disassembler-engine.svg)](https://gitter.im/zyantific/zyan-disassembler-engine?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge)
Fast and lightweight x86/x86-64 disassembler library. Fast and lightweight x86/x86-64 disassembler library.

View File

@ -29,8 +29,8 @@
* @brief Includes and defines some default datatypes. * @brief Includes and defines some default datatypes.
*/ */
#ifndef ZYDIS_TYPES_H #ifndef ZYDIS_COMMONTYPES_H
#define ZYDIS_TYPES_H #define ZYDIS_COMMONTYPES_H
/* ============================================================================================== */ /* ============================================================================================== */
/* Integral types */ /* Integral types */
@ -68,4 +68,4 @@ typedef uint8_t ZydisBool;
} }
#endif #endif
#endif /* ZYDIS_TYPES_H */ #endif /* ZYDIS_COMMONTYPES_H */

View File

@ -27,10 +27,10 @@
#ifndef ZYDIS_DECODER_H #ifndef ZYDIS_DECODER_H
#define ZYDIS_DECODER_H #define ZYDIS_DECODER_H
#include <Zydis/Defines.h> #include <Zydis/CommonTypes.h>
#include <Zydis/Types.h>
#include <Zydis/Status.h>
#include <Zydis/DecoderTypes.h> #include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h>
#include <Zydis/Status.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -50,26 +50,29 @@ typedef uint32_t ZydisDecodeGranularity;
*/ */
enum ZydisDecodeGranularities enum ZydisDecodeGranularities
{ {
/**
* @brief Defaults to `ZYDIS_DECODE_GRANULARITY_FULL`.
*/
ZYDIS_DECODE_GRANULARITY_DEFAULT, ZYDIS_DECODE_GRANULARITY_DEFAULT,
/** /**
* @brief Minimal instruction decoding without semantic analysis. * @brief Minimal instruction decoding without semantic analysis.
* *
* This mode should be sufficient, if you plan to analyse code for pure relocation purposes, * This mode provides access to the mnemonic, the instruction-length, the effective
* as it gives you access to the mnemonic, the instruction-length, displacements, immediates * operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`)
* and the `ZYDIS_ATTRIB_IS_RELATIVE` attribute. * 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 * Operands, most attributes and other specific information (like AVX info) are not
* accessible in this mode. * accessible in this mode.
*/ */
ZYDIS_DECODE_GRANULARITY_MINIMAL, ZYDIS_DECODE_GRANULARITY_MINIMAL,
/** /**
* @brief Full physical and semantical instruction-decoding. * @brief Full physical and semantic instruction-decoding.
*/ */
ZYDIS_DECODE_GRANULARITY_FULL ZYDIS_DECODE_GRANULARITY_FULL
}; };
/** /**
* @brief Defines the @c ZydisDecoder datatype. * @brief Defines the @c ZydisDecoder struct.
*/ */
typedef struct ZydisDecoder_ typedef struct ZydisDecoder_
{ {

View File

@ -32,224 +32,18 @@
#ifndef ZYDIS_INSTRUCTIONINFO_H #ifndef ZYDIS_INSTRUCTIONINFO_H
#define ZYDIS_INSTRUCTIONINFO_H #define ZYDIS_INSTRUCTIONINFO_H
#include <Zydis/Types.h> #include <Zydis/CommonTypes.h>
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
#include <Zydis/Register.h> #include <Zydis/Register.h>
#include <Zydis/SharedTypes.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* ============================================================================================== */ /* ============================================================================================== */
/* Macros */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Constants */
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_MAX_INSTRUCTION_LENGTH 15
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Operand info */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Operand type */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandType datatype.
*/
typedef uint8_t ZydisOperandType;
/**
* @brief Values that represent operand-types.
*/
enum ZydisOperandTypes
{
/**
* @brief The operand is not used.
*/
ZYDIS_OPERAND_TYPE_UNUSED,
/**
* @brief The operand is a register operand.
*/
ZYDIS_OPERAND_TYPE_REGISTER,
/**
* @brief The operand is a memory operand.
*/
ZYDIS_OPERAND_TYPE_MEMORY,
/**
* @brief The operand is a pointer operand with a segment:offset lvalue.
*/
ZYDIS_OPERAND_TYPE_POINTER,
/**
* @brief The operand is an immediate operand.
*/
ZYDIS_OPERAND_TYPE_IMMEDIATE
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand encoding */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandEncoding datatype.
*/
typedef uint8_t ZydisOperandEncoding;
/**
* @brief Values that represent operand-encodings.
*/
enum ZydisOperandEncodings
{
ZYDIS_OPERAND_ENCODING_NONE,
ZYDIS_OPERAND_ENCODING_MODRM_REG,
ZYDIS_OPERAND_ENCODING_MODRM_RM,
ZYDIS_OPERAND_ENCODING_OPCODE,
ZYDIS_OPERAND_ENCODING_NDSNDD,
ZYDIS_OPERAND_ENCODING_IS4,
ZYDIS_OPERAND_ENCODING_MASK,
ZYDIS_OPERAND_ENCODING_DISP8,
ZYDIS_OPERAND_ENCODING_DISP16,
ZYDIS_OPERAND_ENCODING_DISP32,
ZYDIS_OPERAND_ENCODING_DISP64,
ZYDIS_OPERAND_ENCODING_DISP16_32_64,
ZYDIS_OPERAND_ENCODING_DISP32_32_64,
ZYDIS_OPERAND_ENCODING_DISP16_32_32,
ZYDIS_OPERAND_ENCODING_UIMM8,
ZYDIS_OPERAND_ENCODING_UIMM16,
ZYDIS_OPERAND_ENCODING_UIMM32,
ZYDIS_OPERAND_ENCODING_UIMM64,
ZYDIS_OPERAND_ENCODING_UIMM16_32_64,
ZYDIS_OPERAND_ENCODING_UIMM32_32_64,
ZYDIS_OPERAND_ENCODING_UIMM16_32_32,
ZYDIS_OPERAND_ENCODING_SIMM8,
ZYDIS_OPERAND_ENCODING_SIMM16,
ZYDIS_OPERAND_ENCODING_SIMM32,
ZYDIS_OPERAND_ENCODING_SIMM64,
ZYDIS_OPERAND_ENCODING_SIMM16_32_64,
ZYDIS_OPERAND_ENCODING_SIMM32_32_64,
ZYDIS_OPERAND_ENCODING_SIMM16_32_32,
ZYDIS_OPERAND_ENCODING_JIMM8,
ZYDIS_OPERAND_ENCODING_JIMM16,
ZYDIS_OPERAND_ENCODING_JIMM32,
ZYDIS_OPERAND_ENCODING_JIMM64,
ZYDIS_OPERAND_ENCODING_JIMM16_32_64,
ZYDIS_OPERAND_ENCODING_JIMM32_32_64,
ZYDIS_OPERAND_ENCODING_JIMM16_32_32
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand visibility */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandVisibility datatype.
*/
typedef uint8_t ZydisOperandVisibility;
/**
* @brief Values that represent operand-visibilities.
*/
enum ZydisOperandVisibilities
{
ZYDIS_OPERAND_VISIBILITY_INVALID,
/**
* @brief The operand is explicitly encoded in the instruction.
*/
ZYDIS_OPERAND_VISIBILITY_EXPLICIT,
/**
* @brief The operand is part of the opcode, but listed as an operand.
*/
ZYDIS_OPERAND_VISIBILITY_IMPLICIT,
/**
* @brief The operand is part of the opcode, and not typically listed as an operand.
*/
ZYDIS_OPERAND_VISIBILITY_HIDDEN
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand action */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandAction datatype.
*/
typedef uint8_t ZydisOperandAction;
/**
* @brief Values that represent operand-actions.
*/
enum ZydisOperandActions
{
ZYDIS_OPERAND_ACTION_INVALID,
/**
* @brief The operand is read by the instruction.
*/
ZYDIS_OPERAND_ACTION_READ,
/**
* @brief The operand is written by the instruction (must write).
*/
ZYDIS_OPERAND_ACTION_WRITE,
/**
* @brief The operand is read and written by the instruction (must write).
*/
ZYDIS_OPERAND_ACTION_READWRITE,
/**
* @brief The operand is conditionally read by the instruction.
*/
ZYDIS_OPERAND_ACTION_CONDREAD,
/**
* @brief The operand is conditionally written by the instruction (may write).
*/
ZYDIS_OPERAND_ACTION_CONDWRITE,
/**
* @brief The operand is read and conditionally written by the instruction (may write).
*/
ZYDIS_OPERAND_ACTION_READ_CONDWRITE,
/**
* @brief The operand is written and conditionally read by the instruction (must write).
*/
ZYDIS_OPERAND_ACTION_CONDREAD_WRITE,
};
/* ---------------------------------------------------------------------------------------------- */
/* Elements */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisElementType datatype.
*/
typedef uint8_t ZydisElementType;
/**
* @brief Values that represent element-types.
*/
enum ZydisElementTypes
{
ZYDIS_ELEMENT_TYPE_INVALID,
ZYDIS_ELEMENT_TYPE_STRUCT,
ZYDIS_ELEMENT_TYPE_UINT,
ZYDIS_ELEMENT_TYPE_INT,
ZYDIS_ELEMENT_TYPE_FLOAT16,
ZYDIS_ELEMENT_TYPE_FLOAT32,
ZYDIS_ELEMENT_TYPE_FLOAT64,
ZYDIS_ELEMENT_TYPE_FLOAT80,
ZYDIS_ELEMENT_TYPE_LONGBCD
};
/**
* @brief Defines the @c ZydisElementSize datatype.
*/
typedef uint16_t ZydisElementSize;
/* ---------------------------------------------------------------------------------------------- */
/* Decoded operand */ /* Decoded operand */
/* ---------------------------------------------------------------------------------------------- */ /* ============================================================================================== */
/** /**
* @brief Defines the @c ZydisDecodedOperand struct. * @brief Defines the @c ZydisDecodedOperand struct.
@ -370,134 +164,9 @@ typedef struct ZydisDecodedOperand_
} ZydisDecodedOperand; } ZydisDecodedOperand;
/* ============================================================================================== */ /* ============================================================================================== */
/* Instruction info */ /* Decoded instruction */
/* ============================================================================================== */ /* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Machine mode */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisMachineMode datatype.
*/
typedef uint8_t ZydisMachineMode;
/**
* @brief Values that represent machine modes.
*/
enum ZydisMachineModes
{
ZYDIS_MACHINE_MODE_INVALID = 0,
/**
* @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
};
/* ---------------------------------------------------------------------------------------------- */
/* Instruction encoding */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisInstructionEncoding datatype.
*/
typedef uint8_t ZydisInstructionEncoding;
/**
* @brief Values that represent instruction-encodings.
*/
enum ZydisInstructionEncodings
{
/**
* @brief The instruction uses the default encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_DEFAULT = 0x00,
/**
* @brief The instruction uses the AMD 3DNow-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_3DNOW = 0x01,
/**
* @brief The instruction uses the AMD XOP-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_XOP = 0x02,
/**
* @brief The instruction uses the VEX-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_VEX = 0x03,
/**
* @brief The instruction uses the EVEX-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_EVEX = 0x04,
/**
* @brief The instruction uses the MVEX-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_MVEX = 0x05
};
/* ---------------------------------------------------------------------------------------------- */
/* Opcode map */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOpcodeMap map.
*/
typedef uint8_t ZydisOpcodeMap;
/**
* @brief Values that represent opcode-maps.
*/
enum ZydisOpcodeMaps
{
ZYDIS_OPCODE_MAP_DEFAULT = 0x00,
ZYDIS_OPCODE_MAP_EX0 = 0x01,
ZYDIS_OPCODE_MAP_0F = 0x02,
ZYDIS_OPCODE_MAP_0F38 = 0x03,
ZYDIS_OPCODE_MAP_0F3A = 0x04,
ZYDIS_OPCODE_MAP_XOP8 = 0x05,
ZYDIS_OPCODE_MAP_XOP9 = 0x06,
ZYDIS_OPCODE_MAP_XOPA = 0x07
};
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Instruction attributes */ /* Instruction attributes */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -509,8 +178,6 @@ typedef uint64_t ZydisInstructionAttributes;
// TODO: Update values // TODO: Update values
// TODO: Add IsAtomic
/** /**
* @brief The instruction has the ModRM byte. * @brief The instruction has the ModRM byte.
*/ */
@ -885,7 +552,7 @@ typedef struct ZydisDecodedInstruction_
/** /**
* @brief The instruction-mnemonic. * @brief The instruction-mnemonic.
*/ */
ZydisInstructionMnemonic mnemonic; ZydisMnemonic mnemonic;
/** /**
* @brief The length of the decoded instruction. * @brief The length of the decoded instruction.
*/ */

View File

@ -137,6 +137,14 @@
/* Utils */ /* Utils */
/* ============================================================================================== */ /* ============================================================================================== */
/**
* @brief Declares a bitfield.
*/
#define ZYDIS_BITFIELD(x) : x
/**
* @brief Calculates the size of an array.
*/
#define ZYDIS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) #define ZYDIS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -27,9 +27,9 @@
#ifndef ZYDIS_FORMATTER_H #ifndef ZYDIS_FORMATTER_H
#define ZYDIS_FORMATTER_H #define ZYDIS_FORMATTER_H
#include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#include <Zydis/DecoderTypes.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -277,6 +277,26 @@ enum ZydisFormatterHookTypes
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisDecoratorType datatype.
*/
typedef uint8_t ZydisDecoratorType;
/**
* @brief Values that represent decorator-types.
*/
enum ZydisDecoratorTypes
{
ZYDIS_DECORATOR_TYPE_INVALID,
ZYDIS_DECORATOR_TYPE_MASK,
ZYDIS_DECORATOR_TYPE_BROADCAST,
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL,
ZYDIS_DECORATOR_TYPE_SAE,
ZYDIS_DECORATOR_TYPE_SWIZZLE,
ZYDIS_DECORATOR_TYPE_CONVERSION,
ZYDIS_DECORATOR_TYPE_EVICTION_HINT
};
typedef struct ZydisFormatter_ ZydisFormatter; typedef struct ZydisFormatter_ ZydisFormatter;
/** /**
@ -373,6 +393,32 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, uint64_t address); ZydisDecodedOperand* operand, uint64_t address);
/**
* @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer.
*
* @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.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param type The decorator type.
* @param mask The embedded-mask register (`ZYDIS_DECORATOR_TYPE_MASK` only).
*
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail.
*
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
* number of chars written.
*
* Returning @c ZYDIS_STATUS_SUCCESS without increasing the buffer-pointer is valid and will cause
* the formatter to omit the current decorator.
*
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type.
*/
typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, ZydisDecoratorType type, ZydisRegister mask);
/** /**
* @brief Defines the @c ZydisFormatter struct. * @brief Defines the @c ZydisFormatter struct.
*/ */
@ -393,15 +439,10 @@ struct ZydisFormatter_
ZydisFormatterFormatOperandFunc funcFormatOperandImm; ZydisFormatterFormatOperandFunc funcFormatOperandImm;
ZydisFormatterFormatOperandFunc funcPrintOperandSize; ZydisFormatterFormatOperandFunc funcPrintOperandSize;
ZydisFormatterFormatOperandFunc funcPrintSegment; ZydisFormatterFormatOperandFunc funcPrintSegment;
ZydisFormatterFormatOperandFunc funcPrintDecorator; ZydisFormatterFormatDecoratorFunc funcPrintDecorator;
ZydisFormatterFormatAddressFunc funcPrintAddress; ZydisFormatterFormatAddressFunc funcPrintAddress;
ZydisFormatterFormatOperandFunc funcPrintDisplacement; ZydisFormatterFormatOperandFunc funcPrintDisplacement;
ZydisFormatterFormatOperandFunc funcPrintImmediate; ZydisFormatterFormatOperandFunc funcPrintImmediate;
const char* prefixHEX;
const char* prefixOCT;
const char* delimMnemonic;
const char* delimOperands;
const char* fmtDecorator; // TODO:
}; };
/* ============================================================================================== */ /* ============================================================================================== */
@ -435,13 +476,18 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, ZydisFo
ZydisFormatterImmediateFormat immmediateFormat); ZydisFormatterImmediateFormat immmediateFormat);
/** /**
* @brief TODO: * @brief Replaces a formatter function with a custom callback and/or retrieves the currently
* used function.
* *
* @param formatter A pointer to the @c ZydisFormatter instance. * @param formatter A pointer to the @c ZydisFormatter instance.
* @param hook The formatter hook-type. * @param hook The formatter hook-type.
* @param callback TODO: In Out * @param callback A pointer to a variable that contains the pointer of the callback function
* and receives the pointer of the currently used function.
* *
* @return A zydis status code. * @return A zydis status code.
*
* Call this function with `callback` pointing to a `NULL` value to retrieve the currently used
* function without replacing it.
*/ */
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter,
ZydisFormatterHookType hook, const void** callback); ZydisFormatterHookType hook, const void** callback);

View File

@ -28,7 +28,7 @@
#define ZYDIS_MNEMONIC_H #define ZYDIS_MNEMONIC_H
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h> #include <Zydis/CommonTypes.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -39,9 +39,9 @@ extern "C" {
/* ============================================================================================== */ /* ============================================================================================== */
/** /**
* @brief Defines the @c ZydisInstructionMnemonic datatype. * @brief Defines the @c ZydisMnemonic datatype.
*/ */
typedef uint16_t ZydisInstructionMnemonic; typedef uint16_t ZydisMnemonic;
#include <Zydis/Generated/MnemonicDefines.h> #include <Zydis/Generated/MnemonicDefines.h>
@ -56,7 +56,7 @@ typedef uint16_t ZydisInstructionMnemonic;
* *
* @return The instruction mnemonic string or @c NULL, if an invalid mnemonic was passed. * @return The instruction mnemonic string or @c NULL, if an invalid mnemonic was passed.
*/ */
ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic); ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic);
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -28,7 +28,7 @@
#define ZYDIS_REGISTER_H #define ZYDIS_REGISTER_H
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h> #include <Zydis/CommonTypes.h>
#include <Zydis/Status.h> #include <Zydis/Status.h>
#ifdef __cplusplus #ifdef __cplusplus

382
include/Zydis/SharedTypes.h Normal file
View File

@ -0,0 +1,382 @@
/***************************************************************************************************
Zyan Disassembler Library (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.
***************************************************************************************************/
/**
* @file
* @brief Defines decoder/encoder-shared macros and types.
*/
#ifndef ZYDIS_SHAREDTYPES_H
#define ZYDIS_SHAREDTYPES_H
#include <Zydis/CommonTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ============================================================================================== */
/* Macros */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Constants */
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_MAX_INSTRUCTION_LENGTH 15
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Machine mode */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisMachineMode datatype.
*/
typedef uint8_t ZydisMachineMode;
/**
* @brief Values that represent machine modes.
*/
enum ZydisMachineModes
{
ZYDIS_MACHINE_MODE_INVALID = 0,
/**
* @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
};
/* ---------------------------------------------------------------------------------------------- */
/* Element types */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisElementType datatype.
*/
typedef uint8_t ZydisElementType;
/**
* @brief Values that represent element-types.
*/
enum ZydisElementTypes
{
ZYDIS_ELEMENT_TYPE_INVALID,
ZYDIS_ELEMENT_TYPE_STRUCT,
ZYDIS_ELEMENT_TYPE_UINT,
ZYDIS_ELEMENT_TYPE_INT,
ZYDIS_ELEMENT_TYPE_FLOAT16,
ZYDIS_ELEMENT_TYPE_FLOAT32,
ZYDIS_ELEMENT_TYPE_FLOAT64,
ZYDIS_ELEMENT_TYPE_FLOAT80,
ZYDIS_ELEMENT_TYPE_LONGBCD
};
/**
* @brief Defines the @c ZydisElementSize datatype.
*/
typedef uint16_t ZydisElementSize;
/* ---------------------------------------------------------------------------------------------- */
/* Operand type */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandType datatype.
*/
typedef uint8_t ZydisOperandType;
/**
* @brief Values that represent operand-types.
*/
enum ZydisOperandTypes
{
/**
* @brief The operand is not used.
*/
ZYDIS_OPERAND_TYPE_UNUSED,
/**
* @brief The operand is a register operand.
*/
ZYDIS_OPERAND_TYPE_REGISTER,
/**
* @brief The operand is a memory operand.
*/
ZYDIS_OPERAND_TYPE_MEMORY,
/**
* @brief The operand is a pointer operand with a segment:offset lvalue.
*/
ZYDIS_OPERAND_TYPE_POINTER,
/**
* @brief The operand is an immediate operand.
*/
ZYDIS_OPERAND_TYPE_IMMEDIATE
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand encoding */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandEncoding datatype.
*/
typedef uint8_t ZydisOperandEncoding;
/**
* @brief Values that represent operand-encodings.
*/
enum ZydisOperandEncodings
{
ZYDIS_OPERAND_ENCODING_NONE,
ZYDIS_OPERAND_ENCODING_MODRM_REG,
ZYDIS_OPERAND_ENCODING_MODRM_RM,
ZYDIS_OPERAND_ENCODING_OPCODE,
ZYDIS_OPERAND_ENCODING_NDSNDD,
ZYDIS_OPERAND_ENCODING_IS4,
ZYDIS_OPERAND_ENCODING_MASK,
ZYDIS_OPERAND_ENCODING_DISP8,
ZYDIS_OPERAND_ENCODING_DISP16,
ZYDIS_OPERAND_ENCODING_DISP32,
ZYDIS_OPERAND_ENCODING_DISP64,
ZYDIS_OPERAND_ENCODING_DISP16_32_64,
ZYDIS_OPERAND_ENCODING_DISP32_32_64,
ZYDIS_OPERAND_ENCODING_DISP16_32_32,
ZYDIS_OPERAND_ENCODING_UIMM8,
ZYDIS_OPERAND_ENCODING_UIMM16,
ZYDIS_OPERAND_ENCODING_UIMM32,
ZYDIS_OPERAND_ENCODING_UIMM64,
ZYDIS_OPERAND_ENCODING_UIMM16_32_64,
ZYDIS_OPERAND_ENCODING_UIMM32_32_64,
ZYDIS_OPERAND_ENCODING_UIMM16_32_32,
ZYDIS_OPERAND_ENCODING_SIMM8,
ZYDIS_OPERAND_ENCODING_SIMM16,
ZYDIS_OPERAND_ENCODING_SIMM32,
ZYDIS_OPERAND_ENCODING_SIMM64,
ZYDIS_OPERAND_ENCODING_SIMM16_32_64,
ZYDIS_OPERAND_ENCODING_SIMM32_32_64,
ZYDIS_OPERAND_ENCODING_SIMM16_32_32,
ZYDIS_OPERAND_ENCODING_JIMM8,
ZYDIS_OPERAND_ENCODING_JIMM16,
ZYDIS_OPERAND_ENCODING_JIMM32,
ZYDIS_OPERAND_ENCODING_JIMM64,
ZYDIS_OPERAND_ENCODING_JIMM16_32_64,
ZYDIS_OPERAND_ENCODING_JIMM32_32_64,
ZYDIS_OPERAND_ENCODING_JIMM16_32_32
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand visibility */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandVisibility datatype.
*/
typedef uint8_t ZydisOperandVisibility;
/**
* @brief Values that represent operand-visibilities.
*/
enum ZydisOperandVisibilities
{
ZYDIS_OPERAND_VISIBILITY_INVALID,
/**
* @brief The operand is explicitly encoded in the instruction.
*/
ZYDIS_OPERAND_VISIBILITY_EXPLICIT,
/**
* @brief The operand is part of the opcode, but listed as an operand.
*/
ZYDIS_OPERAND_VISIBILITY_IMPLICIT,
/**
* @brief The operand is part of the opcode, and not typically listed as an operand.
*/
ZYDIS_OPERAND_VISIBILITY_HIDDEN
};
/* ---------------------------------------------------------------------------------------------- */
/* Operand action */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOperandAction datatype.
*/
typedef uint8_t ZydisOperandAction;
/**
* @brief Values that represent operand-actions.
*/
enum ZydisOperandActions
{
ZYDIS_OPERAND_ACTION_INVALID,
/**
* @brief The operand is read by the instruction.
*/
ZYDIS_OPERAND_ACTION_READ,
/**
* @brief The operand is written by the instruction (must write).
*/
ZYDIS_OPERAND_ACTION_WRITE,
/**
* @brief The operand is read and written by the instruction (must write).
*/
ZYDIS_OPERAND_ACTION_READWRITE,
/**
* @brief The operand is conditionally read by the instruction.
*/
ZYDIS_OPERAND_ACTION_CONDREAD,
/**
* @brief The operand is conditionally written by the instruction (may write).
*/
ZYDIS_OPERAND_ACTION_CONDWRITE,
/**
* @brief The operand is read and conditionally written by the instruction (may write).
*/
ZYDIS_OPERAND_ACTION_READ_CONDWRITE,
/**
* @brief The operand is written and conditionally read by the instruction (must write).
*/
ZYDIS_OPERAND_ACTION_CONDREAD_WRITE,
};
/* ---------------------------------------------------------------------------------------------- */
/* Instruction encoding */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisInstructionEncoding datatype.
*/
typedef uint8_t ZydisInstructionEncoding;
/**
* @brief Values that represent instruction-encodings.
*/
enum ZydisInstructionEncodings
{
ZYDIS_INSTRUCTION_ENCODING_INVALID,
/**
* @brief The instruction uses the default encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_DEFAULT,
/**
* @brief The instruction uses the AMD 3DNow-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_3DNOW,
/**
* @brief The instruction uses the AMD XOP-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_XOP,
/**
* @brief The instruction uses the VEX-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_VEX,
/**
* @brief The instruction uses the EVEX-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_EVEX,
/**
* @brief The instruction uses the MVEX-encoding.
*/
ZYDIS_INSTRUCTION_ENCODING_MVEX
};
/* ---------------------------------------------------------------------------------------------- */
/* Opcode map */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisOpcodeMap map.
*/
typedef uint8_t ZydisOpcodeMap;
/**
* @brief Values that represent opcode-maps.
*/
enum ZydisOpcodeMaps
{
ZYDIS_OPCODE_MAP_DEFAULT = 0x00,
ZYDIS_OPCODE_MAP_EX0 = 0x01,
ZYDIS_OPCODE_MAP_0F = 0x02,
ZYDIS_OPCODE_MAP_0F38 = 0x03,
ZYDIS_OPCODE_MAP_0F3A = 0x04,
ZYDIS_OPCODE_MAP_XOP8 = 0x05,
ZYDIS_OPCODE_MAP_XOP9 = 0x06,
ZYDIS_OPCODE_MAP_XOPA = 0x07
};
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* ZYDIS_SHAREDTYPES_H */

View File

@ -27,7 +27,7 @@
#ifndef ZYDIS_STATUS_H #ifndef ZYDIS_STATUS_H
#define ZYDIS_STATUS_H #define ZYDIS_STATUS_H
#include <Zydis/Types.h> #include <Zydis/CommonTypes.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -27,14 +27,15 @@
#ifndef ZYDIS_H #ifndef ZYDIS_H
#define ZYDIS_H #define ZYDIS_H
#include <Zydis/CommonTypes.h>
#include <Zydis/Decoder.h>
#include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Types.h> #include <Zydis/Formatter.h>
#include <Zydis/Status.h>
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
#include <Zydis/Register.h> #include <Zydis/Register.h>
#include <Zydis/DecoderTypes.h> #include <Zydis/SharedTypes.h>
#include <Zydis/Decoder.h> #include <Zydis/Status.h>
#include <Zydis/Formatter.h>
#include <Zydis/Utils.h> #include <Zydis/Utils.h>
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -25,9 +25,10 @@
***************************************************************************************************/ ***************************************************************************************************/
#include <string.h> #include <string.h>
#include <Zydis/Status.h>
#include <Zydis/Decoder.h> #include <Zydis/Decoder.h>
#include <InstructionTable.h> #include <Zydis/Status.h>
#include <DecoderData.h>
#include <SharedData.h>
/* ============================================================================================== */ /* ============================================================================================== */
/* Internal enums and types */ /* Internal enums and types */
@ -2026,14 +2027,14 @@ FinalizeOperand:
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Sets prefix-related attributes for the given instruction. * @brief Sets attributes for the given instruction.
* *
* @param context A pointer to the @c ZydisDecoderContext struct. * @param context A pointer to the @c ZydisDecoderContext struct.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param definition A pointer to the @c ZydisInstructionDefinition struct. * @param definition A pointer to the @c ZydisInstructionDefinition struct.
*/ */
static void ZydisSetPrefixRelatedAttributes(ZydisDecoderContext* context, static void ZydisSetAttributes(ZydisDecoderContext* context, ZydisDecodedInstruction* instruction,
ZydisDecodedInstruction* instruction, const ZydisInstructionDefinition* definition) const ZydisInstructionDefinition* definition)
{ {
ZYDIS_ASSERT(context); ZYDIS_ASSERT(context);
ZYDIS_ASSERT(instruction); ZYDIS_ASSERT(instruction);
@ -2046,6 +2047,10 @@ static void ZydisSetPrefixRelatedAttributes(ZydisDecoderContext* context,
const ZydisInstructionDefinitionDEFAULT* def = const ZydisInstructionDefinitionDEFAULT* def =
(const ZydisInstructionDefinitionDEFAULT*)definition; (const ZydisInstructionDefinitionDEFAULT*)definition;
if (def->isPrivileged)
{
instruction->attributes |= ZYDIS_ATTRIB_IS_PRIVILEGED;
}
if (def->acceptsLock) if (def->acceptsLock)
{ {
instruction->attributes |= ZYDIS_ATTRIB_ACCEPTS_LOCK; instruction->attributes |= ZYDIS_ATTRIB_ACCEPTS_LOCK;
@ -3136,20 +3141,20 @@ static ZydisStatus ZydisCollectOptionalPrefixes(ZydisDecoderContext* context,
* @brief Decodes optional instruction parts like the ModRM byte, the SIB byte and additional * @brief Decodes optional instruction parts like the ModRM byte, the SIB byte and additional
* displacements and/or immediate values. * displacements and/or immediate values.
* *
* @param context A pointer to the @c ZydisDecoderContext struct. * @param context A pointer to the @c ZydisDecoderContext struct.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param optionalParts A pointer to the @c ZydisInstructionParts struct. * @param info A pointer to the @c ZydisInstructionEncodingInfo struct.
* *
* @return A zydis status code. * @return A zydis status code.
*/ */
static ZydisStatus ZydisDecodeInstructionPhysical(ZydisDecoderContext* context, static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* context,
ZydisDecodedInstruction* instruction, const ZydisInstructionParts* optionalParts) ZydisDecodedInstruction* instruction, const ZydisInstructionEncodingInfo* info)
{ {
ZYDIS_ASSERT(context); ZYDIS_ASSERT(context);
ZYDIS_ASSERT(instruction); ZYDIS_ASSERT(instruction);
ZYDIS_ASSERT(optionalParts); ZYDIS_ASSERT(info);
if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_MODRM) if (info->flags & ZYDIS_INSTR_ENC_FLAG_HAS_MODRM)
{ {
if (!instruction->raw.modrm.isDecoded) if (!instruction->raw.modrm.isDecoded)
{ {
@ -3159,7 +3164,7 @@ static ZydisStatus ZydisDecodeInstructionPhysical(ZydisDecoderContext* context,
} }
uint8_t hasSIB = 0; uint8_t hasSIB = 0;
uint8_t displacementSize = 0; uint8_t displacementSize = 0;
if (!(optionalParts->flags & ZYDIS_INSTRPART_FLAG_FORCE_REG_FORM)) if (!(info->flags & ZYDIS_INSTR_ENC_FLAG_FORCE_REG_FORM))
{ {
switch (instruction->addressWidth) switch (instruction->addressWidth)
{ {
@ -3231,29 +3236,27 @@ static ZydisStatus ZydisDecodeInstructionPhysical(ZydisDecoderContext* context,
} }
} }
if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_DISP) if (info->flags & ZYDIS_INSTR_ENC_FLAG_HAS_DISP)
{ {
ZYDIS_CHECK(ZydisReadDisplacement( ZYDIS_CHECK(ZydisReadDisplacement(
context, instruction, optionalParts->disp.size[context->easzIndex])); context, instruction, info->disp.size[context->easzIndex]));
} }
if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_IMM0) if (info->flags & ZYDIS_INSTR_ENC_FLAG_HAS_IMM0)
{ {
if (optionalParts->imm[0].isRelative) if (info->imm[0].isRelative)
{ {
instruction->attributes |= ZYDIS_ATTRIB_IS_RELATIVE; instruction->attributes |= ZYDIS_ATTRIB_IS_RELATIVE;
} }
ZYDIS_CHECK(ZydisReadImmediate(context, instruction, 0, ZYDIS_CHECK(ZydisReadImmediate(context, instruction, 0,
optionalParts->imm[0].size[context->eoszIndex], info->imm[0].size[context->eoszIndex], info->imm[0].isSigned, info->imm[0].isRelative));
optionalParts->imm[0].isSigned, optionalParts->imm[0].isRelative));
} }
if (optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_IMM1) if (info->flags & ZYDIS_INSTR_ENC_FLAG_HAS_IMM1)
{ {
ZYDIS_ASSERT(!(optionalParts->flags & ZYDIS_INSTRPART_FLAG_HAS_DISP)); ZYDIS_ASSERT(!(info->flags & ZYDIS_INSTR_ENC_FLAG_HAS_DISP));
ZYDIS_CHECK(ZydisReadImmediate(context, instruction, 1, ZYDIS_CHECK(ZydisReadImmediate(context, instruction, 1,
optionalParts->imm[1].size[context->eoszIndex], info->imm[1].size[context->eoszIndex], info->imm[1].isSigned, info->imm[1].isRelative));
optionalParts->imm[1].isSigned, optionalParts->imm[1].isRelative));
} }
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
@ -4160,7 +4163,7 @@ static ZydisStatus ZydisCheckErrorConditions(ZydisDecoderContext* context,
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Uses the instruction-tree to decode the current instruction. * @brief Uses the decoder-tree to decode the current instruction.
* *
* @param context A pointer to the @c ZydisDecoderContext instance. * @param context A pointer to the @c ZydisDecoderContext instance.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param instruction A pointer to the @c ZydisDecodedInstruction struct.
@ -4173,10 +4176,10 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
ZYDIS_ASSERT(context); ZYDIS_ASSERT(context);
ZYDIS_ASSERT(instruction); ZYDIS_ASSERT(instruction);
// Iterate through the instruction table // Iterate through the decoder tree
const ZydisInstructionTreeNode* node = ZydisInstructionTreeGetRootNode(); const ZydisDecoderTreeNode* node = ZydisDecoderTreeGetRootNode();
const ZydisInstructionTreeNode* temp = NULL; const ZydisDecoderTreeNode* temp = NULL;
ZydisInstructionTreeNodeType nodeType; ZydisDecoderTreeNodeType nodeType;
do do
{ {
nodeType = node->type; nodeType = node->type;
@ -4229,7 +4232,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
break; break;
case ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX: case ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX:
status = ZydisNodeHandlerMandatoryPrefix(context, instruction, &index); status = ZydisNodeHandlerMandatoryPrefix(context, instruction, &index);
temp = ZydisInstructionTreeGetChildNode(node, 0); temp = ZydisDecoderTreeGetChildNode(node, 0);
// TODO: Return to this point, if index == 0 contains a value and the previous path // TODO: Return to this point, if index == 0 contains a value and the previous path
// TODO: was not successfull // TODO: was not successfull
// TODO: Restore consumed prefix // TODO: Restore consumed prefix
@ -4262,30 +4265,31 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
if (nodeType & ZYDIS_NODETYPE_DEFINITION_MASK) if (nodeType & ZYDIS_NODETYPE_DEFINITION_MASK)
{ {
const ZydisInstructionDefinition* definition; const ZydisInstructionDefinition* definition;
ZydisGetInstructionDefinition(node, &definition); ZydisGetInstructionDefinition(instruction->encoding, node->value, &definition);
ZydisSetEffectiveOperandSize(context, instruction, definition); ZydisSetEffectiveOperandSize(context, instruction, definition);
ZydisSetEffectiveAddressWidth(context, instruction); ZydisSetEffectiveAddressWidth(context, instruction);
const ZydisInstructionParts* optionalParts; const ZydisInstructionEncodingInfo* info;
ZydisGetOptionalInstructionParts(node, &optionalParts); ZydisGetInstructionEncodingInfo(node, &info);
ZYDIS_CHECK(ZydisDecodeInstructionPhysical(context, instruction, optionalParts)); ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, instruction, info));
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW) if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW)
{ {
// Get actual 3dnow opcode and definition // Get actual 3dnow opcode and definition
ZYDIS_CHECK(ZydisInputNext(context, instruction, &instruction->opcode)); ZYDIS_CHECK(ZydisInputNext(context, instruction, &instruction->opcode));
node = ZydisInstructionTreeGetRootNode(); node = ZydisDecoderTreeGetRootNode();
node = ZydisInstructionTreeGetChildNode(node, 0x0F); node = ZydisDecoderTreeGetChildNode(node, 0x0F);
node = ZydisInstructionTreeGetChildNode(node, 0x0F); node = ZydisDecoderTreeGetChildNode(node, 0x0F);
node = ZydisInstructionTreeGetChildNode(node, instruction->opcode); node = ZydisDecoderTreeGetChildNode(node, instruction->opcode);
if (node->type == ZYDIS_NODETYPE_INVALID) if (node->type == ZYDIS_NODETYPE_INVALID)
{ {
return ZYDIS_STATUS_DECODING_ERROR; return ZYDIS_STATUS_DECODING_ERROR;
} }
ZYDIS_ASSERT(node->type == ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT); ZYDIS_ASSERT(node->type == ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT);
node = ZydisInstructionTreeGetChildNode( node = ZydisDecoderTreeGetChildNode(
node, (instruction->raw.modrm.mod == 0x3) ? 0 : 1); node, (instruction->raw.modrm.mod == 0x3) ? 0 : 1);
ZydisGetInstructionDefinition(node, &definition); ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK);
ZydisGetInstructionDefinition(instruction->encoding, node->value, &definition);
} }
ZYDIS_CHECK(ZydisCheckErrorConditions(context, instruction, definition)); ZYDIS_CHECK(ZydisCheckErrorConditions(context, instruction, definition));
@ -4294,7 +4298,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
if (context->decoder->decodeGranularity == ZYDIS_DECODE_GRANULARITY_FULL) if (context->decoder->decodeGranularity == ZYDIS_DECODE_GRANULARITY_FULL)
{ {
ZydisSetPrefixRelatedAttributes(context, instruction, definition); ZydisSetAttributes(context, instruction, definition);
switch (instruction->encoding) switch (instruction->encoding)
{ {
case ZYDIS_INSTRUCTION_ENCODING_XOP: case ZYDIS_INSTRUCTION_ENCODING_XOP:
@ -4314,7 +4318,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
} }
ZYDIS_CHECK(status); ZYDIS_CHECK(status);
node = ZydisInstructionTreeGetChildNode(node, index); node = ZydisDecoderTreeGetChildNode(node, index);
} while((nodeType != ZYDIS_NODETYPE_INVALID) && !(nodeType & ZYDIS_NODETYPE_DEFINITION_MASK)); } while((nodeType != ZYDIS_NODETYPE_INVALID) && !(nodeType & ZYDIS_NODETYPE_DEFINITION_MASK));
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
@ -4390,6 +4394,7 @@ ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* bu
void* userData = instruction->userData; void* userData = instruction->userData;
memset(instruction, 0, sizeof(*instruction)); memset(instruction, 0, sizeof(*instruction));
instruction->machineMode = decoder->machineMode; instruction->machineMode = decoder->machineMode;
instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT;
instruction->instrAddress = instructionPointer; instruction->instrAddress = instructionPointer;
instruction->userData = userData; instruction->userData = userData;

View File

@ -24,8 +24,7 @@
***************************************************************************************************/ ***************************************************************************************************/
#include <assert.h> #include <DecoderData.h>
#include <InstructionTable.h>
/* ============================================================================================== */ /* ============================================================================================== */
/* Data tables */ /* Data tables */
@ -44,7 +43,7 @@
* 2 = xop9 * 2 = xop9
* 3 = xopA * 3 = xopA
*/ */
extern const ZydisInstructionTreeNode filtersXOP[][4]; extern const ZydisDecoderTreeNode filtersXOP[][4];
/** /**
* @brief Contains all VEX-map filters. * @brief Contains all VEX-map filters.
@ -68,7 +67,7 @@ extern const ZydisInstructionTreeNode filtersXOP[][4];
* 0F = F2_0F38 * 0F = F2_0F38
* 10 = F2_0F3A * 10 = F2_0F3A
*/ */
extern const ZydisInstructionTreeNode filtersVEX[][17]; extern const ZydisDecoderTreeNode filtersVEX[][17];
/** /**
* @brief Contains all EVEX/MVEX-map filters. * @brief Contains all EVEX/MVEX-map filters.
@ -108,14 +107,14 @@ extern const ZydisInstructionTreeNode filtersVEX[][17];
* 1F = MVEX F2_0F38 * 1F = MVEX F2_0F38
* 20 = MVEX F2_0F3A * 20 = MVEX F2_0F3A
*/ */
extern const ZydisInstructionTreeNode filtersEMVEX[][33]; extern const ZydisDecoderTreeNode filtersEMVEX[][33];
/** /**
* @brief Contains all opcode filters. * @brief Contains all opcode filters.
* *
* Indexed by the numeric value of the opcode. * Indexed by the numeric value of the opcode.
*/ */
extern const ZydisInstructionTreeNode filtersOpcode[][256]; extern const ZydisDecoderTreeNode filtersOpcode[][256];
/** /**
* @brief Contains all instruction-mode filters. * @brief Contains all instruction-mode filters.
@ -125,7 +124,7 @@ extern const ZydisInstructionTreeNode filtersOpcode[][256];
* 1 = 32 bit mode * 1 = 32 bit mode
* 2 = 64 bit mode * 2 = 64 bit mode
*/ */
extern const ZydisInstructionTreeNode filtersMode[][3]; extern const ZydisDecoderTreeNode filtersMode[][3];
/** /**
* @brief Contains all compacted instruction-mode filters. * @brief Contains all compacted instruction-mode filters.
@ -134,14 +133,14 @@ extern const ZydisInstructionTreeNode filtersMode[][3];
* 0 = 64 bit mode * 0 = 64 bit mode
* 1 = not 64 bit mode * 1 = not 64 bit mode
*/ */
extern const ZydisInstructionTreeNode filtersModeCompact[][2]; extern const ZydisDecoderTreeNode filtersModeCompact[][2];
/** /**
* @brief Contains all ModRM.mod filters. * @brief Contains all ModRM.mod filters.
* *
* Indexed by the ordinal value of the ModRM.mod field. * Indexed by the ordinal value of the ModRM.mod field.
*/ */
extern const ZydisInstructionTreeNode filtersModrmMod[][4]; extern const ZydisDecoderTreeNode filtersModrmMod[][4];
/** /**
* @brief Contains all compacted ModRM.mod filters. * @brief Contains all compacted ModRM.mod filters.
@ -150,21 +149,21 @@ extern const ZydisInstructionTreeNode filtersModrmMod[][4];
* 0 = [ModRM.mod == 11] = register * 0 = [ModRM.mod == 11] = register
* 1 = [ModRM.mod == !11] = memory * 1 = [ModRM.mod == !11] = memory
*/ */
extern const ZydisInstructionTreeNode filtersModrmModCompact[][2]; extern const ZydisDecoderTreeNode filtersModrmModCompact[][2];
/** /**
* @brief Contains all ModRM.reg filters. * @brief Contains all ModRM.reg filters.
* *
* Indexed by the numeric value of the ModRM.reg field. * Indexed by the numeric value of the ModRM.reg field.
*/ */
extern const ZydisInstructionTreeNode filtersModrmReg[][8]; extern const ZydisDecoderTreeNode filtersModrmReg[][8];
/** /**
* @brief Contains all ModRM.rm filters. * @brief Contains all ModRM.rm filters.
* *
* Indexed by the numeric value of the ModRM.rm field. * Indexed by the numeric value of the ModRM.rm field.
*/ */
extern const ZydisInstructionTreeNode filtersModrmRm[][8]; extern const ZydisDecoderTreeNode filtersModrmRm[][8];
/** /**
* @brief Contains all mandatory-prefix switch tables. * @brief Contains all mandatory-prefix switch tables.
@ -176,7 +175,7 @@ extern const ZydisInstructionTreeNode filtersModrmRm[][8];
* 3 = F3 * 3 = F3
* 4 = F2 * 4 = F2
*/ */
extern const ZydisInstructionTreeNode filtersMandatoryPrefix[][5]; extern const ZydisDecoderTreeNode filtersMandatoryPrefix[][5];
/** /**
* @brief Contains all operand-size filters. * @brief Contains all operand-size filters.
@ -186,7 +185,7 @@ extern const ZydisInstructionTreeNode filtersMandatoryPrefix[][5];
* 1 = 32 bit * 1 = 32 bit
* 2 = 64 bit * 2 = 64 bit
*/ */
extern const ZydisInstructionTreeNode filtersOperandSize[][3]; extern const ZydisDecoderTreeNode filtersOperandSize[][3];
/** /**
* @brief Contains all address-size filters. * @brief Contains all address-size filters.
@ -196,7 +195,7 @@ extern const ZydisInstructionTreeNode filtersOperandSize[][3];
* 1 = 32 bit * 1 = 32 bit
* 2 = 64 bit * 2 = 64 bit
*/ */
extern const ZydisInstructionTreeNode filtersAddressSize[][3]; extern const ZydisDecoderTreeNode filtersAddressSize[][3];
/** /**
* @brief Contains all vector-length filters. * @brief Contains all vector-length filters.
@ -206,98 +205,59 @@ extern const ZydisInstructionTreeNode filtersAddressSize[][3];
* 1 = 256 bit * 1 = 256 bit
* 2 = 512 bit * 2 = 512 bit
*/ */
extern const ZydisInstructionTreeNode filtersVectorLength[][3]; extern const ZydisDecoderTreeNode 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 ZydisInstructionTreeNode filtersREXW[][2]; extern const ZydisDecoderTreeNode filtersREXW[][2];
/** /**
* @brief Contains all REX/VEX/EVEX.B filters. * @brief Contains all REX/VEX/EVEX.B filters.
* *
* Indexed by the numeric value of the REX/VEX/EVEX.B field. * Indexed by the numeric value of the REX/VEX/EVEX.B field.
*/ */
extern const ZydisInstructionTreeNode filtersREXB[][2]; extern const ZydisDecoderTreeNode filtersREXB[][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 ZydisInstructionTreeNode filtersEVEXB[][2]; extern const ZydisDecoderTreeNode filtersEVEXB[][2];
/** /**
* @brief Contains all EVEX.z filters. * @brief Contains all EVEX.z filters.
* *
* Indexed by the numeric value of the EVEX.z field. * Indexed by the numeric value of the EVEX.z field.
*/ */
extern const ZydisInstructionTreeNode filtersEVEXZ[][2]; extern const ZydisDecoderTreeNode filtersEVEXZ[][2];
/** /**
* @brief Contains all MVEX.E filters. * @brief Contains all MVEX.E filters.
* *
* Indexed by the numeric value of the MVEX.E field. * Indexed by the numeric value of the MVEX.E field.
*/ */
extern const ZydisInstructionTreeNode filtersMVEXE[][2]; extern const ZydisDecoderTreeNode filtersMVEXE[][2];
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Contains all operand-definitions.
*/
extern const ZydisOperandDefinition operandDefinitions[];
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Contains all instruction-definitions with @c DEFAULT encoding.
*/
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[];
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Physical instruction encodings */ /* Physical instruction encodings */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
#include <Generated/InstructionClassMap.inc> #include <Generated/PhysicalEncodings.inc>
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Instruction tree */ /* Decoder 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(encoding, instrclass, id) \ #define ZYDIS_DEFINITION(encoding_id, id) \
{ ZYDIS_NODETYPE_DEFINITION_MASK | instrclass, (encoding << 13) | id } { ZYDIS_NODETYPE_DEFINITION_MASK | encoding_id, id }
#include <Generated/InstructionFilters.inc> #include <Generated/InstructionFilters.inc>
@ -306,40 +266,23 @@ extern const ZydisInstructionDefinitionMVEX instructionDefinitionsMVEX[];
#undef ZYDIS_DEFINITION #undef ZYDIS_DEFINITION
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Instruction definitions */
/* ---------------------------------------------------------------------------------------------- */
#include <Generated/InstructionDefinitions.inc>
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* Operand definitions */
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_OPERAND_DEFINITION(type, encoding, access) \
{ type, encoding, access }
#include <Generated/OperandDefinitions.inc>
#undef ZYDIS_OPERAND_DEFINITION
/* ============================================================================================== */ /* ============================================================================================== */
/* Functions */ /* Functions */
/* ============================================================================================== */ /* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Instruction tree */ /* Decoder tree */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
const ZydisInstructionTreeNode* ZydisInstructionTreeGetRootNode() const ZydisDecoderTreeNode* ZydisDecoderTreeGetRootNode()
{ {
static const ZydisInstructionTreeNode root = { ZYDIS_NODETYPE_FILTER_OPCODE, 0x00000000 }; static const ZydisDecoderTreeNode root = { ZYDIS_NODETYPE_FILTER_OPCODE, 0x00000000 };
return &root; return &root;
} }
const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode( const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(const ZydisDecoderTreeNode* parent,
const ZydisInstructionTreeNode* parent, uint16_t index) uint16_t index)
{ {
switch (parent->type) switch (parent->type)
{ {
@ -403,117 +346,17 @@ const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode(
default: default:
ZYDIS_UNREACHABLE; ZYDIS_UNREACHABLE;
} }
static const ZydisInstructionTreeNode invalid = { ZYDIS_NODETYPE_INVALID, 0x00000000 }; static const ZydisDecoderTreeNode invalid = { ZYDIS_NODETYPE_INVALID, 0x00000000 };
return &invalid; return &invalid;
} }
/* ---------------------------------------------------------------------------------------------- */ void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node,
/* Instruction definition */ const ZydisInstructionEncodingInfo** info)
/* ---------------------------------------------------------------------------------------------- */
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); ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK);
uint8_t class = (node->type) & 0x7F; uint8_t class = (node->type) & 0x7F;
ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(instructionClassMap)); ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(physicalEncodings));
*info = &instructionClassMap[class]; *info = &physicalEncodings[class];
} }
/* ---------------------------------------------------------------------------------------------- */
/* Operand definition */
/* ---------------------------------------------------------------------------------------------- */
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;
}
/* ---------------------------------------------------------------------------------------------- */
/* Element info */
/* ---------------------------------------------------------------------------------------------- */
void ZydisGetElementInfo(ZydisInternalElementType element, ZydisElementType* type,
ZydisElementSize* size)
{
static const struct
{
ZydisElementType type;
ZydisElementSize size;
} lookup[21] =
{
{ ZYDIS_ELEMENT_TYPE_INVALID , 0 },
{ ZYDIS_ELEMENT_TYPE_INVALID , 0 },
{ ZYDIS_ELEMENT_TYPE_STRUCT , 0 },
{ ZYDIS_ELEMENT_TYPE_INT , 0 },
{ ZYDIS_ELEMENT_TYPE_UINT , 0 },
{ ZYDIS_ELEMENT_TYPE_INT , 1 },
{ ZYDIS_ELEMENT_TYPE_INT , 8 },
{ ZYDIS_ELEMENT_TYPE_INT , 16 },
{ ZYDIS_ELEMENT_TYPE_INT , 32 },
{ ZYDIS_ELEMENT_TYPE_INT , 64 },
{ ZYDIS_ELEMENT_TYPE_UINT , 8 },
{ ZYDIS_ELEMENT_TYPE_UINT , 16 },
{ ZYDIS_ELEMENT_TYPE_UINT , 32 },
{ ZYDIS_ELEMENT_TYPE_UINT , 64 },
{ ZYDIS_ELEMENT_TYPE_UINT , 128 },
{ ZYDIS_ELEMENT_TYPE_UINT , 256 },
{ ZYDIS_ELEMENT_TYPE_FLOAT16 , 16 },
{ ZYDIS_ELEMENT_TYPE_FLOAT32 , 32 },
{ ZYDIS_ELEMENT_TYPE_FLOAT64 , 64 },
{ ZYDIS_ELEMENT_TYPE_FLOAT80 , 80 },
{ ZYDIS_ELEMENT_TYPE_LONGBCD , 80 }
};
ZYDIS_ASSERT(element < ZYDIS_ARRAY_SIZE(lookup));
*type = lookup[element].type;
*size = lookup[element].size;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */ /* ============================================================================================== */

292
src/DecoderData.h Normal file
View File

@ -0,0 +1,292 @@
/***************************************************************************************************
Zyan Disassembler Library (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.
***************************************************************************************************/
#ifndef ZYDIS_INSTRUCTIONTABLE_H
#define ZYDIS_INSTRUCTIONTABLE_H
#include <Zydis/Defines.h>
#include <Zydis/DecoderTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
// MSVC does not like types other than (un-)signed int for bitfields
#ifdef ZYDIS_MSVC
# pragma warning(push)
# pragma warning(disable:4214)
#endif
#pragma pack(push, 1)
/* ---------------------------------------------------------------------------------------------- */
/* Decoder tree */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisDecoderTreeNodeType datatype.
*/
typedef uint8_t ZydisDecoderTreeNodeType;
/**
* @brief Values that represent zydis decoder tree node types.
*/
enum ZydisDecoderTreeNodeTypes
{
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 EVEX.z filter.
*/
ZYDIS_NODETYPE_FILTER_EVEX_Z = 0x12,
/**
* @brief Reference to an MVEX.E filter.
*/
ZYDIS_NODETYPE_FILTER_MVEX_E = 0x13,
};
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisDecoderTreeNodeValue datatype.
*/
typedef uint16_t ZydisDecoderTreeNodeValue;
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisDecoderTreeNode struct.
*/
typedef struct ZydisDecoderTreeNode_
{
ZydisDecoderTreeNodeType type;
ZydisDecoderTreeNodeValue value;
} ZydisDecoderTreeNode;
/* ---------------------------------------------------------------------------------------------- */
#pragma pack(pop)
#ifdef ZYDIS_MSVC
# pragma warning(pop)
#endif
/* ---------------------------------------------------------------------------------------------- */
/* Physical instruction encoding info */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisInstructionEncodingFlags datatype.
*/
typedef uint8_t ZydisInstructionEncodingFlags;
/**
* @brief The instruction has an optional modrm byte.
*/
#define ZYDIS_INSTR_ENC_FLAG_HAS_MODRM 0x01
/**
* @brief The instruction has an optional displacement value.
*/
#define ZYDIS_INSTR_ENC_FLAG_HAS_DISP 0x02
/**
* @brief The instruction has an optional immediate value.
*/
#define ZYDIS_INSTR_ENC_FLAG_HAS_IMM0 0x04
/**
* @brief The instruction has a second optional immediate value.
*/
#define ZYDIS_INSTR_ENC_FLAG_HAS_IMM1 0x08
/**
* @brief The instruction ignores the value of `modrm.mod` and always assumes `modrm.mod == 3`
* ("reg, reg" - form).
*
* Instructions with this flag can't have a SIB byte or a displacement value.
*/
#define ZYDIS_INSTR_ENC_FLAG_FORCE_REG_FORM 0x10
/**
* @brief Defines the @c ZydisInstructionEncodingInfo struct.
*/
typedef struct ZydisInstructionEncodingInfo_
{
/**
* @brief Contains flags with information about the physical instruction-encoding.
*/
ZydisInstructionEncodingFlags 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];
} ZydisInstructionEncodingInfo;
/* ============================================================================================== */
/* Functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Decoder tree */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Returns the root node of the instruction tree.
*
* @return The root node of the instruction tree.
*/
ZYDIS_NO_EXPORT const ZydisDecoderTreeNode* ZydisDecoderTreeGetRootNode();
/**
* @brief Returns the child node of @c parent specified by @c index.
*
* @param parent The parent node.
* @param index The index of the child node to retrieve.
*
* @return The specified child node.
*/
ZYDIS_NO_EXPORT const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(
const ZydisDecoderTreeNode* parent, uint16_t index);
/**
* @brief Returns information about optional instruction parts (like modrm, displacement or
* immediates) 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 ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node,
const ZydisInstructionEncodingInfo** info);
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* ZYDIS_INSTRUCTIONTABLE_H */

117
src/EncoderData.c Normal file
View File

@ -0,0 +1,117 @@
/***************************************************************************************************
Zyan Disassembler Library (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 <EncoderData.h>
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
// MSVC does not like types other than (un-)signed int for bitfields
#ifdef ZYDIS_MSVC
# pragma warning(push)
# pragma warning(disable:4214)
#endif
#pragma pack(push, 1)
/* ---------------------------------------------------------------------------------------------- */
/* Encodable instructions */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisEncodableInstructions struct.
*/
typedef struct ZydisEncodableInstructions_
{
uint8_t count;
uint16_t reference;
} ZydisEncodableInstructions;
/* ---------------------------------------------------------------------------------------------- */
#pragma pack(pop)
#ifdef ZYDIS_MSVC
# pragma warning(pop)
#endif
/* ============================================================================================== */
/* Data tables */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Forward declarations */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Contains an item with a reference to all encodable instructions for every mnemonic.
*/
extern const ZydisEncodableInstructions mnemonicLookup[];
/**
* @brief Contains the definition-data for all encodable instructions.
*/
extern const ZydisEncodableInstruction encodableInstructions[];
/* ---------------------------------------------------------------------------------------------- */
/* Mnemonic lookup table */
/* ---------------------------------------------------------------------------------------------- */
#include <Generated/EncoderLookup.inc>
/* ---------------------------------------------------------------------------------------------- */
/* Encodable instructions */
/* ---------------------------------------------------------------------------------------------- */
#include <Generated/EncodableInstructions.inc>
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Encodable instructions */
/* ---------------------------------------------------------------------------------------------- */
uint8_t ZydisGetEncodableInstructions(ZydisMnemonic mnemonic,
const ZydisEncodableInstruction** instruction)
{
if (mnemonic >= ZYDIS_ARRAY_SIZE(mnemonicLookup))
{
*instruction = NULL;
return 0;
}
const ZydisEncodableInstructions* descriptor = &mnemonicLookup[mnemonic];
*instruction = &encodableInstructions[descriptor->reference];
return descriptor->count;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */

115
src/EncoderData.h Normal file
View File

@ -0,0 +1,115 @@
/***************************************************************************************************
Zyan Disassembler Library (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.
***************************************************************************************************/
#ifndef ZYDIS_ENCODERDATA_H
#define ZYDIS_ENCODERDATA_H
#include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h>
#include <Zydis/SharedTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
// MSVC does not like types other than (un-)signed int for bitfields
#ifdef ZYDIS_MSVC
# pragma warning(push)
# pragma warning(disable:4214)
#endif
#pragma pack(push, 1)
/* ---------------------------------------------------------------------------------------------- */
/* Encodable instruction */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisEncodableInstruction struct.
*/
typedef struct ZydisEncodableInstruction_
{
ZydisInstructionEncoding encoding ZYDIS_BITFIELD( 3);
uint16_t definitionReference ZYDIS_BITFIELD(13);
struct
{
uint8_t mode ZYDIS_BITFIELD( 2);
uint8_t modrmMod ZYDIS_BITFIELD( 3);
uint8_t modrmReg ZYDIS_BITFIELD( 4);
uint8_t modrmRm ZYDIS_BITFIELD( 4);
uint8_t mandatoryPrefix ZYDIS_BITFIELD( 3);
uint8_t operandSize ZYDIS_BITFIELD( 2);
uint8_t addressSize ZYDIS_BITFIELD( 2);
uint8_t vectorLength ZYDIS_BITFIELD( 2);
uint8_t rexW ZYDIS_BITFIELD( 2);
uint8_t rexB ZYDIS_BITFIELD( 2);
uint8_t evexB ZYDIS_BITFIELD( 2);
uint8_t evexZ ZYDIS_BITFIELD( 2);
uint8_t mvexE ZYDIS_BITFIELD( 2);
} filterIndizes;
} ZydisEncodableInstruction;
/* ---------------------------------------------------------------------------------------------- */
#pragma pack(pop)
#ifdef ZYDIS_MSVC
# pragma warning(pop)
#endif
/* ============================================================================================== */
/* Functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Encodable instructions */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Returns all encodable instructions matching the given `mnemonic`.
*
* @param mnemonic The mnemonic.
* @param instruction A pointer to the variable that receives a pointer to the first
* `ZydisEncodableInstruction` struct.
*
* @return The number of encodable instructions for the given mnemonic.
*/
ZYDIS_NO_EXPORT uint8_t ZydisGetEncodableInstructions(ZydisMnemonic mnemonic,
const ZydisEncodableInstruction** instruction);
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* ZYDIS_ENCODERDATA_H */

View File

@ -251,6 +251,11 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
if ((operand->id == 1) && (operand->encoding == ZYDIS_OPERAND_ENCODING_MASK))
{
return ZYDIS_STATUS_SUCCESS;
}
const char* reg = ZydisRegisterGetString(operand->reg); const char* reg = ZydisRegisterGetString(operand->reg);
if (!reg) if (!reg)
{ {
@ -514,9 +519,11 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
switch (operand->id) switch (operand->id)
{ {
case 0: case 0:
typecast = ((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) || typecast =
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) || ((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(instruction->operands[0].size != instruction->operands[1].size)) ? instruction->operands[0].size : 0; (instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(instruction->operands[0].size != instruction->operands[1].size)) ?
instruction->operands[0].size : 0;
if (!typecast && if (!typecast &&
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) && (instruction->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(instruction->operands[1].reg == ZYDIS_REGISTER_CL)) (instruction->operands[1].reg == ZYDIS_REGISTER_CL))
@ -539,8 +546,9 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
case 1: case 1:
case 2: case 2:
typecast = typecast =
(instruction->operands[operand->id - 1].size != instruction->operands[operand->id].size) ? (instruction->operands[operand->id - 1].size !=
instruction->operands[operand->id].size : 0; instruction->operands[operand->id].size) ?
instruction->operands[operand->id].size : 0;
break; break;
default: default:
break; break;
@ -627,7 +635,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) ZydisDecodedOperand* operand, ZydisDecoratorType type, ZydisRegister mask)
{ {
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
@ -635,194 +643,197 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
} }
const char* bufEnd = *buffer + bufferLen; const char* bufEnd = *buffer + bufferLen;
switch (type)
if (operand->id == 1)
{ {
if ((operand->type == ZYDIS_OPERAND_TYPE_REGISTER) && case ZYDIS_DECORATOR_TYPE_MASK:
(operand->encoding == ZYDIS_OPERAND_ENCODING_MASK) && {
(operand->reg != ZYDIS_REGISTER_K0)) if (mask != ZYDIS_REGISTER_K0)
{ {
const char* reg = ZydisRegisterGetString(operand->reg); const char* reg = ZydisRegisterGetString(mask);
if (!reg) if (!reg)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, ZYDIS_CHECK(ZydisStringBufferAppendFormat(
" {%s}", reg)); buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, " {%s}", reg));
if (instruction->avx.maskMode == ZYDIS_MASK_MODE_ZERO) if (instruction->avx.maskMode == ZYDIS_MASK_MODE_ZERO)
{ {
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
} }
} }
} else break;
{ }
if (instruction->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY) case ZYDIS_DECORATOR_TYPE_BROADCAST:
if (!instruction->avx.broadcast.isStatic)
{ {
if (!instruction->avx.broadcast.isStatic) switch (instruction->avx.broadcast.mode)
{ {
switch (instruction->avx.broadcast.mode) case ZYDIS_BROADCAST_MODE_INVALID:
{
case ZYDIS_BROADCAST_MODE_INVALID:
break;
case ZYDIS_BROADCAST_MODE_1_TO_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break;
case ZYDIS_BROADCAST_MODE_1_TO_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break;
case ZYDIS_BROADCAST_MODE_1_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break;
case ZYDIS_BROADCAST_MODE_1_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break;
case ZYDIS_BROADCAST_MODE_4_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
break;
case ZYDIS_BROADCAST_MODE_4_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
switch (instruction->avx.conversionMode)
{
case ZYDIS_CONVERSION_MODE_INVALID:
break; break;
case ZYDIS_CONVERSION_MODE_FLOAT16: case ZYDIS_BROADCAST_MODE_1_TO_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {float16}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break; break;
case ZYDIS_CONVERSION_MODE_SINT8: case ZYDIS_BROADCAST_MODE_1_TO_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint8}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break; break;
case ZYDIS_CONVERSION_MODE_UINT8: case ZYDIS_BROADCAST_MODE_1_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint8}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break; break;
case ZYDIS_CONVERSION_MODE_SINT16: case ZYDIS_BROADCAST_MODE_1_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint16}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break; break;
case ZYDIS_CONVERSION_MODE_UINT16: case ZYDIS_BROADCAST_MODE_4_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint16}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
break; break;
default: case ZYDIS_BROADCAST_MODE_4_TO_16:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if (instruction->avx.hasEvictionHint)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}")); ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
}
}
if ((operand->id == (instruction->operandCount - 1)) ||
((operand->id != (instruction->operandCount - 1)) &&
(instruction->operands[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)))
{
if (instruction->avx.hasSAE)
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz-sae}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
} else
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
switch (instruction->avx.swizzleMode)
{
case ZYDIS_SWIZZLE_MODE_INVALID:
case ZYDIS_SWIZZLE_MODE_DCBA:
// Nothing to do here
break;
case ZYDIS_SWIZZLE_MODE_CDAB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cdab}"));
break;
case ZYDIS_SWIZZLE_MODE_BADC:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
break;
case ZYDIS_SWIZZLE_MODE_DACB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
break;
case ZYDIS_SWIZZLE_MODE_AAAA:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
break;
case ZYDIS_SWIZZLE_MODE_BBBB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
break;
case ZYDIS_SWIZZLE_MODE_CCCC:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
break;
case ZYDIS_SWIZZLE_MODE_DDDD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
break; break;
default: default:
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
} }
break;
case ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL:
if (instruction->avx.hasSAE)
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru-sae}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz-sae}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
} else
{
switch (instruction->avx.roundingMode)
{
case ZYDIS_ROUNDING_MODE_INVALID:
break;
case ZYDIS_ROUNDING_MODE_RN:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn}"));
break;
case ZYDIS_ROUNDING_MODE_RD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd}"));
break;
case ZYDIS_ROUNDING_MODE_RU:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru}"));
break;
case ZYDIS_ROUNDING_MODE_RZ:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
}
break;
case ZYDIS_DECORATOR_TYPE_SAE:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
break;
case ZYDIS_DECORATOR_TYPE_SWIZZLE:
switch (instruction->avx.swizzleMode)
{
case ZYDIS_SWIZZLE_MODE_INVALID:
case ZYDIS_SWIZZLE_MODE_DCBA:
// Nothing to do here
break;
case ZYDIS_SWIZZLE_MODE_CDAB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cdab}"));
break;
case ZYDIS_SWIZZLE_MODE_BADC:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
break;
case ZYDIS_SWIZZLE_MODE_DACB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
break;
case ZYDIS_SWIZZLE_MODE_AAAA:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
break;
case ZYDIS_SWIZZLE_MODE_BBBB:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
break;
case ZYDIS_SWIZZLE_MODE_CCCC:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
break;
case ZYDIS_SWIZZLE_MODE_DDDD:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
break;
case ZYDIS_DECORATOR_TYPE_CONVERSION:
switch (instruction->avx.conversionMode)
{
case ZYDIS_CONVERSION_MODE_INVALID:
break;
case ZYDIS_CONVERSION_MODE_FLOAT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {float16}"));
break;
case ZYDIS_CONVERSION_MODE_SINT8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint8}"));
break;
case ZYDIS_CONVERSION_MODE_UINT8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint8}"));
break;
case ZYDIS_CONVERSION_MODE_SINT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint16}"));
break;
case ZYDIS_CONVERSION_MODE_UINT16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint16}"));
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
break;
case ZYDIS_DECORATOR_TYPE_EVICTION_HINT:
if (instruction->avx.hasEvictionHint)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}"));
}
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
} }
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
@ -903,8 +914,55 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
{ {
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, if (i == 0)
instruction, &instruction->operands[i])); {
if (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_MASK, instruction->operands[i + 1].reg));
}
} else
{
if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_BROADCAST, ZYDIS_REGISTER_NONE));
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_CONVERSION, ZYDIS_REGISTER_NONE));
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_EVICTION_HINT, ZYDIS_REGISTER_NONE));
}
} else
{
if ((i == (instruction->operandCount - 1)) ||
(instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
{
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SWIZZLE, ZYDIS_REGISTER_NONE));
}
if (instruction->avx.roundingMode)
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, ZYDIS_REGISTER_NONE));
} else
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SAE, ZYDIS_REGISTER_NONE));
}
}
}
}
} }
} }
} }
@ -1079,7 +1137,7 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT
formatter->funcPrintSegment = *(ZydisFormatterFormatOperandFunc*)&temp; formatter->funcPrintSegment = *(ZydisFormatterFormatOperandFunc*)&temp;
break; break;
case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR: case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR:
formatter->funcPrintDecorator = *(ZydisFormatterFormatOperandFunc*)&temp; formatter->funcPrintDecorator = *(ZydisFormatterFormatDecoratorFunc*)&temp;
break; break;
case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS: case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS:
formatter->funcPrintAddress = *(ZydisFormatterFormatAddressFunc*)&temp; formatter->funcPrintAddress = *(ZydisFormatterFormatAddressFunc*)&temp;

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

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,21 @@
static const ZydisInstructionParts instructionClassMap[] = static const ZydisInstructionEncodingInfo physicalEncodings[] =
{ {
/*00*/ { 0, { { 0, 0, 0 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } }, /*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 } } }, /*01*/ { 0 | ZYDIS_INSTR_ENC_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 } } }, /*02*/ { 0 | ZYDIS_INSTR_ENC_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 } } }, /*03*/ { 0 | ZYDIS_INSTR_ENC_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 } } }, /*04*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_MODRM | ZYDIS_INSTR_ENC_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 } } }, /*05*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_MODRM | ZYDIS_INSTR_ENC_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 } } }, /*06*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_MODRM | ZYDIS_INSTR_ENC_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, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } }, /*07*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*08*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 32, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } }, /*08*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 32, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*09*/ { 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 } } }, /*09*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_IMM0 | ZYDIS_INSTR_ENC_FLAG_HAS_IMM1, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 16, 16, 16 }, 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 } } }, /*0A*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_IMM0 | ZYDIS_INSTR_ENC_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 } } }, /*0B*/ { 0 | ZYDIS_INSTR_ENC_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 } } }, /*0C*/ { 0 | ZYDIS_INSTR_ENC_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 } } }, /*0D*/ { 0 | ZYDIS_INSTR_ENC_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 } } }, /*0E*/ { 0 | ZYDIS_INSTR_ENC_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_MODRM | ZYDIS_INSTRPART_FLAG_FORCE_REG_FORM, { { 0, 0, 0 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } }, /*0F*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_MODRM | ZYDIS_INSTR_ENC_FLAG_FORCE_REG_FORM, { { 0, 0, 0 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*10*/ { 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_INSTR_ENC_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 16, 16 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*11*/ { 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 } } } /*11*/ { 0 | ZYDIS_INSTR_ENC_FLAG_HAS_MODRM | ZYDIS_INSTR_ENC_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 32, 32, 32 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } }
}; };

View File

@ -36,7 +36,7 @@
/* Exported functions */ /* Exported functions */
/* ============================================================================================== */ /* ============================================================================================== */
const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic) const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic)
{ {
if (mnemonic > ZYDIS_ARRAY_SIZE(mnemonicStrings) - 1) if (mnemonic > ZYDIS_ARRAY_SIZE(mnemonicStrings) - 1)
{ {

190
src/SharedData.c Normal file
View File

@ -0,0 +1,190 @@
/***************************************************************************************************
Zyan Disassembler Library (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 <SharedData.h>
/* ============================================================================================== */
/* Data tables */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Forward declarations */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Contains all operand-definitions.
*/
extern const ZydisOperandDefinition operandDefinitions[];
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Contains all instruction-definitions with @c DEFAULT encoding.
*/
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[];
/* ---------------------------------------------------------------------------------------------- */
/* Instruction definitions */
/* ---------------------------------------------------------------------------------------------- */
#include <Generated/InstructionDefinitions.inc>
/* ---------------------------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------------------------- */
/* Operand definitions */
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_OPERAND_DEFINITION(type, encoding, access) \
{ type, encoding, access }
#include <Generated/OperandDefinitions.inc>
#undef ZYDIS_OPERAND_DEFINITION
/* ============================================================================================== */
/* Functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Instruction definition */
/* ---------------------------------------------------------------------------------------------- */
void ZydisGetInstructionDefinition(ZydisInstructionEncoding encoding, uint16_t id,
const ZydisInstructionDefinition** definition)
{
switch (encoding)
{
case ZYDIS_INSTRUCTION_ENCODING_DEFAULT:
*definition = (ZydisInstructionDefinition*)&instructionDefinitionsDEFAULT[id];
break;
case ZYDIS_INSTRUCTION_ENCODING_3DNOW:
*definition = (ZydisInstructionDefinition*)&instructionDefinitions3DNOW[id];
break;
case ZYDIS_INSTRUCTION_ENCODING_XOP:
*definition = (ZydisInstructionDefinition*)&instructionDefinitionsXOP[id];
break;
case ZYDIS_INSTRUCTION_ENCODING_VEX:
*definition = (ZydisInstructionDefinition*)&instructionDefinitionsVEX[id];
break;
case ZYDIS_INSTRUCTION_ENCODING_EVEX:
*definition = (ZydisInstructionDefinition*)&instructionDefinitionsEVEX[id];
break;
case ZYDIS_INSTRUCTION_ENCODING_MVEX:
*definition = (ZydisInstructionDefinition*)&instructionDefinitionsMVEX[id];
break;
default:
ZYDIS_UNREACHABLE;
}
}
/* ---------------------------------------------------------------------------------------------- */
/* Operand definition */
/* ---------------------------------------------------------------------------------------------- */
uint8_t ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition,
const ZydisOperandDefinition** operand)
{
if (definition->operandCount == 0)
{
*operand = NULL;
return 0;
}
ZYDIS_ASSERT(definition->operandReference != 0xFFFF);
*operand = &operandDefinitions[definition->operandReference];
return definition->operandCount;
}
/* ---------------------------------------------------------------------------------------------- */
/* Element info */
/* ---------------------------------------------------------------------------------------------- */
void ZydisGetElementInfo(ZydisInternalElementType element, ZydisElementType* type,
ZydisElementSize* size)
{
static const struct
{
ZydisElementType type;
ZydisElementSize size;
} lookup[21] =
{
{ ZYDIS_ELEMENT_TYPE_INVALID , 0 },
{ ZYDIS_ELEMENT_TYPE_INVALID , 0 },
{ ZYDIS_ELEMENT_TYPE_STRUCT , 0 },
{ ZYDIS_ELEMENT_TYPE_INT , 0 },
{ ZYDIS_ELEMENT_TYPE_UINT , 0 },
{ ZYDIS_ELEMENT_TYPE_INT , 1 },
{ ZYDIS_ELEMENT_TYPE_INT , 8 },
{ ZYDIS_ELEMENT_TYPE_INT , 16 },
{ ZYDIS_ELEMENT_TYPE_INT , 32 },
{ ZYDIS_ELEMENT_TYPE_INT , 64 },
{ ZYDIS_ELEMENT_TYPE_UINT , 8 },
{ ZYDIS_ELEMENT_TYPE_UINT , 16 },
{ ZYDIS_ELEMENT_TYPE_UINT , 32 },
{ ZYDIS_ELEMENT_TYPE_UINT , 64 },
{ ZYDIS_ELEMENT_TYPE_UINT , 128 },
{ ZYDIS_ELEMENT_TYPE_UINT , 256 },
{ ZYDIS_ELEMENT_TYPE_FLOAT16 , 16 },
{ ZYDIS_ELEMENT_TYPE_FLOAT32 , 32 },
{ ZYDIS_ELEMENT_TYPE_FLOAT64 , 64 },
{ ZYDIS_ELEMENT_TYPE_FLOAT80 , 80 },
{ ZYDIS_ELEMENT_TYPE_LONGBCD , 80 }
};
ZYDIS_ASSERT(element < ZYDIS_ARRAY_SIZE(lookup));
*type = lookup[element].type;
*size = lookup[element].size;
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */

View File

@ -24,19 +24,18 @@
***************************************************************************************************/ ***************************************************************************************************/
#ifndef ZYDIS_INSTRUCTIONTABLE_H #ifndef ZYDIS_SHAREDDATA_H
#define ZYDIS_INSTRUCTIONTABLE_H #define ZYDIS_SHAREDDATA_H
#include <Zydis/Defines.h> #include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
#include <Zydis/DecoderTypes.h> #include <Zydis/Register.h>
#include <Zydis/SharedTypes.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define ZYDIS_BITFIELD(x) : x
/* ============================================================================================== */ /* ============================================================================================== */
/* Enums and types */ /* Enums and types */
/* ============================================================================================== */ /* ============================================================================================== */
@ -49,117 +48,6 @@ extern "C" {
#pragma pack(push, 1) #pragma pack(push, 1)
/* ---------------------------------------------------------------------------------------------- */
/* Instruction tree */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisInstructionTreeNodeType datatype.
*/
typedef uint8_t ZydisInstructionTreeNodeType;
/**
* @brief Defines the @c ZydisInstructionTreeNodeValue datatype.
*/
typedef uint16_t ZydisInstructionTreeNodeValue;
/**
* @brief Defines the @c ZydisInstructionTreeNode struct.
*/
typedef struct ZydisInstructionTreeNode_
{
ZydisInstructionTreeNodeType type;
ZydisInstructionTreeNodeValue value;
} ZydisInstructionTreeNode;
/**
* @brief Values that represent zydis instruction tree node types.
*/
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 EVEX.z filter.
*/
ZYDIS_NODETYPE_FILTER_EVEX_Z = 0x12,
/**
* @brief Reference to an MVEX.E filter.
*/
ZYDIS_NODETYPE_FILTER_MVEX_E = 0x13,
};
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Operand definition */ /* Operand definition */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -217,7 +105,7 @@ typedef uint8_t ZydisInternalElementType;
enum ZydisInternalElementTypes enum ZydisInternalElementTypes
{ {
ZYDIS_IELEMENT_TYPE_INVALID, ZYDIS_IELEMENT_TYPE_INVALID,
ZYDIS_IELEMENT_TYPE_VARIABLE, // TODO: Remove ZYDIS_IELEMENT_TYPE_VARIABLE,
ZYDIS_IELEMENT_TYPE_STRUCT, ZYDIS_IELEMENT_TYPE_STRUCT,
ZYDIS_IELEMENT_TYPE_INT, ZYDIS_IELEMENT_TYPE_INT,
ZYDIS_IELEMENT_TYPE_UINT, ZYDIS_IELEMENT_TYPE_UINT,
@ -270,6 +158,9 @@ typedef struct ZydisOperandDefinition_
} op; } op;
} ZydisOperandDefinition; } ZydisOperandDefinition;
/**
* @brief Values that represent implicit-register types.
*/
enum ZydisImplicitRegisterType enum ZydisImplicitRegisterType
{ {
ZYDIS_IMPLREG_TYPE_STATIC, ZYDIS_IMPLREG_TYPE_STATIC,
@ -281,6 +172,9 @@ enum ZydisImplicitRegisterType
ZYDIS_IMPLREG_TYPE_FLAGS_SSZ ZYDIS_IMPLREG_TYPE_FLAGS_SSZ
}; };
/**
* @brief Values that represent implicit-memory base-registers.
*/
enum ZydisImplicitMemBase enum ZydisImplicitMemBase
{ {
ZYDIS_IMPLMEM_BASE_ABX, ZYDIS_IMPLMEM_BASE_ABX,
@ -646,7 +540,7 @@ enum ZydisMaskPolicies
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_INSTRUCTION_DEFINITION_BASE \ #define ZYDIS_INSTRUCTION_DEFINITION_BASE \
ZydisInstructionMnemonic mnemonic ZYDIS_BITFIELD(11); \ ZydisMnemonic mnemonic ZYDIS_BITFIELD(11); \
uint8_t operandCount ZYDIS_BITFIELD( 4); \ uint8_t operandCount ZYDIS_BITFIELD( 4); \
uint16_t operandReference ZYDIS_BITFIELD(15); \ uint16_t operandReference ZYDIS_BITFIELD(15); \
uint8_t operandSizeMap ZYDIS_BITFIELD( 3) uint8_t operandSizeMap ZYDIS_BITFIELD( 3)
@ -657,7 +551,7 @@ enum ZydisMaskPolicies
#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX \ #define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX \
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \ ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \
ZydisBool hasVSIB ZYDIS_BITFIELD( 1) ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
/** /**
* @brief Defines the @c ZydisInstructionDefinition struct. * @brief Defines the @c ZydisInstructionDefinition struct.
@ -670,16 +564,17 @@ typedef struct ZydisInstructionDefinition_
typedef struct ZydisInstructionDefinitionDEFAULT_ typedef struct ZydisInstructionDefinitionDEFAULT_
{ {
ZYDIS_INSTRUCTION_DEFINITION_BASE; ZYDIS_INSTRUCTION_DEFINITION_BASE;
ZydisBool acceptsLock ZYDIS_BITFIELD(1); ZydisBool isPrivileged ZYDIS_BITFIELD( 1);
ZydisBool acceptsREP ZYDIS_BITFIELD(1); ZydisBool acceptsLock ZYDIS_BITFIELD( 1);
ZydisBool acceptsREPEREPZ ZYDIS_BITFIELD(1); ZydisBool acceptsREP ZYDIS_BITFIELD( 1);
ZydisBool acceptsREPNEREPNZ ZYDIS_BITFIELD(1); ZydisBool acceptsREPEREPZ ZYDIS_BITFIELD( 1);
ZydisBool acceptsBOUND ZYDIS_BITFIELD(1); ZydisBool acceptsREPNEREPNZ ZYDIS_BITFIELD( 1);
ZydisBool acceptsXACQUIRE ZYDIS_BITFIELD(1); ZydisBool acceptsBOUND ZYDIS_BITFIELD( 1);
ZydisBool acceptsXRELEASE ZYDIS_BITFIELD(1); ZydisBool acceptsXACQUIRE ZYDIS_BITFIELD( 1);
ZydisBool acceptsHLEWithoutLock ZYDIS_BITFIELD(1); ZydisBool acceptsXRELEASE ZYDIS_BITFIELD( 1);
ZydisBool acceptsBranchHints ZYDIS_BITFIELD(1); ZydisBool acceptsHLEWithoutLock ZYDIS_BITFIELD( 1);
ZydisBool acceptsSegment ZYDIS_BITFIELD(1); ZydisBool acceptsBranchHints ZYDIS_BITFIELD( 1);
ZydisBool acceptsSegment ZYDIS_BITFIELD( 1);
} ZydisInstructionDefinitionDEFAULT; } ZydisInstructionDefinitionDEFAULT;
typedef struct ZydisInstructionDefinition3DNOW_ typedef struct ZydisInstructionDefinition3DNOW_
@ -695,27 +590,27 @@ typedef struct ZydisInstructionDefinitionXOP_
typedef struct ZydisInstructionDefinitionVEX_ typedef struct ZydisInstructionDefinitionVEX_
{ {
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisVEXStaticBroadcast broadcast ZYDIS_BITFIELD(3); ZydisVEXStaticBroadcast broadcast ZYDIS_BITFIELD( 3);
} ZydisInstructionDefinitionVEX; } ZydisInstructionDefinitionVEX;
typedef struct ZydisInstructionDefinitionEVEX_ typedef struct ZydisInstructionDefinitionEVEX_
{ {
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX; ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD(2); ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD( 2);
ZydisEVEXTupleType tupleType ZYDIS_BITFIELD(4); ZydisEVEXTupleType tupleType ZYDIS_BITFIELD( 4);
ZydisInternalElementSize elementSize ZYDIS_BITFIELD(4); ZydisInternalElementSize elementSize ZYDIS_BITFIELD( 4);
ZydisEVEXFunctionality functionality ZYDIS_BITFIELD(2); ZydisEVEXFunctionality functionality ZYDIS_BITFIELD( 2);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2); ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD( 2);
ZydisEVEXStaticBroadcast broadcast ZYDIS_BITFIELD(4); ZydisEVEXStaticBroadcast broadcast ZYDIS_BITFIELD( 4);
} ZydisInstructionDefinitionEVEX; } ZydisInstructionDefinitionEVEX;
typedef struct ZydisInstructionDefinitionMVEX_ typedef struct ZydisInstructionDefinitionMVEX_
{ {
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX; ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
ZydisMVEXFunctionality functionality ZYDIS_BITFIELD(5); ZydisMVEXFunctionality functionality ZYDIS_BITFIELD( 5);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2); ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD( 2);
ZydisBool hasElementGranularity ZYDIS_BITFIELD(1); ZydisBool hasElementGranularity ZYDIS_BITFIELD( 1);
ZydisMVEXStaticBroadcast broadcast ZYDIS_BITFIELD(3); ZydisMVEXStaticBroadcast broadcast ZYDIS_BITFIELD( 3);
} ZydisInstructionDefinitionMVEX; } ZydisInstructionDefinitionMVEX;
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -726,143 +621,40 @@ typedef struct ZydisInstructionDefinitionMVEX_
# pragma warning(pop) # pragma warning(pop)
#endif #endif
/* ---------------------------------------------------------------------------------------------- */
/* Physical instruction info */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisInstructionPartFlags datatype.
*/
typedef uint8_t ZydisInstructionPartFlags;
/**
* @brief The instruction has an optional modrm byte.
*/
#define ZYDIS_INSTRPART_FLAG_HAS_MODRM 0x01
/**
* @brief The instruction has an optional displacement value.
*/
#define ZYDIS_INSTRPART_FLAG_HAS_DISP 0x02
/**
* @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
/**
* @brief The instruction ignores the value of `modrm.mod` and always assumes `modrm.mod == 3`
* ("reg, reg" - form).
*
* Instructions with this flag can't have a SIB byte or a displacement value.
*/
#define ZYDIS_INSTRPART_FLAG_FORCE_REG_FORM 0x10
typedef struct ZydisInstructionParts_
{
/**
* @brief Contains flags with information about the physical instruction-encoding.
*/
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 */
/* ============================================================================================== */ /* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Instruction tree */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Returns the root node of the instruction tree.
*
* @return The root node of the instruction tree.
*/
ZYDIS_NO_EXPORT const ZydisInstructionTreeNode* ZydisInstructionTreeGetRootNode();
/**
* @brief Returns the child node of @c parent specified by @c index.
*
* @param parent The parent node.
* @param index The index of the child node to retrieve.
*
* @return The specified child node.
*/
ZYDIS_NO_EXPORT const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode(
const ZydisInstructionTreeNode* parent, uint16_t index);
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Instruction definition */ /* Instruction definition */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Returns the instruction- and operand-definition that is linked to the given @c node. * @brief Returns the instruction-definition with the given `encoding` and `id`.
* *
* @param node The instruction definition node. * @param encoding The instruction-encoding.
* @param definition A pointer to a variable that receives a pointer to the * @param id The definition-id.
* @param definition A pointer to the variable that receives a pointer to the instruction-
* definition.
*/ */
ZYDIS_NO_EXPORT void ZydisGetInstructionDefinition(const ZydisInstructionTreeNode* node, ZYDIS_NO_EXPORT void ZydisGetInstructionDefinition(ZydisInstructionEncoding encoding,
const ZydisInstructionDefinition** definition); uint16_t id, const ZydisInstructionDefinition** definition);
/**
* @brief Returns information about optional instruction parts (like modrm, displacement or
* immediates) 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);
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Operand definition */ /* Operand definition */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Returns the instruction- and operand-definition that is linked to the given @c node. * @brief Returns the the operand-definitions for the given instruction-`definition`.
* *
* @param definition A pointer to the instruction-definition. * @param definition A pointer to the instruction-definition.
* @param operands A pointer to a variable that receives a pointer to the first * @param operand A pointer to the variable that receives a pointer to the first operand-
* operand-definition of the instruction. * definition of the instruction.
* *
* @return The number of operands for the given instruction-definition. * @return The number of operands for the given instruction-definition.
*/ */
ZYDIS_NO_EXPORT uint8_t ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition, ZYDIS_NO_EXPORT uint8_t ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition,
const ZydisOperandDefinition** operands); const ZydisOperandDefinition** operand);
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Element info */ /* Element info */
@ -886,4 +678,4 @@ ZYDIS_NO_EXPORT void ZydisGetElementInfo(ZydisInternalElementType element, Zydis
} }
#endif #endif
#endif /* ZYDIS_INSTRUCTIONTABLE_H */ #endif /* ZYDIS_SHAREDDATA_H */

View File

@ -97,7 +97,7 @@ double GetCounter()
/* Internal functions */ /* Internal functions */
/* ============================================================================================== */ /* ============================================================================================== */
void processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity granularity, uint64_t processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity granularity,
ZydisBool format) ZydisBool format)
{ {
ZydisDecoder decoder; ZydisDecoder decoder;
@ -121,6 +121,7 @@ void processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity gra
} }
} }
uint64_t count = 0;
size_t offset = 0; size_t offset = 0;
ZydisStatus status; ZydisStatus status;
ZydisDecodedInstruction instruction; ZydisDecodedInstruction instruction;
@ -134,6 +135,7 @@ void processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity gra
puts("Unexpected decoding error"); puts("Unexpected decoding error");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
++count;
if (format) if (format)
{ {
ZydisFormatterFormatInstruction( ZydisFormatterFormatInstruction(
@ -141,17 +143,21 @@ void processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity gra
} }
offset += instruction.length; offset += instruction.length;
} }
return count;
} }
void testPerformance(const char* buffer, size_t length, ZydisDecodeGranularity granularity, void testPerformance(const char* buffer, size_t length, ZydisDecodeGranularity granularity,
ZydisBool format) ZydisBool format)
{ {
uint64_t count = 0;
StartCounter(); StartCounter();
for (uint8_t j = 0; j < 100; ++j) for (uint8_t j = 0; j < 100; ++j)
{ {
processBuffer(buffer, length, granularity, format); count += processBuffer(buffer, length, granularity, format);
} }
printf("Granularity %d, Formatting %d: %8.2f msec\n", granularity, format, GetCounter()); printf("Granularity %d, Formatting %d, Instructions: ~%6.2fM, Time: %8.2f msec\n",
granularity, format, (double)count / 1000000, GetCounter());
} }
void generateTestData(FILE* file, uint8_t encoding) void generateTestData(FILE* file, uint8_t encoding)