Minor refactorings and further preparation for advanced features

This commit is contained in:
flobernd 2016-11-11 22:03:26 +01:00
parent 98e9559d6d
commit 3f09ffca69
19 changed files with 1776 additions and 174 deletions

View File

@ -1,5 +1,4 @@
cmake_minimum_required(VERSION 2.8.12) cmake_minimum_required(VERSION 2.8.12)
cmake_policy(SET CMP0054 NEW)
include(GenerateExportHeader) include(GenerateExportHeader)
project(Zydis) project(Zydis)
@ -84,6 +83,16 @@ generate_export_header(
EXPORT_FILE_NAME "ZydisExportConfig.h") EXPORT_FILE_NAME "ZydisExportConfig.h")
include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR})
if (FEATURE_IMPLICITLY_USED_REGISTERS)
target_compile_definitions(Zydis PRIVATE ZYDIS_ENABLE_FEATURE_IMPLICITLY_USED_REGISTERS)
endif ()
if (FEATURE_AFFECTED_FLAGS)
target_compile_definitions(Zydis PRIVATE ZYDIS_ENABLE_FEATURE_AFFECTED_FLAGS)
endif ()
if (FEATURE_CPUID)
target_compile_definitions(Zydis PRIVATE ZYDIS_ENABLE_FEATURE_CPUID)
endif ()
# Examples # Examples
if (BUILD_EXAMPLES) if (BUILD_EXAMPLES)
include_directories("include") include_directories("include")

View File

