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

View File

@ -1,5 +1,5 @@
# 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.
@ -83,4 +83,4 @@ Zydis builds cleanly on most platforms without any external dependencies. You ca
## License ##
Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses.
Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses.

View File

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

View File

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

View File

@ -32,224 +32,18 @@
#ifndef ZYDIS_INSTRUCTIONINFO_H
#define ZYDIS_INSTRUCTIONINFO_H
#include <Zydis/Types.h>
#include <Zydis/CommonTypes.h>
#include <Zydis/Mnemonic.h>
#include <Zydis/Register.h>
#include <Zydis/SharedTypes.h>
#ifdef __cplusplus
extern "C" {
#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 */
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/**
* @brief Defines the @c ZydisDecodedOperand struct.
@ -370,134 +164,9 @@ typedef struct 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 */
/* ---------------------------------------------------------------------------------------------- */
@ -509,8 +178,6 @@ typedef uint64_t ZydisInstructionAttributes;
// TODO: Update values
// TODO: Add IsAtomic
/**
* @brief The instruction has the ModRM byte.
*/
@ -885,7 +552,7 @@ typedef struct ZydisDecodedInstruction_
/**
* @brief The instruction-mnemonic.
*/
ZydisInstructionMnemonic mnemonic;
ZydisMnemonic mnemonic;
/**
* @brief The length of the decoded instruction.
*/

View File

@ -137,6 +137,14 @@
/* 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]))
/* ============================================================================================== */

View File

@ -27,9 +27,9 @@
#ifndef ZYDIS_FORMATTER_H
#define ZYDIS_FORMATTER_H
#include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h>
#include <Zydis/Status.h>
#include <Zydis/DecoderTypes.h>
#ifdef __cplusplus
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;
/**
@ -373,6 +393,32 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
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.
*/
@ -393,15 +439,10 @@ struct ZydisFormatter_
ZydisFormatterFormatOperandFunc funcFormatOperandImm;
ZydisFormatterFormatOperandFunc funcPrintOperandSize;
ZydisFormatterFormatOperandFunc funcPrintSegment;
ZydisFormatterFormatOperandFunc funcPrintDecorator;
ZydisFormatterFormatDecoratorFunc funcPrintDecorator;
ZydisFormatterFormatAddressFunc funcPrintAddress;
ZydisFormatterFormatOperandFunc funcPrintDisplacement;
ZydisFormatterFormatOperandFunc funcPrintImmediate;
const char* prefixHEX;
const char* prefixOCT;
const char* delimMnemonic;
const char* delimOperands;
const char* fmtDecorator; // TODO:
ZydisFormatterFormatOperandFunc funcPrintImmediate;
};
/* ============================================================================================== */
@ -435,13 +476,18 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, ZydisFo
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 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.
*
* 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,
ZydisFormatterHookType hook, const void** callback);

View File

