From be56ef937d9f1bcf5f4eb71cd00d248b8209a79a Mon Sep 17 00:00:00 2001 From: flobernd Date: Mon, 21 Nov 2016 14:55:17 +0100 Subject: [PATCH] Minor bugfixes and refactorings --- examples/ZydisPE.c | 8 +- include/Zydis/Decoder.h | 4 +- include/Zydis/Formatter.h | 79 +++++++++--- include/Zydis/InstructionInfo.h | 116 ++++++++--------- include/Zydis/Register.h | 132 ++++++++++++++++++-- include/Zydis/Status.h | 6 +- src/Decoder.c | 213 ++++++++++++++++---------------- src/Formatter.c | 56 ++++----- src/InstructionTable.c | 31 +++-- src/Register.c | 2 +- src/Utils.c | 19 ++- tools/ZydisDisasm.c | 2 +- tools/ZydisFuzzIn.c | 6 +- 13 files changed, 422 insertions(+), 252 deletions(-) diff --git a/examples/ZydisPE.c b/examples/ZydisPE.c index ad17ba1..0045023 100644 --- a/examples/ZydisPE.c +++ b/examples/ZydisPE.c @@ -223,7 +223,7 @@ static ZydisStatus ZydisBufferAppendImport(char* buffer, size_t bufferLen, size_ ++descriptor; } } - return ZYDIS_STATUS_USER + 1000; + return 1337 + 1000; } /** @@ -387,14 +387,14 @@ int main(int argc, char** argv) switch (info.mode) { case ZYDIS_DISASSEMBLER_MODE_16BIT: - printf("%04llX ", info.instrAddress); - break; case ZYDIS_DISASSEMBLER_MODE_32BIT: printf("%08llX ", info.instrAddress); break; case ZYDIS_DISASSEMBLER_MODE_64BIT: printf("%016llX ", info.instrAddress); break; + default: + break; } for (int j = 0; j < info.length; ++j) { @@ -404,7 +404,7 @@ int main(int argc, char** argv) { printf(" "); } - if (info.flags & ZYDIS_IFLAG_ERROR_MASK) + if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK) { printf(" db %02x\n", info.data[0]); continue; diff --git a/include/Zydis/Decoder.h b/include/Zydis/Decoder.h index bf62161..ec4023b 100644 --- a/include/Zydis/Decoder.h +++ b/include/Zydis/Decoder.h @@ -48,11 +48,11 @@ typedef uint32_t ZydisDecoderFlags; /** * @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. + * @c ZYDIS_STATUS_DECODING_ERROR, 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. + * have one of the @c ZYDIS_INSTRFLAG_ERROR_MASK flags set. */ #define ZYDIS_DECODER_FLAG_SKIP_DATA 0x00000001 /** diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index e717629..07fc762 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -38,15 +38,11 @@ extern "C" { #endif /* ============================================================================================== */ -/* Instruction formatter */ +/* Enums and types */ /* ============================================================================================== */ -/* ---------------------------------------------------------------------------------------------- */ -/* Enums and types */ -/* ---------------------------------------------------------------------------------------------- */ - /** - * @brief Defines the zydis formatter-style datatype. + * @brief Defines the @c ZydisFormatterStyle datatype. */ typedef uint8_t ZydisFormatterStyle; @@ -62,7 +58,7 @@ enum ZydisFormatterStyles }; /** - * @brief Defines the zydis formatter-flags datatype. + * @brief Defines the @c ZydisFormatterFlags datatype. */ typedef uint8_t ZydisFormatterFlags; @@ -73,7 +69,7 @@ typedef uint8_t ZydisFormatterFlags; #define ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT 0x10 /** - * @brief Defines the zydis address-format datatype. + * @brief Defines the @c ZydisFormatterAddressFormat datatype. */ typedef uint8_t ZydisFormatterAddressFormat; @@ -82,10 +78,11 @@ typedef uint8_t ZydisFormatterAddressFormat; */ enum ZydisFormatterAddressFormat { + ZYDIS_FORMATTER_ADDR_DEFAULT, /** * @brief Displays absolute addresses instead of relative ones. */ - ZYDIS_FORMATTER_ADDRESS_ABSOLUTE, + ZYDIS_FORMATTER_ADDR_ABSOLUTE, /** * @brief Uses signed hexadecimal values to display relative addresses. * @@ -93,7 +90,7 @@ enum ZydisFormatterAddressFormat * "JMP 0x20" * "JMP -0x20" */ - ZYDIS_FORMATTER_ADDRESS_RELATIVE_SIGNED, + ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED, /** * @brief Uses unsigned hexadecimal values to display relative addresses. * @@ -101,11 +98,11 @@ enum ZydisFormatterAddressFormat * "JMP 0x20" * "JMP 0xE0" */ - ZYDIS_FORMATTER_ADDRESS_RELATIVE_UNSIGNED, + ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED, }; /** - * @brief Defines the zydis displacement-format datatype. + * @brief Defines the @c ZydisFormatterDisplacementFormat datatype. */ typedef uint8_t ZydisFormatterDisplacementFormat; @@ -114,6 +111,7 @@ typedef uint8_t ZydisFormatterDisplacementFormat; */ enum ZydisFormatterDisplacementFormats { + ZYDIS_FORMATTER_DISP_DEFAULT, /** * @brief Formats displacements as signed hexadecimal values. * @@ -133,7 +131,7 @@ enum ZydisFormatterDisplacementFormats }; /** - * @brief Defines the zydis formatter immediate-format datatype. + * @brief Defines the @c ZydisFormatterImmediateFormat datatype. */ typedef uint8_t ZydisFormatterImmediateFormat; @@ -142,6 +140,7 @@ typedef uint8_t ZydisFormatterImmediateFormat; */ enum ZydisFormatterImmediateFormats { + ZYDIS_FORMATTER_IMM_DEFAULT, /** * @brief Formats immediates as signed hexadecimal values. * @@ -161,7 +160,38 @@ enum ZydisFormatterImmediateFormats }; /** - * @brief Defines the zydis instruction-formatter struct. + * @brief Defines the @c ZydisFormatterHookType datatype. + */ +typedef uint8_t ZydisFormatterHookType; + +/** + * @brief Values that represent formatter hook-types. + */ +enum ZydisFormatterHookTypes +{ + /** + * @brief This hook is called right + */ + ZYDIS_FORMATTER_HOOK_PRE, + ZYDIS_FORMATTER_HOOK_POST, + ZYDIS_FORMATTER_HOOK_FORMAT_MNEMONIC, + ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND, + ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG, + ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM, + ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, + ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR, + ZYDIS_FORMATTER_HOOK_FORMAT_ADDRESS_ABS, + ZYDIS_FORMATTER_HOOK_FORMAT_ADDRESS_REL, + ZYDIS_FORMATTER_HOOK_FORMAT_DISPLACEMENT, + ZYDIS_FORMATTER_HOOK_FORMAT_IMMEDIATE +}; + +typedef const char* (*ZydisFormatterHookFormatMnemonicFunc)(void* context, + const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint64_t address, + int64_t* offset); + +/** + * @brief Defines the @c ZydisInstructionFormatter struct. */ typedef struct ZydisInstructionFormatter_ { @@ -174,8 +204,12 @@ typedef struct ZydisInstructionFormatter_ } ZydisInstructionFormatter; -/* ---------------------------------------------------------------------------------------------- */ +/* ============================================================================================== */ /* Exported functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Basic functions */ /* ---------------------------------------------------------------------------------------------- */ /** @@ -224,6 +258,9 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterGetSymbolResolver( ZYDIS_EXPORT ZydisStatus ZydisFormatterSetSymbolResolver( ZydisInstructionFormatter* formatter, ZydisCustomSymbolResolver* symbolResolver); +ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter, + ZydisFormatterHookType hook, const void* callback); + /** * @brief Formats the given instruction and writes it into the output buffer. * @@ -238,6 +275,18 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction( ZydisInstructionFormatter* formatter, const ZydisInstructionInfo* info, char* buffer, size_t bufferLen); +/* ---------------------------------------------------------------------------------------------- */ +/* Formatting functions for custom implementations */ +/* ---------------------------------------------------------------------------------------------- */ + +ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatOperandIntel( + const ZydisInstructionFormatter* formatter, char* buffer, size_t bufferLen, size_t* offset, + const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint16_t typecast); + +ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatOperandMemIntel( + const ZydisInstructionFormatter* formatter, char* buffer, size_t bufferLen, size_t* offset, + const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint16_t typecast); + /* ---------------------------------------------------------------------------------------------- */ /* ============================================================================================== */ diff --git a/include/Zydis/InstructionInfo.h b/include/Zydis/InstructionInfo.h index 2d04d35..1713011 100644 --- a/include/Zydis/InstructionInfo.h +++ b/include/Zydis/InstructionInfo.h @@ -69,221 +69,221 @@ enum ZydisDisassemblerModes /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines an alias representing instruction flags. + * @brief Defines the @c ZydisInstructionFlags datatype. */ typedef uint32_t ZydisInstructionFlags; /** * @brief The instruction has the modrm byte. */ -#define ZYDIS_INSTRUCTION_HAS_MODRM 0x00000001 +#define ZYDIS_INSTRFLAG_HAS_MODRM 0x00000001 /** * @brief The instruction has the sib byte. */ -#define ZYDIS_INSTRUCTION_HAS_SIB 0x00000002 +#define ZYDIS_INSTRFLAG_HAS_SIB 0x00000002 /** * @brief The instruction has one or more operands with position-relative offsets. */ -#define ZYDIS_INSTRUCTION_RELATIVE 0x00000004 +#define ZYDIS_INSTRFLAG_IS_RELATIVE 0x00000004 /** * @brief The instruction is privileged and may only be executed in kernel-mode (ring0). */ -#define ZYDIS_INSTRUCTION_PRIVILEGED 0x00000008 +#define ZYDIS_INSTRFLAG_IS_PRIVILEGED 0x00000008 /** * @brief An error occured while decoding the current instruction. */ -#define ZYDIS_INSTRUCTION_ERROR_MASK 0x7F000000 +#define ZYDIS_INSTRFLAG_ERROR_MASK 0x7F000000 /** - * @brief The instruction is invalid. + * @brief The instruction is undefined. */ -#define ZYDIS_INSTRUCTION_ERROR_INVALID 0x01000000 +#define ZYDIS_INSTRFLAG_ERROR_UNDEFINED 0x01000000 /** * @brief The instruction length has exceeded the maximum of 15 bytes. */ -#define ZYDIS_INSTRUCTION_ERROR_INSTRUCTION_LENGTH 0x02000000 +#define ZYDIS_INSTRFLAG_ERROR_MAXLENGTH 0x02000000 /** * @brief An error occured while decoding the vex-prefix. */ -#define ZYDIS_INSTRUCTION_ERROR_MALFORMED_VEX 0x04000000 +#define ZYDIS_INSTRFLAG_ERROR_MALFORMED_VEX 0x04000000 /** * @brief An error occured while decoding the evex-prefix. */ -#define ZYDIS_INSTRUCTION_ERROR_MALFORMED_EVEX 0x08000000 +#define ZYDIS_INSTRFLAG_ERROR_MALFORMED_EVEX 0x08000000 /** * @brief An error occured while decoding the xop-prefix. */ -#define ZYDIS_INSTRUCTION_ERROR_MALFORMED_XOP 0x10000000 +#define ZYDIS_INSTRFLAG_ERROR_MALFORMED_XOP 0x10000000 /** * @brief A rex-prefix was found while decoding a vex/evex/xop instruction. */ -#define ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX 0x20000000 +#define ZYDIS_INSTRFLAG_ERROR_ILLEGAL_REX 0x20000000 /** * @brief An invalid constellation was found while decoding an instruction that uses the VSIB * addressing mode. */ -#define ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB 0x40000000 +#define ZYDIS_INSTRFLAG_ERROR_INVALID_VSIB 0x40000000 /** * @brief An error occured while decoding the instruction-operands. */ -#define ZYDIS_INSTRUCTION_ERROR_OPERANDS 0x40000000 +#define ZYDIS_INSTRFLAG_ERROR_OPERANDS 0x40000000 /* ---------------------------------------------------------------------------------------------- */ /* Prefix flags */ /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the zydis prefix-flags datatype. + * @brief Defines the @c ZydisPrefixFlags datatype. */ typedef uint32_t ZydisPrefixFlags; /** * @brief The instruction has the rex-prefix (0x40 - 0x4F). */ -#define ZYDIS_PREFIX_REX 0x00000001 +#define ZYDIS_PREFIXFLAG_HAS_REX 0x00000001 /** * @brief The instruction has the xop-prefix (0x8F). */ -#define ZYDIS_PREFIX_XOP 0x00000002 +#define ZYDIS_PREFIXFLAG_HAS_XOP 0x00000002 /** * @brief The instruction has the vex-prefix (0xC4 or 0xC5). */ -#define ZYDIS_PREFIX_VEX 0x00000004 +#define ZYDIS_PREFIXFLAG_HAS_VEX 0x00000004 /** * @brief The instruction has the evex-prefix (0x62). */ -#define ZYDIS_PREFIX_EVEX 0x00000008 +#define ZYDIS_PREFIXFLAG_HAS_EVEX 0x00000008 /** * @brief The instruction has the lock-prefix (0x0F) */ -#define ZYDIS_PREFIX_LOCK 0x00000010 +#define ZYDIS_PREFIXFLAG_HAS_LOCK 0x00000010 /** * @brief The instruction has the rep/repe/repz-prefix (0xF3) */ -#define ZYDIS_PREFIX_REP 0x00000020 +#define ZYDIS_PREFIXFLAG_HAS_REP 0x00000020 /** * @brief The instruction has the rep/repe/repz-prefix (0xF3) */ -#define ZYDIS_PREFIX_REPE 0x00000020 +#define ZYDIS_PREFIXFLAG_HAS_REPE 0x00000020 /** * @brief The instruction has the rep/repe/repz-prefix (0xF3) */ -#define ZYDIS_PREFIX_REPZ 0x00000020 +#define ZYDIS_PREFIXFLAGG_HAS_REPZ 0x00000020 /** * @brief The instruction has the repne/repnz-prefix (0xF2) */ -#define ZYDIS_PREFIX_REPNE 0x00000040 +#define ZYDIS_PREFIXFLAG_HAS_REPNE 0x00000040 /** * @brief The instruction has the repne/repnz-prefix (0xF2) */ -#define ZYDIS_PREFIX_REPNZ 0x00000040 +#define ZYDIS_PREFIXFLAG_HAS_REPNZ 0x00000040 /** * @brief The instruction has a segment-override prefix. */ -#define ZYDIS_PREFIX_SEGMENT_MASK 0x00001F80 +#define ZYDIS_PREFIXFLAG_SEGMENT_MASK 0x00001F80 /** * @brief The instruction has the cs segment-override prefix (0x2E). */ -#define ZYDIS_PREFIX_SEGMENT_CS 0x00000080 +#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS 0x00000080 /** * @brief The instruction has the ss segment-override prefix (0x36). */ -#define ZYDIS_PREFIX_SEGMENT_SS 0x00000100 +#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS 0x00000100 /** * @brief The instruction has the ds segment-override prefix (0x3E). */ -#define ZYDIS_PREFIX_SEGMENT_DS 0x00000200 +#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS 0x00000200 /** * @brief The instruction has the es segment-override prefix (0x26). */ -#define ZYDIS_PREFIX_SEGMENT_ES 0x00000400 +#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_ES 0x00000400 /** * @brief The instruction has the fs segment-override prefix (0x64). */ -#define ZYDIS_PREFIX_SEGMENT_FS 0x00000800 +#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_FS 0x00000800 /** * @brief The instruction has the gs segment-override prefix (0x65). */ -#define ZYDIS_PREFIX_SEGMENT_GS 0x00001000 +#define ZYDIS_PREFIXFLAG_HAS_SEGMENT_GS 0x00001000 /** * @brief The instruction has the operand-size-override prefix (0x66). */ -#define ZYDIS_PREFIX_OPERANDSIZE 0x00002000 +#define ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE 0x00002000 /** * @brief The instruction has the address-size-override prefix (0x67). */ -#define ZYDIS_PREFIX_ADDRESSSIZE 0x00004000 +#define ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE 0x00004000 /** * @brief The instruction has the xacquire prefix (0xF2). */ -#define ZYDIS_PREFIX_XACQUIRE 0x00008000 +#define ZYDIS_PREFIXFLAG_HAS_XACQUIRE 0x00008000 /** * @brief The instruction has the xrelease prefix (0xF3). */ -#define ZYDIS_PREFIX_XRELEASE 0x00010000 +#define ZYDIS_PREFIXFLAG_HAS_XRELEASE 0x00010000 /** * @brief The instruction has the branch-not-taken hint (0x2E). */ -#define ZYDIS_PREFIX_BRANCH_NOT_TAKEN 0x00020000 +#define ZYDIS_PREFIXFLAG_HAS_BRANCH_NOT_TAKEN 0x00020000 /** * @brief The instruction has the branch-taken hint (0x3E). */ -#define ZYDIS_PREFIX_BRANCH_TAKEN 0x00040000 +#define ZYDIS_PREFIXFLAG_HAS_BRANCH_TAKEN 0x00040000 /** * @brief The instruction accepts the operand-size override prefix (0x66) */ -#define ZYDIS_PREFIX_ACCEPTS_OPERANDSIZE 0x00080000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_OPERANDSIZE 0x00080000 /** * @brief The instruction accepts the adress-size override prefix (0x67) */ -#define ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE 0x00100000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE 0x00100000 /** * @brief The instruction accepts the lock-prefix. */ -#define ZYDIS_PREFIX_ACCEPTS_LOCK 0x00200000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_LOCK 0x00200000 /** * @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz). */ -#define ZYDIS_PREFIX_ACCEPTS_REP 0x00400000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_REP 0x00400000 /** * @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz). */ -#define ZYDIS_PREFIX_ACCEPTS_REPE 0x00400000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_REPE 0x00400000 /** * @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz). */ -#define ZYDIS_PREFIX_ACCEPTS_REPZ 0x00400000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_REPZ 0x00400000 /** * @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz). */ -#define ZYDIS_PREFIX_ACCEPTS_REPNE 0x00400000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNE 0x00400000 /** * @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz). */ -#define ZYDIS_PREFIX_ACCEPTS_REPNZ 0x00400000 +#define ZYDIS_PREFIXFLAG_ACCEPTS_REPNZ 0x00400000 /** * @brief The instruction has multiple prefixes of the first prefix-group (0x0F, 0xF3, 0xF2). */ -#define ZYDIS_PREFIX_MULTIPLE_GRP1 0x00800000 +#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP1 0x00800000 /** * @brief The instruction has multiple prefixes of the second prefix-group (0x2E, 0x36, * 0x3E, 0x26, 0x64, 0x65). */ -#define ZYDIS_PREFIX_MULTIPLE_GRP2 0x01000000 +#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP2 0x01000000 /** * @brief The instruction has multiple prefixes of the third prefix-group (0x66). */ -#define ZYDIS_PREFIX_MULTIPLE_GRP3 0x02000000 +#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP3 0x02000000 /** * @brief The instruction has multiple prefixes of the fourth prefix-group (0x67). */ -#define ZYDIS_PREFIX_MULTIPLE_GRP4 0x04000000 +#define ZYDIS_PREFIXFLAG_MULTIPLE_GRP4 0x04000000 /* ---------------------------------------------------------------------------------------------- */ /* Instruction encoding */ /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the zydis instruction-encoding datatype. + * @brief Defines the @c ZydisInstructionEncoding datatype. */ typedef uint8_t ZydisInstructionEncoding; @@ -304,12 +304,12 @@ enum ZydisInstructionEncodings /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines an alias representing an opcode map. + * @brief Defines the @c ZydisOpcodeMap map. */ typedef uint8_t ZydisOpcodeMap; /** - * @brief Values that represent opcode maps. + * @brief Values that represent opcode-maps. */ enum ZydisOpcodeMaps { @@ -327,7 +327,7 @@ enum ZydisOpcodeMaps /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines an alias representing an operand-type. + * @brief Defines the @c ZydisOperandType datatype. */ typedef uint8_t ZydisOperandType; @@ -363,7 +363,7 @@ enum ZydisOperandTypes /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines an alias representing an operand-encoding. + * @brief Defines the @c ZydisOperandEncoding datatype. */ typedef uint8_t ZydisOperandEncoding; @@ -657,11 +657,11 @@ typedef struct ZydisInstructionInfo_ /** * @brief Instruction specific info- and error-flags. */ - ZydisInstructionFlags flags; + ZydisInstructionFlags instrFlags; /** * @brief Prefix flags. */ - ZydisPrefixFlags prefixes; + ZydisPrefixFlags prefixFlags; /** * @brief The instruction-mnemonic. */ diff --git a/include/Zydis/Register.h b/include/Zydis/Register.h index bef380b..af447d1 100644 --- a/include/Zydis/Register.h +++ b/include/Zydis/Register.h @@ -190,8 +190,6 @@ enum ZydisRegisterSizes ZYDIS_REGISTERSIZE_512 = 512 }; -/* ---------------------------------------------------------------------------------------------- */ - /* ============================================================================================== */ /* Macros */ /* ============================================================================================== */ @@ -201,7 +199,7 @@ enum ZydisRegisterSizes * * @param reg The register. */ -#define ZYDIS_REGISTER_IS_GPR (reg) \ +#define ZYDIS_REGISTER_IS_GPR(reg) \ ((ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8) ||) \ (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16) || \ (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32)) @@ -211,7 +209,7 @@ enum ZydisRegisterSizes * * @param reg The register. */ -#define ZYDIS_REGISTER_IS_GPR8 (reg) \ +#define ZYDIS_REGISTER_IS_GPR8(reg) \ (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8) /** @@ -219,7 +217,7 @@ enum ZydisRegisterSizes * * @param reg The register. */ -#define ZYDIS_REGISTER_IS_GPR16 (reg) \ +#define ZYDIS_REGISTER_IS_GPR16(reg) \ (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16) /** @@ -227,10 +225,130 @@ enum ZydisRegisterSizes * * @param reg The register. */ -#define ZYDIS_REGISTER_IS_GPR32 (reg) \ +#define ZYDIS_REGISTER_IS_GPR32(reg) \ (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32) -// TODO: Add macros for all register-classes +/** + * @brief Checks, if the given register is a legacy floating-point register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_FLOATING_POINT(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLOATING_POINT) + +/** + * @brief Checks, if the given register is a multimedia floating-point register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_MLUTIMEDIA(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MULTIMEDIA) + +/** + * @brief Checks, if the given register is a vector register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_VECTOR(reg) \ + ((ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128) ||) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256) || \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512)) + +/** + * @brief Checks, if the given register is a 128-bit vector register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_VECTOR128(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128) + +/** + * @brief Checks, if the given register is a 256-bit vector register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_VECTOR256(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256) + +/** + * @brief Checks, if the given register is a 512-bit vector register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_VECTOR512(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512) + +/** + * @brief Checks, if the given register is a flags register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_FLAGS(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLAGS) + +/** + * @brief Checks, if the given register is an instruction-pointer register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_IP(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_IP) + +/** + * @brief Checks, if the given register is a segment register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_SEGMENT(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_SEGMENT) + +/** + * @brief Checks, if the given register is a table register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_TABLE(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_TABLE) + +/** + * @brief Checks, if the given register is a test register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_TEST(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_TEST) + +/** + * @brief Checks, if the given register is a control register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_CONTROL(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_CONTROL) + +/** + * @brief Checks, if the given register is a debug register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_DEBUG(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_DEBUG) + +/** + * @brief Checks, if the given register is a mask register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_MASK(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MASK) + +/** + * @brief Checks, if the given register is a bounds register. + * + * @param reg The register. + */ +#define ZYDIS_REGISTER_IS_BOUNDS(reg) \ + (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_BOUNDS) /* ============================================================================================== */ /* Exported functions */ diff --git a/include/Zydis/Status.h b/include/Zydis/Status.h index e673613..3087671 100644 --- a/include/Zydis/Status.h +++ b/include/Zydis/Status.h @@ -65,10 +65,10 @@ enum ZydisStatusCode */ ZYDIS_STATUS_NO_MORE_DATA = 0x00000003, /** - * @brief An error occured while decoding the current instruction. Check the @c flags field - * of the @c ZydisInstructionInfo struct for further details. + * @brief An error occured while decoding the current instruction. Check the @c instrFlags + * field of the @c ZydisInstructionInfo struct for further details. */ - ZYDIS_STATUS_INVALID_INSTRUCTION = 0x00000004, // TODO: Rename + ZYDIS_STATUS_DECODING_ERROR = 0x00000004, /** * @brief A buffer passed to a function was too small to complete the requested operation. */ diff --git a/src/Decoder.c b/src/Decoder.c index 1fa813c..d05e9b7 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -69,11 +69,11 @@ typedef enum ZydisDecoderStatusCode_ { ZYDIS_STATUS_DECODER_SUCCESS, ZYDIS_STATUS_DECODER_NO_MORE_DATA, - ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION, + ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION, ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION_LENGTH, - ZYDIS_STATUS_DECODER_MALFORMED_VEX_PREFIX, - ZYDIS_STATUS_DECODER_MALFORMED_EVEX_PREFIX, - ZYDIS_STATUS_DECODER_MALFORMED_XOP_PREFIX, + ZYDIS_STATUS_DECODER_MALFORMED_VEX, + ZYDIS_STATUS_DECODER_MALFORMED_EVEX, + ZYDIS_STATUS_DECODER_MALFORMED_XOP, ZYDIS_STATUS_DECODER_ILLEGAL_REX, ZYDIS_STATUS_DECODER_INVALID_VSIB } ZydisDecoderStatusCode; @@ -110,7 +110,7 @@ static ZydisDecoderStatus ZydisInputPeek(ZydisInstructionDecoder* decoder, if (info->length >= ZYDIS_MAX_INSTRUCTION_LENGTH) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_INSTRUCTION_LENGTH; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MAXLENGTH; return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION_LENGTH; } @@ -388,7 +388,7 @@ static void ZydisDecodeModrm(uint8_t modrmByte, ZydisInstructionInfo* info) { ZYDIS_ASSERT(info); - info->flags |= ZYDIS_INSTRUCTION_HAS_MODRM; + info->instrFlags |= ZYDIS_INSTRFLAG_HAS_MODRM; info->details.modrm.isDecoded = true; info->details.modrm.data[0] = modrmByte; 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.rm & 0x7) == 4); - info->flags |= ZYDIS_INSTRUCTION_HAS_SIB; + info->instrFlags |= ZYDIS_INSTRFLAG_HAS_SIB; info->details.sib.isDecoded = true; info->details.sib.data[0] = sibByte; info->details.sib.scale = (sibByte >> 6) & 0x03; @@ -444,58 +444,58 @@ static ZydisDecoderStatus ZydisCollectOptionalPrefixes(ZydisInstructionDecoder* switch (prefixByte) { case 0xF0: - info->prefixes |= ZYDIS_PREFIX_LOCK; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_LOCK; ++groups[0]; break; case 0xF2: // 0xF2 and 0xF3 are mutally exclusive. The one that comes later has precedence. - info->prefixes |= ZYDIS_PREFIX_REPNE; - info->prefixes &= ~ZYDIS_PREFIX_REP; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_REPNE; + info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP; ++groups[0]; break; case 0xF3: // 0xF2 and 0xF3 are mutally exclusive. The one that comes later has precedence. - info->prefixes |= ZYDIS_PREFIX_REP; - info->prefixes &= ~ZYDIS_PREFIX_REPNE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_REP; + info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REPNE; ++groups[0]; break; case 0x2E: - info->prefixes |= ZYDIS_PREFIX_SEGMENT_CS; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS; ++groups[1]; break; case 0x36: - info->prefixes |= ZYDIS_PREFIX_SEGMENT_SS; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS; ++groups[1]; break; case 0x3E: - info->prefixes |= ZYDIS_PREFIX_SEGMENT_DS; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS; ++groups[1]; break; case 0x26: - info->prefixes |= ZYDIS_PREFIX_SEGMENT_ES; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_ES; ++groups[1]; break; case 0x64: - info->prefixes |= ZYDIS_PREFIX_SEGMENT_FS; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_FS; ++groups[1]; break; case 0x65: - info->prefixes |= ZYDIS_PREFIX_SEGMENT_GS; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_SEGMENT_GS; ++groups[1]; break; case 0x66: - info->prefixes |= ZYDIS_PREFIX_OPERANDSIZE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE; ++groups[2]; break; case 0x67: - info->prefixes |= ZYDIS_PREFIX_ADDRESSSIZE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE; ++groups[3]; break; default: if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) && (prefixByte & 0xF0) == 0x40) { - info->prefixes |= ZYDIS_PREFIX_REX; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_REX; info->details.rex.data[0] = prefixByte; } else { @@ -509,26 +509,26 @@ static ZydisDecoderStatus ZydisCollectOptionalPrefixes(ZydisInstructionDecoder* } } while (!done); - if (info->prefixes & ZYDIS_PREFIX_REX) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX) { ZydisDecodeRexPrefix(info, info->details.rex.data[0]); } if (groups[0] > 1) { - info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP1; + info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP1; } if (groups[1] > 1) { - info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP2; + info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP2; } if (groups[2] > 1) { - info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP3; + info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP3; } if (groups[3] > 1) { - info->prefixes |= ZYDIS_PREFIX_MULTIPLE_GRP4; + info->prefixFlags |= ZYDIS_PREFIXFLAG_MULTIPLE_GRP4; } return ZYDIS_STATUS_SUCCESS; @@ -661,7 +661,7 @@ static ZydisDecoderStatus ZydisDecodeOperandRegister(ZydisInstructionInfo* info, operand->type = ZYDIS_OPERAND_TYPE_REGISTER; if (registerClass == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8) { - if ((info->prefixes & ZYDIS_PREFIX_REX) && (registerId >= 4)) + if ((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX) && (registerId >= 4)) { operand->reg = ZYDIS_REGISTER_SPL + (registerId - 4); } else @@ -707,17 +707,17 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec } operand->type = ZYDIS_OPERAND_TYPE_MEMORY; uint8_t displacementSize = 0; - info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE; switch (decoder->disassemblerMode) { case ZYDIS_DISASSEMBLER_MODE_16BIT: - operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 16; + operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 16; break; case ZYDIS_DISASSEMBLER_MODE_32BIT: - operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 16 : 32; + operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 16 : 32; break; case ZYDIS_DISASSEMBLER_MODE_64BIT: - operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 64; + operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 64; break; default: ZYDIS_UNREACHABLE; @@ -762,7 +762,7 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec { if (decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) { - info->flags |= ZYDIS_INSTRUCTION_RELATIVE; + info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE; operand->mem.base = ZYDIS_REGISTER_EIP; } else { @@ -821,7 +821,7 @@ static ZydisDecoderStatus ZydisDecodeOperandModrmRm(ZydisInstructionDecoder* dec case 0: if (modrm_rm == 5) { - info->flags |= ZYDIS_INSTRUCTION_RELATIVE; + info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE; operand->mem.base = ZYDIS_REGISTER_RIP; displacementSize = 32; } @@ -1000,7 +1000,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, registerClass = ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64; break; case ZYDIS_SEM_OPERAND_TYPE_TR: - operand->size = 32; // TODO: ? + operand->size = 32; registerClass = ZYDIS_REGISTERCLASS_TEST; break; case ZYDIS_SEM_OPERAND_TYPE_CR: @@ -1271,13 +1271,13 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, { if (info->details.modrm.rm != 0x04) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_INVALID_VSIB; return ZYDIS_STATUS_DECODER_INVALID_VSIB; } switch (operand->mem.addressSize) { case 16: - info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID_VSIB; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_INVALID_VSIB; return ZYDIS_STATUS_DECODER_INVALID_VSIB; case 32: operand->mem.index = operand->mem.index - ZYDIS_REGISTER_EAX + vsibBaseRegister; @@ -1301,7 +1301,7 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, operand->imm.value.ubyte = 1; return ZYDIS_STATUS_DECODER_SUCCESS; case ZYDIS_SEM_OPERAND_TYPE_REL8: - info->flags |= ZYDIS_INSTRUCTION_RELATIVE; + info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE; operand->imm.isRelative = true; case ZYDIS_SEM_OPERAND_TYPE_IMM8: operand->size = 8; @@ -1312,21 +1312,21 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, operand->imm.isSigned = false; break; case ZYDIS_SEM_OPERAND_TYPE_REL16: - info->flags |= ZYDIS_INSTRUCTION_RELATIVE; + info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE; operand->imm.isRelative = true; case ZYDIS_SEM_OPERAND_TYPE_IMM16: operand->size = 16; operand->imm.isSigned = true; break; case ZYDIS_SEM_OPERAND_TYPE_REL32: - info->flags |= ZYDIS_INSTRUCTION_RELATIVE; + info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE; operand->imm.isRelative = true; case ZYDIS_SEM_OPERAND_TYPE_IMM32: operand->size = 32; operand->imm.isSigned = true; break; case ZYDIS_SEM_OPERAND_TYPE_REL64: - info->flags |= ZYDIS_INSTRUCTION_RELATIVE; + info->instrFlags |= ZYDIS_INSTRFLAG_IS_RELATIVE; operand->imm.isRelative = true; case ZYDIS_SEM_OPERAND_TYPE_IMM64: operand->size = 64; @@ -1469,17 +1469,17 @@ static ZydisDecoderStatus ZydisDecodeOperand(ZydisInstructionDecoder* decoder, } if (srcidx || dstidx) { - info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE; switch (decoder->disassemblerMode) { case ZYDIS_DISASSEMBLER_MODE_16BIT: - operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 16; + operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 16; break; case ZYDIS_DISASSEMBLER_MODE_32BIT: - operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 16 : 32; + operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 16 : 32; break; case ZYDIS_DISASSEMBLER_MODE_64BIT: - operand->mem.addressSize = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 32 : 64; + operand->mem.addressSize = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 32 : 64; break; default: ZYDIS_UNREACHABLE; @@ -1556,33 +1556,33 @@ static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder, info->operand[i].access = definition->operands[i].access; if (status != ZYDIS_STATUS_DECODER_SUCCESS) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_OPERANDS; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_OPERANDS; return status; } // Adjust segment register for memory operands if (info->operand[i].type == ZYDIS_OPERAND_TYPE_MEMORY) { - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_CS) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS) { info->operand[i].mem.segment = ZYDIS_REGISTER_CS; } else - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_SS) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS) { info->operand[i].mem.segment = ZYDIS_REGISTER_SS; } else - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_DS) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS) { info->operand[i].mem.segment = ZYDIS_REGISTER_DS; } else - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_ES) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_ES) { info->operand[i].mem.segment = ZYDIS_REGISTER_ES; } else - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_FS) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_FS) { info->operand[i].mem.segment = ZYDIS_REGISTER_FS; } else - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_GS) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_GS) { info->operand[i].mem.segment = ZYDIS_REGISTER_GS; } else @@ -1637,17 +1637,14 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info) case ZYDIS_MNEMONIC_XCHG: if (info->operand[0].type == ZYDIS_OPERAND_TYPE_MEMORY) { - info->prefixes |= ZYDIS_PREFIX_ACCEPTS_LOCK; + info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_LOCK; } break; case ZYDIS_MNEMONIC_MOVSB: case ZYDIS_MNEMONIC_MOVSW: case ZYDIS_MNEMONIC_MOVSD: case ZYDIS_MNEMONIC_MOVSQ: - case ZYDIS_MNEMONIC_CMPSB: - case ZYDIS_MNEMONIC_CMPSW: - case ZYDIS_MNEMONIC_CMPSD: - case ZYDIS_MNEMONIC_CMPSQ: + case ZYDIS_MNEMONIC_CMPS: // TODO: Only the string-instruction! We will use flags later. case ZYDIS_MNEMONIC_SCASB: case ZYDIS_MNEMONIC_SCASW: case ZYDIS_MNEMONIC_SCASD: @@ -1666,7 +1663,7 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info) case ZYDIS_MNEMONIC_OUTSB: case ZYDIS_MNEMONIC_OUTSW: case ZYDIS_MNEMONIC_OUTSD: - info->prefixes |= ZYDIS_PREFIX_ACCEPTS_REP | ZYDIS_PREFIX_ACCEPTS_REPNE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_REP | ZYDIS_PREFIXFLAG_ACCEPTS_REPNE; break; case ZYDIS_MNEMONIC_JO: case ZYDIS_MNEMONIC_JNO: @@ -1687,44 +1684,46 @@ static void ZydisFinalizeInstructionInfo(ZydisInstructionInfo* info) case ZYDIS_MNEMONIC_JCXZ: case ZYDIS_MNEMONIC_JECXZ: case ZYDIS_MNEMONIC_JRCXZ: - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_CS) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS) { - info->prefixes &= ~ZYDIS_PREFIX_SEGMENT_CS; - info->prefixes |= ZYDIS_PREFIX_BRANCH_NOT_TAKEN; + info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_CS; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_NOT_TAKEN; } else - if (info->prefixes & ZYDIS_PREFIX_SEGMENT_DS) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS) { - info->prefixes &= ~ZYDIS_PREFIX_SEGMENT_DS; - info->prefixes |= ZYDIS_PREFIX_BRANCH_TAKEN; + info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_BRANCH_TAKEN; } break; default: break; } - if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_LOCK) && - ((info->prefixes & ZYDIS_PREFIX_REP) || (info->prefixes & ZYDIS_PREFIX_REPNE))) + if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) && + ((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP) || + (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE))) { if (info->mnemonic != ZYDIS_MNEMONIC_CMPXCHG16B) { - if ((info->prefixes & ZYDIS_PREFIX_LOCK) || (info->mnemonic == ZYDIS_MNEMONIC_XCHG)) + if ((info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK) || + (info->mnemonic == ZYDIS_MNEMONIC_XCHG)) { - if (info->prefixes & ZYDIS_PREFIX_REPNE) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE) { - info->prefixes &= ~ZYDIS_PREFIX_REPNE; - info->prefixes |= ZYDIS_PREFIX_XACQUIRE; + info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REPNE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XACQUIRE; } { - info->prefixes &= ~ZYDIS_PREFIX_REP; - info->prefixes |= ZYDIS_PREFIX_XRELEASE; + info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XRELEASE; } } else if ((info->mnemonic == ZYDIS_MNEMONIC_MOV) && ((info->opcode == 0x88) || (info->opcode == 0x89) || (info->opcode == 0xC6) || (info->opcode == 0xC7))) { - if (info->prefixes & ZYDIS_PREFIX_REP) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP) { - info->prefixes &= ~ZYDIS_PREFIX_REP; - info->prefixes |= ZYDIS_PREFIX_XRELEASE; + info->prefixFlags &= ~ZYDIS_PREFIXFLAG_HAS_REP; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XRELEASE; } } } @@ -1778,9 +1777,9 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode if ((decoder->disassemblerMode == ZYDIS_DISASSEMBLER_MODE_64BIT) || ((nextInput & 0xF0) >= 0xC0)) { - if (info->prefixes & ZYDIS_PREFIX_REX) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_ILLEGAL_REX; return ZYDIS_STATUS_DECODER_ILLEGAL_REX; } uint8_t prefixBytes[3]; @@ -1813,24 +1812,24 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode case 0xC5: // Decode vex-prefix info->encoding = ZYDIS_INSTRUCTION_ENCODING_VEX; - info->prefixes |= ZYDIS_PREFIX_VEX; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_VEX; if (!ZydisDecodeVexPrefix(info->opcode, prefixBytes[0], prefixBytes[1], info)) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_VEX; - return ZYDIS_STATUS_DECODER_MALFORMED_VEX_PREFIX; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MALFORMED_VEX; + return ZYDIS_STATUS_DECODER_MALFORMED_VEX; } info->opcodeMap = info->details.vex.m_mmmm; break; case 0x62: // Decode evex-prefix info->encoding = ZYDIS_INSTRUCTION_ENCODING_EVEX; - info->prefixes |= ZYDIS_PREFIX_EVEX; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_EVEX; if (!ZydisDecodeEvexPrefix(prefixBytes[0], prefixBytes[1], prefixBytes[2], info)) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_EVEX; - return ZYDIS_STATUS_DECODER_MALFORMED_EVEX_PREFIX; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MALFORMED_EVEX; + return ZYDIS_STATUS_DECODER_MALFORMED_EVEX; } info->opcodeMap = info->details.evex.mm; break; @@ -1846,9 +1845,9 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode ZYDIS_CHECK(ZydisInputPeek(decoder, info, &nextInput)); if (((nextInput >> 0) & 0x1F) >= 8) { - if (info->prefixes & ZYDIS_PREFIX_REX) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REX) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_ILLEGAL_REX; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_ILLEGAL_REX; return ZYDIS_STATUS_DECODER_ILLEGAL_REX; } uint8_t prefixBytes[2]; @@ -1858,11 +1857,11 @@ static ZydisDecoderStatus ZydisNodeHandlerOpcode(ZydisInstructionDecoder* decode ZYDIS_CHECK(ZydisInputNext(decoder, info, &prefixBytes[1])); // Decode xop-prefix info->encoding = ZYDIS_INSTRUCTION_ENCODING_XOP; - info->prefixes |= ZYDIS_PREFIX_XOP; + info->prefixFlags |= ZYDIS_PREFIXFLAG_HAS_XOP; if (!ZydisDecodeXopPrefix(prefixBytes[0], prefixBytes[1], info)) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_MALFORMED_XOP; - return ZYDIS_STATUS_DECODER_MALFORMED_XOP_PREFIX; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_MALFORMED_XOP; + return ZYDIS_STATUS_DECODER_MALFORMED_XOP; } info->opcodeMap = ZYDIS_OPCODE_MAP_XOP8 + info->details.xop.m_mmmm - 0x08; } @@ -1974,18 +1973,18 @@ static ZydisDecoderStatus ZydisNodeHandlerMandatoryPrefix(ZydisInstructionInfo* ZYDIS_ASSERT(info); ZYDIS_ASSERT(index); - if (info->prefixes & ZYDIS_PREFIX_REP) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP) { *index = 2; - info->prefixes &= ~ ZYDIS_PREFIX_REP; // TODO: don't remove but mark as mandatory - } else if (info->prefixes & ZYDIS_PREFIX_REPNE) + info->prefixFlags &= ~ ZYDIS_PREFIXFLAG_HAS_REP; // TODO: don't remove but mark as mandatory + } else if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE) { *index = 3; - info->prefixes &= ~ ZYDIS_PREFIX_REPNE; // TODO: don't remove but mark as mandatory - } else if (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE) + info->prefixFlags &= ~ ZYDIS_PREFIXFLAG_HAS_REPNE; // TODO: don't remove but mark as mandatory + } else if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE) { *index = 1; - info->prefixes &= ~ ZYDIS_PREFIX_OPERANDSIZE; // TODO: don't remove but mark as mandatory + info->prefixFlags &= ~ ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE; // TODO: don't remove but mark as mandatory } return ZYDIS_STATUS_DECODER_SUCCESS; } @@ -2048,16 +2047,16 @@ static ZydisDecoderStatus ZydisNodeHandlerOperandSize(ZydisInstructionDecoder* d ZYDIS_ASSERT(info); ZYDIS_ASSERT(index); - info->prefixes |= ZYDIS_PREFIX_ACCEPTS_OPERANDSIZE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_OPERANDSIZE; switch (decoder->disassemblerMode) { case ZYDIS_DISASSEMBLER_MODE_16BIT: - *index = (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE) ? 1 : 0; + *index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE) ? 1 : 0; break; case ZYDIS_DISASSEMBLER_MODE_32BIT: case ZYDIS_DISASSEMBLER_MODE_64BIT: - *index = (info->prefixes & ZYDIS_PREFIX_OPERANDSIZE) ? 0 : 1; + *index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_OPERANDSIZE) ? 0 : 1; break; default: ZYDIS_UNREACHABLE; @@ -2072,18 +2071,18 @@ static ZydisDecoderStatus ZydisNodeHandlerAddressSize(ZydisInstructionDecoder* d ZYDIS_ASSERT(info); ZYDIS_ASSERT(index); - info->prefixes |= ZYDIS_PREFIX_ACCEPTS_ADDRESSSIZE; + info->prefixFlags |= ZYDIS_PREFIXFLAG_ACCEPTS_ADDRESSSIZE; switch (decoder->disassemblerMode) { case ZYDIS_DISASSEMBLER_MODE_16BIT: - *index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 0; + *index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 1 : 0; break; case ZYDIS_DISASSEMBLER_MODE_32BIT: - *index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 0 : 1; + *index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 0 : 1; break; case ZYDIS_DISASSEMBLER_MODE_64BIT: - *index = (info->prefixes & ZYDIS_PREFIX_ADDRESSSIZE) ? 1 : 2; + *index = (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_ADDRESSSIZE) ? 1 : 2; break; default: ZYDIS_UNREACHABLE; @@ -2211,8 +2210,8 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder, { case ZYDIS_NODETYPE_INVALID: { - info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID; - return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_UNDEFINED; + return ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION; } case ZYDIS_NODETYPE_DEFINITION_0OP: case ZYDIS_NODETYPE_DEFINITION_1OP: @@ -2250,8 +2249,8 @@ static ZydisDecoderStatus ZydisDecodeOpcode(ZydisInstructionDecoder* decoder, node = ZydisInstructionTableGetChildNode(node, info->opcode); if (ZydisInstructionTableGetNodeType(node) == ZYDIS_NODETYPE_INVALID) { - info->flags |= ZYDIS_INSTRUCTION_ERROR_INVALID; - return ZYDIS_STATUS_DECODER_INVALID_INSTRUCTION; + info->instrFlags |= ZYDIS_INSTRFLAG_ERROR_UNDEFINED; + return ZYDIS_STATUS_DECODER_UNDEFINED_INSTRUCTION; } node = ZydisInstructionTableGetChildNode(node, (info->details.modrm.mod == 0x3) ? 1 : 0); @@ -2524,7 +2523,7 @@ ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder, DecodeError: { - uint32_t flags = info->flags; + uint32_t flags = info->instrFlags; uint8_t firstByte = info->data[0]; uint64_t instrAddress = info->instrAddress; memset(info, 0, sizeof(*info)); @@ -2551,7 +2550,7 @@ DecodeError: ++decoder->instructionPointer; info->mode = decoder->disassemblerMode; - info->flags = flags & ZYDIS_INSTRUCTION_ERROR_MASK; + info->instrFlags = flags & ZYDIS_INSTRFLAG_ERROR_MASK; info->length = 1; info->data[0] = firstByte; info->instrAddress = instrAddress; @@ -2559,7 +2558,7 @@ DecodeError: if (!decoder->flags & ZYDIS_DECODER_FLAG_SKIP_DATA) { - return ZYDIS_STATUS_INVALID_INSTRUCTION; + return ZYDIS_STATUS_DECODING_ERROR; } } return ZYDIS_STATUS_SUCCESS; diff --git a/src/Formatter.c b/src/Formatter.c index ca8fef2..27a29cc 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -58,14 +58,14 @@ /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Inserts the @c text into the @c buffer at the given @c offset and increases the - * @c offset by the length of the text. + * @brief Appends the @c text to the @c buffer at the given @c offset and increases the + * @c offset by the length of the @c text. * * @param buffer A pointer to the target buffer. * @param bufferLen The length of the buffer. * @param offset A pointer to the buffer-offset. - * @param text The text to insert. * @param uppercase Set true, to convert to uppercase characters. + * @param text The text to append. * * @return A zydis status code. */ @@ -95,12 +95,13 @@ static ZydisStatus ZydisBufferAppend(char* buffer, size_t bufferLen, size_t* off } /** - * @brief Inserts formatted text into the @c buffer at the given @c offset and increases the - * @c offset by the length of the text. + * @brief Appends formatted to into the @c buffer at the given @c offset and increases the + * @c offset by the length of the @c text. * * @param buffer A pointer to the target buffer. * @param bufferLen The length of the buffer. * @param offset A pointer to the buffer-offset. + * @param uppercase Set true, to convert to uppercase characters. * @param format The format string. * * @return A zydis status code. @@ -199,24 +200,17 @@ static ZydisStatus ZydisBufferAppendAbsoluteAddress(const ZydisInstructionFormat switch (info->mode) { case ZYDIS_DISASSEMBLER_MODE_16BIT: - return ZydisBufferAppendFormat(buffer, bufferLen, offset, - (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address); case ZYDIS_DISASSEMBLER_MODE_32BIT: - case ZYDIS_DISASSEMBLER_MODE_64BIT: - switch (operand->size) + if (operand->size == 16) { - case 16: return ZydisBufferAppendFormat(buffer, bufferLen, offset, - (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address); - case 32: - return ZydisBufferAppendFormat(buffer, bufferLen, offset, - (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%08lX", address); - case 64: - return ZydisBufferAppendFormat(buffer, bufferLen, offset, - (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%016llX", address); - default: - return ZYDIS_STATUS_INVALID_PARAMETER; - } + (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address); + } + return ZydisBufferAppendFormat(buffer, bufferLen, offset, + (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%08lX", address); + case ZYDIS_DISASSEMBLER_MODE_64BIT: + return ZydisBufferAppendFormat(buffer, bufferLen, offset, + (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%016llX", address); default: return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -233,7 +227,7 @@ static ZydisStatus ZydisBufferAppendImmediate(const ZydisInstructionFormatter* f ZYDIS_ASSERT(info); ZYDIS_ASSERT(operand); - if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDRESS_ABSOLUTE) && + if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDR_ABSOLUTE) && (operand->imm.isRelative)) { return ZydisBufferAppendAbsoluteAddress(formatter, buffer, bufferLen, offset, info, @@ -241,7 +235,7 @@ static ZydisStatus ZydisBufferAppendImmediate(const ZydisInstructionFormatter* f } bool useSignedHex = ((operand->imm.isSigned && - (formatter->addressFormat == ZYDIS_FORMATTER_ADDRESS_RELATIVE_SIGNED)) || + (formatter->addressFormat == ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED)) || (!operand->imm.isSigned && (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_SIGNED))); if (useSignedHex && (operand->imm.value.sqword < 0)) @@ -340,9 +334,9 @@ static ZydisStatus ZydisBufferAppendOperandIntelMemory(const ZydisInstructionFor { if ((formatter->flags & ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT) || (((operand->mem.segment != ZYDIS_REGISTER_DS) || - (info->prefixes & ZYDIS_PREFIX_SEGMENT_DS)) && + (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_DS)) && ((operand->mem.segment != ZYDIS_REGISTER_SS) || - (info->prefixes & ZYDIS_PREFIX_SEGMENT_SS)))) + (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_SEGMENT_SS)))) { ZYDIS_CHECK(ZydisBufferAppendFormat(buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "%s:", @@ -446,27 +440,27 @@ static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatte { size_t offset = 0; - if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_REPNE) && - (info->prefixes & ZYDIS_PREFIX_REPNE)) + if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REPNE) && + (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REPNE)) { ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "repne ")); } - if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_REP) && (info->prefixes & ZYDIS_PREFIX_REP)) + if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_REP) && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_REP)) { ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "rep ")); } - if ((info->prefixes & ZYDIS_PREFIX_ACCEPTS_LOCK) && (info->prefixes & ZYDIS_PREFIX_LOCK)) + if ((info->prefixFlags & ZYDIS_PREFIXFLAG_ACCEPTS_LOCK) && (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_LOCK)) { ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "lock ")); } - if (info->prefixes & ZYDIS_PREFIX_XACQUIRE) + if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_XACQUIRE) { ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xacquire ")); - } else if (info->prefixes & ZYDIS_PREFIX_XRELEASE) + } else if (info->prefixFlags & ZYDIS_PREFIXFLAG_HAS_XRELEASE) { ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xrelease ")); @@ -652,7 +646,7 @@ ZydisStatus ZydisFormatterInitInstructionFormatterEx( } formatter->style = style; formatter->flags = flags; - formatter->addressFormat = ZYDIS_FORMATTER_ADDRESS_ABSOLUTE; + formatter->addressFormat = ZYDIS_FORMATTER_ADDR_ABSOLUTE; formatter->displacementFormat = ZYDIS_FORMATTER_DISP_HEX_SIGNED; formatter->immediateFormat = ZYDIS_FORMATTER_IMM_HEX_UNSIGNED; formatter->symbolResolver = NULL; diff --git a/src/InstructionTable.c b/src/InstructionTable.c index 0b5781b..108f633 100644 --- a/src/InstructionTable.c +++ b/src/InstructionTable.c @@ -51,21 +51,32 @@ typedef struct ZydisInternalInstructionTableNode_ #define ZYDIS_GET_INSTRUCTIONTABLENODE_VALUE(node) \ node.value -typedef struct ZydisInternalOperandDefinition_ -{ - unsigned int type : 8; - unsigned int encoding : 8; - unsigned int access : 2; -} ZydisInternalOperandDefinition; +//typedef struct ZydisInternalOperandDefinition_ +//{ +// unsigned int type : 8; +// unsigned int encoding : 8; +// unsigned int access : 2; +//} ZydisInternalOperandDefinition; +// +//#define ZYDIS_MAKE_OPERANDDEFINITION(type, encoding, access) \ +// { type, encoding, access } +//#define ZYDIS_GET_OPERANDDEFINITION_TYPE(def) \ +// (ZydisSemanticOperandType)def.type +//#define ZYDIS_GET_OPERANDDEFINITION_ENCODING(def) \ +// (ZydisOperandEncoding)def.encoding +//#define ZYDIS_GET_OPERANDDEFINITION_ACCESS(def) \ +// (ZydisOperandAccess)def.access + +typedef uint8_t ZydisInternalOperandDefinition[2]; #define ZYDIS_MAKE_OPERANDDEFINITION(type, encoding, access) \ - { type, encoding, access } + { type, ((encoding & 0x3F) << 2) | (access & 0x03) } #define ZYDIS_GET_OPERANDDEFINITION_TYPE(def) \ - (ZydisSemanticOperandType)def.type + def[0] #define ZYDIS_GET_OPERANDDEFINITION_ENCODING(def) \ - (ZydisOperandEncoding)def.encoding + ((def[1] >> 2) & 0x3F) #define ZYDIS_GET_OPERANDDEFINITION_ACCESS(def) \ - (ZydisOperandAccess)def.access + (def[1] & 0x03) typedef struct ZydisInternalInstructionDefinition_ { diff --git a/src/Register.c b/src/Register.c index 7ab1e7d..dbc14af 100644 --- a/src/Register.c +++ b/src/Register.c @@ -322,7 +322,7 @@ ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg) case ZYDIS_REGISTERCLASS_TABLE: return ZYDIS_REGISTERSIZE_DYNAMIC; case ZYDIS_REGISTERCLASS_TEST: - return ZYDIS_REGISTERSIZE_INVALID; // TODO: + return ZYDIS_REGISTERSIZE_32; case ZYDIS_REGISTERCLASS_CONTROL: return ZYDIS_REGISTERSIZE_DYNAMIC; case ZYDIS_REGISTERCLASS_DEBUG: diff --git a/src/Utils.c b/src/Utils.c index ea034e3..608d0dd 100644 --- a/src/Utils.c +++ b/src/Utils.c @@ -61,23 +61,20 @@ ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info } break; case ZYDIS_OPERAND_TYPE_IMMEDIATE: - if (operand->imm.isSigned || operand->imm.isRelative) + if (operand->imm.isSigned && operand->imm.isRelative) { *address = (uint64_t)((int64_t)info->instrPointer + operand->imm.value.sqword); - switch (operand->size) + switch (info->mode) { - case 16: - *address = (uint16_t)*address; - break; - case 32: - assert((info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)); // TODO: Remove after fuzzing - if (info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT) + case ZYDIS_DISASSEMBLER_MODE_16BIT: + case ZYDIS_DISASSEMBLER_MODE_32BIT: + if (operand->size == 16) { - *address = (uint32_t)*address; + *address &= 0xFFFF; } break; - case 64: - assert((info->mode == ZYDIS_DISASSEMBLER_MODE_64BIT)); // TODO: Remove after fuzzing + case ZYDIS_DISASSEMBLER_MODE_64BIT: + assert((operand->size == 64)); // TODO: Remove after fuzzing break; default: return ZYDIS_STATUS_INVALID_PARAMETER; diff --git a/tools/ZydisDisasm.c b/tools/ZydisDisasm.c index 7f506aa..400637e 100644 --- a/tools/ZydisDisasm.c +++ b/tools/ZydisDisasm.c @@ -78,7 +78,7 @@ int main(int argc, char** argv) ZydisInstructionInfo info; while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info))) { - if (info.flags & ZYDIS_IFLAG_ERROR_MASK) + if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK) { printf("db %02X\n", info.data[0]); continue; diff --git a/tools/ZydisFuzzIn.c b/tools/ZydisFuzzIn.c index 8d990eb..d343a12 100644 --- a/tools/ZydisFuzzIn.c +++ b/tools/ZydisFuzzIn.c @@ -24,7 +24,9 @@ ***************************************************************************************************/ -/* +/** + * @file + * * This file implements a tool that is supposed to be fed as input for fuzzers like AFL, * reading a control block from stdin, allowing the fuzzer to reach every possible * code-path, testing any possible combination of disassembler configurations. @@ -85,7 +87,7 @@ int main() char *outBuf = malloc(controlBlock.bufSize); while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info))) { - if (info.flags & ZYDIS_IFLAG_ERROR_MASK) + if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK) { printf("db %02X\n", info.data[0]); continue;