diff --git a/examples/FormatterHooks.c b/examples/FormatterHooks.c index 7a3b73e..92313e9 100644 --- a/examples/FormatterHooks.c +++ b/examples/FormatterHooks.c @@ -133,7 +133,7 @@ typedef struct ZydisCustomUserData_ /* Hook callbacks */ /* ============================================================================================== */ -ZydisFormatterFormatFunc defaultPrintMnemonic; +ZydisFormatterFunc defaultPrintMnemonic; static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, ZydisCustomUserData* userData) @@ -191,7 +191,7 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, /* ---------------------------------------------------------------------------------------------- */ -ZydisFormatterFormatOperandFunc defaultFormatOperandImm; +ZydisFormatterOperandFunc defaultFormatOperandImm; static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, @@ -220,15 +220,15 @@ void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, Zydi { ZydisFormatter formatter; ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL); - ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE); - ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE); + ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE); + ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE); if (installHooks) { - defaultPrintMnemonic = (ZydisFormatterFormatFunc)&ZydisFormatterPrintMnemonic; + defaultPrintMnemonic = (ZydisFormatterFunc)&ZydisFormatterPrintMnemonic; ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC, (const void**)&defaultPrintMnemonic); - defaultFormatOperandImm = (ZydisFormatterFormatOperandFunc)&ZydisFormatterFormatOperandImm; + defaultFormatOperandImm = (ZydisFormatterOperandFunc)&ZydisFormatterFormatOperandImm; ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, (const void**)&defaultFormatOperandImm); } diff --git a/examples/ZydisPerfTest.c b/examples/ZydisPerfTest.c index 103cb2a..95cab7d 100644 --- a/examples/ZydisPerfTest.c +++ b/examples/ZydisPerfTest.c @@ -174,9 +174,9 @@ uint64_t processBuffer(const char* buffer, size_t length, ZydisBool minimalMode, { if (!ZYDIS_SUCCESS(ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL)) || !ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter, - ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE)) || + ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE)) || !ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter, - ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE))) + ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE))) { fputs("Failed to initialize instruction-formatter\n", stderr); exit(EXIT_FAILURE); diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index de10be4..4f6d0b4 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -50,7 +50,7 @@ extern "C" { /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the @c ZydisFormatterStyle datatype. + * @brief Defines the `ZydisFormatterStyle` datatype. */ typedef ZydisU8 ZydisFormatterStyle; @@ -75,7 +75,7 @@ enum ZydisFormatterStyles /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the @c ZydisFormatterProperty datatype. + * @brief Defines the `ZydisFormatterProperty` datatype. */ typedef ZydisU8 ZydisFormatterProperty; @@ -100,16 +100,16 @@ enum ZydisFormatterProperties * * The default value is `ZYDIS_FALSE`. */ - ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, + ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, /** - * @brief Controls the printing of operand-sizes. + * @brief Controls the printing of memory-operand sizes. * * Pass `ZYDIS_TRUE` as value to force the formatter to always print the size of memory-operands * or `ZYDIS_FALSE` to only print it on demand. * * The default value is `ZYDIS_FALSE`. */ - ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, + ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, /** * @brief Controls the format of addresses. @@ -141,7 +141,7 @@ enum ZydisFormatterProperties /** * @brief Sets the prefix for hexadecimal values. * - * The default value is `0x`. + * The default value is `"0x"`. */ ZYDIS_FORMATTER_PROP_HEX_PREFIX, /** @@ -176,7 +176,7 @@ enum ZydisFormatterProperties }; /* ---------------------------------------------------------------------------------------------- */ -/* Address format constants */ +/* Address format */ /* ---------------------------------------------------------------------------------------------- */ /** @@ -194,25 +194,23 @@ enum ZydisAddressFormat /** * @brief Uses signed hexadecimal values to display relative addresses. * - * Using this value will cause the formatter to invoke either - * `ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT` or `ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE` to - * format addresses. + * Using this value will cause the formatter to either invoke + * `ZYDIS_FORMATTER_HOOK_PRINT_DISP` or `ZYDIS_FORMATTER_HOOK_PRINT_IMM` to format addresses. * * Examples: - * "JMP 0x20" - * "JMP -0x20" + * - `"JMP 0x20"` + * - `"JMP -0x20"` */ ZYDIS_ADDR_FORMAT_RELATIVE_SIGNED, /** * @brief Uses unsigned hexadecimal values to display relative addresses. * - * Using this value will cause the formatter to invoke either - * `ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT` or `ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE` to - * format addresses. + * Using this value will cause the formatter to either invoke + * `ZYDIS_FORMATTER_HOOK_PRINT_DISP` or `ZYDIS_FORMATTER_HOOK_PRINT_IMM` to format addresses. * * Examples: - * "JMP 0x20" - * "JMP 0xE0" + * - `"JMP 0x20"` + * - `"JMP 0xE0"` */ ZYDIS_ADDR_FORMAT_RELATIVE_UNSIGNED, @@ -223,7 +221,7 @@ enum ZydisAddressFormat }; /* ---------------------------------------------------------------------------------------------- */ -/* Displacement formats */ +/* Displacement format */ /* ---------------------------------------------------------------------------------------------- */ /** @@ -235,16 +233,16 @@ enum ZydisDisplacementFormat * @brief Formats displacements as signed hexadecimal values. * * Examples: - * "MOV EAX, DWORD PTR SS:[ESP+0x400]" - * "MOV EAX, DWORD PTR SS:[ESP-0x400]" + * - `"MOV EAX, DWORD PTR SS:[ESP+0x400]"` + * - `"MOV EAX, DWORD PTR SS:[ESP-0x400]"` */ ZYDIS_DISP_FORMAT_HEX_SIGNED, /** * @brief Formats displacements as unsigned hexadecimal values. * * Examples: - * "MOV EAX, DWORD PTR SS:[ESP+0x400]" - * "MOV EAX, DWORD PTR SS:[ESP+0xFFFFFC00]" + * - `"MOV EAX, DWORD PTR SS:[ESP+0x400]"` + * - `"MOV EAX, DWORD PTR SS:[ESP+0xFFFFFC00]"` */ ZYDIS_DISP_FORMAT_HEX_UNSIGNED, @@ -255,7 +253,7 @@ enum ZydisDisplacementFormat }; /* ---------------------------------------------------------------------------------------------- */ -/* Immediate formats */ +/* Immediate format */ /* ---------------------------------------------------------------------------------------------- */ /** @@ -265,23 +263,23 @@ enum ZydisImmediateFormat { /** * @brief Automatically chooses the most suitable formatting-mode based on the operands - * @c ZydisOperandInfo.imm.isSigned attribute. + * `ZydisOperandInfo.imm.isSigned` attribute. */ ZYDIS_IMM_FORMAT_HEX_AUTO, /** * @brief Formats immediates as signed hexadecimal values. * * Examples: - * "MOV EAX, 0x400" - * "MOV EAX, -0x400" + * - `"MOV EAX, 0x400"` + * - `"MOV EAX, -0x400"` */ ZYDIS_IMM_FORMAT_HEX_SIGNED, /** * @brief Formats immediates as unsigned hexadecimal values. * * Examples: - * "MOV EAX, 0x400" - * "MOV EAX, 0xFFFFFC00" + * - `"MOV EAX, 0x400"` + * - `"MOV EAX, 0xFFFFFC00"` */ ZYDIS_IMM_FORMAT_HEX_UNSIGNED, @@ -296,7 +294,7 @@ enum ZydisImmediateFormat /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the @c ZydisFormatterHookType datatype. + * @brief Defines the `ZydisFormatterHookType` datatype. */ typedef ZydisU8 ZydisFormatterHookType; @@ -306,90 +304,98 @@ typedef ZydisU8 ZydisFormatterHookType; enum ZydisFormatterHookTypes { /** - * @brief This function is called before the formatter starts formatting an instruction. + * @brief This function is invoked before the formatter formats an instruction. */ - ZYDIS_FORMATTER_HOOK_PRE, + ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION, /** - * @brief This function is called before the formatter finished formatting an instruction. + * @brief This function is invoked before the formatter formatted an instruction. */ - ZYDIS_FORMATTER_HOOK_POST, + ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION, /** - * @brief This function refers to the main formatting function, that internally calls all - * other function except the ones that are hooked by @c ZYDIS_FORMATTER_HOOK_PRE and - * @c ZYDIS_FORMATTER_HOOK_POST. + * @brief This function is invoked before the formatter formats an operand. + */ + ZYDIS_FORMATTER_HOOK_PRE_OPERAND, + /** + * @brief This function is invoked before the formatter formatted an operand. + */ + ZYDIS_FORMATTER_HOOK_POST_OPERAND, + + /** + * @brief This function refers to the main formatting function. * * Replacing this function allows for complete custom formatting, but indirectly disables all - * other hooks except for @c ZYDIS_FORMATTER_HOOK_PRE and @c ZYDIS_FORMATTER_HOOK_POST. + * other hooks except for `ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION` and + * `ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION`. */ ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION, /** - * @brief This function is called to print the instruction prefixes. - */ - ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES, - /** - * @brief This function is called to print the instruction mnemonic. - */ - ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC, - /** - * @brief This function is called to format an register operand. + * @brief This function is invoked to format a register operand. */ ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG, /** - * @brief This function is called to format an memory operand. + * @brief This function is invoked to format a memory operand. * * Replacing this function might indirectly disable some specific calls to the - * @c ZYDIS_FORMATTER_PRINT_ADDRESS and @c ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT functions. + * `ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS` and `ZYDIS_FORMATTER_HOOK_PRINT_DISP` functions. */ ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM, /** - * @brief This function is called to format an pointer operand. + * @brief This function is invoked to format a pointer operand. */ ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR, /** - * @brief This function is called to format an immediate operand. + * @brief This function is invoked to format an immediate operand. * * Replacing this function might indirectly disable some specific calls to the - * @c ZYDIS_FORMATTER_PRINT_ADDRESS and @c ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE functions. + * `ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS` and `ZYDIS_FORMATTER_HOOK_PRINT_IMM` functions. */ ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, + /** - * @brief This function is called right before formatting an memory operand to print the - * optional size-specifier. + * @brief This function is invoked to print the instruction mnemonic. */ - ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE, + ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC, /** - * @brief This function is called right before formatting an memory operand to print the - * optional segment-register. + * @brief This function is invoked to print a register. */ - ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT, + ZYDIS_FORMATTER_HOOK_PRINT_REGISTER, /** - * @brief This function is called right after formatting an operand to print the optional - * EVEX/MVEX operand-decorator. - */ - ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR, - /** - * @brief This function is called to print an absolute address. + * @brief This function is invoked to print an absolute address. */ ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS, /** - * @brief This function is called to print a memory displacement value. + * @brief This function is invoked to print a memory displacement value. */ - ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT, + ZYDIS_FORMATTER_HOOK_PRINT_DISP, /** - * @brief This function is called to print an immediate value. + * @brief This function is invoked to print an immediate value. */ - ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE, + ZYDIS_FORMATTER_HOOK_PRINT_IMM, + + /** + * @brief This function is invoked to print the size of a memory operand. + */ + ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE, + /** + * @brief This function is invoked to print the instruction prefixes. + */ + ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES, + /** + * @brief This function is invoked after formatting an operand to print a `EVEX`/`MVEX` + * decorator. + */ + ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR, /** * @brief Maximum value of this enum. */ - ZYDIS_FORMATTER_HOOK_MAX_VALUE = ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE + ZYDIS_FORMATTER_HOOK_MAX_VALUE = ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR }; /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the @c ZydisDecoratorType datatype. + * @brief Defines the `ZydisDecoratorType` datatype. */ typedef ZydisU8 ZydisDecoratorType; @@ -399,18 +405,39 @@ typedef ZydisU8 ZydisDecoratorType; enum ZydisDecoratorTypes { ZYDIS_DECORATOR_TYPE_INVALID, + /** + * @brief The embedded-mask decorator. + */ ZYDIS_DECORATOR_TYPE_MASK, - ZYDIS_DECORATOR_TYPE_BROADCAST, - ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, + /** + * @brief The broadcast decorator. + */ + ZYDIS_DECORATOR_TYPE_BC, + /** + * @brief The rounding-control decorator. + */ + ZYDIS_DECORATOR_TYPE_RC, + /** + * @brief The suppress-all-exceptions decorator. + */ ZYDIS_DECORATOR_TYPE_SAE, + /** + * @brief The register-swizzle decorator. + */ ZYDIS_DECORATOR_TYPE_SWIZZLE, + /** + * @brief The conversion decorator. + */ ZYDIS_DECORATOR_TYPE_CONVERSION, - ZYDIS_DECORATOR_TYPE_EVICTION_HINT, + /** + * @brief The eviction-hint decorator. + */ + ZYDIS_DECORATOR_TYPE_EH, /** * @brief Maximum value of this enum. */ - ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EVICTION_HINT + ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EH }; /* ---------------------------------------------------------------------------------------------- */ @@ -418,108 +445,128 @@ enum ZydisDecoratorTypes typedef struct ZydisFormatter_ ZydisFormatter; /** - * @brief Defines the @c ZydisFormatterNotifyFunc function pointer. + * @brief Defines the `ZydisFormatterFunc` function pointer. * - * @param formatter A pointer to the @c ZydisFormatter instance. + * @param formatter A pointer to the `ZydisFormatter` instance. * @param string A pointer to the string. - * @param instruction A pointer to the @c ZydisDecodedInstruction struct. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param userData A pointer to user-defined data. * - * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the - * formatting process to fail. + * @return A zydis status code. * - * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRE and - * @c ZYDIS_FORMATTER_HOOK_POST hook-types. + * Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the formatting + * process to fail. + * + * Returning `ZYDIS_STATUS_SUCCESS` in `ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES` without writing to + * the string is valid and signals that the corresponding element should not be printed. + * + * This function type is used for: + * - `ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION` + * - `ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION` + * - `ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION` + * - `ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC` + * - `ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES` */ -typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterFunc)(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData); /** - * @brief Defines the @c ZydisFormatterFormatFunc function pointer. + * @brief Defines the `ZydisFormatterOperandFunc` function pointer. * - * @param formatter A pointer to the @c ZydisFormatter instance. + * @param formatter A pointer to the `ZydisFormatter` instance. * @param string A pointer to the string. - * @param instruction A pointer to the @c ZydisDecodedInstruction struct. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param operand A pointer to the `ZydisDecodedOperand` struct. * @param userData A pointer to user-defined data. * - * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the - * formatting process to fail. - * - * This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION, - * @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types. - */ -typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, - ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData); - -/** - * @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer. - * - * @param formatter A pointer to the @c ZydisFormatter instance. - * @param string A pointer to the string. - * @param instruction A pointer to the @c ZydisDecodedInstruction struct. - * @param operand A pointer to the @c ZydisDecodedOperand struct. - * @param userData A pointer to user-defined data. + * @return A zydis status code. * - * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the - * formatting process to fail. + * Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the formatting + * process to fail. * - * Returning @c ZYDIS_STATUS_SUCCESS in one of the @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_X hooks + * Returning `ZYDIS_STATUS_SUCCESS` in one of the `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_X` hooks * without writing to the string is valid and will cause the formatter to omit the current * operand. * - * Returning @c ZYDIS_STATUS_SUCCESS in @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE, - * @c ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT or @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR without - * writing to the string is valid and signals that the corresponding element should not be - * printed for the current operand. + * Returning `ZYDIS_STATUS_SUCCESS` in `ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE` or + * `ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR` without writing to the string is valid and signals that + * the corresponding element should not be printed for the current operand. * - * This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG, - * @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM, @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR, - * @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE, - * @c ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT, @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR, - * @c ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT and @c ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE - * hook-types. + * This function type is used for: + * - `ZYDIS_FORMATTER_HOOK_PRE_OPERAND` + * - `ZYDIS_FORMATTER_HOOK_POST_OPERAND` + * - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG` + * - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM` + * - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR` + * - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM` + * - `ZYDIS_FORMATTER_HOOK_PRINT_DISP` + * - `ZYDIS_FORMATTER_HOOK_PRINT_IMM` + * - `ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE` */ -typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterOperandFunc)(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData); /** - * @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer. + * @brief Defines the `ZydisFormatterRegisterFunc` function pointer. * - * @param formatter A pointer to the @c ZydisFormatter instance. + * @param formatter A pointer to the `ZydisFormatter` instance. * @param string A pointer to the string. - * @param instruction A pointer to the @c ZydisDecodedInstruction struct. - * @param operand A pointer to the @c ZydisDecodedOperand struct. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param operand A pointer to the `ZydisDecodedOperand` struct. + * @param reg The register. * @param userData A pointer to user-defined data. * - * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the + * @return Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the * formatting process to fail. * - * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type. + * This function type is used for: + * - `ZYDIS_FORMATTER_HOOK_PRINT_REGISTER`. */ -typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterRegisterFunc)(const ZydisFormatter* formatter, + ZydisString* string, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, ZydisRegister reg, void* userData); + + /** + * @brief Defines the `ZydisFormatterAddressFunc` function pointer. + * + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param string A pointer to the string. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param operand A pointer to the `ZydisDecodedOperand` struct. + * @param address The address. + * @param userData A pointer to user-defined data. + * + * @return Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the + * formatting process to fail. + * + * This function type is used for: + * - `ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS` + */ +typedef ZydisStatus (*ZydisFormatterAddressFunc)(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisU64 address, void* userData); /** - * @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer. + * @brief Defines the `ZydisFormatterDecoratorFunc` function pointer. * - * @param formatter A pointer to the @c ZydisFormatter instance. + * @param formatter A pointer to the `ZydisFormatter` instance. * @param string A pointer to the string. - * @param instruction A pointer to the @c ZydisDecodedInstruction struct. - * @param operand A pointer to the @c ZydisDecodedOperand struct. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. + * @param operand A pointer to the `ZydisDecodedOperand` struct. * @param type The decorator type. * @param userData A pointer to user-defined data. * - * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the + * @return Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the * formatting process to fail. * - * Returning @c ZYDIS_STATUS_SUCCESS without writing to the string is valid and will cause the + * Returning `ZYDIS_STATUS_SUCCESS` without writing to the string is valid and will cause the * formatter to omit the current decorator. * - * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type. + * This function type is used for: + * - `ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR` */ -typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter, +typedef ZydisStatus (*ZydisFormatterDecoratorFunc)(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData); @@ -528,39 +575,41 @@ typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* f /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the @c ZydisFormatter struct. + * @brief Defines the `ZydisFormatter` struct. */ struct ZydisFormatter_ { - ZydisU8 letterCase; - ZydisBool forceSegments; - ZydisBool forceOperandSize; - ZydisU8 addressFormat; - ZydisU8 displacementFormat; - ZydisU8 immediateFormat; + ZydisLetterCase letterCase; + ZydisBool forceMemorySegment; + ZydisBool forceMemorySize; + ZydisU8 formatAddress; + ZydisU8 formatDisp; + ZydisU8 formatImm; ZydisBool hexUppercase; ZydisString* hexPrefix; ZydisString hexPrefixData; ZydisString* hexSuffix; ZydisString hexSuffixData; ZydisU8 hexPaddingAddress; - ZydisU8 hexPaddingDisplacement; - ZydisU8 hexPaddingImmediate; - ZydisFormatterNotifyFunc funcPre; - ZydisFormatterNotifyFunc funcPost; - ZydisFormatterFormatFunc funcFormatInstruction; - ZydisFormatterFormatFunc funcPrintPrefixes; - ZydisFormatterFormatFunc funcPrintMnemonic; - ZydisFormatterFormatOperandFunc funcFormatOperandReg; - ZydisFormatterFormatOperandFunc funcFormatOperandMem; - ZydisFormatterFormatOperandFunc funcFormatOperandPtr; - ZydisFormatterFormatOperandFunc funcFormatOperandImm; - ZydisFormatterFormatOperandFunc funcPrintOperandSize; - ZydisFormatterFormatOperandFunc funcPrintSegment; - ZydisFormatterFormatDecoratorFunc funcPrintDecorator; - ZydisFormatterFormatAddressFunc funcPrintAddress; - ZydisFormatterFormatOperandFunc funcPrintDisplacement; - ZydisFormatterFormatOperandFunc funcPrintImmediate; + ZydisU8 hexPaddingDisp; + ZydisU8 hexPaddingImm; + ZydisFormatterFunc funcPreInstruction; + ZydisFormatterFunc funcPostInstruction; + ZydisFormatterOperandFunc funcPreOperand; + ZydisFormatterOperandFunc funcPostOperand; + ZydisFormatterFunc funcFormatInstruction; + ZydisFormatterOperandFunc funcFormatOperandReg; + ZydisFormatterOperandFunc funcFormatOperandMem; + ZydisFormatterOperandFunc funcFormatOperandPtr; + ZydisFormatterOperandFunc funcFormatOperandImm; + ZydisFormatterFunc funcPrintMnemonic; + ZydisFormatterRegisterFunc funcPrintRegister; + ZydisFormatterAddressFunc funcPrintAddress; + ZydisFormatterOperandFunc funcPrintDisp; + ZydisFormatterOperandFunc funcPrintImm; + ZydisFormatterOperandFunc funcPrintMemSize; + ZydisFormatterFunc funcPrintPrefixes; + ZydisFormatterDecoratorFunc funcPrintDecorator; }; /* ---------------------------------------------------------------------------------------------- */ @@ -570,9 +619,9 @@ struct ZydisFormatter_ /* ============================================================================================== */ /** - * @brief Initializes the given @c ZydisFormatter instance. + * @brief Initializes the given `ZydisFormatter` instance. * - * @param formatter A pointer to the @c ZydisFormatter instance. + * @param formatter A pointer to the `ZydisFormatter` instance. * @param style The formatter style. * * @return A zydis status code. @@ -582,20 +631,20 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisForm /** * @brief Sets the value of the specified formatter `attribute`. * - * @param formatter A pointer to the @c ZydisFormatter instance. + * @param formatter A pointer to the `ZydisFormatter` instance. * @param property The id of the formatter-property. * @param value The new value. * * @return A zydis status code. */ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetProperty(ZydisFormatter* formatter, - ZydisFormatterProperty property, ZydisUSize value); + ZydisFormatterProperty property, ZydisUPointer value); /** * @brief Replaces a formatter function with a custom callback and/or retrieves the currently * used function. * - * @param formatter A pointer to the @c ZydisFormatter instance. + * @param formatter A pointer to the `ZydisFormatter` instance. * @param hook The formatter hook-type. * @param callback A pointer to a variable that contains the pointer of the callback function * and receives the pointer of the currently used function. @@ -611,8 +660,8 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, /** * @brief Formats the given instruction and writes it into the output buffer. * - * @param formatter A pointer to the @c ZydisFormatter instance. - * @param instruction A pointer to the @c ZydisDecodedInstruction struct. + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param buffer A pointer to the output buffer. * @param bufferLen The length of the output buffer. * @@ -624,8 +673,8 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* f /** * @brief Formats the given instruction and writes it into the output buffer. * - * @param formatter A pointer to the @c ZydisFormatter instance. - * @param instruction A pointer to the @c ZydisDecodedInstruction struct. + * @param formatter A pointer to the `ZydisFormatter` instance. + * @param instruction A pointer to the `ZydisDecodedInstruction` struct. * @param buffer A pointer to the output buffer. * @param bufferLen The length of the output buffer. * @param userData A pointer to user-defined data which can be used in custom formatter diff --git a/src/Formatter.c b/src/Formatter.c index 4e7d59f..235c746 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -39,16 +39,16 @@ static ZydisStatus ZydisFormatInstruction(const ZydisFormatter* formatter, const ZydisDecodedInstruction* instruction, ZydisString* string, void* userData) { - if (formatter->funcPre) + if (formatter->funcPreInstruction) { - ZYDIS_CHECK(formatter->funcPre(formatter, string, instruction, userData)); + ZYDIS_CHECK(formatter->funcPreInstruction(formatter, string, instruction, userData)); } ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, string, instruction, userData)); - if (formatter->funcPost) + if (formatter->funcPostInstruction) { - return formatter->funcPost(formatter, string, instruction, userData); + return formatter->funcPostInstruction(formatter, string, instruction, userData); } return ZYDIS_STATUS_SUCCESS; @@ -58,71 +58,43 @@ static ZydisStatus ZydisFormatInstruction(const ZydisFormatter* formatter, const /* Intel style */ /* ---------------------------------------------------------------------------------------------- */ -static ZydisStatus ZydisPrintPrefixesIntel(const ZydisFormatter* formatter, ZydisString* string, - const ZydisDecodedInstruction* instruction, void* userData) +static ZydisStatus ZydisPrintSegmentIntel(const ZydisFormatter* formatter, ZydisString* string, + const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - ZYDIS_UNUSED_PARAMETER(userData); + ZYDIS_ASSERT(formatter); + ZYDIS_ASSERT(string); + ZYDIS_ASSERT(instruction); + ZYDIS_ASSERT(operand); - if (!formatter || !instruction) + switch (operand->mem.segment) { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - - if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK) - { - return ZydisStringAppendExC(string, "lock ", formatter->letterCase); - } - - if (instruction->attributes & ZYDIS_ATTRIB_HAS_REP) - { - return ZydisStringAppendExC(string, "rep ", formatter->letterCase); - } - if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPE) - { - return ZydisStringAppendExC(string, "repe ", formatter->letterCase); - } - if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE) - { - return ZydisStringAppendExC(string, "repne ", formatter->letterCase); - } - - if (instruction->attributes & ZYDIS_ATTRIB_HAS_BOUND) - { - return ZydisStringAppendExC(string, "bnd ", formatter->letterCase); - } - - if (instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE) - { - return ZydisStringAppendExC(string, "xacquire ", formatter->letterCase); - } - if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE) - { - return ZydisStringAppendExC(string, "xrelease ", formatter->letterCase); - } - - return ZYDIS_STATUS_SUCCESS; -} - -static ZydisStatus ZydisPrintMnemonicIntel(const ZydisFormatter* formatter, ZydisString* string, - const ZydisDecodedInstruction* instruction, void* userData) -{ - ZYDIS_UNUSED_PARAMETER(userData); - - if (!formatter || !instruction) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - - const ZydisStaticString* mnemonic = ZydisMnemonicGetStaticString(instruction->mnemonic); - if (!mnemonic) - { - return ZydisStringAppendExC(string, "invalid", formatter->letterCase); - } - ZYDIS_CHECK(ZydisStringAppendExStatic(string, mnemonic, formatter->letterCase)); - - if (instruction->attributes & ZYDIS_ATTRIB_IS_FAR_BRANCH) - { - return ZydisStringAppendExC(string, " far", formatter->letterCase); + case ZYDIS_REGISTER_ES: + case ZYDIS_REGISTER_CS: + case ZYDIS_REGISTER_FS: + case ZYDIS_REGISTER_GS: + ZYDIS_CHECK(formatter->funcPrintRegister(formatter, string, instruction, operand, + operand->mem.segment, userData)); + return ZydisStringAppendC(string, ":"); + case ZYDIS_REGISTER_SS: + if ((formatter->forceMemorySegment) || + (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS)) + { + ZYDIS_CHECK(formatter->funcPrintRegister(formatter, string, instruction, operand, + operand->mem.segment, userData)); + return ZydisStringAppendC(string, ":"); + } + break; + case ZYDIS_REGISTER_DS: + if ((formatter->forceMemorySegment) || + (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS)) + { + ZYDIS_CHECK(formatter->funcPrintRegister(formatter, string, instruction, operand, + operand->mem.segment, userData)); + return ZydisStringAppendC(string, ":"); + } + break; + default: + break; } return ZYDIS_STATUS_SUCCESS; @@ -130,27 +102,149 @@ static ZydisStatus ZydisPrintMnemonicIntel(const ZydisFormatter* formatter, Zydi /* ---------------------------------------------------------------------------------------------- */ -static ZydisStatus ZydisFormatOperandRegIntel(const ZydisFormatter* formatter, ZydisString* string, - const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) +static ZydisStatus ZydisFormatInstrIntel(const ZydisFormatter* formatter, ZydisString* string, + const ZydisDecodedInstruction* instruction, void* userData) { - ZYDIS_UNUSED_PARAMETER(userData); - - if (!formatter || !instruction || !operand) + if (!formatter || !string || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } + ZYDIS_CHECK(formatter->funcPrintPrefixes(formatter, string, instruction, userData)); + ZYDIS_CHECK(formatter->funcPrintMnemonic(formatter, string, instruction, userData)); + + for (ZydisU8 i = 0; i < instruction->operandCount; ++i) + { + if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN) + { + break; + } + + const ZydisUSize strLenRestore = string->length; + if (i == 0) + { + ZYDIS_CHECK(ZydisStringAppendC(string, " ")); + } else + { + ZYDIS_CHECK(ZydisStringAppendC(string, ", ")); + } + + if (formatter->funcPreOperand) + { + formatter->funcPreOperand(formatter, string, instruction, &instruction->operands[i], + userData); + } + + const ZydisUSize strLenPreOperand = string->length; + switch (instruction->operands[i].type) + { + case ZYDIS_OPERAND_TYPE_REGISTER: + ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, string, instruction, + &instruction->operands[i], userData)); + break; + case ZYDIS_OPERAND_TYPE_MEMORY: + { + ZYDIS_CHECK(formatter->funcPrintMemSize(formatter, string, instruction, + &instruction->operands[i], userData)); + const ZydisUSize strLenTemp = string->length; + ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, string, instruction, + &instruction->operands[i], userData)); + if (strLenTemp == string->length) + { + string->length = strLenPreOperand; + } + break; + } + case ZYDIS_OPERAND_TYPE_POINTER: + ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, string, instruction, + &instruction->operands[i], userData)); + break; + case ZYDIS_OPERAND_TYPE_IMMEDIATE: + ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, string, instruction, + &instruction->operands[i], userData)); + break; + default: + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + if (strLenPreOperand == string->length) + { + // Omit whole operand, if the string did not change during the formatting-callback + string->length = strLenRestore; + + if (formatter->funcPostOperand) + { + formatter->funcPostOperand(formatter, string, instruction, + &instruction->operands[i], userData); + } + + continue; + } + + if (formatter->funcPostOperand) + { + formatter->funcPostOperand(formatter, string, instruction, &instruction->operands[i], + userData); + } + + if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || + (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) + { + if ((i == 0) && + (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)) + { + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_MASK, userData)); + } + if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY) + { + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_BC, userData)); + if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) + { + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_CONVERSION, userData)); + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_EH, userData)); + } + } else + { + if ((i == (instruction->operandCount - 1)) || + (instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) + { + if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) + { + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SWIZZLE, userData)); + } + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_RC, userData)); + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SAE, userData)); + } + } + } + } + + return ZYDIS_STATUS_SUCCESS; +} + +static ZydisStatus ZydisFormatOperandRegIntel(const ZydisFormatter* formatter, ZydisString* string, + const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) +{ + if (!operand) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + // We want to print embedded-mask registers as decorator instead of a regular operand if ((operand->id == 1) && (operand->encoding == ZYDIS_OPERAND_ENCODING_MASK)) { return ZYDIS_STATUS_SUCCESS; } - const ZydisStaticString* reg = ZydisRegisterGetStaticString(operand->reg.value); - if (!reg) - { - return ZydisStringAppendExC(string, "invalid", formatter->letterCase); - } - return ZydisStringAppendExStatic(string, reg, formatter->letterCase); + return formatter->funcPrintRegister(formatter, string, instruction, operand, + operand->reg.value, userData); } static ZydisStatus ZydisFormatOperandMemIntel(const ZydisFormatter* formatter, ZydisString* string, @@ -161,6 +255,7 @@ static ZydisStatus ZydisFormatOperandMemIntel(const ZydisFormatter* formatter, Z return ZYDIS_STATUS_INVALID_PARAMETER; } + ZYDIS_CHECK(ZydisPrintSegmentIntel(formatter, string, instruction, operand, userData)); ZYDIS_CHECK(ZydisStringAppendC(string, "[")); if (operand->mem.disp.hasDisplacement && ( @@ -170,7 +265,7 @@ static ZydisStatus ZydisFormatOperandMemIntel(const ZydisFormatter* formatter, Z (operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0)) { // EIP/RIP-relative or absolute-displacement address operand - if ((formatter->addressFormat == ZYDIS_ADDR_FORMAT_ABSOLUTE) || + if ((formatter->formatAddress == ZYDIS_ADDR_FORMAT_ABSOLUTE) || (operand->mem.base == ZYDIS_REGISTER_NONE)) { ZydisU64 address; @@ -179,9 +274,9 @@ static ZydisStatus ZydisFormatOperandMemIntel(const ZydisFormatter* formatter, Z address, userData)); } else { - ZYDIS_CHECK(ZydisStringAppendExStatic(string, - ZydisRegisterGetStaticString(operand->mem.base), formatter->letterCase)); - ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, string, instruction, operand, + ZYDIS_CHECK(formatter->funcPrintRegister(formatter, string, instruction, operand, + operand->mem.base, userData)); + ZYDIS_CHECK(formatter->funcPrintDisp(formatter, string, instruction, operand, userData)); } } else @@ -189,34 +284,25 @@ static ZydisStatus ZydisFormatOperandMemIntel(const ZydisFormatter* formatter, Z // Regular memory operand if (operand->mem.base != ZYDIS_REGISTER_NONE) { - const ZydisStaticString* reg = ZydisRegisterGetStaticString(operand->mem.base); - if (!reg) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - ZYDIS_CHECK(ZydisStringAppendExStatic(string, reg, formatter->letterCase)); + ZYDIS_CHECK(formatter->funcPrintRegister(formatter, string, instruction, operand, + operand->mem.base, userData)); } if ((operand->mem.index != ZYDIS_REGISTER_NONE) && (operand->mem.type != ZYDIS_MEMOP_TYPE_MIB)) { - const ZydisStaticString* reg = ZydisRegisterGetStaticString(operand->mem.index); - if (!reg) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } if (operand->mem.base != ZYDIS_REGISTER_NONE) { ZYDIS_CHECK(ZydisStringAppendC(string, "+")); } - ZYDIS_CHECK(ZydisStringAppendExStatic(string, reg, formatter->letterCase)); + ZYDIS_CHECK(formatter->funcPrintRegister(formatter, string, instruction, operand, + operand->mem.index, userData)); if (operand->mem.scale) { ZYDIS_CHECK(ZydisStringAppendC(string, "*")); ZYDIS_CHECK(ZydisPrintDecU(string, operand->mem.scale, 0)); } } - ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, string, instruction, operand, - userData)); + ZYDIS_CHECK(formatter->funcPrintDisp(formatter, string, instruction, operand, userData)); } return ZydisStringAppendC(string, "]"); @@ -225,9 +311,10 @@ static ZydisStatus ZydisFormatOperandMemIntel(const ZydisFormatter* formatter, Z static ZydisStatus ZydisFormatOperandPtrIntel(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { + ZYDIS_UNUSED_PARAMETER(instruction); ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !instruction || !operand) + if (!formatter || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -251,7 +338,7 @@ static ZydisStatus ZydisFormatOperandImmIntel(const ZydisFormatter* formatter, Z if (operand->imm.isRelative) { ZydisBool printSignedHEX = ZYDIS_FALSE; - switch (formatter->addressFormat) + switch (formatter->formatAddress) { case ZYDIS_ADDR_FORMAT_ABSOLUTE: { @@ -281,18 +368,65 @@ static ZydisStatus ZydisFormatOperandImmIntel(const ZydisFormatter* formatter, Z } // The immediate operand contains an actual ordinal value - return formatter->funcPrintImmediate(formatter, string, instruction, operand, userData); + return formatter->funcPrintImm(formatter, string, instruction, operand, userData); } /* ---------------------------------------------------------------------------------------------- */ -static ZydisStatus ZydisPrintAddressIntel(const ZydisFormatter* formatter, ZydisString* string, - const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, - ZydisU64 address, void* userData) +static ZydisStatus ZydisPrintMnemonicIntel(const ZydisFormatter* formatter, ZydisString* string, + const ZydisDecodedInstruction* instruction, void* userData) { ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !instruction || !operand) + if (!formatter || !instruction) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + const ZydisStaticString* mnemonic = ZydisMnemonicGetStaticString(instruction->mnemonic); + if (!mnemonic) + { + return ZydisStringAppendExC(string, "invalid", formatter->letterCase); + } + ZYDIS_CHECK(ZydisStringAppendExStatic(string, mnemonic, formatter->letterCase)); + + if (instruction->attributes & ZYDIS_ATTRIB_IS_FAR_BRANCH) + { + return ZydisStringAppendExC(string, " far", formatter->letterCase); + } + + return ZYDIS_STATUS_SUCCESS; +} + +static ZydisStatus ZydisPrintRegisterIntel(const ZydisFormatter* formatter, ZydisString* string, + const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, + ZydisRegister reg, void* userData) +{ + ZYDIS_UNUSED_PARAMETER(instruction); + ZYDIS_UNUSED_PARAMETER(operand); + ZYDIS_UNUSED_PARAMETER(userData); + + if (!formatter) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + const ZydisStaticString* str = ZydisRegisterGetStaticString(reg); + if (!str) + { + return ZydisStringAppendExC(string, "invalid", formatter->letterCase); + } + return ZydisStringAppendExStatic(string, str, formatter->letterCase); +} + +static ZydisStatus ZydisPrintAddrIntel(const ZydisFormatter* formatter, ZydisString* string, + const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, + ZydisU64 address, void* userData) +{ + ZYDIS_UNUSED_PARAMETER(operand); + ZYDIS_UNUSED_PARAMETER(userData); + + if (!formatter || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -313,12 +447,13 @@ static ZydisStatus ZydisPrintAddressIntel(const ZydisFormatter* formatter, Zydis } } -static ZydisStatus ZydisPrintDisplacementIntel(const ZydisFormatter* formatter, ZydisString* string, +static ZydisStatus ZydisPrintDispIntel(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { + ZYDIS_UNUSED_PARAMETER(instruction); ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !instruction || !operand) + if (!formatter || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -327,29 +462,26 @@ static ZydisStatus ZydisPrintDisplacementIntel(const ZydisFormatter* formatter, ((operand->mem.base == ZYDIS_REGISTER_NONE) && (operand->mem.index == ZYDIS_REGISTER_NONE)))) { - const ZydisBool printSignedHEX = - (formatter->displacementFormat != ZYDIS_DISP_FORMAT_HEX_UNSIGNED); + const ZydisBool printSignedHEX = (formatter->formatDisp != ZYDIS_DISP_FORMAT_HEX_UNSIGNED); if (printSignedHEX && (operand->mem.disp.value < 0) && ( (operand->mem.base != ZYDIS_REGISTER_NONE) || (operand->mem.index != ZYDIS_REGISTER_NONE))) { - return ZydisPrintHexS(string, operand->mem.disp.value, - formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexS(string, operand->mem.disp.value, formatter->hexPaddingDisp, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } if ((operand->mem.base != ZYDIS_REGISTER_NONE) || (operand->mem.index != ZYDIS_REGISTER_NONE)) { ZYDIS_CHECK(ZydisStringAppendC(string, "+")); } - return ZydisPrintHexU(string, (ZydisU64)operand->mem.disp.value, - formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexU(string, (ZydisU64)operand->mem.disp.value, formatter->hexPaddingDisp, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisPrintImmediateIntel(const ZydisFormatter* formatter, ZydisString* string, +static ZydisStatus ZydisPrintImmIntel(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { ZYDIS_UNUSED_PARAMETER(userData); @@ -359,8 +491,8 @@ static ZydisStatus ZydisPrintImmediateIntel(const ZydisFormatter* formatter, Zyd return ZYDIS_STATUS_INVALID_PARAMETER; } - ZydisBool printSignedHEX = (formatter->immediateFormat == ZYDIS_IMM_FORMAT_HEX_SIGNED); - if (formatter->immediateFormat == ZYDIS_IMM_FORMAT_HEX_AUTO) + ZydisBool printSignedHEX = (formatter->formatImm == ZYDIS_IMM_FORMAT_HEX_SIGNED); + if (formatter->formatImm == ZYDIS_IMM_FORMAT_HEX_AUTO) { printSignedHEX = operand->imm.isSigned; } @@ -370,21 +502,17 @@ static ZydisStatus ZydisPrintImmediateIntel(const ZydisFormatter* formatter, Zyd switch (operand->size) { case 8: - return ZydisPrintHexS(string, (ZydisI8)operand->imm.value.s, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexS(string, (ZydisI8)operand->imm.value.s, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 16: - return ZydisPrintHexS(string, (ZydisI16)operand->imm.value.s, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexS(string, (ZydisI16)operand->imm.value.s, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexS(string, (ZydisI32)operand->imm.value.s, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexS(string, (ZydisI32)operand->imm.value.s, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexS(string, operand->imm.value.s, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexS(string, operand->imm.value.s, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -392,29 +520,23 @@ static ZydisStatus ZydisPrintImmediateIntel(const ZydisFormatter* formatter, Zyd switch (instruction->operandWidth) { case 8: - return ZydisPrintHexU(string, (ZydisU8)operand->imm.value.u, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexU(string, (ZydisU8)operand->imm.value.u, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 16: - return ZydisPrintHexU(string, (ZydisU16)operand->imm.value.u, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexU(string, (ZydisU16)operand->imm.value.u, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexU(string, (ZydisU32)operand->imm.value.u, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexU(string, (ZydisU32)operand->imm.value.u, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexU(string, operand->imm.value.u, - formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, - formatter->hexSuffix); + return ZydisPrintHexU(string, operand->imm.value.u, formatter->formatImm, + formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: return ZYDIS_STATUS_INVALID_PARAMETER; } } -/* ---------------------------------------------------------------------------------------------- */ - -static ZydisStatus ZydisPrintOperandSizeIntel(const ZydisFormatter* formatter, ZydisString* string, +static ZydisStatus ZydisPrintMemSizeIntel(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { ZYDIS_UNUSED_PARAMETER(userData); @@ -427,7 +549,7 @@ static ZydisStatus ZydisPrintOperandSizeIntel(const ZydisFormatter* formatter, Z // TODO: refactor ZydisU32 typecast = 0; - if (formatter->forceOperandSize) + if (formatter->forceMemorySize) { if ((operand->type == ZYDIS_OPERAND_TYPE_MEMORY) && (operand->mem.type == ZYDIS_MEMOP_TYPE_MEM)) @@ -521,57 +643,58 @@ static ZydisStatus ZydisPrintOperandSizeIntel(const ZydisFormatter* formatter, Z return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisPrintSegmentIntel(const ZydisFormatter* formatter, ZydisString* string, - const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) +/* ---------------------------------------------------------------------------------------------- */ + +static ZydisStatus ZydisPrintPrefixesIntel(const ZydisFormatter* formatter, ZydisString* string, + const ZydisDecodedInstruction* instruction, void* userData) { ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !instruction || !operand) + if (!formatter || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } - switch (operand->mem.segment) + if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK) { - case ZYDIS_REGISTER_ES: - case ZYDIS_REGISTER_CS: - case ZYDIS_REGISTER_FS: - case ZYDIS_REGISTER_GS: - ZYDIS_CHECK(ZydisStringAppendExStatic(string, - ZydisRegisterGetStaticString(operand->mem.segment), formatter->letterCase)); - return ZydisStringAppendC(string, ":"); - case ZYDIS_REGISTER_SS: - if ((formatter->forceSegments) || - (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS)) - { - ZYDIS_CHECK(ZydisStringAppendExStatic(string, - ZydisRegisterGetStaticString(operand->mem.segment), formatter->letterCase)); - return ZydisStringAppendC(string, ":"); - } - break; - case ZYDIS_REGISTER_DS: - if ((formatter->forceSegments) || - (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS)) - { - ZYDIS_CHECK(ZydisStringAppendExStatic(string, - ZydisRegisterGetStaticString(operand->mem.segment), formatter->letterCase)); - return ZydisStringAppendC(string, ":"); - } - break; - default: - break; + return ZydisStringAppendExC(string, "lock ", formatter->letterCase); } - return ZYDIS_STATUS_SUCCESS; + if (instruction->attributes & ZYDIS_ATTRIB_HAS_REP) + { + return ZydisStringAppendExC(string, "rep ", formatter->letterCase); + } + if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPE) + { + return ZydisStringAppendExC(string, "repe ", formatter->letterCase); + } + if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE) + { + return ZydisStringAppendExC(string, "repne ", formatter->letterCase); + } + + if (instruction->attributes & ZYDIS_ATTRIB_HAS_BOUND) + { + return ZydisStringAppendExC(string, "bnd ", formatter->letterCase); + } + + if (instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE) + { + return ZydisStringAppendExC(string, "xacquire ", formatter->letterCase); + } + if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE) + { + return ZydisStringAppendExC(string, "xrelease ", formatter->letterCase); + } + + return ZYDIS_STATUS_SUCCESS; } static ZydisStatus ZydisPrintDecoratorIntel(const ZydisFormatter* formatter, ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData) { - ZYDIS_UNUSED_PARAMETER(userData); - - if (!formatter || !instruction || !operand) + if (!formatter || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -582,13 +705,9 @@ static ZydisStatus ZydisPrintDecoratorIntel(const ZydisFormatter* formatter, Zyd { if (instruction->avx.mask.reg != ZYDIS_REGISTER_K0) { - const ZydisStaticString* reg = ZydisRegisterGetStaticString(instruction->avx.mask.reg); - if (!reg) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } ZYDIS_CHECK(ZydisStringAppendC(string, " {")); - ZYDIS_CHECK(ZydisStringAppendExStatic(string, reg, formatter->letterCase)); + ZYDIS_CHECK(formatter->funcPrintRegister(formatter, string, instruction, operand, + instruction->avx.mask.reg, userData)); ZYDIS_CHECK(ZydisStringAppendC(string, "}")); if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO) { @@ -597,7 +716,7 @@ static ZydisStatus ZydisPrintDecoratorIntel(const ZydisFormatter* formatter, Zyd } break; } - case ZYDIS_DECORATOR_TYPE_BROADCAST: + case ZYDIS_DECORATOR_TYPE_BC: if (!instruction->avx.broadcast.isStatic) { switch (instruction->avx.broadcast.mode) @@ -627,7 +746,7 @@ static ZydisStatus ZydisPrintDecoratorIntel(const ZydisFormatter* formatter, Zyd } } break; - case ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL: + case ZYDIS_DECORATOR_TYPE_RC: if (instruction->avx.hasSAE) { switch (instruction->avx.rounding.mode) @@ -734,7 +853,7 @@ static ZydisStatus ZydisPrintDecoratorIntel(const ZydisFormatter* formatter, Zyd return ZYDIS_STATUS_INVALID_PARAMETER; } break; - case ZYDIS_DECORATOR_TYPE_EVICTION_HINT: + case ZYDIS_DECORATOR_TYPE_EH: if (instruction->avx.hasEvictionHint) { ZYDIS_CHECK(ZydisStringAppendC(string, " {eh}")); @@ -747,117 +866,6 @@ static ZydisStatus ZydisPrintDecoratorIntel(const ZydisFormatter* formatter, Zyd return ZYDIS_STATUS_SUCCESS; } -static ZydisStatus ZydisFormatInstrIntel(const ZydisFormatter* formatter, ZydisString* string, - const ZydisDecodedInstruction* instruction, void* userData) -{ - if (!formatter || !string || !instruction) - { - return ZYDIS_STATUS_INVALID_PARAMETER; - } - - ZYDIS_CHECK(formatter->funcPrintPrefixes(formatter, string, instruction, userData)); - ZYDIS_CHECK(formatter->funcPrintMnemonic(formatter, string, instruction, userData)); - - for (ZydisU8 i = 0; i < instruction->operandCount; ++i) - { - if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN) - { - break; - } - - const ZydisUSize strLenRestore = string->length; - if (i == 0) - { - ZYDIS_CHECK(ZydisStringAppendC(string, " ")); - } else - { - ZYDIS_CHECK(ZydisStringAppendC(string, ", ")); - } - - const ZydisUSize strLenPreOperand = string->length; - switch (instruction->operands[i].type) - { - case ZYDIS_OPERAND_TYPE_REGISTER: - ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, string, instruction, - &instruction->operands[i], userData)); - break; - case ZYDIS_OPERAND_TYPE_MEMORY: - { - ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, string, instruction, - &instruction->operands[i], userData)); - ZYDIS_CHECK(formatter->funcPrintSegment(formatter, string, instruction, - &instruction->operands[i], userData)); - const ZydisUSize strLenTemp = string->length; - ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, string, instruction, - &instruction->operands[i], userData)); - if (strLenTemp == string->length) - { - string->length = strLenPreOperand; - } - break; - } - case ZYDIS_OPERAND_TYPE_POINTER: - ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, string, instruction, - &instruction->operands[i], userData)); - break; - case ZYDIS_OPERAND_TYPE_IMMEDIATE: - ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, string, instruction, - &instruction->operands[i], userData)); - break; - default: - return ZYDIS_STATUS_INVALID_PARAMETER; - } - - if (strLenPreOperand == string->length) - { - // Omit whole operand, if the string did not change during the formatting-callback - string->length = strLenRestore; - continue; - } - - if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || - (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) - { - if ((i == 0) && - (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)) - { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, - &instruction->operands[i], ZYDIS_DECORATOR_TYPE_MASK, userData)); - } - if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY) - { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, - &instruction->operands[i], ZYDIS_DECORATOR_TYPE_BROADCAST, userData)); - if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) - { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, - &instruction->operands[i], ZYDIS_DECORATOR_TYPE_CONVERSION, userData)); - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, - &instruction->operands[i], ZYDIS_DECORATOR_TYPE_EVICTION_HINT, userData)); - } - } else - { - if ((i == (instruction->operandCount - 1)) || - (instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) - { - if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) - { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, - &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SWIZZLE, userData)); - } - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, - &instruction->operands[i], ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, - userData)); - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, - &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SAE, userData)); - } - } - } - } - - return ZYDIS_STATUS_SUCCESS; -} - /* ---------------------------------------------------------------------------------------------- */ /* ============================================================================================== */ @@ -875,34 +883,34 @@ ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle st ZydisMemorySet(formatter, 0, sizeof(ZydisFormatter)); formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT; - formatter->forceSegments = ZYDIS_FALSE; - formatter->forceOperandSize = ZYDIS_FALSE; - formatter->addressFormat = ZYDIS_ADDR_FORMAT_ABSOLUTE; - formatter->displacementFormat = ZYDIS_DISP_FORMAT_HEX_SIGNED; - formatter->immediateFormat = ZYDIS_IMM_FORMAT_HEX_UNSIGNED; + formatter->forceMemorySegment = ZYDIS_FALSE; + formatter->forceMemorySize = ZYDIS_FALSE; + formatter->formatAddress = ZYDIS_ADDR_FORMAT_ABSOLUTE; + formatter->formatDisp = ZYDIS_DISP_FORMAT_HEX_SIGNED; + formatter->formatImm = ZYDIS_IMM_FORMAT_HEX_UNSIGNED; formatter->hexUppercase = ZYDIS_TRUE; formatter->hexPrefix = &hexPrefixDefault; formatter->hexSuffix = ZYDIS_NULL; formatter->hexPaddingAddress = 2; - formatter->hexPaddingDisplacement = 2; - formatter->hexPaddingImmediate = 2; + formatter->hexPaddingDisp = 2; + formatter->hexPaddingImm = 2; switch (style) { case ZYDIS_FORMATTER_STYLE_INTEL: formatter->funcFormatInstruction = &ZydisFormatInstrIntel; - formatter->funcPrintPrefixes = &ZydisPrintPrefixesIntel; - formatter->funcPrintMnemonic = &ZydisPrintMnemonicIntel; formatter->funcFormatOperandReg = &ZydisFormatOperandRegIntel; formatter->funcFormatOperandMem = &ZydisFormatOperandMemIntel; formatter->funcFormatOperandPtr = &ZydisFormatOperandPtrIntel; - formatter->funcFormatOperandImm = &ZydisFormatOperandImmIntel; - formatter->funcPrintOperandSize = &ZydisPrintOperandSizeIntel; - formatter->funcPrintSegment = &ZydisPrintSegmentIntel; + formatter->funcFormatOperandImm = &ZydisFormatOperandImmIntel; + formatter->funcPrintMnemonic = &ZydisPrintMnemonicIntel; + formatter->funcPrintRegister = &ZydisPrintRegisterIntel; + formatter->funcPrintAddress = &ZydisPrintAddrIntel; + formatter->funcPrintDisp = &ZydisPrintDispIntel; + formatter->funcPrintImm = &ZydisPrintImmIntel; + formatter->funcPrintMemSize = &ZydisPrintMemSizeIntel; + formatter->funcPrintPrefixes = &ZydisPrintPrefixesIntel; formatter->funcPrintDecorator = &ZydisPrintDecoratorIntel; - formatter->funcPrintAddress = &ZydisPrintAddressIntel; - formatter->funcPrintDisplacement = &ZydisPrintDisplacementIntel; - formatter->funcPrintImmediate = &ZydisPrintImmediateIntel; break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -912,7 +920,7 @@ ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle st } ZydisStatus ZydisFormatterSetProperty(ZydisFormatter* formatter, - ZydisFormatterProperty property, ZydisUSize value) + ZydisFormatterProperty property, ZydisUPointer value) { if (!formatter) { @@ -924,32 +932,32 @@ ZydisStatus ZydisFormatterSetProperty(ZydisFormatter* formatter, case ZYDIS_FORMATTER_PROP_UPPERCASE: formatter->letterCase = (value) ? ZYDIS_LETTER_CASE_UPPER : ZYDIS_LETTER_CASE_DEFAULT; break; - case ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS: - formatter->forceSegments = (value) ? ZYDIS_TRUE : ZYDIS_FALSE; + case ZYDIS_FORMATTER_PROP_FORCE_MEMSEG: + formatter->forceMemorySegment = (value) ? ZYDIS_TRUE : ZYDIS_FALSE; break; - case ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE: - formatter->forceOperandSize = (value) ? ZYDIS_TRUE : ZYDIS_FALSE; + case ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE: + formatter->forceMemorySize = (value) ? ZYDIS_TRUE : ZYDIS_FALSE; break; case ZYDIS_FORMATTER_PROP_ADDR_FORMAT: if (value > ZYDIS_ADDR_FORMAT_MAX_VALUE) { return ZYDIS_STATUS_INVALID_PARAMETER; } - formatter->addressFormat = (ZydisU8)value; + formatter->formatAddress = (ZydisU8)value; break; case ZYDIS_FORMATTER_PROP_DISP_FORMAT: if (value > ZYDIS_DISP_FORMAT_MAX_VALUE) { return ZYDIS_STATUS_INVALID_PARAMETER; } - formatter->displacementFormat = (ZydisU8)value; + formatter->formatDisp = (ZydisU8)value; break; case ZYDIS_FORMATTER_PROP_IMM_FORMAT: if (value > ZYDIS_IMM_FORMAT_MAX_VALUE) { return ZYDIS_STATUS_INVALID_PARAMETER; } - formatter->immediateFormat = (ZydisU8)value; + formatter->formatImm = (ZydisU8)value; break; case ZYDIS_FORMATTER_PROP_HEX_UPPERCASE: formatter->hexUppercase = (value) ? ZYDIS_TRUE : ZYDIS_FALSE; @@ -980,14 +988,14 @@ ZydisStatus ZydisFormatterSetProperty(ZydisFormatter* formatter, { return ZYDIS_STATUS_INVALID_PARAMETER; } - formatter->hexPaddingDisplacement = (ZydisU8)value; + formatter->hexPaddingDisp = (ZydisU8)value; break; case ZYDIS_FORMATTER_PROP_HEX_PADDING_IMM: if (value > 20) { return ZYDIS_STATUS_INVALID_PARAMETER; } - formatter->hexPaddingImmediate = (ZydisU8)value; + formatter->hexPaddingImm = (ZydisU8)value; break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -1009,21 +1017,21 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT // Backup the function-pointer switch (hook) { - case ZYDIS_FORMATTER_HOOK_PRE: - *callback = *(const void**)&formatter->funcPre; + case ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION: + *callback = *(const void**)&formatter->funcPreInstruction; break; - case ZYDIS_FORMATTER_HOOK_POST: - *callback = *(const void**)&formatter->funcPost; + case ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION: + *callback = *(const void**)&formatter->funcPostInstruction; + break; + case ZYDIS_FORMATTER_HOOK_PRE_OPERAND: + *callback = *(const void**)&formatter->funcPreOperand; + break; + case ZYDIS_FORMATTER_HOOK_POST_OPERAND: + *callback = *(const void**)&formatter->funcPostOperand; break; case ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION: *callback = *(const void**)&formatter->funcFormatInstruction; break; - case ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES: - *callback = *(const void**)&formatter->funcPrintPrefixes; - break; - case ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC: - *callback = *(const void**)&formatter->funcPrintMnemonic; - break; case ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG: *callback = *(const void**)&formatter->funcFormatOperandReg; break; @@ -1036,23 +1044,29 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT case ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM: *callback = *(const void**)&formatter->funcFormatOperandImm; break; - case ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE: - *callback = *(const void**)&formatter->funcPrintOperandSize; + case ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC: + *callback = *(const void**)&formatter->funcPrintMnemonic; break; - case ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT: - *callback = *(const void**)&formatter->funcPrintSegment; - break; - case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR: - *callback = *(const void**)&formatter->funcPrintDecorator; + case ZYDIS_FORMATTER_HOOK_PRINT_REGISTER: + *callback = *(const void**)&formatter->funcPrintRegister; break; case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS: *callback = *(const void**)&formatter->funcPrintAddress; break; - case ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT: - *callback = *(const void**)&formatter->funcPrintDisplacement; + case ZYDIS_FORMATTER_HOOK_PRINT_DISP: + *callback = *(const void**)&formatter->funcPrintDisp; break; - case ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE: - *callback = *(const void**)&formatter->funcPrintImmediate; + case ZYDIS_FORMATTER_HOOK_PRINT_IMM: + *callback = *(const void**)&formatter->funcPrintImm; + break; + case ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE: + *callback = *(const void**)&formatter->funcPrintMemSize; + break; + case ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES: + *callback = *(const void**)&formatter->funcPrintPrefixes; + break; + case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR: + *callback = *(const void**)&formatter->funcPrintDecorator; break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -1067,50 +1081,56 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT // Replace the function-pointer switch (hook) { - case ZYDIS_FORMATTER_HOOK_PRE: - formatter->funcPre = *(ZydisFormatterNotifyFunc*)&temp; + case ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION: + formatter->funcPreInstruction = *(ZydisFormatterFunc*)&temp; break; - case ZYDIS_FORMATTER_HOOK_POST: - formatter->funcPost = *(ZydisFormatterNotifyFunc*)&temp; + case ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION: + formatter->funcPostInstruction = *(ZydisFormatterFunc*)&temp; + break; + case ZYDIS_FORMATTER_HOOK_PRE_OPERAND: + formatter->funcPreOperand = *(ZydisFormatterOperandFunc*)&temp; + break; + case ZYDIS_FORMATTER_HOOK_POST_OPERAND: + formatter->funcPostOperand = *(ZydisFormatterOperandFunc*)&temp; break; case ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION: - formatter->funcFormatInstruction = *(ZydisFormatterFormatFunc*)&temp; - break; - case ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES: - formatter->funcPrintPrefixes = *(ZydisFormatterFormatFunc*)&temp; - break; - case ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC: - formatter->funcPrintMnemonic = *(ZydisFormatterFormatFunc*)&temp; + formatter->funcFormatInstruction = *(ZydisFormatterFunc*)&temp; break; case ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG: - formatter->funcFormatOperandReg = *(ZydisFormatterFormatOperandFunc*)&temp; + formatter->funcFormatOperandReg = *(ZydisFormatterOperandFunc*)&temp; break; case ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM: - formatter->funcFormatOperandMem = *(ZydisFormatterFormatOperandFunc*)&temp; + formatter->funcFormatOperandMem = *(ZydisFormatterOperandFunc*)&temp; break; case ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR: - formatter->funcFormatOperandPtr = *(ZydisFormatterFormatOperandFunc*)&temp; + formatter->funcFormatOperandPtr = *(ZydisFormatterOperandFunc*)&temp; break; case ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM: - formatter->funcFormatOperandImm = *(ZydisFormatterFormatOperandFunc*)&temp; + formatter->funcFormatOperandImm = *(ZydisFormatterOperandFunc*)&temp; break; - case ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE: - formatter->funcPrintOperandSize = *(ZydisFormatterFormatOperandFunc*)&temp; + case ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC: + formatter->funcPrintMnemonic = *(ZydisFormatterFunc*)&temp; break; - case ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT: - formatter->funcPrintSegment = *(ZydisFormatterFormatOperandFunc*)&temp; - break; - case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR: - formatter->funcPrintDecorator = *(ZydisFormatterFormatDecoratorFunc*)&temp; + case ZYDIS_FORMATTER_HOOK_PRINT_REGISTER: + formatter->funcPrintRegister = *(ZydisFormatterRegisterFunc*)&temp; break; case ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS: - formatter->funcPrintAddress = *(ZydisFormatterFormatAddressFunc*)&temp; + formatter->funcPrintAddress = *(ZydisFormatterAddressFunc*)&temp; break; - case ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT: - formatter->funcPrintDisplacement = *(ZydisFormatterFormatOperandFunc*)&temp; + case ZYDIS_FORMATTER_HOOK_PRINT_DISP: + formatter->funcPrintDisp = *(ZydisFormatterOperandFunc*)&temp; break; - case ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE: - formatter->funcPrintImmediate = *(ZydisFormatterFormatOperandFunc*)&temp; + case ZYDIS_FORMATTER_HOOK_PRINT_IMM: + formatter->funcPrintImm = *(ZydisFormatterOperandFunc*)&temp; + break; + case ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE: + formatter->funcPrintMemSize = *(ZydisFormatterOperandFunc*)&temp; + break; + case ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES: + formatter->funcPrintPrefixes = *(ZydisFormatterFunc*)&temp; + break; + case ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR: + formatter->funcPrintDecorator = *(ZydisFormatterDecoratorFunc*)&temp; break; default: return ZYDIS_STATUS_INVALID_PARAMETER; diff --git a/src/MetaInfo.c b/src/MetaInfo.c index 853e9c8..1b8281e 100644 --- a/src/MetaInfo.c +++ b/src/MetaInfo.c @@ -40,7 +40,7 @@ const char* ZydisCategoryGetString(ZydisInstructionCategory category) { - if (category > ZYDIS_ARRAY_SIZE(zydisInstructionCategoryStrings) - 1) + if (category >= ZYDIS_ARRAY_SIZE(zydisInstructionCategoryStrings)) { return ZYDIS_NULL; } @@ -49,7 +49,7 @@ const char* ZydisCategoryGetString(ZydisInstructionCategory category) const char* ZydisISASetGetString(ZydisISASet isaSet) { - if (isaSet > ZYDIS_ARRAY_SIZE(zydisISASetStrings) - 1) + if (isaSet >= ZYDIS_ARRAY_SIZE(zydisISASetStrings)) { return ZYDIS_NULL; } @@ -58,7 +58,7 @@ const char* ZydisISASetGetString(ZydisISASet isaSet) const char* ZydisISAExtGetString(ZydisISAExt isaExt) { - if (isaExt > ZYDIS_ARRAY_SIZE(zydisISAExtStrings) - 1) + if (isaExt >= ZYDIS_ARRAY_SIZE(zydisISAExtStrings)) { return ZYDIS_NULL; } diff --git a/src/Mnemonic.c b/src/Mnemonic.c index 7fc56f8..fcacb14 100644 --- a/src/Mnemonic.c +++ b/src/Mnemonic.c @@ -33,7 +33,7 @@ const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic) { - if (mnemonic > ZYDIS_ARRAY_SIZE(zydisMnemonicStrings) - 1) + if (mnemonic >= ZYDIS_ARRAY_SIZE(zydisMnemonicStrings)) { return ZYDIS_NULL; } @@ -42,7 +42,7 @@ const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic) const ZydisStaticString* ZydisMnemonicGetStaticString(ZydisMnemonic mnemonic) { - if (mnemonic > ZYDIS_ARRAY_SIZE(zydisMnemonicStrings) - 1) + if (mnemonic >= ZYDIS_ARRAY_SIZE(zydisMnemonicStrings)) { return ZYDIS_NULL; } diff --git a/tools/ZydisDisasm.c b/tools/ZydisDisasm.c index b7289ca..e6a7f3a 100644 --- a/tools/ZydisDisasm.c +++ b/tools/ZydisDisasm.c @@ -69,9 +69,9 @@ int main(int argc, char** argv) ZydisFormatter formatter; if (!ZYDIS_SUCCESS(ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL)) || !ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter, - ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE)) || + ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE)) || !ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter, - ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE))) + ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE))) { fputs("Failed to initialized instruction-formatter\n", stderr); return EXIT_FAILURE; diff --git a/tools/ZydisInfo.c b/tools/ZydisInfo.c index 78584cd..5c26a85 100644 --- a/tools/ZydisInfo.c +++ b/tools/ZydisInfo.c @@ -551,9 +551,9 @@ void printInstruction(ZydisDecodedInstruction* instruction) ZydisFormatter formatter; if (!ZYDIS_SUCCESS((status = ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL))) || !ZYDIS_SUCCESS((status = ZydisFormatterSetProperty(&formatter, - ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE))) || + ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE))) || !ZYDIS_SUCCESS((status = ZydisFormatterSetProperty(&formatter, - ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE)))) + ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE)))) { fputs("Failed to initialize instruction-formatter\n", stderr); exit(status);