Merge branch 'mrexodia-const_party' into develop

This commit is contained in:
flobernd 2017-10-14 18:39:53 +02:00
commit c5e418f34f
5 changed files with 132 additions and 76 deletions

View File

@ -81,6 +81,18 @@ static const char* conditionCodeStrings[0x20] =
/*1F*/ "true_us" /*1F*/ "true_us"
}; };
/* ============================================================================================== */
/* Enums and Types */
/* ============================================================================================== */
/**
* @brief Custom user data struct.
*/
typedef struct ZydisCustomUserData_
{
ZydisBool ommitImmediate;
} ZydisCustomUserData;
/* ============================================================================================== */ /* ============================================================================================== */
/* Hook callbacks */ /* Hook callbacks */
/* ============================================================================================== */ /* ============================================================================================== */
@ -88,13 +100,11 @@ static const char* conditionCodeStrings[0x20] =
ZydisFormatterFormatFunc defaultPrintMnemonic; ZydisFormatterFormatFunc defaultPrintMnemonic;
static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, 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 // We use the user-data to pass data to the @c ZydisFormatterFormatOperandImm function.
// @c ZydisFormatterFormatOperandImm function. userData->ommitImmediate = ZYDIS_TRUE;
// 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;
// Rewrite the instruction-mnemonic for the given instructions // Rewrite the instruction-mnemonic for the given instructions
if (instruction->operands[instruction->operandCount - 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) 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 // We did not rewrite the instruction-mnemonic. Signal the @c ZydisFormatterFormatOperandImm
// function not to omit the operand // function not to omit the operand
instruction->userData = (void*)0; userData->ommitImmediate = ZYDIS_FALSE;
// Default mnemonic printing // 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; ZydisFormatterFormatOperandFunc defaultFormatOperandImm;
static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, ZydisCustomUserData* userData)
{ {
// The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code) // The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code)
// operand, because it got replaced by the alias-mnemonic // 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 // The formatter will automatically omit the operand, if the buffer remains unchanged
// after the callback returns // after the callback returns
@ -166,7 +176,7 @@ static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatte
} }
// Default immediate formatting // 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) if (installHooks)
{ {
defaultPrintMnemonic = &ZydisFormatterPrintMnemonic; defaultPrintMnemonic = (ZydisFormatterFormatFunc)&ZydisFormatterPrintMnemonic;
ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC, ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC,
(const void**)&defaultPrintMnemonic); (const void**)&defaultPrintMnemonic);
defaultFormatOperandImm = &ZydisFormatterFormatOperandImm; defaultFormatOperandImm = (ZydisFormatterFormatOperandFunc)&ZydisFormatterFormatOperandImm;
ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
(const void**)&defaultFormatOperandImm); (const void**)&defaultFormatOperandImm);
} }
@ -195,6 +205,7 @@ void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, Zydi
uint64_t instructionPointer = 0x007FFFFFFF400000; uint64_t instructionPointer = 0x007FFFFFFF400000;
ZydisDecodedInstruction instruction; ZydisDecodedInstruction instruction;
ZydisCustomUserData userData;
char buffer[256]; char buffer[256];
while (ZYDIS_SUCCESS( while (ZYDIS_SUCCESS(
ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction))) ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction)))
@ -203,7 +214,8 @@ void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, Zydi
length -= instruction.length; length -= instruction.length;
instructionPointer += instruction.length; instructionPointer += instruction.length;
printf("%016" PRIX64 " ", instruction.instrAddress); 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]); printf(" %s\n", &buffer[0]);
} }
} }

View File

@ -1273,10 +1273,6 @@ typedef struct ZydisDecodedInstruction_
uint8_t offset; uint8_t offset;
} imm[2]; } imm[2];
} raw; } raw;
/**
* @brief This field is intended for custom data and may be freely set by the user.
*/
void* userData;
} ZydisDecodedInstruction; } ZydisDecodedInstruction;
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */

View File

