From d459b39bb7de0e53302f5586a28e706062dd375d Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Sat, 14 Oct 2017 13:39:00 +0200 Subject: [PATCH 1/2] Convert all functions in ZydisFormatter to take const arguments --- include/Zydis/Formatter.h | 18 +++++++-------- src/Formatter.c | 46 +++++++++++++++++++-------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index 033bbb4..8d8fca8 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -326,7 +326,7 @@ enum ZydisDecoratorTypes ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EVICTION_HINT }; -typedef struct ZydisFormatter_ ZydisFormatter; +typedef struct ZydisFormatter_ ZydisFormatter; /** * @brief Defines the @c ZydisFormatterNotifyFunc function pointer. @@ -341,7 +341,7 @@ typedef struct ZydisFormatter_ ZydisFormatter; * @c ZYDIS_FORMATTER_HOOK_POST hook-types. */ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, - ZydisDecodedInstruction* instruction); + const ZydisDecodedInstruction* instruction); /** * @brief Defines the @c ZydisFormatterFormatFunc function pointer. @@ -361,7 +361,7 @@ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, * @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types. */ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction); + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction); /** * @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer. @@ -397,8 +397,8 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, * hook-types. */ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand); + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand); /** * @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer. @@ -419,8 +419,8 @@ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* for * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type. */ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand, uint64_t address); + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, uint64_t address); /** * @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer. @@ -444,8 +444,8 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type. */ typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand, ZydisDecoratorType type); + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, ZydisDecoratorType type); /** * @brief Defines the @c ZydisFormatter struct. diff --git a/src/Formatter.c b/src/Formatter.c index bf1dafe..bb5bae4 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -47,7 +47,7 @@ /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) { @@ -90,7 +90,7 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* format } static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) { @@ -117,8 +117,8 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -139,8 +139,8 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for } static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -213,8 +213,8 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for } static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -230,8 +230,8 @@ static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* for } static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -276,8 +276,8 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand, uint64_t address) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, uint64_t address) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -298,8 +298,8 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt } static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -332,8 +332,8 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo } static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -388,8 +388,8 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -486,8 +486,8 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for } static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -532,8 +532,8 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt } static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand, ZydisDecoratorType type) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, ZydisDecoratorType type) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -742,7 +742,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma } static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) { From 943993ae4a50037d25325e6409be5597ca33a1de Mon Sep 17 00:00:00 2001 From: flobernd Date: Sat, 14 Oct 2017 18:37:59 +0200 Subject: [PATCH 2/2] Changed the way how user-data is passed to custom formatter-callbacks * Removed `userData` from the `ZydisDecodedInstruction` struct * Added `userData` as parameter to all formatter-callbacks * Added `ZydisFormatterFormatInstructionEx` function with the additional `userData` paramter * Updated the `FormatterHooks.c` demo --- examples/FormatterHooks.c | 42 +++++++++------ include/Zydis/DecoderTypes.h | 4 -- include/Zydis/Formatter.h | 30 +++++++++-- src/Decoder.c | 2 - src/Formatter.c | 102 ++++++++++++++++++++++------------- 5 files changed, 118 insertions(+), 62 deletions(-) diff --git a/examples/FormatterHooks.c b/examples/FormatterHooks.c index 6a2733a..3224441 100644 --- a/examples/FormatterHooks.c +++ b/examples/FormatterHooks.c @@ -81,6 +81,18 @@ static const char* conditionCodeStrings[0x20] = /*1F*/ "true_us" }; +/* ============================================================================================== */ +/* Enums and Types */ +/* ============================================================================================== */ + +/** + * @brief Custom user data struct. + */ +typedef struct ZydisCustomUserData_ +{ + ZydisBool ommitImmediate; +} ZydisCustomUserData; + /* ============================================================================================== */ /* Hook callbacks */ /* ============================================================================================== */ @@ -88,13 +100,11 @@ static const char* conditionCodeStrings[0x20] = ZydisFormatterFormatFunc defaultPrintMnemonic; static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + ZydisCustomUserData* userData) { - // We use the user-data field of the instruction-info to pass data to the - // @c ZydisFormatterFormatOperandImm function. - // In this case we are using a simple ordinal value, but you could pass a pointer to a - // complex datatype as well. - instruction->userData = (void*)1; + // We use the user-data to pass data to the @c ZydisFormatterFormatOperandImm function. + userData->ommitImmediate = ZYDIS_TRUE; // Rewrite the instruction-mnemonic for the given instructions if (instruction->operands[instruction->operandCount - 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) @@ -142,10 +152,10 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, // We did not rewrite the instruction-mnemonic. Signal the @c ZydisFormatterFormatOperandImm // function not to omit the operand - instruction->userData = (void*)0; + userData->ommitImmediate = ZYDIS_FALSE; // Default mnemonic printing - return defaultPrintMnemonic(formatter, buffer, bufferLen, instruction); + return defaultPrintMnemonic(formatter, buffer, bufferLen, instruction, userData); } /* ---------------------------------------------------------------------------------------------- */ @@ -153,12 +163,12 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, ZydisFormatterFormatOperandFunc defaultFormatOperandImm; static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, - ZydisDecodedOperand* operand) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + const ZydisDecodedOperand* operand, ZydisCustomUserData* userData) { // The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code) // operand, because it got replaced by the alias-mnemonic - if ((uintptr_t)instruction->userData == 1) + if (userData->ommitImmediate) { // The formatter will automatically omit the operand, if the buffer remains unchanged // after the callback returns @@ -166,7 +176,7 @@ static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatte } // Default immediate formatting - return defaultFormatOperandImm(formatter, buffer, bufferLen, instruction, operand); + return defaultFormatOperandImm(formatter, buffer, bufferLen, instruction, operand, userData); } /* ---------------------------------------------------------------------------------------------- */ @@ -184,10 +194,10 @@ void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, Zydi if (installHooks) { - defaultPrintMnemonic = &ZydisFormatterPrintMnemonic; + defaultPrintMnemonic = (ZydisFormatterFormatFunc)&ZydisFormatterPrintMnemonic; ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC, (const void**)&defaultPrintMnemonic); - defaultFormatOperandImm = &ZydisFormatterFormatOperandImm; + defaultFormatOperandImm = (ZydisFormatterFormatOperandFunc)&ZydisFormatterFormatOperandImm; ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, (const void**)&defaultFormatOperandImm); } @@ -195,6 +205,7 @@ void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, Zydi uint64_t instructionPointer = 0x007FFFFFFF400000; ZydisDecodedInstruction instruction; + ZydisCustomUserData userData; char buffer[256]; while (ZYDIS_SUCCESS( ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction))) @@ -203,7 +214,8 @@ void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, Zydi length -= instruction.length; instructionPointer += instruction.length; printf("%016" PRIX64 " ", instruction.instrAddress); - ZydisFormatterFormatInstruction(&formatter, &instruction, &buffer[0], sizeof(buffer)); + ZydisFormatterFormatInstructionEx( + &formatter, &instruction, &buffer[0], sizeof(buffer), &userData); printf(" %s\n", &buffer[0]); } } diff --git a/include/Zydis/DecoderTypes.h b/include/Zydis/DecoderTypes.h index 89dad8b..10859ae 100644 --- a/include/Zydis/DecoderTypes.h +++ b/include/Zydis/DecoderTypes.h @@ -1273,10 +1273,6 @@ typedef struct ZydisDecodedInstruction_ uint8_t offset; } imm[2]; } raw; - /** - * @brief This field is intended for custom data and may be freely set by the user. - */ - void* userData; } ZydisDecodedInstruction; /* ---------------------------------------------------------------------------------------------- */ diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index 8d8fca8..9593b4a 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -333,6 +333,7 @@ typedef struct ZydisFormatter_ ZydisFormatter; * * @param formatter A pointer to the @c ZydisFormatter instance. * @param instruction A pointer to the @c 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. @@ -341,7 +342,7 @@ typedef struct ZydisFormatter_ ZydisFormatter; * @c ZYDIS_FORMATTER_HOOK_POST hook-types. */ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, - const ZydisDecodedInstruction* instruction); + const ZydisDecodedInstruction* instruction, void* userData); /** * @brief Defines the @c ZydisFormatterFormatFunc function pointer. @@ -350,6 +351,7 @@ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, * @param buffer A pointer to the string-buffer. * @param bufferLen The length of the string-buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. + * @param 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. @@ -361,7 +363,7 @@ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, * @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types. */ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction); + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData); /** * @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer. @@ -371,6 +373,7 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, * @param bufferLen The length of the string-buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param operand A pointer to the @c ZydisDecodedOperand struct. + * @param 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. @@ -398,7 +401,7 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, */ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand); + const ZydisDecodedOperand* operand, void* userData); /** * @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer. @@ -408,6 +411,7 @@ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* for * @param bufferLen The length of the string-buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param operand A pointer to the @c ZydisDecodedOperand struct. + * @param 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. @@ -420,7 +424,7 @@ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* for */ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand, uint64_t address); + const ZydisDecodedOperand* operand, uint64_t address, void* userData); /** * @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer. @@ -431,6 +435,7 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param operand A pointer to the @c 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 * formatting process to fail. @@ -445,7 +450,7 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for */ typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand, ZydisDecoratorType type); + const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData); /** * @brief Defines the @c ZydisFormatter struct. @@ -533,6 +538,21 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen); +/** + * @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 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 + * callbacks. + * + * @return A zydis status code. + */ +ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter, + ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen, void* userData); + /* ============================================================================================== */ #ifdef __cplusplus diff --git a/src/Decoder.c b/src/Decoder.c index 2a06434..a64c59a 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -4420,13 +4420,11 @@ ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* bu context.lastSegmentPrefix = 0; context.mandatoryCandidate = 0; - void* userData = instruction->userData; memset(instruction, 0, sizeof(*instruction)); instruction->machineMode = decoder->machineMode; instruction->stackWidth = decoder->addressWidth; instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT; instruction->instrAddress = instructionPointer; - instruction->userData = userData; ZYDIS_CHECK(ZydisCollectOptionalPrefixes(&context, instruction)); ZYDIS_CHECK(ZydisDecodeInstruction(&context, instruction)); diff --git a/src/Formatter.c b/src/Formatter.c index bb5bae4..3943ed9 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -47,8 +47,10 @@ /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -90,8 +92,10 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* format } static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -118,8 +122,10 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -140,7 +146,7 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -165,13 +171,13 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for uint64_t address; ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, bufEnd - *buffer, - instruction, operand, address)); + instruction, operand, address, userData)); } else { ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ZydisRegisterGetString(operand->mem.base), ZYDIS_LETTER_CASE)); ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer, - instruction, operand)); + instruction, operand, userData)); } } else { @@ -206,7 +212,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for } } ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer, - instruction, operand)); + instruction, operand, userData)); } return ZydisPrintStr(buffer, bufEnd - *buffer, "]", ZYDIS_LETTER_CASE_DEFAULT); @@ -214,8 +220,10 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -231,7 +239,7 @@ static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* for static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { @@ -250,7 +258,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for uint64_t address; ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); return formatter->funcPrintAddress(formatter, buffer, bufferLen, instruction, operand, - address); + address, userData); } case ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED: printSignedHEX = ZYDIS_TRUE; @@ -270,15 +278,18 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for } // The immediate operand contains an actual ordinal value - return formatter->funcPrintImmediate(formatter, buffer, bufferLen, instruction, operand); + return formatter->funcPrintImmediate( + formatter, buffer, bufferLen, instruction, operand, userData); } /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand, uint64_t address) + const ZydisDecodedOperand* operand, uint64_t address, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -299,8 +310,10 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -333,8 +346,10 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -389,8 +404,10 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -487,8 +504,10 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand) + const ZydisDecodedOperand* operand, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -533,8 +552,10 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - const ZydisDecodedOperand* operand, ZydisDecoratorType type) + const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData) { + (void)userData; + if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; @@ -742,7 +763,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma } static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction) + char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData) { if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) { @@ -750,8 +771,10 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte } char* bufEnd = *buffer + bufferLen; - ZYDIS_CHECK(formatter->funcPrintPrefixes(formatter, buffer, bufEnd - *buffer, instruction)); - ZYDIS_CHECK(formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction)); + ZYDIS_CHECK( + formatter->funcPrintPrefixes(formatter, buffer, bufEnd - *buffer, instruction, userData)); + ZYDIS_CHECK( + formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction, userData)); char* bufRestore = *buffer; for (uint8_t i = 0; i < instruction->operandCount; ++i) @@ -775,17 +798,17 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte { case ZYDIS_OPERAND_TYPE_REGISTER: ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer, - instruction, &instruction->operands[i])); + instruction, &instruction->operands[i], userData)); break; case ZYDIS_OPERAND_TYPE_MEMORY: { ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, bufEnd - *buffer, - instruction, &instruction->operands[i])); + instruction, &instruction->operands[i], userData)); ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, bufEnd - *buffer, - instruction, &instruction->operands[i])); + instruction, &instruction->operands[i], userData)); const char* bufTemp = *buffer; ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer, - instruction, &instruction->operands[i])); + instruction, &instruction->operands[i], userData)); if (bufTemp == *buffer) { *buffer = (char*)bufPreOperand; @@ -794,11 +817,11 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte } case ZYDIS_OPERAND_TYPE_POINTER: ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer, - instruction, &instruction->operands[i])); + instruction, &instruction->operands[i], userData)); break; case ZYDIS_OPERAND_TYPE_IMMEDIATE: ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer, - instruction, &instruction->operands[i])); + instruction, &instruction->operands[i], userData)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -819,21 +842,21 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte { ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_MASK)); + ZYDIS_DECORATOR_TYPE_MASK, userData)); } if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY) { ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_BROADCAST)); + ZYDIS_DECORATOR_TYPE_BROADCAST, userData)); if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) { ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_CONVERSION)); + ZYDIS_DECORATOR_TYPE_CONVERSION, userData)); ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_EVICTION_HINT)); + ZYDIS_DECORATOR_TYPE_EVICTION_HINT, userData)); } } else { @@ -844,14 +867,14 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte { ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_SWIZZLE)); + ZYDIS_DECORATOR_TYPE_SWIZZLE, userData)); } ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL)); + ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, userData)); ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, bufEnd - *buffer, instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_SAE)); + ZYDIS_DECORATOR_TYPE_SAE, userData)); } } } @@ -1048,6 +1071,12 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen) +{ + return ZydisFormatterFormatInstructionEx(formatter, instruction, buffer, bufferLen, NULL); +} + +ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter, + ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen, void* userData) { if (!formatter || !instruction || !buffer || (bufferLen == 0)) { @@ -1056,12 +1085,13 @@ ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, if (formatter->funcPre) { - ZYDIS_CHECK(formatter->funcPre(formatter, instruction)); + ZYDIS_CHECK(formatter->funcPre(formatter, instruction, userData)); } - ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, &buffer, bufferLen, instruction)); + ZYDIS_CHECK( + formatter->funcFormatInstruction(formatter, &buffer, bufferLen, instruction, userData)); if (formatter->funcPost) { - return formatter->funcPost(formatter, instruction); + return formatter->funcPost(formatter, instruction, userData); } return ZYDIS_STATUS_SUCCESS; }