Add hook for operand seperator to formatter

This commit is contained in:
th0rex 2017-12-01 15:40:08 +01:00 committed by Joel Höner
parent 930c4df970
commit 022a4e7423
2 changed files with 68 additions and 24 deletions

View File

@ -363,10 +363,14 @@ enum ZydisFormatterHookTypes
* @brief This function is called to print an immediate value.
*/
ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE,
/**
* @brief This function is called before each operand is formatted, to print a separator.
*/
ZYDIS_FORMATTER_HOOK_PRINT_OPERAND_SEPARATOR,
/**
* @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_OPERAND_SEPARATOR
};
/* ---------------------------------------------------------------------------------------------- */
@ -523,6 +527,29 @@ typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* f
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData);
/**
* @brief Defines the @c ZydisFormatterPrintOperandSeparatorFunc function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param index The current index of the operand.
* @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.
*
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
* number of chars written.
*
* Returning @c ZYDIS_STATUS_SUCCESS without increasing the buffer-pointer is valid and will cause
* the formatter to omit separator.
*
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_OPERAND_SEPARATOR hook-type.
*/
typedef ZydisStatus(*ZydisFormatterPrintOperandSeparatorFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, ZydisU8 index, void* userData);
/* ---------------------------------------------------------------------------------------------- */
/* Formatter struct */
/* ---------------------------------------------------------------------------------------------- */
@ -558,7 +585,8 @@ struct ZydisFormatter_
ZydisFormatterFormatDecoratorFunc funcPrintDecorator;
ZydisFormatterFormatAddressFunc funcPrintAddress;
ZydisFormatterFormatOperandFunc funcPrintDisplacement;
ZydisFormatterFormatOperandFunc funcPrintImmediate;
ZydisFormatterFormatOperandFunc funcPrintImmediate;
ZydisFormatterPrintOperandSeparatorFunc funcPrintOperandSeparator;
};
/* ---------------------------------------------------------------------------------------------- */

View File

@ -776,6 +776,21 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisFormatterPrintOperandSeparatorIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, ZydisU8 index, void* userData)
{
const char* bufEnd = *buffer + bufferLen;
if (index == 0)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " ", ZYDIS_LETTER_CASE_DEFAULT));
}
else
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT));
}
return ZYDIS_STATUS_SUCCESS;
}
static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData)
{
@ -790,7 +805,7 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
ZYDIS_CHECK(
formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction, userData));
char* bufRestore = *buffer;
char* bufRestore;
for (ZydisU8 i = 0; i < instruction->operandCount; ++i)
{
if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN)
@ -798,14 +813,8 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
break;
}
if (i == 0)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " ", ZYDIS_LETTER_CASE_DEFAULT));
} else
{
bufRestore = *buffer;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT));
}
bufRestore = *buffer;
ZYDIS_CHECK(formatter->funcPrintOperandSeparator(formatter, buffer, bufEnd - *buffer, i, userData));
const char* bufPreOperand = *buffer;
switch (instruction->operands[i].type)
@ -926,19 +935,20 @@ ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle st
switch (style)
{
case ZYDIS_FORMATTER_STYLE_INTEL:
formatter->funcFormatInstruction = &ZydisFormatterFormatInstrIntel;
formatter->funcPrintPrefixes = &ZydisFormatterPrintPrefixesIntel;
formatter->funcPrintMnemonic = &ZydisFormatterPrintMnemonicIntel;
formatter->funcFormatOperandReg = &ZydisFormatterFormatOperandRegIntel;
formatter->funcFormatOperandMem = &ZydisFormatterFormatOperandMemIntel;
formatter->funcFormatOperandPtr = &ZydisFormatterFormatOperandPtrIntel;
formatter->funcFormatOperandImm = &ZydisFormatterFormatOperandImmIntel;
formatter->funcPrintOperandSize = &ZydisFormatterPrintOperandSizeIntel;
formatter->funcPrintSegment = &ZydisFormatterPrintSegmentIntel;
formatter->funcPrintDecorator = &ZydisFormatterPrintDecoratorIntel;
formatter->funcPrintAddress = &ZydisFormatterPrintAddressIntel;
formatter->funcPrintDisplacement = &ZydisFormatterPrintDisplacementIntel;
formatter->funcPrintImmediate = &ZydisFormatterPrintImmediateIntel;
formatter->funcFormatInstruction = &ZydisFormatterFormatInstrIntel;
formatter->funcPrintPrefixes = &ZydisFormatterPrintPrefixesIntel;
formatter->funcPrintMnemonic = &ZydisFormatterPrintMnemonicIntel;
formatter->funcFormatOperandReg = &ZydisFormatterFormatOperandRegIntel;
formatter->funcFormatOperandMem = &ZydisFormatterFormatOperandMemIntel;
formatter->funcFormatOperandPtr = &ZydisFormatterFormatOperandPtrIntel;
formatter->funcFormatOperandImm = &ZydisFormatterFormatOperandImmIntel;
formatter->funcPrintOperandSize = &ZydisFormatterPrintOperandSizeIntel;
formatter->funcPrintSegment = &ZydisFormatterPrintSegmentIntel;
formatter->funcPrintDecorator = &ZydisFormatterPrintDecoratorIntel;
formatter->funcPrintAddress = &ZydisFormatterPrintAddressIntel;
formatter->funcPrintDisplacement = &ZydisFormatterPrintDisplacementIntel;
formatter->funcPrintImmediate = &ZydisFormatterPrintImmediateIntel;
formatter->funcPrintOperandSeparator = &ZydisFormatterPrintOperandSeparatorIntel;
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
@ -1082,6 +1092,9 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT
case ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE:
*callback = *(const void**)&formatter->funcPrintImmediate;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_OPERAND_SEPARATOR:
*callback = *(const void**)&formatter->funcPrintOperandSeparator;
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}
@ -1140,6 +1153,9 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT
case ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE:
formatter->funcPrintImmediate = *(ZydisFormatterFormatOperandFunc*)&temp;
break;
case ZYDIS_FORMATTER_HOOK_PRINT_OPERAND_SEPARATOR:
formatter->funcPrintOperandSeparator = *(ZydisFormatterPrintOperandSeparatorFunc*)&temp;
break;
default:
return ZYDIS_STATUS_INVALID_PARAMETER;
}