@ -326,13 +326,14 @@ enum ZydisDecoratorTypes
ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EVICTION_HINT 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. * @brief Defines the @c ZydisFormatterNotifyFunc function pointer.
* *
* @param formatter A pointer to the @c ZydisFormatter instance. * @param formatter A pointer to the @c ZydisFormatter instance.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @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 * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail. * formatting process to fail.
@ -341,7 +342,7 @@ typedef struct ZydisFormatter_ ZydisFormatter;
* @c ZYDIS_FORMATTER_HOOK_POST hook-types. * @c ZYDIS_FORMATTER_HOOK_POST hook-types.
*/ */
typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter,
ZydisDecodedInstruction* instruction); const ZydisDecodedInstruction* instruction, void* userData);
/** /**
* @brief Defines the @c ZydisFormatterFormatFunc function pointer. * @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 buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer. * @param bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @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 * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail. * 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. * @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types.
*/ */
typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction); char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData);
/** /**
* @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer. * @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 bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand 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 * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail. * formatting process to fail.
@ -397,8 +400,8 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter,
* hook-types. * hook-types.
*/ */
typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter, typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand); const ZydisDecodedOperand* operand, void* userData);
/** /**
* @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer. * @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 bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand 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 * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail. * formatting process to fail.
@ -419,8 +423,8 @@ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* for
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type. * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type.
*/ */
typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter, typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, uint64_t address); const ZydisDecodedOperand* operand, uint64_t address, void* userData);
/** /**
* @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer. * @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 instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct. * @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param type The decorator type. * @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 @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail. * formatting process to fail.
@ -444,8 +449,8 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type. * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type.
*/ */
typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter, typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, ZydisDecoratorType type); const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData);
/** /**
* @brief Defines the @c ZydisFormatter struct. * @brief Defines the @c ZydisFormatter struct.
@ -533,6 +538,21 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter,
ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,
ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen); 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 #ifdef __cplusplus

View File

@ -4420,13 +4420,11 @@ ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* bu
context.lastSegmentPrefix = 0; context.lastSegmentPrefix = 0;
context.mandatoryCandidate = 0; context.mandatoryCandidate = 0;
void* userData = instruction->userData;
memset(instruction, 0, sizeof(*instruction)); memset(instruction, 0, sizeof(*instruction));
instruction->machineMode = decoder->machineMode; instruction->machineMode = decoder->machineMode;
instruction->stackWidth = decoder->addressWidth; instruction->stackWidth = decoder->addressWidth;
instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT; instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT;
instruction->instrAddress = instructionPointer; instruction->instrAddress = instructionPointer;
instruction->userData = userData;
ZYDIS_CHECK(ZydisCollectOptionalPrefixes(&context, instruction)); ZYDIS_CHECK(ZydisCollectOptionalPrefixes(&context, instruction));
ZYDIS_CHECK(ZydisDecodeInstruction(&context, instruction)); ZYDIS_CHECK(ZydisDecodeInstruction(&context, instruction));

View File

@ -47,8 +47,10 @@
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -90,8 +92,10 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* format
} }
static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -117,9 +121,11 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -139,8 +145,8 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for
} }
static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
@ -165,13 +171,13 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
uint64_t address; uint64_t address;
ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address));
ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, bufEnd - *buffer,
instruction, operand, address)); instruction, operand, address, userData));
} else } else
{ {
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer,
ZydisRegisterGetString(operand->mem.base), ZYDIS_LETTER_CASE)); ZydisRegisterGetString(operand->mem.base), ZYDIS_LETTER_CASE));
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer,
instruction, operand)); instruction, operand, userData));
} }
} else } else
{ {
@ -206,16 +212,18 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
} }
} }
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer,
instruction, operand)); instruction, operand, userData));
} }
return ZydisPrintStr(buffer, bufEnd - *buffer, "]", ZYDIS_LETTER_CASE_DEFAULT); return ZydisPrintStr(buffer, bufEnd - *buffer, "]", ZYDIS_LETTER_CASE_DEFAULT);
} }
static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -230,8 +238,8 @@ static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* for
} }
static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
@ -250,7 +258,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for
uint64_t address; uint64_t address;
ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address));
return formatter->funcPrintAddress(formatter, buffer, bufferLen, instruction, operand, return formatter->funcPrintAddress(formatter, buffer, bufferLen, instruction, operand,
address); address, userData);
} }
case ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED: case ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED:
printSignedHEX = ZYDIS_TRUE; printSignedHEX = ZYDIS_TRUE;
@ -270,15 +278,18 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for
} }
// The immediate operand contains an actual ordinal value // 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, static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, uint64_t address) const ZydisDecodedOperand* operand, uint64_t address, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -298,9 +309,11 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt
} }
static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -332,9 +345,11 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo
} }
static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -388,9 +403,11 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -486,9 +503,11 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
} }
static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand) const ZydisDecodedOperand* operand, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -532,9 +551,11 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
} }
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction, char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisDecodedOperand* operand, ZydisDecoratorType type) const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData)
{ {
(void)userData;
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand)
{ {
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -742,7 +763,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
} }
static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter, static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, ZydisDecodedInstruction* instruction) char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, void* userData)
{ {
if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction)
{ {
@ -750,8 +771,10 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
} }
char* bufEnd = *buffer + bufferLen; char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(formatter->funcPrintPrefixes(formatter, buffer, bufEnd - *buffer, instruction)); ZYDIS_CHECK(
ZYDIS_CHECK(formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction)); formatter->funcPrintPrefixes(formatter, buffer, bufEnd - *buffer, instruction, userData));
ZYDIS_CHECK(
formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction, userData));
char* bufRestore = *buffer; char* bufRestore = *buffer;
for (uint8_t i = 0; i < instruction->operandCount; ++i) for (uint8_t i = 0; i < instruction->operandCount; ++i)
@ -775,17 +798,17 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
{ {
case ZYDIS_OPERAND_TYPE_REGISTER: case ZYDIS_OPERAND_TYPE_REGISTER:
ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer,
instruction, &instruction->operands[i])); instruction, &instruction->operands[i], userData));
break; break;
case ZYDIS_OPERAND_TYPE_MEMORY: case ZYDIS_OPERAND_TYPE_MEMORY:
{ {
ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, bufEnd - *buffer, 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, ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, bufEnd - *buffer,
instruction, &instruction->operands[i])); instruction, &instruction->operands[i], userData));
const char* bufTemp = *buffer; const char* bufTemp = *buffer;
ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer,
instruction, &instruction->operands[i])); instruction, &instruction->operands[i], userData));
if (bufTemp == *buffer) if (bufTemp == *buffer)
{ {
*buffer = (char*)bufPreOperand; *buffer = (char*)bufPreOperand;
@ -794,11 +817,11 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
} }
case ZYDIS_OPERAND_TYPE_POINTER: case ZYDIS_OPERAND_TYPE_POINTER:
ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer,
instruction, &instruction->operands[i])); instruction, &instruction->operands[i], userData));
break; break;
case ZYDIS_OPERAND_TYPE_IMMEDIATE: case ZYDIS_OPERAND_TYPE_IMMEDIATE:
ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer, ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer,
instruction, &instruction->operands[i])); instruction, &instruction->operands[i], userData));
break; break;
default: default:
return ZYDIS_STATUS_INVALID_PARAMETER; return ZYDIS_STATUS_INVALID_PARAMETER;
@ -819,21 +842,21 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
{ {
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i], bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_MASK)); ZYDIS_DECORATOR_TYPE_MASK, userData));
} }
if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY) if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
{ {
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i], bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_BROADCAST)); ZYDIS_DECORATOR_TYPE_BROADCAST, userData));
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
{ {
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i], bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_CONVERSION)); ZYDIS_DECORATOR_TYPE_CONVERSION, userData));
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i], bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_EVICTION_HINT)); ZYDIS_DECORATOR_TYPE_EVICTION_HINT, userData));
} }
} else } else
{ {
@ -844,14 +867,14 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
{ {
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i], bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_SWIZZLE)); ZYDIS_DECORATOR_TYPE_SWIZZLE, userData));
} }
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i], bufEnd - *buffer, instruction, &instruction->operands[i],
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL)); ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, userData));
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
bufEnd - *buffer, instruction, &instruction->operands[i], 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, ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,
ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen) 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)) if (!formatter || !instruction || !buffer || (bufferLen == 0))
{ {
@ -1056,12 +1085,13 @@ ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,
if (formatter->funcPre) 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) if (formatter->funcPost)
{ {
return formatter->funcPost(formatter, instruction); return formatter->funcPost(formatter, instruction, userData);
} }
return ZYDIS_STATUS_SUCCESS; return ZYDIS_STATUS_SUCCESS;
} }