From cbf06b1bf3f8864cec4858fd81019841b39bf8eb Mon Sep 17 00:00:00 2001 From: flobernd Date: Fri, 3 Nov 2017 02:24:02 +0100 Subject: [PATCH] Minor interface changes - Reverted last change - Removed `ZydisFormatterInitEx` - Added `ZydisFormatterSetAttribute` --- examples/FormatterHooks.c | 6 +- examples/ZydisFuzzIn.c | 22 ++--- examples/ZydisPerfTest.c | 11 +-- include/Zydis/Decoder.h | 1 - include/Zydis/Formatter.h | 150 +++++++++++++++++++++------------- src/Decoder.c | 1 - src/Formatter.c | 166 ++++++++++++++++++++++++-------------- tools/ZydisDisasm.c | 8 +- tools/ZydisInfo.c | 14 +++- 9 files changed, 237 insertions(+), 142 deletions(-) diff --git a/examples/FormatterHooks.c b/examples/FormatterHooks.c index 3224441..dad8624 100644 --- a/examples/FormatterHooks.c +++ b/examples/FormatterHooks.c @@ -188,9 +188,9 @@ static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatte void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, ZydisBool installHooks) { ZydisFormatter formatter; - ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, - ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, - ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); + ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL); + ZydisFormatterSetAttribute(&formatter, ZYDIS_FORMATTER_ATTRIB_FORCE_SEGMENTS, ZYDIS_TRUE); + ZydisFormatterSetAttribute(&formatter, ZYDIS_FORMATTER_ATTRIB_FORCE_OPERANDSIZE, ZYDIS_TRUE); if (installHooks) { diff --git a/examples/ZydisFuzzIn.c b/examples/ZydisFuzzIn.c index 3a68a2c..4f9bd2f 100644 --- a/examples/ZydisFuzzIn.c +++ b/examples/ZydisFuzzIn.c @@ -45,10 +45,7 @@ typedef struct ZydisFuzzControlBlock_ ZydisAddressWidth addressWidth; ZydisBool decoderMode[ZYDIS_DECODER_MODE_MAX_VALUE + 1]; ZydisFormatterStyle formatterStyle; - ZydisFormatterFlags formatterFlags; - ZydisFormatterAddressFormat formatterAddrFormat; - ZydisFormatterDisplacementFormat formatterDispFormat; - ZydisFormatterImmediateFormat formatterImmFormat; + uintptr_t formatterAttributes[ZYDIS_FORMATTER_ATTRIB_MAX_VALUE + 1]; } ZydisFuzzControlBlock; /* ============================================================================================== */ @@ -77,7 +74,7 @@ int main() fputs("Failed to initialize decoder\n", stderr); return EXIT_FAILURE; } - for (ZydisDecoderMode mode = 1; mode <= ZYDIS_DECODER_MODE_MAX_VALUE; ++mode) + for (ZydisDecoderMode mode = 0; mode <= ZYDIS_DECODER_MODE_MAX_VALUE; ++mode) { if (!ZYDIS_SUCCESS( ZydisDecoderEnableMode(&decoder, mode, controlBlock.decoderMode[mode] ? 1 : 0))) @@ -88,13 +85,20 @@ int main() } ZydisFormatter formatter; - if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, controlBlock.formatterStyle, - controlBlock.formatterFlags, controlBlock.formatterAddrFormat, - controlBlock.formatterDispFormat, controlBlock.formatterImmFormat))) + if (!ZYDIS_SUCCESS(ZydisFormatterInit(&formatter, controlBlock.formatterStyle))) { - fputs("failed to initialize instruction-formatter\n", stderr); + fputs("Failed to initialize instruction-formatter\n", stderr); return EXIT_FAILURE; } + for (ZydisFormatterAttribute attrib = 0; attrib <= ZYDIS_FORMATTER_ATTRIB_MAX_VALUE; ++attrib) + { + if (!ZYDIS_SUCCESS(ZydisFormatterSetAttribute(&formatter, attrib, + controlBlock.formatterAttributes[attrib]))) + { + fputs("Failed to set formatter-attribute\n", stderr); + return EXIT_FAILURE; + } + } uint8_t readBuf[ZYDIS_MAX_INSTRUCTION_LENGTH * 1024]; size_t numBytesRead; diff --git a/examples/ZydisPerfTest.c b/examples/ZydisPerfTest.c index 4b47ec7..3a72e69 100644 --- a/examples/ZydisPerfTest.c +++ b/examples/ZydisPerfTest.c @@ -171,12 +171,13 @@ uint64_t processBuffer(const char* buffer, size_t length, ZydisBool minimalMode, ZydisFormatter formatter; if (format) { - if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, - ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, - ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, - ZYDIS_FORMATTER_IMM_DEFAULT))) + if (!ZYDIS_SUCCESS(ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL)) || + !ZYDIS_SUCCESS(ZydisFormatterSetAttribute(&formatter, + ZYDIS_FORMATTER_ATTRIB_FORCE_SEGMENTS, ZYDIS_TRUE)) || + !ZYDIS_SUCCESS(ZydisFormatterSetAttribute(&formatter, + ZYDIS_FORMATTER_ATTRIB_FORCE_OPERANDSIZE, ZYDIS_TRUE))) { - fputs("Failed to initialized instruction-formatter\n", stderr); + fputs("Failed to initialize instruction-formatter\n", stderr); exit(EXIT_FAILURE); } } diff --git a/include/Zydis/Decoder.h b/include/Zydis/Decoder.h index 4ed2eef..526595e 100644 --- a/include/Zydis/Decoder.h +++ b/include/Zydis/Decoder.h @@ -59,7 +59,6 @@ typedef uint8_t ZydisDecoderMode; */ enum ZydisDecoderModes { - ZYDIS_DECODER_MODE_INVALID, /** * @brief Enables minimal instruction decoding without semantic analysis. * diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index 92fea83..50806cf 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -44,6 +44,10 @@ extern "C" { /* Enums and types */ /* ============================================================================================== */ +/* ---------------------------------------------------------------------------------------------- */ +/* Formatter style */ +/* ---------------------------------------------------------------------------------------------- */ + /** * @brief Defines the @c ZydisFormatterStyle datatype. */ @@ -65,42 +69,78 @@ enum ZydisFormatterStyles }; /* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Defines the @c ZydisFormatFlags datatype. - */ -typedef uint32_t ZydisFormatterFlags; - -/** - * @brief Formats the instruction in uppercase instead of lowercase. - */ -#define ZYDIS_FMTFLAG_UPPERCASE 0x00000001 // (1 << 0) -/** - * @brief Forces the formatter to always print the segment register of memory-operands, instead - * of ommiting implicit DS/SS segments. - */ -#define ZYDIS_FMTFLAG_FORCE_SEGMENTS 0x00000002 // (1 << 1) -/** - * @brief Forces the formatter to always print the size of memory-operands. - */ -#define ZYDIS_FMTFLAG_FORCE_OPERANDSIZE 0x00000004 // (1 << 2) - +/* Attributes */ /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Defines the @c ZydisFormatterAddressFormat datatype. + * @brief Defines the @c ZydisFormatterAttribute datatype. */ -typedef uint8_t ZydisFormatterAddressFormat; +typedef uint8_t ZydisFormatterAttribute; + +/** + * @brief Values that represent formatter-attributes. + */ +enum ZydisFormatterAttributes +{ + /** + * @brief Controls the letter-case. + * + * Pass `ZYDIS_TRUE` as value to format in uppercase and `ZYDIS_FALSE` to format in lowercase. + * + * The default value is `ZYDIS_FALSE`. + */ + ZYDIS_FORMATTER_ATTRIB_UPPERCASE, + /** + * @brief Controls the printing of segment prefixes. + * + * Pass `ZYDIS_TRUE` as value to force the formatter to always print the segment register of + * memory-operands or `ZYDIS_FALSE` to ommit implicit DS/SS segments. + * + * The default value is `ZYDIS_FALSE`. + */ + ZYDIS_FORMATTER_ATTRIB_FORCE_SEGMENTS, + /** + * @brief Controls the printing of 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_ATTRIB_FORCE_OPERANDSIZE, + /** + * @brief Controls the format of addresses. + * + * The default value is `ZYDIS_FORMATTER_ADDR_ABSOLUTE`. + */ + ZYDIS_FORMATTER_ATTRIB_ADDR_FORMAT, + /** + * @brief Controls the format of displacement values. + * + * The default value is `ZYDIS_FORMATTER_DISP_HEX_SIGNED`. + */ + ZYDIS_FORMATTER_ATTRIB_DISP_FORMAT, + /** + * @brief Controls the format of immediate values. + * + * The default value is `ZYDIS_FORMATTER_IMM_HEX_UNSIGNED`. + */ + ZYDIS_FORMATTER_ATTRIB_IMM_FORMAT, + /** + * @brief Maximum value of this enum. + */ + ZYDIS_FORMATTER_ATTRIB_MAX_VALUE = ZYDIS_FORMATTER_ATTRIB_IMM_FORMAT +}; + +/* ---------------------------------------------------------------------------------------------- */ +/* Address format constants */ +/* ---------------------------------------------------------------------------------------------- */ /** * @brief Values that represent address-formats. */ enum ZydisFormatterAddressFormats { - /** - * @brief Currently defaults to @c ZYDIS_FORMATTER_ADDR_ABSOLUTE. - */ - ZYDIS_FORMATTER_ADDR_DEFAULT, /** * @brief Displays absolute addresses instead of relative ones. */ @@ -128,21 +168,14 @@ enum ZydisFormatterAddressFormats }; /* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Defines the @c ZydisFormatterDisplacementFormat datatype. - */ -typedef uint8_t ZydisFormatterDisplacementFormat; +/* Displacement formats */ +/* ---------------------------------------------------------------------------------------------- */ /** * @brief Values that represent displacement-formats. */ enum ZydisFormatterDisplacementFormats { - /** - * @brief Currently defaults to @c ZYDIS_FORMATTER_DISP_HEX_SIGNED. - */ - ZYDIS_FORMATTER_DISP_DEFAULT, /** * @brief Formats displacements as signed hexadecimal values. * @@ -166,21 +199,14 @@ enum ZydisFormatterDisplacementFormats }; /* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Defines the @c ZydisFormatterImmediateFormat datatype. - */ -typedef uint8_t ZydisFormatterImmediateFormat; +/* Immediate formats */ +/* ---------------------------------------------------------------------------------------------- */ /** * @brief Values that represent formatter immediate-formats. */ enum ZydisFormatterImmediateFormats { - /** - * @brief Currently defaults to @c ZYDIS_FORMATTER_IMM_HEX_UNSIGNED. - */ - ZYDIS_FORMATTER_IMM_DEFAULT, /** * @brief Automatically chooses the most suitable formatting-mode based on the operands * @c ZydisOperandInfo.imm.isSigned attribute. @@ -208,6 +234,8 @@ enum ZydisFormatterImmediateFormats ZYDIS_FORMATTER_IMM_MAX_VALUE = ZYDIS_FORMATTER_IMM_HEX_UNSIGNED }; +/* ---------------------------------------------------------------------------------------------- */ +/* Hooks */ /* ---------------------------------------------------------------------------------------------- */ /** @@ -326,6 +354,8 @@ enum ZydisDecoratorTypes ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EVICTION_HINT }; +/* ---------------------------------------------------------------------------------------------- */ + typedef struct ZydisFormatter_ ZydisFormatter; /** @@ -452,15 +482,21 @@ typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* f char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData); +/* ---------------------------------------------------------------------------------------------- */ +/* Formatter struct */ +/* ---------------------------------------------------------------------------------------------- */ + /** * @brief Defines the @c ZydisFormatter struct. */ struct ZydisFormatter_ { - ZydisFormatterFlags flags; - ZydisFormatterAddressFormat addressFormat; - ZydisFormatterDisplacementFormat displacementFormat; - ZydisFormatterImmediateFormat immediateFormat; + uint8_t letterCase; + ZydisBool forceSegments; + ZydisBool forceOperandSize; + uint8_t addressFormat; + uint8_t displacementFormat; + uint8_t immediateFormat; ZydisFormatterNotifyFunc funcPre; ZydisFormatterNotifyFunc funcPost; ZydisFormatterFormatFunc funcFormatInstruction; @@ -478,6 +514,8 @@ struct ZydisFormatter_ ZydisFormatterFormatOperandFunc funcPrintImmediate; }; +/* ---------------------------------------------------------------------------------------------- */ + /* ============================================================================================== */ /* Exported functions */ /* ============================================================================================== */ @@ -493,20 +531,16 @@ struct ZydisFormatter_ ZYDIS_EXPORT ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle style); /** - * @brief Initializes the given @c ZydisFormatter instance. + * @brief Sets the value of the specified formatter `attribute`. * - * @param formatter A pointer to the @c ZydisFormatter instance. - * @param style The formatter style. - * @param addressFormat The address format. - * @param displacementFormat The displacement format. - * @param immmediateFormat The immediate format. + * @param formatter A pointer to the @c ZydisFormatter instance. + * @param attribute The id of the formatter-attribute. + * @param value The new value. * * @return A zydis status code. */ -ZYDIS_EXPORT ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, ZydisFormatterStyle style, - ZydisFormatterFlags flags, ZydisFormatterAddressFormat addressFormat, - ZydisFormatterDisplacementFormat displacementFormat, - ZydisFormatterImmediateFormat immmediateFormat); +ZYDIS_EXPORT ZydisStatus ZydisFormatterSetAttribute(ZydisFormatter* formatter, + ZydisFormatterAttribute attribute, uintptr_t value); /** * @brief Replaces a formatter function with a custom callback and/or retrieves the currently diff --git a/src/Decoder.c b/src/Decoder.c index a560435..c614588 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -4398,7 +4398,6 @@ ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode { static const ZydisBool decoderModes[ZYDIS_DECODER_MODE_MAX_VALUE + 1] = { - ZYDIS_FALSE, // ZYDIS_DECODER_MODE_INVALID ZYDIS_FALSE, // ZYDIS_DECODER_MODE_MINIMAL ZYDIS_FALSE, // ZYDIS_DECODER_MODE_AMD_BRANCHES ZYDIS_TRUE , // ZYDIS_DECODER_MODE_MPX diff --git a/src/Formatter.c b/src/Formatter.c index d186069..7d42b3a 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -34,14 +34,6 @@ /* Instruction formatter */ /* ============================================================================================== */ -/* ---------------------------------------------------------------------------------------------- */ -/* Internal macros */ -/* ---------------------------------------------------------------------------------------------- */ - -#define ZYDIS_LETTER_CASE \ - (formatter->flags & ZYDIS_FMTFLAG_UPPERCASE) ? \ - ZYDIS_LETTER_CASE_UPPER : ZYDIS_LETTER_CASE_DEFAULT - /* ---------------------------------------------------------------------------------------------- */ /* Intel style */ /* ---------------------------------------------------------------------------------------------- */ @@ -58,34 +50,34 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* format if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK) { - return ZydisPrintStr(buffer, bufferLen, "lock ", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, "lock ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REP) { - return ZydisPrintStr(buffer, bufferLen, "rep ", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, "rep ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPE) { - return ZydisPrintStr(buffer, bufferLen, "repe ", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, "repe ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE) { - return ZydisPrintStr(buffer, bufferLen, "repne ", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, "repne ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_BOUND) { - return ZydisPrintStr(buffer, bufferLen, "bnd ", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, "bnd ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE) { - return ZydisPrintStr(buffer, bufferLen, "xacquire ", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, "xacquire ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE) { - return ZydisPrintStr(buffer, bufferLen, "xrelease ", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, "xrelease ", formatter->letterCase); } return ZYDIS_STATUS_SUCCESS; @@ -108,11 +100,11 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format { mnemonic = "invalid"; } - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, mnemonic, ZYDIS_LETTER_CASE)); + ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, mnemonic, formatter->letterCase)); if (instruction->attributes & ZYDIS_ATTRIB_IS_FAR_BRANCH) { - return ZydisPrintStr(buffer, bufEnd - *buffer, " far", ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufEnd - *buffer, " far", formatter->letterCase); } return ZYDIS_STATUS_SUCCESS; @@ -141,7 +133,7 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for { reg = "invalid"; } - return ZydisPrintStr(buffer, bufferLen, reg, ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, reg, formatter->letterCase); } static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter, @@ -164,8 +156,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for (operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0)) { // EIP/RIP-relative or absolute-displacement address operand - if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDR_DEFAULT) || - (formatter->addressFormat == ZYDIS_FORMATTER_ADDR_ABSOLUTE) || + if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDR_ABSOLUTE) || (operand->mem.base == ZYDIS_REGISTER_NONE)) { uint64_t address; @@ -175,7 +166,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for } else { ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.base), ZYDIS_LETTER_CASE)); + ZydisRegisterGetString(operand->mem.base), formatter->letterCase)); ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer, instruction, operand, userData)); } @@ -189,7 +180,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, ZYDIS_LETTER_CASE)); + ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase)); } if ((operand->mem.index != ZYDIS_REGISTER_NONE) && (operand->mem.type != ZYDIS_MEMOP_TYPE_MIB)) @@ -204,7 +195,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for ZYDIS_CHECK( ZydisPrintStr(buffer, bufEnd - *buffer, "+", ZYDIS_LETTER_CASE_DEFAULT)); } - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, ZYDIS_LETTER_CASE)); + ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase)); if (operand->mem.scale) { ZYDIS_CHECK( @@ -253,7 +244,6 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for ZydisBool printSignedHEX = ZYDIS_FALSE; switch (formatter->addressFormat) { - case ZYDIS_FORMATTER_ADDR_DEFAULT: case ZYDIS_FORMATTER_ADDR_ABSOLUTE: { uint64_t address; @@ -417,7 +407,7 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for // TODO: refactor uint32_t typecast = 0; - if (formatter->flags & ZYDIS_FMTFLAG_FORCE_OPERANDSIZE) + if (formatter->forceOperandSize) { if ((operand->type == ZYDIS_OPERAND_TYPE_MEMORY) && (operand->mem.type == ZYDIS_MEMOP_TYPE_MEM)) @@ -504,7 +494,7 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for if (str) { - return ZydisPrintStr(buffer, bufferLen, str, ZYDIS_LETTER_CASE); + return ZydisPrintStr(buffer, bufferLen, str, formatter->letterCase); } } return ZYDIS_STATUS_SUCCESS; @@ -530,25 +520,25 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt case ZYDIS_REGISTER_GS: ZYDIS_CHECK( ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.segment), ZYDIS_LETTER_CASE)); + ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); case ZYDIS_REGISTER_SS: - if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) || + if ((formatter->forceSegments) || (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS)) { ZYDIS_CHECK( ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.segment), ZYDIS_LETTER_CASE)); + ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); } break; case ZYDIS_REGISTER_DS: - if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) || + if ((formatter->forceSegments) || (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS)) { ZYDIS_CHECK( ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.segment), ZYDIS_LETTER_CASE)); + ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); } break; @@ -582,7 +572,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma return ZYDIS_STATUS_INVALID_PARAMETER; } ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " {", ZYDIS_LETTER_CASE_DEFAULT)); - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, ZYDIS_LETTER_CASE)); + ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase)); ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, "}", ZYDIS_LETTER_CASE_DEFAULT)); if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO) { @@ -896,39 +886,20 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte /* Exported functions */ /* ---------------------------------------------------------------------------------------------- */ -ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, - ZydisFormatterStyle style) +ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle style) { - return ZydisFormatterInitEx(formatter, style, 0, ZYDIS_FORMATTER_ADDR_DEFAULT, - ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); -} - -ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, - ZydisFormatterStyle style, ZydisFormatterFlags flags, ZydisFormatterAddressFormat addressFormat, - ZydisFormatterDisplacementFormat displacementFormat, - ZydisFormatterImmediateFormat immmediateFormat) -{ - if (!formatter || - ((addressFormat != ZYDIS_FORMATTER_ADDR_DEFAULT) && - (addressFormat != ZYDIS_FORMATTER_ADDR_ABSOLUTE) && - (addressFormat != ZYDIS_FORMATTER_ADDR_RELATIVE_SIGNED) && - (addressFormat != ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED)) || - ((displacementFormat != ZYDIS_FORMATTER_DISP_DEFAULT) && - (displacementFormat != ZYDIS_FORMATTER_DISP_HEX_SIGNED) && - (displacementFormat != ZYDIS_FORMATTER_DISP_HEX_UNSIGNED)) || - ((immmediateFormat != ZYDIS_FORMATTER_IMM_DEFAULT) && - (immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_AUTO) && - (immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_SIGNED) && - (immmediateFormat != ZYDIS_FORMATTER_IMM_HEX_UNSIGNED))) + if (!formatter) { return ZYDIS_STATUS_INVALID_PARAMETER; } memset(formatter, 0, sizeof(ZydisFormatter)); - formatter->flags = flags; - formatter->addressFormat = addressFormat; - formatter->displacementFormat = displacementFormat; - formatter->immediateFormat = immmediateFormat; + formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT; + formatter->forceSegments = ZYDIS_FALSE; + formatter->forceOperandSize = ZYDIS_FALSE; + formatter->addressFormat = ZYDIS_FORMATTER_ADDR_ABSOLUTE; + formatter->displacementFormat = ZYDIS_FORMATTER_DISP_HEX_SIGNED; + formatter->immediateFormat = ZYDIS_FORMATTER_IMM_HEX_UNSIGNED; switch (style) { @@ -951,6 +922,83 @@ ZydisStatus ZydisFormatterInitEx(ZydisFormatter* formatter, return ZYDIS_STATUS_INVALID_PARAMETER; } + return ZYDIS_STATUS_SUCCESS; +} + +ZydisStatus ZydisFormatterSetAttribute(ZydisFormatter* formatter, + ZydisFormatterAttribute attribute, uintptr_t value) +{ + if (!formatter) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + switch (attribute) + { + case ZYDIS_FORMATTER_ATTRIB_UPPERCASE: + switch (value) + { + case ZYDIS_FALSE: + formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT; + break; + case ZYDIS_TRUE: + formatter->letterCase = ZYDIS_LETTER_CASE_UPPER; + break; + default: + return ZYDIS_STATUS_INVALID_PARAMETER; + } + break; + case ZYDIS_FORMATTER_ATTRIB_FORCE_SEGMENTS: + switch (value) + { + case ZYDIS_FALSE: + formatter->forceSegments = ZYDIS_LETTER_CASE_DEFAULT; + break; + case ZYDIS_TRUE: + formatter->forceSegments = ZYDIS_LETTER_CASE_UPPER; + break; + default: + return ZYDIS_STATUS_INVALID_PARAMETER; + } + break; + case ZYDIS_FORMATTER_ATTRIB_FORCE_OPERANDSIZE: + switch (value) + { + case ZYDIS_FALSE: + formatter->forceOperandSize = ZYDIS_LETTER_CASE_DEFAULT; + break; + case ZYDIS_TRUE: + formatter->forceOperandSize = ZYDIS_LETTER_CASE_UPPER; + break; + default: + return ZYDIS_STATUS_INVALID_PARAMETER; + } + break; + case ZYDIS_FORMATTER_ATTRIB_ADDR_FORMAT: + if (value > ZYDIS_FORMATTER_ADDR_MAX_VALUE) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + formatter->addressFormat = (uint8_t)value; + break; + case ZYDIS_FORMATTER_ATTRIB_DISP_FORMAT: + if (value > ZYDIS_FORMATTER_DISP_MAX_VALUE) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + formatter->displacementFormat = (uint8_t)value; + break; + case ZYDIS_FORMATTER_ATTRIB_IMM_FORMAT: + if (value > ZYDIS_FORMATTER_IMM_MAX_VALUE) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + formatter->immediateFormat = (uint8_t)value; + break; + default: + return ZYDIS_STATUS_INVALID_PARAMETER; + } + return ZYDIS_STATUS_SUCCESS; } diff --git a/tools/ZydisDisasm.c b/tools/ZydisDisasm.c index e642a23..e596aa7 100644 --- a/tools/ZydisDisasm.c +++ b/tools/ZydisDisasm.c @@ -67,9 +67,11 @@ int main(int argc, char** argv) } ZydisFormatter formatter; - if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, - ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, - ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT))) + if (!ZYDIS_SUCCESS(ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL)) || + !ZYDIS_SUCCESS(ZydisFormatterSetAttribute(&formatter, + ZYDIS_FORMATTER_ATTRIB_FORCE_SEGMENTS, ZYDIS_TRUE)) || + !ZYDIS_SUCCESS(ZydisFormatterSetAttribute(&formatter, + ZYDIS_FORMATTER_ATTRIB_FORCE_OPERANDSIZE, ZYDIS_TRUE))) { fputs("Failed to initialized instruction-formatter\n", stderr); return EXIT_FAILURE; diff --git a/tools/ZydisInfo.c b/tools/ZydisInfo.c index 3f85087..5463406 100644 --- a/tools/ZydisInfo.c +++ b/tools/ZydisInfo.c @@ -29,6 +29,7 @@ * @brief TODO */ +#include #include #include #include @@ -545,10 +546,17 @@ void printInstruction(ZydisDecodedInstruction* instruction) printAVXInfo(instruction); } + ZydisStatus status; ZydisFormatter formatter; - ZydisFormatterInitEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL, - ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE, - ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT); + if (!ZYDIS_SUCCESS((status = ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL))) || + !ZYDIS_SUCCESS((status = ZydisFormatterSetAttribute(&formatter, + ZYDIS_FORMATTER_ATTRIB_FORCE_SEGMENTS, ZYDIS_TRUE))) || + !ZYDIS_SUCCESS((status = ZydisFormatterSetAttribute(&formatter, + ZYDIS_FORMATTER_ATTRIB_FORCE_OPERANDSIZE, ZYDIS_TRUE)))) + { + fputs("Failed to initialize instruction-formatter\n", stderr); + exit(status); + } char buffer[256]; ZydisFormatterFormatInstruction(&formatter, instruction, &buffer[0], sizeof(buffer)); fputs("\n== [ DISASM ] =====================================================", stdout);