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. * @brief This function is called to print an immediate value.
*/ */
ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE, 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. * @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, char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData); 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 */ /* Formatter struct */
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */
@ -558,7 +585,8 @@ struct ZydisFormatter_
ZydisFormatterFormatDecoratorFunc funcPrintDecorator; ZydisFormatterFormatDecoratorFunc funcPrintDecorator;
ZydisFormatterFormatAddressFunc funcPrintAddress; ZydisFormatterFormatAddressFunc funcPrintAddress;
ZydisFormatterFormatOperandFunc funcPrintDisplacement; ZydisFormatterFormatOperandFunc funcPrintDisplacement;
ZydisFormatterFormatOperandFunc funcPrintImmediate; ZydisFormatterFormatOperandFunc funcPrintImmediate;
ZydisFormatterPrintOperandSeparatorFunc funcPrintOperandSeparator;
}; };
/* ---------------------------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------------------------------- */

View File

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