@ -28,7 +28,7 @@
#define ZYDIS_MNEMONIC_H
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/CommonTypes.h>
#ifdef __cplusplus
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>
@ -56,7 +56,7 @@ typedef uint16_t ZydisInstructionMnemonic;
*
* @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
#include <Zydis/Defines.h>
#include <Zydis/Types.h>
#include <Zydis/CommonTypes.h>
#include <Zydis/Status.h>
#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
#define ZYDIS_STATUS_H
#include <Zydis/Types.h>
#include <Zydis/CommonTypes.h>
#ifdef __cplusplus
extern "C" {

View File

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

View File

@ -25,9 +25,10 @@
***************************************************************************************************/
#include <string.h>
#include <Zydis/Status.h>
#include <Zydis/Decoder.h>
#include <InstructionTable.h>
#include <Zydis/Status.h>
#include <DecoderData.h>
#include <SharedData.h>
/* ============================================================================================== */
/* 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 instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param definition A pointer to the @c ZydisInstructionDefinition struct.
*/
static void ZydisSetPrefixRelatedAttributes(ZydisDecoderContext* context,
ZydisDecodedInstruction* instruction, const ZydisInstructionDefinition* definition)
static void ZydisSetAttributes(ZydisDecoderContext* context, ZydisDecodedInstruction* instruction,
const ZydisInstructionDefinition* definition)
{
ZYDIS_ASSERT(context);
ZYDIS_ASSERT(instruction);
@ -2046,6 +2047,10 @@ static void ZydisSetPrefixRelatedAttributes(ZydisDecoderContext* context,
const ZydisInstructionDefinitionDEFAULT* def =
(const ZydisInstructionDefinitionDEFAULT*)definition;
if (def->isPrivileged)
{
instruction->attributes |= ZYDIS_ATTRIB_IS_PRIVILEGED;
}
if (def->acceptsLock)
{
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
* displacements and/or immediate values.
*
* @param context A pointer to the @c ZydisDecoderContext struct.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param optionalParts A pointer to the @c ZydisInstructionParts struct.
* @param context A pointer to the @c ZydisDecoderContext struct.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param info A pointer to the @c ZydisInstructionEncodingInfo struct.
*
* @return A zydis status code.
*/
static ZydisStatus ZydisDecodeInstructionPhysical(ZydisDecoderContext* context,
ZydisDecodedInstruction* instruction, const ZydisInstructionParts* optionalParts)
static ZydisStatus ZydisDecodeOptionalInstructionParts(ZydisDecoderContext* context,
ZydisDecodedInstruction* instruction, const ZydisInstructionEncodingInfo* info)
{
ZYDIS_ASSERT(context);
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)
{
@ -3159,7 +3164,7 @@ static ZydisStatus ZydisDecodeInstructionPhysical(ZydisDecoderContext* context,
}
uint8_t hasSIB = 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)
{
@ -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(
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;
}
ZYDIS_CHECK(ZydisReadImmediate(context, instruction, 0,
optionalParts->imm[0].size[context->eoszIndex],
optionalParts->imm[0].isSigned, optionalParts->imm[0].isRelative));
info->imm[0].size[context->eoszIndex], info->imm[0].isSigned, info->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,
optionalParts->imm[1].size[context->eoszIndex],
optionalParts->imm[1].isSigned, optionalParts->imm[1].isRelative));
info->imm[1].size[context->eoszIndex], info->imm[1].isSigned, info->imm[1].isRelative));
}
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 instruction A pointer to the @c ZydisDecodedInstruction struct.
@ -4173,10 +4176,10 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
ZYDIS_ASSERT(context);
ZYDIS_ASSERT(instruction);
// Iterate through the instruction table
const ZydisInstructionTreeNode* node = ZydisInstructionTreeGetRootNode();
const ZydisInstructionTreeNode* temp = NULL;
ZydisInstructionTreeNodeType nodeType;
// Iterate through the decoder tree
const ZydisDecoderTreeNode* node = ZydisDecoderTreeGetRootNode();
const ZydisDecoderTreeNode* temp = NULL;
ZydisDecoderTreeNodeType nodeType;
do
{
nodeType = node->type;
@ -4229,7 +4232,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
break;
case ZYDIS_NODETYPE_FILTER_MANDATORY_PREFIX:
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: was not successfull
// TODO: Restore consumed prefix
@ -4262,30 +4265,31 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
if (nodeType & ZYDIS_NODETYPE_DEFINITION_MASK)
{
const ZydisInstructionDefinition* definition;
ZydisGetInstructionDefinition(node, &definition);
ZydisGetInstructionDefinition(instruction->encoding, node->value, &definition);
ZydisSetEffectiveOperandSize(context, instruction, definition);
ZydisSetEffectiveAddressWidth(context, instruction);
const ZydisInstructionParts* optionalParts;
ZydisGetOptionalInstructionParts(node, &optionalParts);
ZYDIS_CHECK(ZydisDecodeInstructionPhysical(context, instruction, optionalParts));
const ZydisInstructionEncodingInfo* info;
ZydisGetInstructionEncodingInfo(node, &info);
ZYDIS_CHECK(ZydisDecodeOptionalInstructionParts(context, instruction, info));
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_3DNOW)
{
// Get actual 3dnow opcode and definition
ZYDIS_CHECK(ZydisInputNext(context, instruction, &instruction->opcode));
node = ZydisInstructionTreeGetRootNode();
node = ZydisInstructionTreeGetChildNode(node, 0x0F);
node = ZydisInstructionTreeGetChildNode(node, 0x0F);
node = ZydisInstructionTreeGetChildNode(node, instruction->opcode);
node = ZydisDecoderTreeGetRootNode();
node = ZydisDecoderTreeGetChildNode(node, 0x0F);
node = ZydisDecoderTreeGetChildNode(node, 0x0F);
node = ZydisDecoderTreeGetChildNode(node, instruction->opcode);
if (node->type == ZYDIS_NODETYPE_INVALID)
{
return ZYDIS_STATUS_DECODING_ERROR;
}
ZYDIS_ASSERT(node->type == ZYDIS_NODETYPE_FILTER_MODRM_MOD_COMPACT);
node = ZydisInstructionTreeGetChildNode(
node = ZydisDecoderTreeGetChildNode(
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));
@ -4294,7 +4298,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
if (context->decoder->decodeGranularity == ZYDIS_DECODE_GRANULARITY_FULL)
{
ZydisSetPrefixRelatedAttributes(context, instruction, definition);
ZydisSetAttributes(context, instruction, definition);
switch (instruction->encoding)
{
case ZYDIS_INSTRUCTION_ENCODING_XOP:
@ -4314,7 +4318,7 @@ static ZydisStatus ZydisDecodeInstruction(ZydisDecoderContext* context,
ZYDIS_UNREACHABLE;
}
ZYDIS_CHECK(status);
node = ZydisInstructionTreeGetChildNode(node, index);
node = ZydisDecoderTreeGetChildNode(node, index);
} while((nodeType != ZYDIS_NODETYPE_INVALID) && !(nodeType & ZYDIS_NODETYPE_DEFINITION_MASK));
return ZYDIS_STATUS_SUCCESS;
}
@ -4390,6 +4394,7 @@ ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* bu
void* userData = instruction->userData;
memset(instruction, 0, sizeof(*instruction));
instruction->machineMode = decoder->machineMode;
instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT;
instruction->instrAddress = instructionPointer;
instruction->userData = userData;

View File

@ -24,8 +24,7 @@
***************************************************************************************************/
#include <assert.h>
#include <InstructionTable.h>
#include <DecoderData.h>
/* ============================================================================================== */
/* Data tables */
@ -44,7 +43,7 @@
* 2 = xop9
* 3 = xopA
*/
extern const ZydisInstructionTreeNode filtersXOP[][4];
extern const ZydisDecoderTreeNode filtersXOP[][4];
/**
* @brief Contains all VEX-map filters.
@ -68,7 +67,7 @@ extern const ZydisInstructionTreeNode filtersXOP[][4];
* 0F = F2_0F38
* 10 = F2_0F3A
*/
extern const ZydisInstructionTreeNode filtersVEX[][17];
extern const ZydisDecoderTreeNode filtersVEX[][17];
/**
* @brief Contains all EVEX/MVEX-map filters.
@ -108,14 +107,14 @@ extern const ZydisInstructionTreeNode filtersVEX[][17];
* 1F = MVEX F2_0F38
* 20 = MVEX F2_0F3A
*/
extern const ZydisInstructionTreeNode filtersEMVEX[][33];
extern const ZydisDecoderTreeNode filtersEMVEX[][33];
/**
* @brief Contains all opcode filters.
*
* Indexed by the numeric value of the opcode.
*/
extern const ZydisInstructionTreeNode filtersOpcode[][256];
extern const ZydisDecoderTreeNode filtersOpcode[][256];
/**
* @brief Contains all instruction-mode filters.
@ -125,7 +124,7 @@ extern const ZydisInstructionTreeNode filtersOpcode[][256];
* 1 = 32 bit mode
* 2 = 64 bit mode
*/
extern const ZydisInstructionTreeNode filtersMode[][3];
extern const ZydisDecoderTreeNode filtersMode[][3];
/**
* @brief Contains all compacted instruction-mode filters.
@ -134,14 +133,14 @@ extern const ZydisInstructionTreeNode filtersMode[][3];
* 0 = 64 bit mode
* 1 = not 64 bit mode
*/
extern const ZydisInstructionTreeNode filtersModeCompact[][2];
extern const ZydisDecoderTreeNode filtersModeCompact[][2];
/**
* @brief Contains all ModRM.mod filters.
*
* 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.
@ -150,21 +149,21 @@ extern const ZydisInstructionTreeNode filtersModrmMod[][4];
* 0 = [ModRM.mod == 11] = register
* 1 = [ModRM.mod == !11] = memory
*/
extern const ZydisInstructionTreeNode filtersModrmModCompact[][2];
extern const ZydisDecoderTreeNode filtersModrmModCompact[][2];
/**
* @brief Contains all ModRM.reg filters.
*
* 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.
*
* 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.
@ -176,7 +175,7 @@ extern const ZydisInstructionTreeNode filtersModrmRm[][8];
* 3 = F3
* 4 = F2
*/
extern const ZydisInstructionTreeNode filtersMandatoryPrefix[][5];
extern const ZydisDecoderTreeNode filtersMandatoryPrefix[][5];
/**
* @brief Contains all operand-size filters.
@ -186,7 +185,7 @@ extern const ZydisInstructionTreeNode filtersMandatoryPrefix[][5];
* 1 = 32 bit
* 2 = 64 bit
*/
extern const ZydisInstructionTreeNode filtersOperandSize[][3];
extern const ZydisDecoderTreeNode filtersOperandSize[][3];
/**
* @brief Contains all address-size filters.
@ -196,7 +195,7 @@ extern const ZydisInstructionTreeNode filtersOperandSize[][3];
* 1 = 32 bit
* 2 = 64 bit
*/
extern const ZydisInstructionTreeNode filtersAddressSize[][3];
extern const ZydisDecoderTreeNode filtersAddressSize[][3];
/**
* @brief Contains all vector-length filters.
@ -206,98 +205,59 @@ extern const ZydisInstructionTreeNode filtersAddressSize[][3];
* 1 = 256 bit
* 2 = 512 bit
*/
extern const ZydisInstructionTreeNode filtersVectorLength[][3];
extern const ZydisDecoderTreeNode filtersVectorLength[][3];
/**
* @brief Contains all REX/VEX/EVEX.w filters.
*
* 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.
*
* 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.
*
* 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.
*
* 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.
*
* Indexed by the numeric value of the MVEX.E field.
*/
extern const ZydisInstructionTreeNode 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[];
extern const ZydisDecoderTreeNode filtersMVEXE[][2];
/* ---------------------------------------------------------------------------------------------- */
/* Physical instruction encodings */
/* ---------------------------------------------------------------------------------------------- */
#include <Generated/InstructionClassMap.inc>
#include <Generated/PhysicalEncodings.inc>
/* ---------------------------------------------------------------------------------------------- */
/* Instruction tree */
/* Decoder tree */
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_INVALID \
{ ZYDIS_NODETYPE_INVALID, 0x00000000 }
#define ZYDIS_FILTER(type, id) \
{ type, id }
#define ZYDIS_DEFINITION(encoding, instrclass, id) \
{ ZYDIS_NODETYPE_DEFINITION_MASK | instrclass, (encoding << 13) | id }
#define ZYDIS_DEFINITION(encoding_id, id) \
{ ZYDIS_NODETYPE_DEFINITION_MASK | encoding_id, id }
#include <Generated/InstructionFilters.inc>
@ -306,40 +266,23 @@ extern const ZydisInstructionDefinitionMVEX instructionDefinitionsMVEX[];
#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 */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* 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;
}
const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode(
const ZydisInstructionTreeNode* parent, uint16_t index)
const ZydisDecoderTreeNode* ZydisDecoderTreeGetChildNode(const ZydisDecoderTreeNode* parent,
uint16_t index)
{
switch (parent->type)
{
@ -403,117 +346,17 @@ const ZydisInstructionTreeNode* ZydisInstructionTreeGetChildNode(
default:
ZYDIS_UNREACHABLE;
}
static const ZydisInstructionTreeNode invalid = { ZYDIS_NODETYPE_INVALID, 0x00000000 };
static const ZydisDecoderTreeNode invalid = { ZYDIS_NODETYPE_INVALID, 0x00000000 };
return &invalid;
}
/* ---------------------------------------------------------------------------------------------- */
/* Instruction definition */
/* ---------------------------------------------------------------------------------------------- */
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)
void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node,
const ZydisInstructionEncodingInfo** info)
{
ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK);
uint8_t class = (node->type) & 0x7F;
ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(instructionClassMap));
*info = &instructionClassMap[class];
ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(physicalEncodings));
*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;
}
if ((operand->id == 1) && (operand->encoding == ZYDIS_OPERAND_ENCODING_MASK))
{
return ZYDIS_STATUS_SUCCESS;
}
const char* reg = ZydisRegisterGetString(operand->reg);
if (!reg)
{
@ -514,9 +519,11 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
switch (operand->id)
{
case 0:
typecast = ((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(instruction->operands[0].size != instruction->operands[1].size)) ? instruction->operands[0].size : 0;
typecast =
((instruction->operands[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
(instruction->operands[0].size != instruction->operands[1].size)) ?
instruction->operands[0].size : 0;
if (!typecast &&
(instruction->operands[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(instruction->operands[1].reg == ZYDIS_REGISTER_CL))
@ -539,8 +546,9 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
case 1:
case 2:
typecast =
(instruction->operands[operand->id - 1].size != instruction->operands[operand->id].size) ?
instruction->operands[operand->id].size : 0;
(instruction->operands[operand->id - 1].size !=
instruction->operands[operand->id].size) ?
instruction->operands[operand->id].size : 0;
break;
default:
break;
@ -627,7 +635,7 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand)
ZydisDecodedOperand* operand, ZydisDecoratorType type, ZydisRegister mask)
{
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{
@ -635,194 +643,197 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
}
const char* bufEnd = *buffer + bufferLen;
if (operand->id == 1)
switch (type)
{
if ((operand->type == ZYDIS_OPERAND_TYPE_REGISTER) &&
(operand->encoding == ZYDIS_OPERAND_ENCODING_MASK) &&
(operand->reg != ZYDIS_REGISTER_K0))
case ZYDIS_DECORATOR_TYPE_MASK:
{
if (mask != ZYDIS_REGISTER_K0)
{
const char* reg = ZydisRegisterGetString(operand->reg);
const char* reg = ZydisRegisterGetString(mask);
if (!reg)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
" {%s}", reg));
ZYDIS_CHECK(ZydisStringBufferAppendFormat(
buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, " {%s}", reg));
if (instruction->avx.maskMode == ZYDIS_MASK_MODE_ZERO)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
}
}
} else
{
if (instruction->operands[operand->id].type == ZYDIS_OPERAND_TYPE_MEMORY)
{
if (!instruction->avx.broadcast.isStatic)
{
switch (instruction->avx.broadcast.mode)
{
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;
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;
}
if (instruction->avx.hasEvictionHint)
{
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}"));
}
}
}
if ((operand->id == (instruction->operandCount - 1)) ||
((operand->id != (instruction->operandCount - 1)) &&
(instruction->operands[operand->id + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)))
break;
}
case ZYDIS_DECORATOR_TYPE_BROADCAST:
if (!instruction->avx.broadcast.isStatic)
{
if (instruction->avx.hasSAE)
switch (instruction->avx.broadcast.mode)
{
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}"));
case ZYDIS_BROADCAST_MODE_INVALID:
break;
case ZYDIS_SWIZZLE_MODE_BADC:
case ZYDIS_BROADCAST_MODE_1_TO_2:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
break;
case ZYDIS_SWIZZLE_MODE_DACB:
case ZYDIS_BROADCAST_MODE_1_TO_4:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
break;
case ZYDIS_SWIZZLE_MODE_AAAA:
case ZYDIS_BROADCAST_MODE_1_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
break;
case ZYDIS_SWIZZLE_MODE_BBBB:
case ZYDIS_BROADCAST_MODE_1_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
break;
case ZYDIS_SWIZZLE_MODE_CCCC:
case ZYDIS_BROADCAST_MODE_4_TO_8:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
break;
case ZYDIS_SWIZZLE_MODE_DDDD:
case ZYDIS_BROADCAST_MODE_4_TO_16:
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
break;
default:
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;
@ -903,8 +914,55 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
{
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer,
instruction, &instruction->operands[i]));
if (i == 0)
{
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;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR:
formatter->funcPrintDecorator = *(ZydisFormatterFormatOperandFunc*)&temp;
formatter->funcPrintDecorator = *(ZydisFormatterFormatDecoratorFunc*)&temp;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS:
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 } } },
/*01*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*02*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM, { { 0, 0, 0 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*03*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*04*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*05*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 32 }, ZYDIS_TRUE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*06*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*07*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 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 } } },
/*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 } } },
/*0A*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0 | ZYDIS_INSTRPART_FLAG_HAS_IMM1, { { 0, 0, 0 } }, { { { 16, 16, 16 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 8, 8, 8 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0B*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0C*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 8, 8, 8 }, ZYDIS_TRUE, ZYDIS_TRUE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0D*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_DISP, { { 16, 32, 64 } }, { { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0E*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_IMM0, { { 0, 0, 0 } }, { { { 16, 32, 64 }, ZYDIS_FALSE, ZYDIS_FALSE }, { { 0, 0, 0 }, ZYDIS_FALSE, ZYDIS_FALSE } } },
/*0F*/ { 0 | ZYDIS_INSTRPART_FLAG_HAS_MODRM | ZYDIS_INSTRPART_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 } } },
/*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 } } }
/*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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 */
/* ============================================================================================== */
const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic)
const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic)
{
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
#define ZYDIS_INSTRUCTIONTABLE_H
#ifndef ZYDIS_SHAREDDATA_H
#define ZYDIS_SHAREDDATA_H
#include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h>
#include <Zydis/DecoderTypes.h>
#include <Zydis/Register.h>
#include <Zydis/SharedTypes.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ZYDIS_BITFIELD(x) : x
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
@ -49,117 +48,6 @@ extern "C" {
#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 */
/* ---------------------------------------------------------------------------------------------- */
@ -217,7 +105,7 @@ typedef uint8_t ZydisInternalElementType;
enum ZydisInternalElementTypes
{
ZYDIS_IELEMENT_TYPE_INVALID,
ZYDIS_IELEMENT_TYPE_VARIABLE, // TODO: Remove
ZYDIS_IELEMENT_TYPE_VARIABLE,
ZYDIS_IELEMENT_TYPE_STRUCT,
ZYDIS_IELEMENT_TYPE_INT,
ZYDIS_IELEMENT_TYPE_UINT,
@ -270,6 +158,9 @@ typedef struct ZydisOperandDefinition_
} op;
} ZydisOperandDefinition;
/**
* @brief Values that represent implicit-register types.
*/
enum ZydisImplicitRegisterType
{
ZYDIS_IMPLREG_TYPE_STATIC,
@ -281,6 +172,9 @@ enum ZydisImplicitRegisterType
ZYDIS_IMPLREG_TYPE_FLAGS_SSZ
};
/**
* @brief Values that represent implicit-memory base-registers.
*/
enum ZydisImplicitMemBase
{
ZYDIS_IMPLMEM_BASE_ABX,
@ -646,7 +540,7 @@ enum ZydisMaskPolicies
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_INSTRUCTION_DEFINITION_BASE \
ZydisInstructionMnemonic mnemonic ZYDIS_BITFIELD(11); \
ZydisMnemonic mnemonic ZYDIS_BITFIELD(11); \
uint8_t operandCount ZYDIS_BITFIELD( 4); \
uint16_t operandReference ZYDIS_BITFIELD(15); \
uint8_t operandSizeMap ZYDIS_BITFIELD( 3)
@ -657,7 +551,7 @@ enum ZydisMaskPolicies
#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX \
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR; \
ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
ZydisBool hasVSIB ZYDIS_BITFIELD( 1)
/**
* @brief Defines the @c ZydisInstructionDefinition struct.
@ -670,16 +564,17 @@ typedef struct ZydisInstructionDefinition_
typedef struct ZydisInstructionDefinitionDEFAULT_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE;
ZydisBool acceptsLock ZYDIS_BITFIELD(1);
ZydisBool acceptsREP ZYDIS_BITFIELD(1);
ZydisBool acceptsREPEREPZ ZYDIS_BITFIELD(1);
ZydisBool acceptsREPNEREPNZ ZYDIS_BITFIELD(1);
ZydisBool acceptsBOUND ZYDIS_BITFIELD(1);
ZydisBool acceptsXACQUIRE ZYDIS_BITFIELD(1);
ZydisBool acceptsXRELEASE ZYDIS_BITFIELD(1);
ZydisBool acceptsHLEWithoutLock ZYDIS_BITFIELD(1);
ZydisBool acceptsBranchHints ZYDIS_BITFIELD(1);
ZydisBool acceptsSegment ZYDIS_BITFIELD(1);
ZydisBool isPrivileged ZYDIS_BITFIELD( 1);
ZydisBool acceptsLock ZYDIS_BITFIELD( 1);
ZydisBool acceptsREP ZYDIS_BITFIELD( 1);
ZydisBool acceptsREPEREPZ ZYDIS_BITFIELD( 1);
ZydisBool acceptsREPNEREPNZ ZYDIS_BITFIELD( 1);
ZydisBool acceptsBOUND ZYDIS_BITFIELD( 1);
ZydisBool acceptsXACQUIRE ZYDIS_BITFIELD( 1);
ZydisBool acceptsXRELEASE ZYDIS_BITFIELD( 1);
ZydisBool acceptsHLEWithoutLock ZYDIS_BITFIELD( 1);
ZydisBool acceptsBranchHints ZYDIS_BITFIELD( 1);
ZydisBool acceptsSegment ZYDIS_BITFIELD( 1);
} ZydisInstructionDefinitionDEFAULT;
typedef struct ZydisInstructionDefinition3DNOW_
@ -695,27 +590,27 @@ typedef struct ZydisInstructionDefinitionXOP_
typedef struct ZydisInstructionDefinitionVEX_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR;
ZydisVEXStaticBroadcast broadcast ZYDIS_BITFIELD(3);
ZydisVEXStaticBroadcast broadcast ZYDIS_BITFIELD( 3);
} ZydisInstructionDefinitionVEX;
typedef struct ZydisInstructionDefinitionEVEX_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD(2);
ZydisEVEXTupleType tupleType ZYDIS_BITFIELD(4);
ZydisInternalElementSize elementSize ZYDIS_BITFIELD(4);
ZydisEVEXFunctionality functionality ZYDIS_BITFIELD(2);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2);
ZydisEVEXStaticBroadcast broadcast ZYDIS_BITFIELD(4);
} ZydisInstructionDefinitionEVEX;
ZydisInternalVectorLength vectorLength ZYDIS_BITFIELD( 2);
ZydisEVEXTupleType tupleType ZYDIS_BITFIELD( 4);
ZydisInternalElementSize elementSize ZYDIS_BITFIELD( 4);
ZydisEVEXFunctionality functionality ZYDIS_BITFIELD( 2);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD( 2);
ZydisEVEXStaticBroadcast broadcast ZYDIS_BITFIELD( 4);
} ZydisInstructionDefinitionEVEX;
typedef struct ZydisInstructionDefinitionMVEX_
{
ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR_EX;
ZydisMVEXFunctionality functionality ZYDIS_BITFIELD(5);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD(2);
ZydisBool hasElementGranularity ZYDIS_BITFIELD(1);
ZydisMVEXStaticBroadcast broadcast ZYDIS_BITFIELD(3);
ZydisMVEXFunctionality functionality ZYDIS_BITFIELD( 5);
ZydisMaskPolicy maskPolicy ZYDIS_BITFIELD( 2);
ZydisBool hasElementGranularity ZYDIS_BITFIELD( 1);
ZydisMVEXStaticBroadcast broadcast ZYDIS_BITFIELD( 3);
} ZydisInstructionDefinitionMVEX;
/* ---------------------------------------------------------------------------------------------- */
@ -726,143 +621,40 @@ typedef struct ZydisInstructionDefinitionMVEX_
# pragma warning(pop)
#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 */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* 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 */
/* ---------------------------------------------------------------------------------------------- */
/**
* @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 definition A pointer to a variable that receives a pointer to the
* @param encoding The instruction-encoding.
* @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,
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);
ZYDIS_NO_EXPORT void ZydisGetInstructionDefinition(ZydisInstructionEncoding encoding,
uint16_t id, const ZydisInstructionDefinition** 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 operands A pointer to a variable that receives a pointer to the first
* operand-definition of the instruction.
* @param definition A pointer to the instruction-definition.
* @param operand A pointer to the variable that receives a pointer to the first operand-
* definition of the instruction.
*
* @return The number of operands for the given instruction-definition.
*/
ZYDIS_NO_EXPORT uint8_t ZydisGetOperandDefinitions(const ZydisInstructionDefinition* definition,
const ZydisOperandDefinition** operands);
const ZydisOperandDefinition** operand);
/* ---------------------------------------------------------------------------------------------- */
/* Element info */
@ -886,4 +678,4 @@ ZYDIS_NO_EXPORT void ZydisGetElementInfo(ZydisInternalElementType element, Zydis
}
#endif
#endif /* ZYDIS_INSTRUCTIONTABLE_H */
#endif /* ZYDIS_SHAREDDATA_H */

View File

@ -97,7 +97,7 @@ double GetCounter()
/* 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)
{
ZydisDecoder decoder;
@ -121,6 +121,7 @@ void processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity gra
}
}
uint64_t count = 0;
size_t offset = 0;
ZydisStatus status;
ZydisDecodedInstruction instruction;
@ -134,24 +135,29 @@ void processBuffer(const char* buffer, size_t length, ZydisDecodeGranularity gra
puts("Unexpected decoding error");
exit(EXIT_FAILURE);
}
++count;
if (format)
{
ZydisFormatterFormatInstruction(
&formatter, &instruction, formatBuffer, sizeof(formatBuffer));
}
offset += instruction.length;
}
}
return count;
}
void testPerformance(const char* buffer, size_t length, ZydisDecodeGranularity granularity,
ZydisBool format)
{
uint64_t count = 0;
StartCounter();
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)