2015-05-16 11:05:17 +08:00
|
|
|
|
/***************************************************************************************************
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
2015-05-16 11:05:17 +08:00
|
|
|
|
Zyan Disassembler Engine
|
2014-10-25 05:11:16 +08:00
|
|
|
|
Version 1.0
|
|
|
|
|
|
|
|
|
|
Remarks : Freeware, Copyright must be included
|
|
|
|
|
|
|
|
|
|
Original Author : Florian Bernd
|
2015-05-16 11:05:17 +08:00
|
|
|
|
Modifications : Joel H<EFBFBD>ner
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
|
|
|
|
* 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:
|
2015-05-16 11:05:17 +08:00
|
|
|
|
*
|
2014-10-25 05:11:16 +08:00
|
|
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
|
|
|
* copies or substantial portions of the Software.
|
2015-05-16 11:05:17 +08:00
|
|
|
|
*
|
2014-10-25 05:11:16 +08:00
|
|
|
|
* 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.
|
|
|
|
|
|
2015-05-16 11:05:17 +08:00
|
|
|
|
***************************************************************************************************/
|
2015-03-16 23:37:15 +08:00
|
|
|
|
|
2015-05-16 11:05:17 +08:00
|
|
|
|
#ifndef _ZYDIS_TYPES_H_
|
|
|
|
|
#define _ZYDIS_TYPES_H_
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
2015-03-16 23:37:15 +08:00
|
|
|
|
#include <stdbool.h>
|
2015-05-16 11:05:17 +08:00
|
|
|
|
#include "ZydisOpcodeTable.h"
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
2015-03-16 23:37:15 +08:00
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C"
|
2014-10-25 05:11:16 +08:00
|
|
|
|
{
|
2015-03-16 23:37:15 +08:00
|
|
|
|
#endif
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Values that represent additional flags of a decoded instruction.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
typedef enum _ZydisInstructionFlags /* : uint32_t */
|
2014-10-25 05:11:16 +08:00
|
|
|
|
{
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_NONE = 0x00000000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction was decoded in 16 bit disassembler mode.
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_DISASSEMBLER_MODE_16 = 0x00000001,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction was decoded in 32 bit disassembler mode.
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_DISASSEMBLER_MODE_32 = 0x00000002,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction was decoded in 64 bit disassembler mode.
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_DISASSEMBLER_MODE_64 = 0x00000004,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction has a segment prefix (0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65).
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_SEGMENT = 0x00000008,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction has a lock prefix (0xF0).
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_LOCK = 0x00000010,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction has a repne prefix (0xF2).
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_REPNE = 0x00000020,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction has a rep prefix (0xF3).
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_REP = 0x00000040,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction has an operand size prefix (0x66).
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_OPERAND_SIZE = 0x00000080,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction has an address size prefix (0x67).
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_ADDRESS_SIZE = 0x00000100,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction has a rex prefix (0x40 - 0x4F).
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_REX = 0x00000200,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction has a vex prefix (0xC4 or 0xC5).
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_PREFIX_VEX = 0x00000400,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction has a modrm byte.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_MODRM = 0x00000800,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction has a sib byte.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_SIB = 0x00001000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction has an operand with a relative address.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_RELATIVE = 0x00002000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief An error occured while decoding the instruction.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_ERROR_MASK = 0xFFF00000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief End of input reached while decoding the instruction.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_ERROR_END_OF_INPUT = 0x00100000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction length has exceeded the maximum of 15 bytes.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_ERROR_LENGTH = 0x00200000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction is invalid.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_ERROR_INVALID = 0x00400000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction is invalid in 64 bit mode.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_ERROR_INVALID_64 = 0x00800000,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief An error occured while decoding the instruction operands.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_ERROR_OPERAND = 0x01000000,
|
2015-03-16 23:37:15 +08:00
|
|
|
|
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_IF_FORCE_DWORD = 0x7FFFFFFF
|
|
|
|
|
} ZydisInstructionFlags;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Values that represent a cpu register.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
typedef enum _ZydisRegister /* : uint16_t */
|
2014-10-25 05:11:16 +08:00
|
|
|
|
{
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_NONE,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* 8 bit general purpose registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_AL, ZYDIS_REG_CL, ZYDIS_REG_DL, ZYDIS_REG_BL,
|
|
|
|
|
ZYDIS_REG_AH, ZYDIS_REG_CH, ZYDIS_REG_DH, ZYDIS_REG_BH,
|
|
|
|
|
ZYDIS_REG_SPL, ZYDIS_REG_BPL, ZYDIS_REG_SIL, ZYDIS_REG_DIL,
|
|
|
|
|
ZYDIS_REG_R8B, ZYDIS_REG_R9B, ZYDIS_REG_R10B, ZYDIS_REG_R11B,
|
|
|
|
|
ZYDIS_REG_R12B, ZYDIS_REG_R13B, ZYDIS_REG_R14B, ZYDIS_REG_R15B,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* 16 bit general purpose registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_AX, ZYDIS_REG_CX, ZYDIS_REG_DX, ZYDIS_REG_BX,
|
|
|
|
|
ZYDIS_REG_SP, ZYDIS_REG_BP, ZYDIS_REG_SI, ZYDIS_REG_DI,
|
|
|
|
|
ZYDIS_REG_R8W, ZYDIS_REG_R9W, ZYDIS_REG_R10W, ZYDIS_REG_R11W,
|
|
|
|
|
ZYDIS_REG_R12W, ZYDIS_REG_R13W, ZYDIS_REG_R14W, ZYDIS_REG_R15W,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* 32 bit general purpose registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_EAX, ZYDIS_REG_ECX, ZYDIS_REG_EDX, ZYDIS_REG_EBX,
|
|
|
|
|
ZYDIS_REG_ESP, ZYDIS_REG_EBP, ZYDIS_REG_ESI, ZYDIS_REG_EDI,
|
|
|
|
|
ZYDIS_REG_R8D, ZYDIS_REG_R9D, ZYDIS_REG_R10D, ZYDIS_REG_R11D,
|
|
|
|
|
ZYDIS_REG_R12D, ZYDIS_REG_R13D, ZYDIS_REG_R14D, ZYDIS_REG_R15D,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* 64 bit general purpose registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_RAX, ZYDIS_REG_RCX, ZYDIS_REG_RDX, ZYDIS_REG_RBX,
|
|
|
|
|
ZYDIS_REG_RSP, ZYDIS_REG_RBP, ZYDIS_REG_RSI, ZYDIS_REG_RDI,
|
|
|
|
|
ZYDIS_REG_R8, ZYDIS_REG_R9, ZYDIS_REG_R10, ZYDIS_REG_R11,
|
|
|
|
|
ZYDIS_REG_R12, ZYDIS_REG_R13, ZYDIS_REG_R14, ZYDIS_REG_R15,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* segment registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_ES, ZYDIS_REG_CS, ZYDIS_REG_SS,
|
|
|
|
|
ZYDIS_REG_DS, ZYDIS_REG_FS, ZYDIS_REG_GS,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* control registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_CR0, ZYDIS_REG_CR1, ZYDIS_REG_CR2, ZYDIS_REG_CR3,
|
|
|
|
|
ZYDIS_REG_CR4, ZYDIS_REG_CR5, ZYDIS_REG_CR6, ZYDIS_REG_CR7,
|
|
|
|
|
ZYDIS_REG_CR8, ZYDIS_REG_CR9, ZYDIS_REG_CR10, ZYDIS_REG_CR11,
|
|
|
|
|
ZYDIS_REG_CR12, ZYDIS_REG_CR13, ZYDIS_REG_CR14, ZYDIS_REG_CR15,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* debug registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_DR0, ZYDIS_REG_DR1, ZYDIS_REG_DR2, ZYDIS_REG_DR3,
|
|
|
|
|
ZYDIS_REG_DR4, ZYDIS_REG_DR5, ZYDIS_REG_DR6, ZYDIS_REG_DR7,
|
|
|
|
|
ZYDIS_REG_DR8, ZYDIS_REG_DR9, ZYDIS_REG_DR10, ZYDIS_REG_DR11,
|
|
|
|
|
ZYDIS_REG_DR12, ZYDIS_REG_DR13, ZYDIS_REG_DR14, ZYDIS_REG_DR15,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* mmx registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_MM0, ZYDIS_REG_MM1, ZYDIS_REG_MM2, ZYDIS_REG_MM3,
|
|
|
|
|
ZYDIS_REG_MM4, ZYDIS_REG_MM5, ZYDIS_REG_MM6, ZYDIS_REG_MM7,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* x87 registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_ST0, ZYDIS_REG_ST1, ZYDIS_REG_ST2, ZYDIS_REG_ST3,
|
|
|
|
|
ZYDIS_REG_ST4, ZYDIS_REG_ST5, ZYDIS_REG_ST6, ZYDIS_REG_ST7,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* extended multimedia registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_XMM0, ZYDIS_REG_XMM1, ZYDIS_REG_XMM2, ZYDIS_REG_XMM3,
|
|
|
|
|
ZYDIS_REG_XMM4, ZYDIS_REG_XMM5, ZYDIS_REG_XMM6, ZYDIS_REG_XMM7,
|
|
|
|
|
ZYDIS_REG_XMM8, ZYDIS_REG_XMM9, ZYDIS_REG_XMM10, ZYDIS_REG_XMM11,
|
|
|
|
|
ZYDIS_REG_XMM12, ZYDIS_REG_XMM13, ZYDIS_REG_XMM14, ZYDIS_REG_XMM15,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* 256 bit multimedia registers */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_YMM0, ZYDIS_REG_YMM1, ZYDIS_REG_YMM2, ZYDIS_REG_YMM3,
|
|
|
|
|
ZYDIS_REG_YMM4, ZYDIS_REG_YMM5, ZYDIS_REG_YMM6, ZYDIS_REG_YMM7,
|
|
|
|
|
ZYDIS_REG_YMM8, ZYDIS_REG_YMM9, ZYDIS_REG_YMM10, ZYDIS_REG_YMM11,
|
|
|
|
|
ZYDIS_REG_YMM12, ZYDIS_REG_YMM13, ZYDIS_REG_YMM14, YMM15,
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/* instruction pointer register */
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_RIP,
|
2015-03-16 23:37:15 +08:00
|
|
|
|
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_REG_FORCE_WORD = 0x7FFF
|
|
|
|
|
} ZydisRegister;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief Values that represent the type of a decoded operand.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
typedef enum _ZydisOperandType /*: uint8_t*/
|
2014-10-27 21:10:22 +08:00
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is not used.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPTYPE_NONE,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is a register operand.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPTYPE_REGISTER,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is a memory operand.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPTYPE_MEMORY,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is a pointer operand.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPTYPE_POINTER,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is an immediate operand.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPTYPE_IMMEDIATE,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is a relative immediate operand.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPTYPE_REL_IMMEDIATE,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is a constant value.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPTYPE_CONSTANT
|
|
|
|
|
} ZydisOperandType;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Values that represent the operand access mode.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
typedef enum _ZydisOperandAccessMode /* : uint8_t */
|
2014-10-27 21:10:22 +08:00
|
|
|
|
{
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPACCESSMODE_NA,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is accessed in read-only mode.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPACCESSMODE_READ,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is accessed in write mode.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPACCESSMODE_WRITE,
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand is accessed in read-write mode.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZYDIS_OPACCESSMODE_READWRITE
|
|
|
|
|
} ZydisOperandAccessMode;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief This struct holds information about a decoded operand.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
typedef struct _ZydisOperandInfo
|
2014-10-25 05:11:16 +08:00
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* @brief The type of the operand.
|
2015-05-16 11:05:17 +08:00
|
|
|
|
* @see ZydisOperandType
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-03-16 23:37:15 +08:00
|
|
|
|
uint8_t type;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The size of the operand.
|
|
|
|
|
*/
|
|
|
|
|
uint16_t size;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The operand access mode.
|
2015-05-16 11:05:17 +08:00
|
|
|
|
* @see ZydisOperandAccessMode
|
2014-10-27 21:10:22 +08:00
|
|
|
|
*/
|
2015-03-16 23:37:15 +08:00
|
|
|
|
uint8_t access_mode;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The base register.
|
2015-05-16 11:05:17 +08:00
|
|
|
|
* @see ZydisRegister
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-03-16 23:37:15 +08:00
|
|
|
|
uint16_t base;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The index register.
|
2015-05-16 11:05:17 +08:00
|
|
|
|
* @see ZydisRegister
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-03-16 23:37:15 +08:00
|
|
|
|
uint16_t index;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The scale factor.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t scale;
|
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The lvalue offset. If the @c offset is zero and the operand @c type is not
|
|
|
|
|
* @c CONSTANT, no lvalue is present.
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
|
|
|
|
uint8_t offset;
|
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief Signals, if the lval is signed.
|
|
|
|
|
*/
|
|
|
|
|
bool signed_lval;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The lvalue.
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
|
|
|
|
union {
|
|
|
|
|
int8_t sbyte;
|
|
|
|
|
uint8_t ubyte;
|
|
|
|
|
int16_t sword;
|
|
|
|
|
uint16_t uword;
|
|
|
|
|
int32_t sdword;
|
|
|
|
|
uint32_t udword;
|
|
|
|
|
int64_t sqword;
|
|
|
|
|
uint64_t uqword;
|
|
|
|
|
struct {
|
|
|
|
|
uint16_t seg;
|
|
|
|
|
uint32_t off;
|
|
|
|
|
} ptr;
|
|
|
|
|
} lval;
|
2015-05-16 11:05:17 +08:00
|
|
|
|
} ZydisOperandInfo;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief This struct holds information about a decoded instruction.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
typedef struct _ZydisInstructionInfo
|
2014-10-25 05:11:16 +08:00
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction flags.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t flags;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction mnemonic.
|
2015-05-16 11:05:17 +08:00
|
|
|
|
* @see ZydisInstructionMnemonic
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-03-16 23:37:15 +08:00
|
|
|
|
uint16_t mnemonic;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The total length of the instruction.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t length;
|
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief Contains all bytes of the instruction.
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2014-10-27 21:10:22 +08:00
|
|
|
|
uint8_t data[15];
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The length of the instruction opcodes.
|
|
|
|
|
*/
|
2014-10-27 21:10:22 +08:00
|
|
|
|
uint8_t opcode_length;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction opcodes.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t opcode[3];
|
|
|
|
|
/**
|
|
|
|
|
* @brief The operand mode.
|
|
|
|
|
*/
|
2014-10-27 21:10:22 +08:00
|
|
|
|
uint8_t operand_mode;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The address mode.
|
|
|
|
|
*/
|
2014-10-27 21:10:22 +08:00
|
|
|
|
uint8_t address_mode;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The decoded operands.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
ZydisOperandInfo operand[4];
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The segment register. This value will default to @c NONE, if no segment register
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* prefix is present.
|
2015-05-16 11:05:17 +08:00
|
|
|
|
* @see ZydisRegister
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2015-03-16 23:37:15 +08:00
|
|
|
|
uint16_t segment;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The rex prefix byte.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t rex;
|
|
|
|
|
/**
|
|
|
|
|
* @brief When 1, a 64-bit operand size is used. Otherwise, when 0, the default operand size
|
|
|
|
|
* is used.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t rex_w;
|
|
|
|
|
/**
|
|
|
|
|
* @brief This 1-bit value is an extension to the MODRM.reg field.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t rex_r;
|
|
|
|
|
/**
|
|
|
|
|
* @brief This 1-bit value is an extension to the SIB.index field.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t rex_x;
|
|
|
|
|
/**
|
|
|
|
|
* @brief This 1-bit value is an extension to the MODRM.rm field or the SIB.base field.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t rex_b;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The modrm byte.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t modrm;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The modrm modus bits. When this field is b11, then register-direct addressing mode
|
|
|
|
|
* is used; otherwise register-indirect addressing mode is used.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t modrm_mod;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The modrm register bits. The REX.R, VEX.~R or XOP.~R field can extend this field
|
|
|
|
|
* with 1 most-significant bit to 4 bits total.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t modrm_reg;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The extended modrm register bits. If the instruction definition does not have the
|
|
|
|
|
* @c IDF_ACCEPTS_REXR flag set, this value defaults to the normal @c modrm_reg
|
|
|
|
|
* field.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t modrm_reg_ext;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The modrm register/memory bits. Specifies a direct or indirect register operand,
|
|
|
|
|
* optionally with a displacement. The REX.B, VEX.~B or XOP.~B field can extend this
|
|
|
|
|
* field with 1 most-significant bit to 4 bits total.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t modrm_rm;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The extended modrm register/memory bits. If the instruction definition does not
|
|
|
|
|
* have the @c IDF_ACCEPTS_REXB flag set, this value defaults to the normal
|
|
|
|
|
* @c modrm_rm field.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t modrm_rm_ext;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The sib byte.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t sib;
|
|
|
|
|
/**
|
|
|
|
|
* @brief This field indicates the scaling factor of SIB.index.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t sib_scale;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The index register to use. The REX.X, VEX.~X or XOP.~X field can extend this field
|
|
|
|
|
* with 1 most-significant bit to 4 bits total.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t sib_index;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The extended index register. If the instruction definition does not have the
|
|
|
|
|
* @c IDF_ACCEPTS_REXX flag set, this value defaults to the normal @c sib_index
|
|
|
|
|
* field.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t sib_index_ext;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The base register to use. The REX.B, VEX.~B or XOP.~B field can extend this field
|
|
|
|
|
* with 1 most-significant bit to 4 bits total.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t sib_base;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The extended base register. If the instruction definition does not have the
|
|
|
|
|
* @c IDF_ACCEPTS_REXB flag set, this value defaults to the normal @c sib_index
|
|
|
|
|
* field.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t sib_base_ext;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The primary vex prefix byte.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_op;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The second vex prefix byte.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_b1;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The third vex prefix byte.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_b2;
|
|
|
|
|
/**
|
|
|
|
|
* @brief This 1-bit value is an 'inverted' extension to the MODRM.reg field. The inverse of
|
|
|
|
|
* REX.R.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_r;
|
|
|
|
|
/**
|
|
|
|
|
* @brief This 1-bit value is an 'inverted' extension to the SIB.index field. The inverse of
|
|
|
|
|
* REX.X.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_x;
|
|
|
|
|
/**
|
|
|
|
|
* @brief This 1-bit value is an 'inverted' extension to the MODRM.rm field or the SIB.base
|
|
|
|
|
* field. The inverse of REX.B.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_b;
|
|
|
|
|
/**
|
|
|
|
|
* @brief Specifies the opcode map to use.
|
|
|
|
|
* 00 = 0x0F
|
|
|
|
|
* 01 = 0x0F 0x38
|
|
|
|
|
* 02 = 0x0F 0x3A
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_m_mmmm;
|
|
|
|
|
/**
|
|
|
|
|
* @brief For integer instructions: when 1, a 64-bit operand size is used; otherwise,
|
|
|
|
|
* when 0, the default operand size is used (equivalent with REX.W). For non-integer
|
|
|
|
|
* instructions, this bit is a general opcode extension bit.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_w;
|
|
|
|
|
/**
|
|
|
|
|
* @brief An additional operand for the instruction. The value of the XMM or YMM register
|
|
|
|
|
* is 'inverted'.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_vvvv;
|
|
|
|
|
/**
|
|
|
|
|
* @brief When 0, a 128-bit vector lengh is used. Otherwise, when 1, a 256-bit vector length
|
|
|
|
|
* is used.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_l;
|
|
|
|
|
/**
|
|
|
|
|
* @brief Specifies an implied mandatory prefix for the opcode.
|
|
|
|
|
* 00 = none
|
|
|
|
|
* 01 = 0x66
|
|
|
|
|
* 10 = 0xF3
|
|
|
|
|
* 11 = 0xF2
|
|
|
|
|
*/
|
|
|
|
|
uint8_t vex_pp;
|
2014-10-27 21:10:22 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The effectively used REX/VEX.w value. If the instruction definition does not have
|
|
|
|
|
* the @c IDF_ACCEPTS_REXW flag set, this value defaults to zero.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t eff_rexvex_w;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The effectively used REX/VEX.r value. If the instruction definition does not have
|
|
|
|
|
* the @c IDF_ACCEPTS_REXR flag set, this value defaults to zero.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t eff_rexvex_r;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The effectively used REX/VEX.x value. If the instruction definition does not have
|
|
|
|
|
* the @c IDF_ACCEPTS_REXX flag set, this value defaults to zero.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t eff_rexvex_x;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The effectively used REX/VEX.b value. If the instruction definition does not have
|
|
|
|
|
* the @c IDF_ACCEPTS_REXB flag set, this value defaults to zero.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t eff_rexvex_b;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The effectively used VEX.l value. If the instruction definition does not have
|
|
|
|
|
* the @c IDF_ACCEPTS_VEXL flag set, this value defaults to zero.
|
|
|
|
|
*/
|
|
|
|
|
uint8_t eff_vex_l;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction definition.
|
|
|
|
|
*/
|
2015-05-16 11:05:17 +08:00
|
|
|
|
const void* instrDefinition; /* TODO: Port instruction definition types */
|
2014-10-25 05:11:16 +08:00
|
|
|
|
/**
|
2014-10-27 21:10:22 +08:00
|
|
|
|
* @brief The instruction address points to the current instruction (relative to the
|
|
|
|
|
* initial instruction pointer).
|
|
|
|
|
*/
|
|
|
|
|
uint64_t instrAddress;
|
|
|
|
|
/**
|
|
|
|
|
* @brief The instruction pointer points to the address of the next instruction (relative
|
|
|
|
|
* to the initial instruction pointer).
|
|
|
|
|
* This field is used to properly format relative instructions.
|
2014-10-25 05:11:16 +08:00
|
|
|
|
*/
|
2014-10-27 21:10:22 +08:00
|
|
|
|
uint64_t instrPointer;
|
2015-05-16 11:05:17 +08:00
|
|
|
|
} ZydisInstructionInfo;
|
2014-10-25 05:11:16 +08:00
|
|
|
|
|
2015-03-16 23:37:15 +08:00
|
|
|
|
#ifdef __cplusplus
|
2014-10-25 05:11:16 +08:00
|
|
|
|
}
|
2015-03-16 23:37:15 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
2015-05-16 11:05:17 +08:00
|
|
|
|
#endif /* _ZYDIS_TYPES_H_ */
|