@ -64,8 +64,7 @@ begin
Generator.OnWorkStart := GeneratorWorkStart; Generator.OnWorkStart := GeneratorWorkStart;
Generator.OnWork := GeneratorWork; Generator.OnWork := GeneratorWork;
Generator.OnWorkEnd := GeneratorWorkEnd; Generator.OnWorkEnd := GeneratorWorkEnd;
Generator.GenerateCode( Generator.GenerateCode(FEditor, 'F:\Development\GitHub\zyan-disassembler-engine\', Statistics);
FEditor, 'D:\Verteron Development\GitHub\zyan-disassembler-engine\', Statistics);
// TODO: Display statistics // TODO: Display statistics
finally finally
Generator.Free; Generator.Free;

View File

@ -243,8 +243,6 @@ object frmMain: TfrmMain
OnGetImageIndex = EditorTreeGetImageIndex OnGetImageIndex = EditorTreeGetImageIndex
OnKeyDown = EditorTreeKeyDown OnKeyDown = EditorTreeKeyDown
OnMouseUp = EditorTreeMouseUp OnMouseUp = EditorTreeMouseUp
ExplicitLeft = 370
ExplicitTop = 133
Columns = < Columns = <
item item
Position = 0 Position = 0

View File

@ -16,7 +16,9 @@ uses
// definitions // definitions
// http://www.delphipraxis.net/136601-virtual-treeview-multiselect-onchange-event-problem.html // http://www.delphipraxis.net/136601-virtual-treeview-multiselect-onchange-event-problem.html
// TODO: Update inspector after inspected object changed // TODO: [ ] Update inspector after inspected object changed
// [ ] Create seperated class for persistent settings
// [ ] Seperate view from business logic
type type
TfrmMain = class(TdxRibbonForm) TfrmMain = class(TdxRibbonForm)
@ -803,7 +805,7 @@ procedure TfrmMain.EditorTreeGetImageIndex(Sender: TBaseVirtualTree;
var var
NodeData: PEditorNodeData; NodeData: PEditorNodeData;
begin begin
if (Column <> 0) or (Kind = ikOverlay) then if (Column <> 0) or (not (Kind in [ikNormal, ikSelected])) then
begin begin
Exit; Exit;
end; end;

View File

@ -154,7 +154,7 @@ const
SIZEOF_OPERANDDEFINITION = 2; SIZEOF_OPERANDDEFINITION = 2;
DIRECTORY_INCLUDE_INTERNAL = 'include\Zydis\Internal'; DIRECTORY_INCLUDE_INTERNAL = 'include\Zydis\Internal';
FILENAME_INSTRUCTIONFILTERS = 'InstructionFilters.inc'; FILENAME_INSTRUCTIONFILTERS = 'InstructionFilters.inc';
FILENAME_MNEMONICENUM = 'MnemonicEnum.inc'; FILENAME_MNEMONICDEFINES = 'MnemonicDefines.inc';
FILENAME_MNEMONICSTRINGS = 'MnemonicStrings.inc'; FILENAME_MNEMONICSTRINGS = 'MnemonicStrings.inc';
FILENAME_INSTRUCTIONDEFINITIONS = 'InstructionDefinitions.inc'; FILENAME_INSTRUCTIONDEFINITIONS = 'InstructionDefinitions.inc';
FILENAME_OPERANDDEFINITIONS = 'OperandDefinitions.inc'; FILENAME_OPERANDDEFINITIONS = 'OperandDefinitions.inc';
@ -769,24 +769,18 @@ var
begin begin
List := TStringList.Create; List := TStringList.Create;
try try
WorkStart('Generating mnemonic enum', Low(MnemonicList), High(MnemonicList)); WorkStart('Generating mnemonic defines', Low(MnemonicList), High(MnemonicList));
Buffer := TStringBuffer.Create; Buffer := TStringBuffer.Create;
try try
for I := Low(MnemonicList) to High(MnemonicList) do for I := Low(MnemonicList) to High(MnemonicList) do
begin begin
Buffer.Append( Buffer.Append(Format('#define /*%.4x*/ ZYDIS_MNEMONIC_%s 0x%.4x', [
Format(' /*%.4x*/ ZYDIS_MNEMONIC_%s', [I, AnsiUpperCase(MnemonicList[I])])); I, AnsiUpperCase(MnemonicList[I]), I]));
if (I = High(MnemonicList)) then Buffer.AppendLn('');
begin
Buffer.AppendLn('');
end else
begin
Buffer.AppendLn(',');
end;
Work(I); Work(I);
end; end;
List.Text := Buffer.Value; List.Text := Buffer.Value;
List.SaveToFile(IncludeTrailingPathDelimiter(OutputDirectory) + FILENAME_MNEMONICENUM); List.SaveToFile(IncludeTrailingPathDelimiter(OutputDirectory) + FILENAME_MNEMONICDEFINES);
finally finally
Buffer.Free; Buffer.Free;
end; end;

View File

@ -47,12 +47,48 @@ extern "C" {
typedef uint32_t ZydisDecoderFlags; typedef uint32_t ZydisDecoderFlags;
/** /**
* @brief Values that represent zydis decoder-flags. * @brief Set this flag if you do not want @c ZydisDecoderDecodeNextInstruction to fail with
* @c ZYDIS_STATUS_INVALID_INSTRUCTION, if an invalid instruction was found.
*
* If this flag is set, @c ZydisDecoderDecodeNextInstruction just skips one byte and
* returns @c ZYDIS_STATUS_SUCCESS. The returned @c ZydisInstructionInfo struct will
* have one of the @c ZYDIS_IFLAG_ERROR_MASK flags set.
*/ */
enum ZydisDecoderFlag #define ZYDIS_DECODER_FLAG_SKIP_DATA 0x00000001
{ /**
ZYDIS_DECODER_FLAG_SKIP_DATA = 0x00000001 * @brief Includes information about all registers implicitly used by the instruction.
}; *
* If the @c ZYDIS_FEATURE_IMPLICITLY_USED_REGISTERS feature is not available,
* @c ZydisDecoderDecodeNextInstruction will fail with
* @c ZYDIS_STATUS_INVALID_OPERATION.
*/
#define ZYDIS_DECODER_FLAG_REGISTER_USAGE_IMPLICIT 0x00000002
/**
* @brief Includes information about all registers explicitly used by the instruction.
*/
#define ZYDIS_DECODER_FLAG_REGISTER_USAGE_EXPLICIT 0x00000004
/**
* @brief Includes information about all registers indicrectly used by the instruction.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the EAX/AX/AL/AH
* registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the AX/EAX/RAX
* registers as well.
*
* This flag only works if either the @c ZYDIS_DECODER_FLAG_REGISTER_USAGE_IMPLICIT and/or the
* @c ZYDIS_DECODER_FLAG_REGISTER_USAGE_EXPLICIT flag is set.
*/
#define ZYDIS_DECODER_FLAG_REGISTER_USAGE_INDIRECT 0x00000008
/**
* @brief Includes information about bits of the FLAGS/EFLAGS/RFLAGS register that are
* affected by the instruction.
*/
#define ZYDIS_DECODER_FLAG_AFFECTED_REGISTERS 0x00000010
/**
* @brief Includes information about the CPUID feature flags of the the instruction.
*/
#define ZYDIS_DECODER_FLAG_CPUID 0x00000020
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -77,6 +113,15 @@ typedef struct ZydisInstructionDecoder_
* @brief The current instruction-pointer value. * @brief The current instruction-pointer value.
*/ */
uint64_t instructionPointer; uint64_t instructionPointer;
/**
* @brief Internal field. @c TRUE, if the @c imm8 value is already initialized.
*/
bool imm8initialized;
/**
* @brief Internal field. We have to store a copy of the imm8 value for instructions that
* encode different operands in the lo and hi part of the immediate.
*/
uint8_t imm8;
/** /**
* @brief Internal buffer. * @brief Internal buffer.
*/ */

View File

@ -66,17 +66,11 @@ enum ZydisFormatterStyles
*/ */
typedef uint8_t ZydisFormatterFlags; typedef uint8_t ZydisFormatterFlags;
/** #define ZYDIS_FORMATTER_FLAG_UPPERCASE 0x01
* @brief Values that represent formatter-flags. #define ZYDIS_FORMATTER_FLAG_TAB_AFTER_MNEMONIC 0x02
*/ #define ZYDIS_FORMATTER_FLAG_NO_SPACE_BETWEEN_OPERANDS 0x04
enum ZydisFormatterFlag #define ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SIZE 0x08
{ #define ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT 0x10
ZYDIS_FORMATTER_FLAG_UPPERCASE = 0x01,
ZYDIS_FORMATTER_FLAG_TAB_AFTER_MNEMONIC = 0x02,
ZYDIS_FORMATTER_FLAG_NO_SPACE_BETWEEN_OPERANDS = 0x04,
ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SIZE = 0x08,
ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT = 0x10
};
/** /**
* @brief Defines the zydis address-format datatype. * @brief Defines the zydis address-format datatype.

View File

@ -44,6 +44,96 @@ extern "C" {
/* Enums and types */ /* Enums and types */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisRegisterAccessFlags datatype.
*/
typedef uint8_t ZydisRegisterAccessFlags;
/**
* @brief The instruction reads from this register.
*/
#define ZYDIS_REGISTER_ACCESS_READ 0x01
/**
* @brief The instruction writes to this register.
*/
#define ZYDIS_REGISTER_ACCESS_WRITE 0x02
/**
* @brief The instruction implicitly reads from this register.
*/
#define ZYDIS_REGISTER_ACCESS_IMPLICIT_READ 0x04
/**
* @brief The instruction implicitly writes to this register.
*/
#define ZYDIS_REGISTER_ACCESS_IMPLICIT_WRITE 0x08
/**
* @brief The instruction indirectly reads from this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_READ 0x10
/**
* @brief The instruction indirectly writes to this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_WRITE 0x20
/**
* @brief The instruction indirectly and implicitly reads from this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_IMPLICIT_READ 0x40
/**
* @brief The instruction indirectly and implicitly writes to this register.
*
* For example:
* [1] If the instruction accesses the RAX register, it indirectly accesses the
* EAX/AX/AL/AH registers as well.
* [2] If the instruction accesses the AL register, it indirectly accesses the
* AX/EAX/RAX registers as well.
*/
#define ZYDIS_REGISTER_ACCESS_INDIRECT_IMPLICIT_WRITE 0x80
/**
* @brief Defines the @c ZydisRegisterInfo struct.
*/
typedef struct ZydisRegisterInfo_
{
/**
* @brief The number of items in the @c reg array.
*/
uint8_t count;
/**
* @brief Array with advanced information about every register used by the current
* instruction.
*/
struct
{
/**
* @brief The register id.
*/
ZydisRegister id;
/**
* @brief The register access-flags.
*/
ZydisRegisterAccessFlags access;
} reg[255];
} ZydisRegisterInfo;
/* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Defines the zydis cpuid-feature-flag datatype. * @brief Defines the zydis cpuid-feature-flag datatype.
*/ */

View File

@ -73,55 +73,59 @@ enum ZydisDisassemblerModes
*/ */
typedef uint32_t ZydisInstructionFlags; typedef uint32_t ZydisInstructionFlags;
/**
* @brief The instruction has one or more operand with position-relative offsets.
*/
#define ZYDIS_IFLAG_RELATIVE 0x00000001
/** /**
* @brief The instruction has the modrm byte. * @brief The instruction has the modrm byte.
*/ */
#define ZYDIS_IFLAG_HAS_MODRM 0x00000002 #define ZYDIS_INSTRUCTION_HAS_MODRM 0x00000001
/** /**
* @brief The instruction has the sib byte. * @brief The instruction has the sib byte.
*/ */
#define ZYDIS_IFLAG_HAS_SIB 0x00000004 #define ZYDIS_INSTRUCTION_HAS_SIB 0x00000002
/**
* @brief The instruction has one or more operands with position-relative offsets.
*/
#define ZYDIS_INSTRUCTION_RELATIVE 0x00000004
/**
* @brief The instruction is privileged and may only be executed in kernel-mode (ring0).
*/
#define ZYDIS_INSTRUCTION_PRIVILEGED 0x00000008
/** /**
* @brief An error occured while decoding the current instruction. * @brief An error occured while decoding the current instruction.
*/ */
#define ZYDIS_IFLAG_ERROR_MASK 0x7F000000 #define ZYDIS_INSTRUCTION_ERROR_MASK 0x7F000000
/** /**
* @brief The instruction is invalid. * @brief The instruction is invalid.
*/ */
#define ZYDIS_IFLAG_ERROR_INVALID 0x01000000 #define ZYDIS_INSTRUCTION_ERROR_INVALID 0x01000000
/** /**
* @brief The instruction length has exceeded the maximum of 15 bytes. * @brief The instruction length has exceeded the maximum of 15 bytes.
*/ */
#define ZYDIS_IFLAG_ERROR_INSTRUCTION_LENGTH 0x02000000 #define ZYDIS_INSTRUCTION_ERROR_INSTRUCTION_LENGTH 0x02000000
/** /**
* @brief An error occured while decoding the vex-prefix. * @brief An error occured while decoding the vex-prefix.
*/ */
#define ZYDIS_IFLAG_ERROR_MALFORMED_VEX 0x04000000 #define ZYDIS_INSTRUCTION_ERROR_MALFORMED_VEX 0x04000000
/** /**
* @brief An error occured while decoding the evex-prefix. * @brief An error occured while decoding the evex-prefix.
*/ */
#define ZYDIS_IFLAG_ERROR_MALFORMED_EVEX 0x08000000 #define ZYDIS_INSTRUCTION_ERROR_MALFORMED_EVEX 0x08000000
/** /**
* @brief An error occured while decoding the xop-prefix. * @brief An error occured while decoding the xop-prefix.
*/ */
#define ZYDIS_IFLAG_ERROR_MALFORMED_XOP 0x10000000 #define ZYDIS_INSTRUCTION_ERROR_MALFORMED_XOP 0x10000000
/** /**
* @brief A rex-prefix was found while decoding a vex/evex/xop instruction. * @brief A rex-prefix was found while decoding a vex/evex/xop instruction.
*/ */
#define ZYDIS_IFLAG_ERROR_ILLEGAL_REX 0x20000000 #define ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX 0x20000000
/** /**
* @brief An invalid constellation was found while decoding an instruction that uses the VSIB * @brief An invalid constellation was found while decoding an instruction that uses the VSIB
* addressing mode. * addressing mode.
*/ */
#define ZYDIS_IFLAG_ERROR_INVALID_VSIB 0x40000000 #define ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB 0x40000000
/** /**
* @brief An error occured while decoding the instruction-operands. * @brief An error occured while decoding the instruction-operands.
*/ */
#define ZYDIS_IFLAG_ERROR_OPERANDS 0x40000000 #define ZYDIS_INSTRUCTION_ERROR_OPERANDS 0x40000000
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/* Prefix flags */ /* Prefix flags */
@ -385,7 +389,7 @@ enum ZydisOperandEncodings
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Defines an alias representing an operand-access mode. * @brief Defines the @c ZydisOperandAccess datatype.
*/ */
typedef uint8_t ZydisOperandAccess; typedef uint8_t ZydisOperandAccess;
@ -554,10 +558,6 @@ typedef struct ZydisOperandInfo_
*/ */
struct struct
{ {
/**
* @brief The physical displacement size.
*/
uint8_t size;
/** /**
* @brief The displacement value * @brief The displacement value
*/ */
@ -568,6 +568,10 @@ typedef struct ZydisOperandInfo_
int32_t sdword; int32_t sdword;
int64_t sqword; int64_t sqword;
} value; } value;
/**
* @brief The physical displacement size.
*/
uint8_t dataSize;
/** /**
* @brief The offset of the displacement data, relative to the beginning of the * @brief The offset of the displacement data, relative to the beginning of the
* instruction. * instruction.
@ -596,10 +600,6 @@ typedef struct ZydisOperandInfo_
* @brief Signals, if the immediate value contains a relative offset. * @brief Signals, if the immediate value contains a relative offset.
*/ */
bool isRelative; bool isRelative;
/**
* @brief The physical immediate size.
*/
uint8_t size;
/** /**
* @brief The immediate value. * @brief The immediate value.
*/ */
@ -614,6 +614,10 @@ typedef struct ZydisOperandInfo_
int64_t sqword; int64_t sqword;
uint64_t uqword; uint64_t uqword;
} value; } value;
/**
* @brief The physical immediate size.
*/
uint8_t dataSize;
/** /**
* @brief The offset of the immediate data, relative to the beginning of the instruction. * @brief The offset of the immediate data, relative to the beginning of the instruction.
*/ */
@ -708,7 +712,7 @@ typedef struct ZydisInstructionInfo_
*/ */
ZydisAVXRoundingMode roundingMode; ZydisAVXRoundingMode roundingMode;
/** /**
* @brief The AVX suppress-all-exceptions flag. * @brief @c TRUE, if the AVX suppress-all-exceptions flag is set.
*/ */
bool sae; bool sae;
} avx; } avx;
@ -721,7 +725,7 @@ typedef struct ZydisInstructionInfo_
* @brief The instruction pointer points at the address of the next instruction (relative * @brief The instruction pointer points at the address of the next instruction (relative
* to the initial instruction pointer). * to the initial instruction pointer).
* *
* This field is used to properly format relative instructions. * This field is used to properly format relative instructions.
*/ */
uint64_t instrPointer; uint64_t instrPointer;
/** /**
@ -902,9 +906,6 @@ typedef struct ZydisInstructionInfo_
*/ */
struct struct
{ {
// TODO: Move from this struct to the decoder instance
bool imm8initialized;
uint8_t imm8;
uint8_t w; uint8_t w;
uint8_t r; uint8_t r;
uint8_t x; uint8_t x;

File diff suppressed because it is too large Load Diff

View File

@ -44,13 +44,7 @@ extern "C" {
*/ */
typedef uint16_t ZydisInstructionMnemonic; typedef uint16_t ZydisInstructionMnemonic;
/** #include <Zydis/Internal/MnemonicDefines.inc>
* @brief Values that represent zydis instruction-mnemonics.
*/
enum ZydisInstructionMnemonics
{
#include <Zydis/Internal/MnemonicEnum.inc>
};
/* ============================================================================================== */ /* ============================================================================================== */
/* Exported functions */ /* Exported functions */

View File

@ -158,6 +158,8 @@ enum ZydisRegisterClasses
ZYDIS_REGISTERCLASS_BOUNDS ZYDIS_REGISTERCLASS_BOUNDS
}; };
/* ---------------------------------------------------------------------------------------------- */
/** /**
* @brief Defines the @c ZydisRegisterSize datatype. * @brief Defines the @c ZydisRegisterSize datatype.
*/ */

View File

@ -73,10 +73,6 @@ enum ZydisStatusCode
* @brief A buffer passed to a function was too small to complete the requested operation. * @brief A buffer passed to a function was too small to complete the requested operation.
*/ */
ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE = 0x00000008, ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE = 0x00000008,
/**
* @brief The start range of user defined status-codes.
*/
ZYDIS_STATUS_USER = 0x10000000 // TODO: Remove
}; };
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -30,6 +30,7 @@
#include <Zydis/Status.h> #include <Zydis/Status.h>
#include <Zydis/Mnemonic.h> #include <Zydis/Mnemonic.h>
#include <Zydis/Register.h> #include <Zydis/Register.h>
#include <Zydis/InstructionDetails.h>
#include <Zydis/InstructionInfo.h> #include <Zydis/InstructionInfo.h>
#include <Zydis/Input.h> #include <Zydis/Input.h>
#include <Zydis/Decoder.h> #include <Zydis/Decoder.h>

