From fa12ccb64bb6bfc074b006eb915f75a681a94bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Ho=CC=88ner?= Date: Fri, 1 Dec 2017 20:40:56 +0100 Subject: [PATCH] Switch to length aware string --- include/Zydis/Formatter.h | 23 ++- include/Zydis/Status.h | 6 +- include/Zydis/String.h | 45 ++++++ src/FormatHelper.c | 326 +++++++++++++------------------------- src/FormatHelper.h | 65 +++++--- src/Formatter.c | 314 ++++++++++++++++++------------------ 6 files changed, 363 insertions(+), 416 deletions(-) create mode 100644 include/Zydis/String.h diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index 3f07918..8b29588 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -35,6 +35,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -413,14 +414,13 @@ typedef struct ZydisFormatter_ ZydisFormatter; * @c ZYDIS_FORMATTER_HOOK_POST hook-types. */ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, - const ZydisDecodedInstruction* instruction, void* userData); + ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData); /** * @brief Defines the @c ZydisFormatterFormatFunc 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 str A pointer to the string buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param userData A pointer to user-defined data. * @@ -434,14 +434,13 @@ 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, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData); + ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData); /** * @brief Defines the @c ZydisFormatterFormatOperandFunc 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 str A pointer to 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. @@ -471,15 +470,14 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, * hook-types. */ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData); /** * @brief Defines the @c ZydisFormatterFormatAddressFunc 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 str A pointer to 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. @@ -494,15 +492,14 @@ 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, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisU64 address, void* userData); /** * @brief Defines the @c ZydisFormatterFormatDecoratorFunc 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 str A pointer to the string buffer. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param operand A pointer to the @c ZydisDecodedOperand struct. * @param type The decorator type. @@ -520,7 +517,7 @@ 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, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData); /* ---------------------------------------------------------------------------------------------- */ diff --git a/include/Zydis/Status.h b/include/Zydis/Status.h index 2a81f5d..aec256e 100644 --- a/include/Zydis/Status.h +++ b/include/Zydis/Status.h @@ -164,10 +164,10 @@ enum ZydisStatusCodes #define ZYDIS_CHECK(status) \ do \ { \ - ZydisStatus s = status; \ - if (!ZYDIS_SUCCESS(s)) \ + ZydisStatus status_w4587ntvmEgDG = status; \ + if (!ZYDIS_SUCCESS(status_w4587ntvmEgDG)) \ { \ - return s; \ + return status_w4587ntvmEgDG; \ } \ } while (0) diff --git a/include/Zydis/String.h b/include/Zydis/String.h new file mode 100644 index 0000000..bb18e77 --- /dev/null +++ b/include/Zydis/String.h @@ -0,0 +1,45 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Joel Höner + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + +***************************************************************************************************/ + +#ifndef ZYDIS_STRING_H +#define ZYDIS_STRING_H + +#include + +/* ============================================================================================== */ +/* String struct */ +/* ============================================================================================== */ + +typedef struct ZydisString_ +{ + char *s; // NOT always 0-terminated! + ZydisUSize length; + ZydisUSize capacity; // always -1 for 0 byte +} ZydisString; + +/* ============================================================================================== */ + +#endif // ZYDIS_STRING_H diff --git a/src/FormatHelper.c b/src/FormatHelper.c index e54018e..b9e4250 100644 --- a/src/FormatHelper.c +++ b/src/FormatHelper.c @@ -25,7 +25,6 @@ ***************************************************************************************************/ #include -#include /* ============================================================================================== */ /* Constants */ @@ -98,127 +97,16 @@ void ZydisToUpperCase(char* buffer, ZydisUSize bufferLen) } } -#if defined(ZYDIS_X86) || defined(ZYDIS_ARM) -ZydisStatus ZydisPrintDecU32(char** buffer, ZydisUSize bufferLen, ZydisU32 value, ZydisU8 paddingLength) +ZydisStatus ZydisPrintDecU64(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength) { - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen > 0); - - char temp[ZYDIS_MAXCHARS_DEC_32 + 1]; - char *p = &temp[ZYDIS_MAXCHARS_DEC_32]; - *p = '\0'; - while (value >= 100) - { - ZydisU32 const old = value; - p -= 2; - value /= 100; - ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], sizeof(ZydisU16)); - } - p -= 2; - ZydisMemoryCopy(p, &decimalLookup[value * 2], sizeof(ZydisU16)); - - const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_32] - p; - if ((bufferLen < (ZydisUSize)(n + 1)) || (bufferLen < (ZydisUSize)(paddingLength + 1))) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - - ZydisUSize offset = 0; - if (n <= paddingLength) - { - offset = paddingLength - n + 1; - ZydisMemorySet(*buffer, '0', offset); - } - - ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1); - *buffer += n + offset - (ZydisU8)(value < 10); - - return ZYDIS_STATUS_SUCCESS; -} - -ZydisStatus ZydisPrintHexU32(char** buffer, ZydisUSize bufferLen, ZydisU32 value, ZydisU8 paddingLength, - ZydisBool uppercase, const char* prefix, const char* suffix) -{ - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen); - - if (prefix) - { - const char* bufEnd = *buffer + bufferLen; - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, prefix, ZYDIS_LETTER_CASE_DEFAULT)); - bufferLen = bufEnd - *buffer; - } - if (bufferLen < (ZydisUSize)(paddingLength + 1)) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - - if (!value) - { - const ZydisU8 n = (paddingLength ? paddingLength : 1); - - if (bufferLen < (ZydisUSize)(n + 1)) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - - ZydisMemorySet(*buffer, '0', n); - (*buffer)[n] = '\0'; - *buffer += n; - return ZYDIS_STATUS_SUCCESS; - } - - ZydisU8 n = 0; - for (ZydisI8 i = ZYDIS_MAXCHARS_HEX_32 - 1; i >= 0; --i) - { - const ZydisU8 v = (value >> i * 4) & 0x0F; - if (!n) - { - if (!v) - { - continue; - } - if (bufferLen <= (ZydisU8)(i + 1)) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - if (paddingLength > i) - { - n = paddingLength - i - 1; - ZydisMemorySet(*buffer, '0', n); - } - } - if (uppercase) - { - (*buffer)[n++] = "0123456789ABCDEF"[v]; - } else - { - (*buffer)[n++] = "0123456789abcdef"[v]; - } - } - (*buffer)[n] = '\0'; - *buffer += n; - - if (suffix) - { - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen - n, suffix, ZYDIS_LETTER_CASE_DEFAULT)); - } - - return ZYDIS_STATUS_SUCCESS; -} -#endif - -ZydisStatus ZydisPrintDecU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength) -{ - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen > 0); + ZYDIS_ASSERT(s); char temp[ZYDIS_MAXCHARS_DEC_64 + 1]; char *p = &temp[ZYDIS_MAXCHARS_DEC_64]; - *p = '\0'; + while (value >= 100) { - ZydisU64 const old = value; + const ZydisU64 old = value; p -= 2; value /= 100; ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], 2); @@ -227,7 +115,8 @@ ZydisStatus ZydisPrintDecU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value ZydisMemoryCopy(p, &decimalLookup[value * 2], 2); const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_64] - p; - if ((bufferLen < (ZydisUSize)(n + 1)) || (bufferLen < (ZydisUSize)(paddingLength + 1))) + if ((s->capacity - s->length < (ZydisUSize)(n + 1)) || + (s->capacity - s->length < (ZydisUSize)(paddingLength + 1))) { return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; } @@ -236,179 +125,176 @@ ZydisStatus ZydisPrintDecU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value if (n <= paddingLength) { offset = paddingLength - n + 1; - ZydisMemorySet(*buffer, '0', offset); + ZydisMemorySet(s->s + s->length, '0', offset); } - ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1); - *buffer += n + offset - (ZydisU8)(value < 10); + ZydisMemoryCopy(s->s + s->length + offset, &p[value < 10], n + 1); + s->length += n + offset - (ZydisU8)(value < 10); return ZYDIS_STATUS_SUCCESS; } -ZydisStatus ZydisPrintHexU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength, - ZydisBool uppercase, const char* prefix, const char* suffix) -{ - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen); - - if (prefix) - { - const char* bufEnd = *buffer + bufferLen; - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, prefix, ZYDIS_LETTER_CASE_DEFAULT)); - bufferLen = bufEnd - *buffer; - } - if (bufferLen < (ZydisUSize)(paddingLength + 1)) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - - if (!value) - { - const ZydisU8 n = (paddingLength ? paddingLength : 1); - - if (bufferLen < (ZydisUSize)(n + 1)) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - - ZydisMemorySet(*buffer, '0', n); - (*buffer)[n] = '\0'; - *buffer += n; - return ZYDIS_STATUS_SUCCESS; - } - - ZydisU8 n = 0; - const ZydisU8 c = ((value & 0xFFFFFFFF00000000) ? ZYDIS_MAXCHARS_HEX_64 : ZYDIS_MAXCHARS_HEX_32); - for (ZydisI8 i = c - 1; i >= 0; --i) - { - const ZydisU8 v = (value >> i * 4) & 0x0F; - if (!n) - { - if (!v) - { - continue; - } - if (bufferLen <= (ZydisU8)(i + 1)) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - if (paddingLength > i) - { - n = paddingLength - i - 1; - ZydisMemorySet(*buffer, '0', n); - } - } - if (uppercase) - { - (*buffer)[n++] = "0123456789ABCDEF"[v]; - } else - { - (*buffer)[n++] = "0123456789abcdef"[v]; - } - } - (*buffer)[n] = '\0'; - *buffer += n; - - if (suffix) - { - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen - n, suffix, ZYDIS_LETTER_CASE_DEFAULT)); - } - - return ZYDIS_STATUS_SUCCESS; +ZydisStatus ZydisPrintHexU64(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength, + ZydisBool uppercase, const char* prefix, const char* suffix) +{ + ZYDIS_ASSERT(s); + + if (prefix) + { + ZYDIS_CHECK(ZydisStringAppendC(s, prefix, ZYDIS_LETTER_CASE_DEFAULT)); + } + + char* buffer = s->s + s->length; + ZydisUSize numRemainingBytes = s->capacity - s->length; + + if (numRemainingBytes < (ZydisUSize)paddingLength) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + if (!value) + { + const ZydisU8 n = (paddingLength ? paddingLength : 1); + + if (numRemainingBytes < (ZydisUSize)n) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZydisMemorySet(buffer, '0', n); + s->length += n; + return ZYDIS_STATUS_SUCCESS; + } + + ZydisU8 n = 0; + const ZydisU8 c = ((value & 0xFFFFFFFF00000000) ? ZYDIS_MAXCHARS_HEX_64 : ZYDIS_MAXCHARS_HEX_32); + for (ZydisI8 i = c - 1; i >= 0; --i) + { + const ZydisU8 v = (value >> i * 4) & 0x0F; + if (!n) + { + if (!v) + { + continue; + } + if (numRemainingBytes <= (ZydisU8)(i + 1)) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + if (paddingLength > i) + { + n = paddingLength - i - 1; + ZydisMemorySet(buffer, '0', n); + } + } + if (uppercase) + { + buffer[n++] = "0123456789ABCDEF"[v]; + } else + { + buffer[n++] = "0123456789abcdef"[v]; + } + } + s->length += n; + + if (suffix) + { + ZYDIS_CHECK(ZydisStringAppendC(s, suffix, ZYDIS_LETTER_CASE_DEFAULT)); + } + + return ZYDIS_STATUS_SUCCESS; } /* ---------------------------------------------------------------------------------------------- */ /* Public Functions */ /* ---------------------------------------------------------------------------------------------- */ -ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, const char* text, - ZydisLetterCase letterCase) +ZydisStatus ZydisStringAppend(ZydisString* s, const ZydisString* text, ZydisLetterCase letterCase) { - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen > 0); + ZYDIS_ASSERT(s); + ZYDIS_ASSERT(s->capacity >= s->length); ZYDIS_ASSERT(text); + ZYDIS_ASSERT(text->capacity >= s->length); - const ZydisUSize strLen = ZydisStrLen(text); - if (strLen >= bufferLen) + if (s->length + text->length >= s->capacity) { return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; } - ZydisMemoryCopy(*buffer, text, strLen + 1); + ZydisMemoryCopy(s->s + s->length, text->s, text->length); + switch (letterCase) { case ZYDIS_LETTER_CASE_DEFAULT: break; case ZYDIS_LETTER_CASE_LOWER: - ZydisToLowerCase(*buffer, strLen); + ZydisToLowerCase(s->s + s->length, text->length); break; case ZYDIS_LETTER_CASE_UPPER: - ZydisToUpperCase(*buffer, strLen); + ZydisToUpperCase(s->s + s->length, text->length); break; default: ZYDIS_UNREACHABLE; } - *buffer += strLen; + + s->length += text->length; return ZYDIS_STATUS_SUCCESS; } -ZydisStatus ZydisPrintDecU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength) +ZydisStatus ZydisPrintDecU(ZydisString *s, ZydisU64 value, ZydisU8 paddingLength) { #if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64) - return ZydisPrintDecU64(buffer, bufferLen, value, paddingLength); + return ZydisPrintDecU64(s, value, paddingLength); #else if (value & 0xFFFFFFFF00000000) { - return ZydisPrintDecU64(buffer, bufferLen, value, paddingLength); + return ZydisPrintDecU64(s, value, paddingLength); } else { - return ZydisPrintDecU32(buffer, bufferLen, (ZydisU32)value, paddingLength); + return ZydisPrintDecU32(s, (ZydisU32)value, paddingLength); } #endif } -ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, ZydisU8 paddingLength) +ZydisStatus ZydisPrintDecS(ZydisString *s, ZydisI64 value, ZydisU8 paddingLength) { if (value < 0) { - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT)); - return ZydisPrintDecU(buffer, bufferLen - 1, -value, paddingLength); + ZYDIS_CHECK(ZydisStringAppendC(s, "-", ZYDIS_LETTER_CASE_DEFAULT)); + return ZydisPrintDecU(s, -value, paddingLength); } - return ZydisPrintDecU(buffer, bufferLen, value, paddingLength); + return ZydisPrintDecU(s, value, paddingLength); } -ZydisStatus ZydisPrintHexU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength, +ZydisStatus ZydisPrintHexU(ZydisString *s, ZydisU64 value, ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix) { #if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64) - return ZydisPrintHexU64(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix); + return ZydisPrintHexU64(s, value, paddingLength, uppercase, prefix, suffix); #else if (value & 0xFFFFFFFF00000000) { - return ZydisPrintHexU64(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix); + return ZydisPrintHexU64(s, value, paddingLength, uppercase, prefix, suffix); } else { - return ZydisPrintHexU32(buffer, bufferLen, (ZydisU32)value, paddingLength, uppercase, - prefix, suffix); + return ZydisPrintHexU32(s, (ZydisU32)value, paddingLength, uppercase, prefix, suffix); } #endif } -ZydisStatus ZydisPrintHexS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, ZydisU8 paddingLength, +ZydisStatus ZydisPrintHexS(ZydisString *s, ZydisI64 value, ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix) { if (value < 0) { - const char* bufEnd = *buffer + bufferLen; - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(s, "-", ZYDIS_LETTER_CASE_DEFAULT)); if (prefix) { - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, prefix, ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(s, prefix, ZYDIS_LETTER_CASE_DEFAULT)); } - return ZydisPrintHexU(buffer, bufEnd - *buffer, -value, paddingLength, uppercase, - ZYDIS_NULL, suffix); + return ZydisPrintHexU(s, -value, paddingLength, uppercase, ZYDIS_NULL, suffix); } - return ZydisPrintHexU(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix); + return ZydisPrintHexU(s, value, paddingLength, uppercase, prefix, suffix); } /* ---------------------------------------------------------------------------------------------- */ diff --git a/src/FormatHelper.h b/src/FormatHelper.h index 5395cc8..b6133bb 100644 --- a/src/FormatHelper.h +++ b/src/FormatHelper.h @@ -29,6 +29,8 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -77,22 +79,44 @@ enum ZydisLetterCases /* ---------------------------------------------------------------------------------------------- */ /** - * @brief Appends the given @c text to the @c buffer. + * @brief Appends the @c ZydisString to another @c ZydisString. * - * @param buffer A pointer to the string-buffer. - * @param bufferLen The length of the string-buffer. + * @param buffer The string to append to. + * @param text The string to append. + * @param letterCase The desired letter-case. + * + * @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or + * @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not + * sufficient to append the given @c text. + */ +ZYDIS_NO_EXPORT ZydisStatus ZydisStringAppend( + ZydisString* s, const ZydisString* text, ZydisLetterCase letterCase); + +/** + * @brief Appends the given C string to the @c ZydisString. + * + * @param s The string to append to. * @param text The text to append. * @param letterCase The desired letter-case. * * @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or * @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not * sufficient to append the given @c text. - * - * The string-buffer pointer is increased by the number of chars written, if the call was - * successfull. */ -ZYDIS_NO_EXPORT ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, const char* text, - ZydisLetterCase letterCase); +ZYDIS_INLINE ZydisStatus ZydisStringAppendC( + ZydisString* s, const char* text, ZydisLetterCase letterCase) +{ + ZYDIS_ASSERT(text); + + ZydisUSize len = ZydisStrLen(text); + ZydisString zyStr = { + .s = (char*)text, + .length = len, + .capacity = len + }; + + return ZydisStringAppend(s, &zyStr, letterCase); +} /* ---------------------------------------------------------------------------------------------- */ /* Decimal values */ @@ -100,10 +124,9 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, c /** * @brief Formats the given unsigned ordinal @c value to its decimal text-representation and - * appends it to the @c buffer. + * appends it to @c s. * - * @param buffer A pointer to the string-buffer. - * @param bufferLen The length of the string-buffer. + * @param s A pointer to the string. * @param value The value. * @param paddingLength Padds the converted value with leading zeros, if the number of chars is * less than the @c paddingLength. @@ -115,15 +138,13 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, c * The string-buffer pointer is increased by the number of chars written, if the call was * successfull. */ -ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, - ZydisU8 paddingLength); +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecU(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength); /** * @brief Formats the given signed ordinal @c value to its decimal text-representation and - * appends it to the @c buffer. + * appends it to @c s. * - * @param buffer A pointer to the string-buffer. - * @param bufferLen The length of the string-buffer. + * @param s A pointer to the string. * @param value The value. * @param paddingLength Padds the converted value with leading zeros, if the number of chars is * less than the @c paddingLength (the sign char is ignored). @@ -135,7 +156,7 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecU(char** buffer, ZydisUSize bufferLen, * The string-buffer pointer is increased by the number of chars written, if the call was * successfull. */ -ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(ZydisString* s, ZydisI64 value, ZydisU8 paddingLength); /* ---------------------------------------------------------------------------------------------- */ @@ -146,8 +167,7 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen, * @brief Formats the given unsigned ordinal @c value to its hexadecimal text-representation and * appends it to the @c buffer. * - * @param buffer A pointer to the string-buffer. - * @param bufferLen The length of the string-buffer. + * @param s A pointer to the string. * @param value The value. * @param paddingLength Padds the converted value with leading zeros, if the number of chars is * less than the @c paddingLength. @@ -163,15 +183,14 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen, * The string-buffer pointer is increased by the number of chars written, if the call was * successfull. */ -ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexU(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix); /** * @brief Formats the given signed ordinal @c value to its hexadecimal text-representation and * appends it to the @c buffer. * - * @param buffer A pointer to the string-buffer. - * @param bufferLen The length of the string-buffer. + * @param s A pointer to the string. * @param value The value. * @param paddingLength Padds the converted value with leading zeros, if the number of chars is * less than the @c paddingLength (the sign char is ignored). @@ -187,7 +206,7 @@ ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexU(char** buffer, ZydisUSize bufferLen, * The string-buffer pointer is increased by the number of chars written, if the call was * successfull. */ -ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexS(ZydisString* s, ZydisI64 value, ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix); /* ---------------------------------------------------------------------------------------------- */ diff --git a/src/Formatter.c b/src/Formatter.c index 75e9454..c719b0e 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -39,72 +39,70 @@ /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData) + ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) + if (!formatter || !buffer || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK) { - return ZydisPrintStr(buffer, bufferLen, "lock ", formatter->letterCase); + return ZydisStringAppendC(buffer, "lock ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REP) { - return ZydisPrintStr(buffer, bufferLen, "rep ", formatter->letterCase); + return ZydisStringAppendC(buffer, "rep ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPE) { - return ZydisPrintStr(buffer, bufferLen, "repe ", formatter->letterCase); + return ZydisStringAppendC(buffer, "repe ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE) { - return ZydisPrintStr(buffer, bufferLen, "repne ", formatter->letterCase); + return ZydisStringAppendC(buffer, "repne ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_BOUND) { - return ZydisPrintStr(buffer, bufferLen, "bnd ", formatter->letterCase); + return ZydisStringAppendC(buffer, "bnd ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE) { - return ZydisPrintStr(buffer, bufferLen, "xacquire ", formatter->letterCase); + return ZydisStringAppendC(buffer, "xacquire ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE) { - return ZydisPrintStr(buffer, bufferLen, "xrelease ", formatter->letterCase); + return ZydisStringAppendC(buffer, "xrelease ", formatter->letterCase); } return ZYDIS_STATUS_SUCCESS; } static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData) + ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) + if (!formatter || !buffer || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } - const char* bufEnd = *buffer + bufferLen; - const char* mnemonic = ZydisMnemonicGetString(instruction->mnemonic); if (!mnemonic) { mnemonic = "invalid"; } - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, mnemonic, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, mnemonic, formatter->letterCase)); if (instruction->attributes & ZYDIS_ATTRIB_IS_FAR_BRANCH) { - return ZydisPrintStr(buffer, bufEnd - *buffer, " far", formatter->letterCase); + return ZydisStringAppendC(buffer, " far", formatter->letterCase); } return ZYDIS_STATUS_SUCCESS; @@ -113,12 +111,12 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -133,21 +131,20 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for { reg = "invalid"; } - return ZydisPrintStr(buffer, bufferLen, reg, formatter->letterCase); + + return ZydisStringAppendC(buffer, reg, formatter->letterCase); } static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } - const char* bufEnd = *buffer + bufferLen; - - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, "[", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, "[", ZYDIS_LETTER_CASE_DEFAULT)); if (operand->mem.disp.hasDisplacement && ( (operand->mem.base == ZYDIS_REGISTER_NONE) || @@ -161,14 +158,14 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for { ZydisU64 address; ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); - ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, bufEnd - *buffer, - instruction, operand, address, userData)); + ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, instruction, operand, + address, userData)); } else { - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.base), formatter->letterCase)); - ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer, - instruction, operand, userData)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.base), + formatter->letterCase)); + ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, instruction, operand, + userData)); } } else { @@ -180,7 +177,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase)); } if ((operand->mem.index != ZYDIS_REGISTER_NONE) && (operand->mem.type != ZYDIS_MEMOP_TYPE_MIB)) @@ -193,47 +190,46 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for if (operand->mem.base != ZYDIS_REGISTER_NONE) { ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, "+", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, "+", ZYDIS_LETTER_CASE_DEFAULT)); } - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase)); if (operand->mem.scale) { ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, "*", ZYDIS_LETTER_CASE_DEFAULT)); - ZYDIS_CHECK(ZydisPrintDecU(buffer, bufEnd - *buffer, operand->mem.scale, 0)); + ZydisStringAppendC(buffer, "*", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisPrintDecU(buffer, operand->mem.scale, 0)); } } - ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer, + ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, instruction, operand, userData)); } - return ZydisPrintStr(buffer, bufEnd - *buffer, "]", ZYDIS_LETTER_CASE_DEFAULT); + return ZydisStringAppendC(buffer, "]", ZYDIS_LETTER_CASE_DEFAULT); } static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } - const char* bufEnd = *buffer + bufferLen; - ZYDIS_CHECK(ZydisPrintHexU(buffer, bufEnd - *buffer, operand->ptr.segment, 4, + ZYDIS_CHECK(ZydisPrintHexU(buffer, operand->ptr.segment, 4, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix)); - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT)); - return ZydisPrintHexU(buffer, bufEnd - *buffer, operand->ptr.offset, 8, + ZYDIS_CHECK(ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT)); + return ZydisPrintHexU(buffer, operand->ptr.offset, 8, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -248,7 +244,7 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for { ZydisU64 address; ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); - return formatter->funcPrintAddress(formatter, buffer, bufferLen, instruction, operand, + return formatter->funcPrintAddress(formatter, buffer, instruction, operand, address, userData); } case ZYDIS_ADDR_FORMAT_RELATIVE_SIGNED: @@ -262,29 +258,29 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for if (printSignedHEX) { - return ZydisPrintHexS(buffer, bufferLen, (ZydisI32)operand->imm.value.s, + return ZydisPrintHexS(buffer, (ZydisI32)operand->imm.value.s, formatter->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } - return ZydisPrintHexU(buffer, bufferLen, operand->imm.value.u, + return ZydisPrintHexU(buffer, operand->imm.value.u, formatter->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } // The immediate operand contains an actual ordinal value return formatter->funcPrintImmediate( - formatter, buffer, bufferLen, instruction, operand, userData); + formatter, buffer, instruction, operand, userData); } /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisU64 address, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -292,13 +288,13 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt switch (instruction->stackWidth) { case 16: - return ZydisPrintHexU(buffer, bufferLen, (ZydisU16)address, 4, + return ZydisPrintHexU(buffer, (ZydisU16)address, 4, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexU(buffer, bufferLen, (ZydisU32)address, 8, + return ZydisPrintHexU(buffer, (ZydisU32)address, 8, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexU(buffer, bufferLen, address, 16, + return ZydisPrintHexU(buffer, address, 16, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -306,12 +302,12 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt } static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -326,17 +322,16 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo (operand->mem.base != ZYDIS_REGISTER_NONE) || (operand->mem.index != ZYDIS_REGISTER_NONE))) { - return ZydisPrintHexS(buffer, bufferLen, operand->mem.disp.value, + return ZydisPrintHexS(buffer, operand->mem.disp.value, formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } - const char* bufEnd = *buffer + bufferLen; if ((operand->mem.base != ZYDIS_REGISTER_NONE) || (operand->mem.index != ZYDIS_REGISTER_NONE)) { - ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "+", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, "+", ZYDIS_LETTER_CASE_DEFAULT)); } - return ZydisPrintHexU(buffer, bufEnd - *buffer, (ZydisU64)operand->mem.disp.value, + return ZydisPrintHexU(buffer, (ZydisU64)operand->mem.disp.value, formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } @@ -344,12 +339,12 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo } static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -365,19 +360,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma switch (operand->size) { case 8: - return ZydisPrintHexS(buffer, bufferLen, (ZydisI8)operand->imm.value.s, + return ZydisPrintHexS(buffer, (ZydisI8)operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 16: - return ZydisPrintHexS(buffer, bufferLen, (ZydisI16)operand->imm.value.s, + return ZydisPrintHexS(buffer, (ZydisI16)operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexS(buffer, bufferLen, (ZydisI32)operand->imm.value.s, + return ZydisPrintHexS(buffer, (ZydisI32)operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexS(buffer, bufferLen, operand->imm.value.s, + return ZydisPrintHexS(buffer, operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: @@ -387,19 +382,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma switch (instruction->operandWidth) { case 8: - return ZydisPrintHexU(buffer, bufferLen, (ZydisU8)operand->imm.value.u, + return ZydisPrintHexU(buffer, (ZydisU8)operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 16: - return ZydisPrintHexU(buffer, bufferLen, (ZydisU16)operand->imm.value.u, + return ZydisPrintHexU(buffer, (ZydisU16)operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexU(buffer, bufferLen, (ZydisU32)operand->imm.value.u, + return ZydisPrintHexU(buffer, (ZydisU32)operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexU(buffer, bufferLen, operand->imm.value.u, + return ZydisPrintHexU(buffer, operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: @@ -410,12 +405,12 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -510,24 +505,23 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for if (str) { - return ZydisPrintStr(buffer, bufferLen, str, formatter->letterCase); + return ZydisStringAppendC(buffer, str, formatter->letterCase); } } return ZYDIS_STATUS_SUCCESS; } static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } - const char* bufEnd = *buffer + bufferLen; switch (operand->mem.segment) { case ZYDIS_REGISTER_ES: @@ -535,17 +529,17 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt case ZYDIS_REGISTER_FS: case ZYDIS_REGISTER_GS: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); - return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); + ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment), + formatter->letterCase)); + return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); case ZYDIS_REGISTER_SS: if ((formatter->forceSegments) || (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS)) { ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); - return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); + ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment), + formatter->letterCase)); + return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); } break; case ZYDIS_REGISTER_DS: @@ -553,9 +547,9 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS)) { ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, - ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); - return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); + ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment), + formatter->letterCase)); + return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); } break; default: @@ -565,17 +559,16 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt } static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* buffer, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData) { (void)userData; - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction || !operand) + if (!formatter || !buffer || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } - const char* bufEnd = *buffer + bufferLen; switch (type) { case ZYDIS_DECORATOR_TYPE_MASK: @@ -587,13 +580,13 @@ 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, formatter->letterCase)); - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, "}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, " {", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, "}", ZYDIS_LETTER_CASE_DEFAULT)); if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO) { ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {z}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {z}", ZYDIS_LETTER_CASE_DEFAULT)); } } break; @@ -607,27 +600,27 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma break; case ZYDIS_BROADCAST_MODE_1_TO_2: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {1to2}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {1to2}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_BROADCAST_MODE_1_TO_4: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {1to4}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {1to4}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_BROADCAST_MODE_1_TO_8: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {1to8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {1to8}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_BROADCAST_MODE_1_TO_16: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {1to16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {1to16}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_BROADCAST_MODE_4_TO_8: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {4to8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {4to8}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_BROADCAST_MODE_4_TO_16: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {4to16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {4to16}", ZYDIS_LETTER_CASE_DEFAULT)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -642,20 +635,20 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma case ZYDIS_ROUNDING_MODE_INVALID: break; case ZYDIS_ROUNDING_MODE_RN: - ZYDIS_CHECK(ZydisPrintStr( - buffer, bufEnd - *buffer, " {rn-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC( + buffer, " {rn-sae}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_ROUNDING_MODE_RD: - ZYDIS_CHECK(ZydisPrintStr( - buffer, bufEnd - *buffer, " {rd-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC( + buffer, " {rd-sae}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_ROUNDING_MODE_RU: - ZYDIS_CHECK(ZydisPrintStr( - buffer, bufEnd - *buffer, " {ru-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC( + buffer, " {ru-sae}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_ROUNDING_MODE_RZ: - ZYDIS_CHECK(ZydisPrintStr( - buffer, bufEnd - *buffer, " {rz-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC( + buffer, " {rz-sae}", ZYDIS_LETTER_CASE_DEFAULT)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -668,19 +661,19 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma break; case ZYDIS_ROUNDING_MODE_RN: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {rn}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {rn}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_ROUNDING_MODE_RD: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {rd}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {rd}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_ROUNDING_MODE_RU: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {ru}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {ru}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_ROUNDING_MODE_RZ: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {rz}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {rz}", ZYDIS_LETTER_CASE_DEFAULT)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -691,7 +684,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma if (instruction->avx.hasSAE && !instruction->avx.rounding.mode) { ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {sae}", ZYDIS_LETTER_CASE_DEFAULT)); } break; case ZYDIS_DECORATOR_TYPE_SWIZZLE: @@ -703,31 +696,31 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma break; case ZYDIS_SWIZZLE_MODE_CDAB: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {cdab}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {cdab}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_SWIZZLE_MODE_BADC: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {badc}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {badc}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_SWIZZLE_MODE_DACB: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {dacb}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {dacb}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_SWIZZLE_MODE_AAAA: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {aaaa}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {aaaa}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_SWIZZLE_MODE_BBBB: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {bbbb}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {bbbb}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_SWIZZLE_MODE_CCCC: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {cccc}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {cccc}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_SWIZZLE_MODE_DDDD: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {dddd}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {dddd}", ZYDIS_LETTER_CASE_DEFAULT)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -740,23 +733,23 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma break; case ZYDIS_CONVERSION_MODE_FLOAT16: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {float16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {float16}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_CONVERSION_MODE_SINT8: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {sint8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {sint8}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_CONVERSION_MODE_UINT8: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {uint8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {uint8}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_CONVERSION_MODE_SINT16: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {sint16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {sint16}", ZYDIS_LETTER_CASE_DEFAULT)); break; case ZYDIS_CONVERSION_MODE_UINT16: ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {uint16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {uint16}", ZYDIS_LETTER_CASE_DEFAULT)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -766,7 +759,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma if (instruction->avx.hasEvictionHint) { ZYDIS_CHECK( - ZydisPrintStr(buffer, bufEnd - *buffer, " {eh}", ZYDIS_LETTER_CASE_DEFAULT)); + ZydisStringAppendC(buffer, " {eh}", ZYDIS_LETTER_CASE_DEFAULT)); } break; default: @@ -777,20 +770,19 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma } static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter, - char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData) + ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData) { - if (!formatter || !buffer || !*buffer || (bufferLen <= 0) || !instruction) + if (!formatter || !buffer || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } - const char* bufEnd = *buffer + bufferLen; ZYDIS_CHECK( - formatter->funcPrintPrefixes(formatter, buffer, bufEnd - *buffer, instruction, userData)); + formatter->funcPrintPrefixes(formatter, buffer, instruction, userData)); ZYDIS_CHECK( - formatter->funcPrintMnemonic(formatter, buffer, bufEnd - *buffer, instruction, userData)); + formatter->funcPrintMnemonic(formatter, buffer, instruction, userData)); - char* bufRestore = *buffer; + ZydisUSize lenRestore = buffer->length; for (ZydisU8 i = 0; i < instruction->operandCount; ++i) { if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN) @@ -800,52 +792,51 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte if (i == 0) { - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " ", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(buffer, " ", ZYDIS_LETTER_CASE_DEFAULT)); } else { - bufRestore = *buffer; - ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT)); + lenRestore = buffer->length; + ZYDIS_CHECK(ZydisStringAppendC(buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT)); } - const char* bufPreOperand = *buffer; + ZydisUSize bufPreOperandLen = buffer->length; switch (instruction->operands[i].type) { case ZYDIS_OPERAND_TYPE_REGISTER: - ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, bufEnd - *buffer, + ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, instruction, &instruction->operands[i], userData)); break; case ZYDIS_OPERAND_TYPE_MEMORY: { - ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, bufEnd - *buffer, + ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, instruction, &instruction->operands[i], userData)); - ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, bufEnd - *buffer, + ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, instruction, &instruction->operands[i], userData)); - const char* bufTemp = *buffer; - ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, bufEnd - *buffer, + ZydisUSize lenTemp = buffer->length; + ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, instruction, &instruction->operands[i], userData)); - if (bufTemp == *buffer) + if (lenTemp == buffer->length) { - *buffer = (char*)bufPreOperand; + buffer->length = bufPreOperandLen; } break; } case ZYDIS_OPERAND_TYPE_POINTER: - ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, bufEnd - *buffer, + ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, instruction, &instruction->operands[i], userData)); break; case ZYDIS_OPERAND_TYPE_IMMEDIATE: - ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, bufEnd - *buffer, + ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, instruction, &instruction->operands[i], userData)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; } - if (bufPreOperand == *buffer) + if (lenRestore == buffer->length) { // Omit whole operand, if the buffer did not change during the formatting-callback - *buffer = bufRestore; - *buffer[0] = 0; + buffer->length = lenRestore; } else { if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || @@ -855,21 +846,21 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)) { ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - bufEnd - *buffer, instruction, &instruction->operands[i], + instruction, &instruction->operands[i], 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], + instruction, &instruction->operands[i], ZYDIS_DECORATOR_TYPE_BROADCAST, userData)); if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) { ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - bufEnd - *buffer, instruction, &instruction->operands[i], + instruction, &instruction->operands[i], ZYDIS_DECORATOR_TYPE_CONVERSION, userData)); ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - bufEnd - *buffer, instruction, &instruction->operands[i], + instruction, &instruction->operands[i], ZYDIS_DECORATOR_TYPE_EVICTION_HINT, userData)); } } else @@ -880,14 +871,14 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) { ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - bufEnd - *buffer, instruction, &instruction->operands[i], + instruction, &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SWIZZLE, userData)); } ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - bufEnd - *buffer, instruction, &instruction->operands[i], + instruction, &instruction->operands[i], ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, userData)); ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - bufEnd - *buffer, instruction, &instruction->operands[i], + instruction, &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SAE, userData)); } } @@ -1156,21 +1147,30 @@ ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter, const ZydisDecodedInstruction* instruction, char* buffer, ZydisUSize bufferLen, void* userData) { - if (!formatter || !instruction || !buffer || (bufferLen == 0)) + if (!formatter || !instruction || !buffer || !bufferLen) { return ZYDIS_STATUS_INVALID_PARAMETER; } + ZydisString str = { + .s = buffer, + .length = 0, + .capacity = bufferLen - 1 + }; + if (formatter->funcPre) { - ZYDIS_CHECK(formatter->funcPre(formatter, instruction, userData)); + ZYDIS_CHECK(formatter->funcPre(formatter, &str, instruction, userData)); } - ZYDIS_CHECK( - formatter->funcFormatInstruction(formatter, &buffer, bufferLen, instruction, userData)); + + ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, &str, instruction, userData)); + if (formatter->funcPost) { - return formatter->funcPost(formatter, instruction, userData); + ZYDIS_CHECK(formatter->funcPost(formatter, &str, instruction, userData)); } + + str.s[str.length] = 0; return ZYDIS_STATUS_SUCCESS; }