View File

@ -110,7 +110,7 @@ static ZydisDecoderStatus ZydisInputPeek(ZydisInstructionDecoder* decoder,
if (info->length >= ZYDIS_MAX_INSTRUCTION_LENGTH) if (info->length >= ZYDIS_MAX_INSTRUCTION_LENGTH)
{ {
info->flags |= ZYDIS_IFLAG_ERROR_INSTRUCTION_LENGTH; info->flags |= ZYDIS_INSTRUCTION_ERROR_INSTRUCTION_LENGTH;
return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION_LENGTH; return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION_LENGTH;
} }
@ -388,7 +388,7 @@ static void ZydisDecodeModrm(uint8_t modrmByte, ZydisInstructionInfo* info)
{ {
ZYDIS_ASSERT(info); ZYDIS_ASSERT(info);
info->flags |= ZYDIS_IFLAG_HAS_MODRM; info->flags |= ZYDIS_INSTRUCTION_HAS_MODRM;
info->details.modrm.isDecoded = true; info->details.modrm.isDecoded = true;
info->details.modrm.data[0] = modrmByte; info->details.modrm.data[0] = modrmByte;
info->details.modrm.mod = (modrmByte >> 6) & 0x03; info->details.modrm.mod = (modrmByte >> 6) & 0x03;
@ -408,7 +408,7 @@ static void ZydisDecodeSib(uint8_t sibByte, ZydisInstructionInfo* info)
ZYDIS_ASSERT(info->details.modrm.isDecoded); ZYDIS_ASSERT(info->details.modrm.isDecoded);
ZYDIS_ASSERT((info->details.modrm.rm & 0x7) == 4); ZYDIS_ASSERT((info->details.modrm.rm & 0x7) == 4);
info->flags |= ZYDIS_IFLAG_HAS_SIB; info->flags |= ZYDIS_INSTRUCTION_HAS_SIB;
info->details.sib.isDecoded = true; info->details.sib.isDecoded = true;
info->details.sib.data[0] = sibByte; info->details.sib.data[0] = sibByte;
info->details.sib.scale = (sibByte >> 6) & 0x03; info->details.sib.scale = (sibByte >> 6) & 0x03;
@ -556,7 +556,7 @@ static ZydisDecoderStatus ZydisDecodeOperandImmediate(ZydisInstructionDecoder* d
operand->type = ZYDIS_OPERAND_TYPE_IMMEDIATE; operand->type = ZYDIS_OPERAND_TYPE_IMMEDIATE;
operand->imm.isSigned = isSigned; operand->imm.isSigned = isSigned;
operand->imm.size = physicalSize; operand->imm.dataSize = physicalSize;
operand->imm.dataOffset = info->length; operand->imm.dataOffset = info->length;
switch (physicalSize) switch (physicalSize)
{ {
@ -564,10 +564,9 @@ static ZydisDecoderStatus ZydisDecodeOperandImmediate(ZydisInstructionDecoder* d
{ {
// We have to store a copy of the imm8 value for instructions that encode different operands // We have to store a copy of the imm8 value for instructions that encode different operands
// in the lo and hi part of the immediate. // in the lo and hi part of the immediate.
if (info->details.internal.imm8initialized) if (decoder->imm8initialized)
{ {
// TODO: Implement clean solution operand->imm.value.ubyte = decoder->imm8;
operand->imm.value.ubyte = info->details.internal.imm8;
} else } else
{ {
uint8_t immediate; uint8_t immediate;
@ -579,8 +578,8 @@ static ZydisDecoderStatus ZydisDecodeOperandImmediate(ZydisInstructionDecoder* d
{ {
operand->imm.value.uqword = immediate; operand->imm.value.uqword = immediate;
} }
info->details.internal.imm8initialized = true; decoder->imm8initialized = true;
info->details.internal.imm8 = operand->imm.value.ubyte; decoder->imm8 = operand->imm.value.ubyte;
} }
break; break;
} }
@ -646,7 +645,6 @@ static ZydisDecoderStatus ZydisDecodeOperandImmediate(ZydisInstructionDecoder* d
/** /**
* @brief Decodes an register-operand. * @brief Decodes an register-operand.
* *
* @param decoder A pointer to the @c ZydisInstructionDecoder decoder instance.
* @param info A pointer to the @c ZydisInstructionInfo struct. * @param info A pointer to the @c ZydisInstructionInfo struct.
* @param operand A pointer to the @c ZydisOperandInfo struct. * @param operand A pointer to the @c ZydisOperandInfo struct.
* @param registerClass The register class. * @param registerClass The register class.
@ -749,7 +747,7 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec
{ {
if (decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) if (decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT)
{ {
info->flags |= ZYDIS_IFLAG_RELATIVE; info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
operand->mem.base = ZYDIS_REGISTER_EIP; operand->mem.base = ZYDIS_REGISTER_EIP;
} else } else
{ {
@ -808,7 +806,7 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec
case 0: case 0:
if (modrm_rm == 5) if (modrm_rm == 5)
{ {
info->flags |= ZYDIS_IFLAG_RELATIVE; info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
operand->mem.base = ZYDIS_REGISTER_RIP; operand->mem.base = ZYDIS_REGISTER_RIP;
displacementSize = 32; displacementSize = 32;
} }
@ -862,13 +860,13 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec
if (displacementSize) if (displacementSize)
{ {
ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, displacementSize, true)); ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, displacementSize, true));
info->details.internal.imm8initialized = false; decoder->imm8initialized = false;
operand->type = ZYDIS_OPERAND_TYPE_MEMORY; operand->type = ZYDIS_OPERAND_TYPE_MEMORY;
operand->mem.disp.size = displacementSize; operand->mem.disp.dataSize = displacementSize;
operand->mem.disp.value.sqword = operand->imm.value.sqword; operand->mem.disp.value.sqword = operand->imm.value.sqword;
operand->mem.disp.dataOffset = operand->imm.dataOffset; operand->mem.disp.dataOffset = operand->imm.dataOffset;
operand->imm.isSigned = false; operand->imm.isSigned = false;
operand->imm.size = 0; operand->imm.dataSize = 0;
operand->imm.value.sqword = 0; operand->imm.value.sqword = 0;
operand->imm.dataOffset = 0; operand->imm.dataOffset = 0;
} }
@ -962,6 +960,8 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
operand->type = ZYDIS_OPERAND_TYPE_REGISTER; operand->type = ZYDIS_OPERAND_TYPE_REGISTER;
operand->reg = ZYDIS_REGISTER_ST0; operand->reg = ZYDIS_REGISTER_ST0;
return ZYDIS_STATUS_DECODER_SUCCESS; return ZYDIS_STATUS_DECODER_SUCCESS;
default:
break;
} }
// Register operands // Register operands
@ -1024,6 +1024,8 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
operand->size = 128; operand->size = 128;
registerClass = ZYDIS_REGISTERCLASS_BOUNDS; registerClass = ZYDIS_REGISTERCLASS_BOUNDS;
break; break;
default:
break;
} }
if (registerClass != ZYDIS_REGISTERCLASS_INVALID) if (registerClass != ZYDIS_REGISTERCLASS_INVALID)
{ {
@ -1078,7 +1080,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 8, false)); ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 8, false));
ZYDIS_CHECK(ZydisDecodeOperandRegister(info, operand, registerClass, ZYDIS_CHECK(ZydisDecodeOperandRegister(info, operand, registerClass,
(operand->imm.value.ubyte & 0xF0) >> 4)); (operand->imm.value.ubyte & 0xF0) >> 4));
operand->imm.size = 0; operand->imm.dataSize = 0;
operand->imm.dataOffset = 0; operand->imm.dataOffset = 0;
operand->imm.value.uqword = 0; operand->imm.value.uqword = 0;
return ZYDIS_STATUS_DECODER_SUCCESS; return ZYDIS_STATUS_DECODER_SUCCESS;
@ -1109,6 +1111,8 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
case ZYDIS_OPERAND_ENCODING_RM_CD64: case ZYDIS_OPERAND_ENCODING_RM_CD64:
evexCD8Scale = 64; evexCD8Scale = 64;
break; break;
default:
break;
}; };
ZydisRegister vsibBaseRegister = ZYDIS_REGISTER_NONE; ZydisRegister vsibBaseRegister = ZYDIS_REGISTER_NONE;
switch (type) switch (type)
@ -1233,11 +1237,13 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
operand->size = 64; operand->size = 64;
ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID)); ZYDIS_CHECK(ZydisDecodeOperandModrmRm(decoder, info, operand, ZYDIS_REGISTERCLASS_INVALID));
break; break;
default:
break;
} }
if (evexCD8Scale) if (evexCD8Scale)
{ {
ZYDIS_ASSERT(info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX); ZYDIS_ASSERT(info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX);
if (operand->mem.disp.size == 8) if (operand->mem.disp.dataSize == 8)
{ {
operand->mem.disp.value.sdword *= evexCD8Scale; operand->mem.disp.value.sdword *= evexCD8Scale;
} }
@ -1246,13 +1252,13 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
{ {
if (info->details.modrm.rm != 0x04) if (info->details.modrm.rm != 0x04)
{ {
info->flags |= ZYDIS_IFLAG_ERROR_INVALID_VSIB; info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB;
return ZYDIS_STATUS_DECODER_INVALID_VSIB; return ZYDIS_STATUS_DECODER_INVALID_VSIB;
} }
switch (info->addressMode) switch (info->addressMode)
{ {
case 16: case 16:
info->flags |= ZYDIS_IFLAG_ERROR_INVALID_VSIB; info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB;
return ZYDIS_STATUS_DECODER_INVALID_VSIB; return ZYDIS_STATUS_DECODER_INVALID_VSIB;
case 32: case 32:
operand->mem.index = operand->mem.index - ZYDIS_REGISTER_EAX + vsibBaseRegister; operand->mem.index = operand->mem.index - ZYDIS_REGISTER_EAX + vsibBaseRegister;
@ -1276,7 +1282,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
operand->imm.value.ubyte = 1; operand->imm.value.ubyte = 1;
return ZYDIS_STATUS_DECODER_SUCCESS; return ZYDIS_STATUS_DECODER_SUCCESS;
case ZYDIS_SEM_OPERAND_TYPE_REL8: case ZYDIS_SEM_OPERAND_TYPE_REL8:
info->flags |= ZYDIS_IFLAG_RELATIVE; info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
operand->imm.isRelative = true; operand->imm.isRelative = true;
case ZYDIS_SEM_OPERAND_TYPE_IMM8: case ZYDIS_SEM_OPERAND_TYPE_IMM8:
operand->size = 8; operand->size = 8;
@ -1287,26 +1293,28 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
operand->imm.isSigned = false; operand->imm.isSigned = false;
break; break;
case ZYDIS_SEM_OPERAND_TYPE_REL16: case ZYDIS_SEM_OPERAND_TYPE_REL16:
info->flags |= ZYDIS_IFLAG_RELATIVE; info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
operand->imm.isRelative = true; operand->imm.isRelative = true;
case ZYDIS_SEM_OPERAND_TYPE_IMM16: case ZYDIS_SEM_OPERAND_TYPE_IMM16:
operand->size = 16; operand->size = 16;
operand->imm.isSigned = true; operand->imm.isSigned = true;
break; break;
case ZYDIS_SEM_OPERAND_TYPE_REL32: case ZYDIS_SEM_OPERAND_TYPE_REL32:
info->flags |= ZYDIS_IFLAG_RELATIVE; info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
operand->imm.isRelative = true; operand->imm.isRelative = true;
case ZYDIS_SEM_OPERAND_TYPE_IMM32: case ZYDIS_SEM_OPERAND_TYPE_IMM32:
operand->size = 32; operand->size = 32;
operand->imm.isSigned = true; operand->imm.isSigned = true;
break; break;
case ZYDIS_SEM_OPERAND_TYPE_REL64: case ZYDIS_SEM_OPERAND_TYPE_REL64:
info->flags |= ZYDIS_IFLAG_RELATIVE; info->flags |= ZYDIS_INSTRUCTION_RELATIVE;
operand->imm.isRelative = true; operand->imm.isRelative = true;
case ZYDIS_SEM_OPERAND_TYPE_IMM64: case ZYDIS_SEM_OPERAND_TYPE_IMM64:
operand->size = 64; operand->size = 64;
operand->imm.isSigned = true; operand->imm.isSigned = true;
break; break;
default:
break;
} }
switch (type) switch (type)
{ {
@ -1343,7 +1351,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
operand->ptr.offset = operand->imm.value.uword; operand->ptr.offset = operand->imm.value.uword;
ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 16, false)); ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 16, false));
operand->ptr.segment = operand->imm.value.uword; operand->ptr.segment = operand->imm.value.uword;
operand->imm.size = 0; operand->imm.dataSize = 0;
operand->imm.dataOffset = 0; operand->imm.dataOffset = 0;
operand->imm.value.uqword = 0; operand->imm.value.uqword = 0;
operand->type = ZYDIS_OPERAND_TYPE_POINTER; operand->type = ZYDIS_OPERAND_TYPE_POINTER;
@ -1354,7 +1362,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
operand->ptr.offset = operand->imm.value.udword; operand->ptr.offset = operand->imm.value.udword;
ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 16, false)); ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 16, false));
operand->ptr.segment = operand->imm.value.uword; operand->ptr.segment = operand->imm.value.uword;
operand->imm.size = 0; operand->imm.dataSize = 0;
operand->imm.dataOffset = 0; operand->imm.dataOffset = 0;
operand->imm.value.uqword = 0; operand->imm.value.uqword = 0;
operand->type = ZYDIS_OPERAND_TYPE_POINTER; operand->type = ZYDIS_OPERAND_TYPE_POINTER;
@ -1364,6 +1372,8 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
// TODO: ? // TODO: ?
assert(0); assert(0);
return ZYDIS_STATUS_DECODER_SUCCESS; return ZYDIS_STATUS_DECODER_SUCCESS;
default:
break;
} }
// Moffs // Moffs
@ -1373,10 +1383,10 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 16, false)); ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 16, false));
operand->type = ZYDIS_OPERAND_TYPE_MEMORY; operand->type = ZYDIS_OPERAND_TYPE_MEMORY;
operand->size = 16; operand->size = 16;
operand->mem.disp.size = 16; operand->mem.disp.dataSize = 16;
operand->mem.disp.dataOffset = operand->imm.dataOffset; operand->mem.disp.dataOffset = operand->imm.dataOffset;
operand->mem.disp.value.sword = operand->imm.value.sword; operand->mem.disp.value.sword = operand->imm.value.sword;
operand->imm.size = 0; operand->imm.dataSize = 0;
operand->imm.dataOffset = 0; operand->imm.dataOffset = 0;
operand->imm.value.uqword = 0; operand->imm.value.uqword = 0;
return ZYDIS_STATUS_DECODER_SUCCESS; return ZYDIS_STATUS_DECODER_SUCCESS;
@ -1384,10 +1394,10 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 32, false)); ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 32, false));
operand->type = ZYDIS_OPERAND_TYPE_MEMORY; operand->type = ZYDIS_OPERAND_TYPE_MEMORY;
operand->size = 32; operand->size = 32;
operand->mem.disp.size = 32; operand->mem.disp.dataSize = 32;
operand->mem.disp.dataOffset = operand->imm.dataOffset; operand->mem.disp.dataOffset = operand->imm.dataOffset;
operand->mem.disp.value.sdword = operand->imm.value.sdword; operand->mem.disp.value.sdword = operand->imm.value.sdword;
operand->imm.size = 0; operand->imm.dataSize = 0;
operand->imm.dataOffset = 0; operand->imm.dataOffset = 0;
operand->imm.value.uqword = 0; operand->imm.value.uqword = 0;
return ZYDIS_STATUS_DECODER_SUCCESS; return ZYDIS_STATUS_DECODER_SUCCESS;
@ -1395,13 +1405,15 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 64, false)); ZYDIS_CHECK(ZydisDecodeOperandImmediate(decoder, info, operand, 64, false));
operand->type = ZYDIS_OPERAND_TYPE_MEMORY; operand->type = ZYDIS_OPERAND_TYPE_MEMORY;
operand->size = 64; operand->size = 64;
operand->mem.disp.size = 64; operand->mem.disp.dataSize = 64;
operand->mem.disp.dataOffset = operand->imm.dataOffset; operand->mem.disp.dataOffset = operand->imm.dataOffset;
operand->mem.disp.value.sqword = operand->imm.value.sqword; operand->mem.disp.value.sqword = operand->imm.value.sqword;
operand->imm.size = 0; operand->imm.dataSize = 0;
operand->imm.dataOffset = 0; operand->imm.dataOffset = 0;
operand->imm.value.uqword = 0; operand->imm.value.uqword = 0;
return ZYDIS_STATUS_DECODER_SUCCESS; return ZYDIS_STATUS_DECODER_SUCCESS;
default:
break;
} }
// SrcIdx and DstIdx operands // SrcIdx and DstIdx operands
@ -1433,6 +1445,8 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder,
case ZYDIS_SEM_OPERAND_TYPE_DSTIDX64: case ZYDIS_SEM_OPERAND_TYPE_DSTIDX64:
dstidx = 64; dstidx = 64;
break; break;
default:
break;
} }
if (srcidx || dstidx) if (srcidx || dstidx)
{ {
@ -1508,7 +1522,7 @@ static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder,
info->operand[i].access = definition->operands[i].access; info->operand[i].access = definition->operands[i].access;
if (status != ZYDIS_STATUS_DECODER_SUCCESS) if (status != ZYDIS_STATUS_DECODER_SUCCESS)
{ {
info->flags |= ZYDIS_IFLAG_ERROR_OPERANDS; info->flags |= ZYDIS_INSTRUCTION_ERROR_OPERANDS;
return status; return status;
} }
// Adjust segment register for memory operands // Adjust segment register for memory operands
@ -1568,7 +1582,7 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
// Adjust operand-mode // Adjust operand-mode
/*if (info->mode == ZYDIS_DISASSEMBLER_MODE_64BIT) /*if (info->mode == ZYDIS_DISASSEMBLER_MODE_64BIT)
{ {
if ((info->flags & ZYDIS_IFLAG_RELATIVE) && if ((info->flags & ZYDIS_INSTRUCTION_RELATIVE) &&
(info->operand[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) (info->operand[0].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
{ {
info->operandMode = 64; info->operandMode = 64;
@ -1690,6 +1704,8 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info)
info->prefixFlags |= ZYDIS_PREFIX_BRANCH_TAKEN; info->prefixFlags |= ZYDIS_PREFIX_BRANCH_TAKEN;
} }
break; break;
default:
break;
} }
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_LOCK) && if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_LOCK) &&
((info->prefixFlags & ZYDIS_PREFIX_REP) || (info->prefixFlags & ZYDIS_PREFIX_REPNE))) ((info->prefixFlags & ZYDIS_PREFIX_REP) || (info->prefixFlags & ZYDIS_PREFIX_REPNE)))
@ -1770,7 +1786,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
{ {
if (info->prefixFlags & ZYDIS_PREFIX_REX) if (info->prefixFlags & ZYDIS_PREFIX_REX)
{ {
info->flags |= ZYDIS_IFLAG_ERROR_ILLEGAL_REX; info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX;
return ZYDIS_STATUS_DECODER_ILLEGAL_REX; return ZYDIS_STATUS_DECODER_ILLEGAL_REX;
} }
uint8_t prefixBytes[3]; uint8_t prefixBytes[3];
@ -1807,7 +1823,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
if (!ZydisDecodeVexPrefix(info->opcode, prefixBytes[0], prefixBytes[1], if (!ZydisDecodeVexPrefix(info->opcode, prefixBytes[0], prefixBytes[1],
info)) info))
{ {
info->flags |= ZYDIS_IFLAG_ERROR_MALFORMED_VEX; info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_VEX;
return ZYDIS_STATUS_DECODER_MALFORMED_VEX_PREFIX; return ZYDIS_STATUS_DECODER_MALFORMED_VEX_PREFIX;
} }
info->opcodeMap = info->details.vex.m_mmmm; info->opcodeMap = info->details.vex.m_mmmm;
@ -1819,7 +1835,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
if (!ZydisDecodeEvexPrefix(prefixBytes[0], prefixBytes[1], prefixBytes[2], if (!ZydisDecodeEvexPrefix(prefixBytes[0], prefixBytes[1], prefixBytes[2],
info)) info))
{ {
info->flags |= ZYDIS_IFLAG_ERROR_MALFORMED_EVEX; info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_EVEX;
return ZYDIS_STATUS_DECODER_MALFORMED_EVEX_PREFIX; return ZYDIS_STATUS_DECODER_MALFORMED_EVEX_PREFIX;
} }
info->opcodeMap = info->details.evex.mm; info->opcodeMap = info->details.evex.mm;
@ -1838,7 +1854,7 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
{ {
if (info->prefixFlags & ZYDIS_PREFIX_REX) if (info->prefixFlags & ZYDIS_PREFIX_REX)
{ {
info->flags |= ZYDIS_IFLAG_ERROR_ILLEGAL_REX; info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX;
return ZYDIS_STATUS_DECODER_ILLEGAL_REX; return ZYDIS_STATUS_DECODER_ILLEGAL_REX;
} }
uint8_t prefixBytes[2]; uint8_t prefixBytes[2];
@ -1851,13 +1867,15 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
info->prefixFlags |= ZYDIS_PREFIX_XOP; info->prefixFlags |= ZYDIS_PREFIX_XOP;
if (!ZydisDecodeXopPrefix(prefixBytes[0], prefixBytes[1], info)) if (!ZydisDecodeXopPrefix(prefixBytes[0], prefixBytes[1], info))
{ {
info->flags |= ZYDIS_IFLAG_ERROR_MALFORMED_XOP; info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_XOP;
return ZYDIS_STATUS_DECODER_MALFORMED_XOP_PREFIX; return ZYDIS_STATUS_DECODER_MALFORMED_XOP_PREFIX;
} }
info->opcodeMap = ZYDIS_OPCODE_MAP_XOP8 + info->details.xop.m_mmmm - 0x08; info->opcodeMap = ZYDIS_OPCODE_MAP_XOP8 + info->details.xop.m_mmmm - 0x08;
} }
break; break;
} }
default:
break;
} }
break; break;
case ZYDIS_OPCODE_MAP_0F: case ZYDIS_OPCODE_MAP_0F:
@ -1873,6 +1891,8 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode
case 0x3A: case 0x3A:
info->opcodeMap = ZYDIS_OPCODE_MAP_0F3A; info->opcodeMap = ZYDIS_OPCODE_MAP_0F3A;
break; break;
default:
break;
} }
break; break;
case ZYDIS_OPCODE_MAP_0F38: case ZYDIS_OPCODE_MAP_0F38:
@ -2193,7 +2213,7 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
{ {
case ZYDIS_NODETYPE_INVALID: case ZYDIS_NODETYPE_INVALID:
{ {
info->flags |= ZYDIS_IFLAG_ERROR_INVALID; info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID;
return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION; return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION;
} }
case ZYDIS_NODETYPE_DEFINITION_0OP: case ZYDIS_NODETYPE_DEFINITION_0OP:
@ -2262,7 +2282,7 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder,
node = ZydisInstructionTableGetChildNode(node, info->opcode); node = ZydisInstructionTableGetChildNode(node, info->opcode);
if (ZydisInstructionTableGetNodeType(node) == ZYDIS_NODETYPE_INVALID) if (ZydisInstructionTableGetNodeType(node) == ZYDIS_NODETYPE_INVALID)
{ {
info->flags |= ZYDIS_IFLAG_ERROR_INVALID; info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID;
return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION; return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION;
} }
node = ZydisInstructionTableGetChildNode(node, node = ZydisInstructionTableGetChildNode(node,
@ -2437,6 +2457,9 @@ ZydisStatus ZydisDecoderSetDecoderInput(ZydisInstructionDecoder* decoder,
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
decoder->input = input; decoder->input = input;
decoder->buffer.count = 0;
decoder->buffer.posRead = 0;
decoder->buffer.posWrite = 0;
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
@ -2496,6 +2519,8 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
return ZYDIS_STATUS_NO_MORE_DATA; return ZYDIS_STATUS_NO_MORE_DATA;
} }
decoder->imm8initialized = false;
void* userData[6]; void* userData[6];
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
@ -2560,7 +2585,7 @@ DecodeError:
++decoder->instructionPointer; ++decoder->instructionPointer;
info->mode = decoder->disassemblerMode; info->mode = decoder->disassemblerMode;
info->flags = flags & ZYDIS_IFLAG_ERROR_MASK; info->flags = flags & ZYDIS_INSTRUCTION_ERROR_MASK;
info->length = 1; info->length = 1;
info->data[0] = firstByte; info->data[0] = firstByte;
info->instrAddress = instrAddress; info->instrAddress = instrAddress;

View File

@ -153,7 +153,7 @@ static ZydisStatus ZydisBufferAppendAbsoluteAddress(const ZydisInstructionFormat
switch (operand->type) switch (operand->type)
{ {
case ZYDIS_OPERAND_TYPE_MEMORY: case ZYDIS_OPERAND_TYPE_MEMORY:
ZYDIS_ASSERT(operand->mem.disp.size != 0); ZYDIS_ASSERT(operand->mem.disp.dataSize != 0);
if ((operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP)) if ((operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP))
{ {
ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(info, operand, &address)); ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(info, operand, &address));
@ -168,6 +168,8 @@ static ZydisStatus ZydisBufferAppendAbsoluteAddress(const ZydisInstructionFormat
case ZYDIS_OPERAND_TYPE_IMMEDIATE: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(info, operand, &address)); ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(info, operand, &address));
break; break;
default:
break;
} }
const char* symbol = NULL; const char* symbol = NULL;
@ -323,6 +325,8 @@ static ZydisStatus ZydisBufferAppendOperandIntelMemory(const ZydisInstructionFor
case 512: case 512:
str = "zmmword ptr "; str = "zmmword ptr ";
break; break;
default:
break;
} }
ZYDIS_CHECK(ZydisBufferAppend( ZYDIS_CHECK(ZydisBufferAppend(
buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), str)); buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), str));
@ -342,7 +346,7 @@ static ZydisStatus ZydisBufferAppendOperandIntelMemory(const ZydisInstructionFor
} }
ZYDIS_CHECK(ZydisBufferAppend( ZYDIS_CHECK(ZydisBufferAppend(
buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "[")); buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "["));
if ((operand->mem.disp.size != 0) && ((operand->mem.base == ZYDIS_REGISTER_NONE) || if ((operand->mem.disp.dataSize != 0) && ((operand->mem.base == ZYDIS_REGISTER_NONE) ||
(operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP)) && (operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP)) &&
(operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0)) (operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0))
{ {
@ -369,7 +373,7 @@ static ZydisStatus ZydisBufferAppendOperandIntelMemory(const ZydisInstructionFor
operand->mem.scale)); operand->mem.scale));
} }
} }
if ((operand->mem.disp.size) && ((operand->mem.disp.value.sqword) || if ((operand->mem.disp.dataSize) && ((operand->mem.disp.value.sqword) ||
((operand->mem.base == ZYDIS_REGISTER_NONE) && ((operand->mem.base == ZYDIS_REGISTER_NONE) &&
(operand->mem.index == ZYDIS_REGISTER_NONE)))) (operand->mem.index == ZYDIS_REGISTER_NONE))))
{ {
@ -426,6 +430,8 @@ static ZydisStatus ZydisBufferAppendOperandIntel(const ZydisInstructionFormatter
operand->ptr.segment, operand->ptr.offset); operand->ptr.segment, operand->ptr.offset);
case ZYDIS_OPERAND_TYPE_IMMEDIATE: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
return ZydisBufferAppendImmediate(formatter, buffer, bufferLen, offset, info, operand); return ZydisBufferAppendImmediate(formatter, buffer, bufferLen, offset, info, operand);
default:
break;
} }
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
@ -526,6 +532,8 @@ static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatte
case ZYDIS_MNEMONIC_SHR: case ZYDIS_MNEMONIC_SHR:
case ZYDIS_MNEMONIC_SAR: case ZYDIS_MNEMONIC_SAR:
typecast = info->operand[0].size; typecast = info->operand[0].size;
default:
break;
} }
} }
break; break;
@ -534,6 +542,8 @@ static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatte
typecast = (info->operand[i - 1].size != info->operand[i].size) ? typecast = (info->operand[i - 1].size != info->operand[i].size) ?
info->operand[i].size : 0; info->operand[i].size : 0;
break; break;
default:
break;
} }
} }
ZYDIS_CHECK(ZydisBufferAppendOperandIntel(formatter, buffer, bufferLen, &offset, info, ZYDIS_CHECK(ZydisBufferAppendOperandIntel(formatter, buffer, bufferLen, &offset, info,
@ -575,6 +585,8 @@ static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatte
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset, ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {1to16}")); (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {1to16}"));
break; break;
default:
break;
} }
} }
if ((i == (info->operandCount - 1)) || ((i != (info->operandCount - 1)) && if ((i == (info->operandCount - 1)) || ((i != (info->operandCount - 1)) &&

View File

@ -121,93 +121,81 @@ ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id)
switch (registerClass) switch (registerClass)
{ {
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8: case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
if (id > 19) if (id <= 19)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_AL + id;
} }
return ZYDIS_REGISTER_AL + id;
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16: case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
if (id > 15) if (id <= 15)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_AX + id;
} }
return ZYDIS_REGISTER_AX + id;
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32: case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32:
if (id > 15) if (id <= 15)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_EAX + id;
} }
return ZYDIS_REGISTER_EAX + id;
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64: case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64:
if (id > 15) if (id <= 15)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_RAX + id;
} }
return ZYDIS_REGISTER_RAX + id;
case ZYDIS_REGISTERCLASS_FLOATING_POINT: case ZYDIS_REGISTERCLASS_FLOATING_POINT:
if (id > 7) if (id <= 7)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_ST0 + id;
} }
return ZYDIS_REGISTER_ST0 + id;
case ZYDIS_REGISTERCLASS_MULTIMEDIA: case ZYDIS_REGISTERCLASS_MULTIMEDIA:
if (id > 7) if (id <= 7)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_MM0 + id;
} }
return ZYDIS_REGISTER_MM0 + id;
case ZYDIS_REGISTERCLASS_VECTOR128: case ZYDIS_REGISTERCLASS_VECTOR128:
if (id > 31) if (id <= 31)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_XMM0 + id;
} }
return ZYDIS_REGISTER_XMM0 + id;
case ZYDIS_REGISTERCLASS_VECTOR256: case ZYDIS_REGISTERCLASS_VECTOR256:
if (id > 31) if (id <= 31)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_YMM0 + id;
} }
return ZYDIS_REGISTER_YMM0 + id;
case ZYDIS_REGISTERCLASS_VECTOR512: case ZYDIS_REGISTERCLASS_VECTOR512:
if (id > 31) if (id <= 31)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_ZMM0 + id;
} }
return ZYDIS_REGISTER_ZMM0 + id;
case ZYDIS_REGISTERCLASS_SEGMENT: case ZYDIS_REGISTERCLASS_SEGMENT:
if (id > 5) if (id <= 5)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_ES + id;
} }
return ZYDIS_REGISTER_ES + id;
case ZYDIS_REGISTERCLASS_CONTROL: case ZYDIS_REGISTERCLASS_CONTROL:
if (id > 15) if (id <= 15)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_CR0 + id;
} }
return ZYDIS_REGISTER_CR0 + id;
case ZYDIS_REGISTERCLASS_DEBUG: case ZYDIS_REGISTERCLASS_DEBUG:
if (id > 15) if (id <= 15)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_DR0 + id;
} }
return ZYDIS_REGISTER_DR0 + id;
case ZYDIS_REGISTERCLASS_MASK: case ZYDIS_REGISTERCLASS_MASK:
if (id > 7) if (id <= 7)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_K0 + id;
} }
return ZYDIS_REGISTER_K0 + id;
case ZYDIS_REGISTERCLASS_BOUNDS: case ZYDIS_REGISTERCLASS_BOUNDS:
if (id > 3) if (id <= 3)
{ {
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_BND0 + id;
} }
return ZYDIS_REGISTER_BND0 + id;
case ZYDIS_REGISTERCLASS_FLAGS: case ZYDIS_REGISTERCLASS_FLAGS:
case ZYDIS_REGISTERCLASS_IP: case ZYDIS_REGISTERCLASS_IP:
// These registers are unique // These registers are unique
break; break;
default:
break;
} }
return ZYDIS_REGISTER_NONE; return ZYDIS_REGISTER_NONE;
} }
@ -323,6 +311,8 @@ ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg)
return ZYDIS_REGISTERSIZE_64; return ZYDIS_REGISTERSIZE_64;
case ZYDIS_REGISTERCLASS_BOUNDS: case ZYDIS_REGISTERCLASS_BOUNDS:
return ZYDIS_REGISTERSIZE_128; return ZYDIS_REGISTERSIZE_128;
default:
break;
} }
return ZYDIS_REGISTERSIZE_INVALID; return ZYDIS_REGISTERSIZE_INVALID;
} }
@ -336,6 +326,8 @@ bool ZydisRegisterIsGPR(ZydisRegister reg)
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16: case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8: case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
return true; return true;
default:
break;
} }
return false; return false;
} }
@ -378,6 +370,8 @@ bool ZydisRegisterIsVR(ZydisRegister reg)
case ZYDIS_REGISTERCLASS_VECTOR256: case ZYDIS_REGISTERCLASS_VECTOR256:
case ZYDIS_REGISTERCLASS_VECTOR128: case ZYDIS_REGISTERCLASS_VECTOR128:
return true; return true;
default:
break;
} }
return false; return false;
} }

View File

@ -45,7 +45,7 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
switch (operand->type) switch (operand->type)
{ {
case ZYDIS_OPERAND_TYPE_MEMORY: case ZYDIS_OPERAND_TYPE_MEMORY:
if (operand->mem.disp.size == 0) if (operand->mem.disp.dataSize == 0)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }
@ -75,10 +75,14 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info
*address = (uint32_t)*address; *address = (uint32_t)*address;
} }
break; break;
default:
break;
} }
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }
break; break;
default:
break;
} }
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
} }

View File

@ -57,6 +57,8 @@ bool ZydisIsFeatureEnabled(ZydisFeature feature)
#else #else
return false; return false;
#endif #endif
default:
break;
} }
return false; return false;
} }