diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c35624..db6f0f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,15 +104,18 @@ target_sources("Zydis" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Mnemonic.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/SharedTypes.h" - "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h" + "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h" + "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/String.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Utils.h" "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h" PRIVATE + "src/LibC.h" "src/MetaInfo.c" "src/Mnemonic.c" "src/Register.c" "src/SharedData.h" "src/SharedData.c" + "src/String.c" "src/Utils.c" "src/Zydis.c") @@ -124,11 +127,9 @@ if (ZYDIS_FEATURE_DECODER) "${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h" PRIVATE "src/DecoderData.h" - "src/FormatHelper.h" "src/Decoder.c" "src/DecoderData.c" - "src/Formatter.c" - "src/FormatHelper.c") + "src/Formatter.c") endif () if (BUILD_SHARED_LIBS AND WIN32) @@ -148,9 +149,7 @@ install(DIRECTORY "include" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if (ZYDIS_BUILD_EXAMPLES) if (ZYDIS_FEATURE_DECODER) - add_executable("FormatterHooks" - "examples/FormatterHooks.c" - "examples/FormatHelper.h") + add_executable("FormatterHooks" "examples/FormatterHooks.c") target_link_libraries("FormatterHooks" "Zydis") set_target_properties("FormatterHooks" PROPERTIES FOLDER "Examples/Formatter") target_compile_definitions("FormatterHooks" PRIVATE "_CRT_SECURE_NO_WARNINGS") diff --git a/examples/FormatHelper.h b/examples/FormatHelper.h deleted file mode 100644 index 481d922..0000000 --- a/examples/FormatHelper.h +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************************************** - - Zyan Disassembler Engine (Zydis) - - Original Author : Florian Bernd - - * 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_FORMATHELPER_H -#define ZYDIS_FORMATHELPER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -/* ============================================================================================== */ -/* Format helper functions */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Enums and types */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Defines the @c ZydisStringBufferAppendMode datatype. - */ -typedef uint8_t ZydisStringBufferAppendMode; - -/** - * @brief Values that represent zydis string-buffer append-modes. - */ -enum ZydisStringBufferAppendModes -{ - /** - * @brief Appends the string as it is. - */ - ZYDIS_STRBUF_APPEND_MODE_DEFAULT, - /** - * @brief Converts the string to lowercase characters. - */ - ZYDIS_STRBUF_APPEND_MODE_LOWERCASE, - /** - * @brief Converts the string to uppercase characters. - */ - ZYDIS_STRBUF_APPEND_MODE_UPPERCASE -}; - -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Appends the @c text to the given @c buffer and increases the string-buffer pointer by - * the number of chars written. - * - * @param buffer A pointer to the string-buffer. - * @param bufferLen The length of the string-buffer. - * @param mode The append-mode. - * @param text The text to append. - * - * @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_INLINE ZydisStatus ZydisStringBufferAppend(char** buffer, size_t bufferLen, - ZydisStringBufferAppendMode mode, const char* text) -{ - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen != 0); - ZYDIS_ASSERT(text); - - size_t strLen = strlen(text); - if (strLen >= bufferLen) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - strncpy(*buffer, text, strLen + 1); - switch (mode) - { - case ZYDIS_STRBUF_APPEND_MODE_LOWERCASE: - for (size_t i = 0; i < strLen; ++i) - { - (*buffer[i]) = (char)tolower((*buffer)[i]); - } - break; - case ZYDIS_STRBUF_APPEND_MODE_UPPERCASE: - for (size_t i = 0; i < strLen; ++i) - { - (*buffer)[i] = (char)toupper((*buffer)[i]); - } - break; - default: - break; - } - *buffer += strLen; - return ZYDIS_STATUS_SUCCESS; -} - -/** - * @brief Appends formatted text to the given @c buffer and increases the string-buffer pointer - * by the number of chars written. - * - * @param buffer A pointer to the string-buffer. - * @param bufferLen The length of the string-buffer. - * @param mode The append-mode. - * @param format The format string. - * - * @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 text. - */ -ZYDIS_INLINE ZydisStatus ZydisStringBufferAppendFormat(char** buffer, size_t bufferLen, - ZydisStringBufferAppendMode mode, const char* format, ...) -{ - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen != 0); - ZYDIS_ASSERT(format); - - va_list arglist; - va_start(arglist, format); - int w = vsnprintf(*buffer, bufferLen, format, arglist); - if ((w < 0) || ((size_t)w >= bufferLen)) - { - va_end(arglist); - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - switch (mode) - { - case ZYDIS_STRBUF_APPEND_MODE_LOWERCASE: - for (size_t i = 0; i < (size_t)w; ++i) - { - (*buffer)[i] = (char)tolower((*buffer)[i]); - } - break; - case ZYDIS_STRBUF_APPEND_MODE_UPPERCASE: - for (size_t i = 0; i < (size_t)w; ++i) - { - (*buffer)[i] = (char)toupper((*buffer)[i]); - } - break; - default: - break; - } - *buffer += (size_t)w; - va_end(arglist); - return ZYDIS_STATUS_SUCCESS; -} - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ - -#endif /* ZYDIS_FORMATHELPER_H */ diff --git a/examples/FormatterHooks.c b/examples/FormatterHooks.c index 0faa231..7a3b73e 100644 --- a/examples/FormatterHooks.c +++ b/examples/FormatterHooks.c @@ -33,10 +33,46 @@ * the condition encoded in the immediate operand). */ +#include +#include #include #include #include -#include "FormatHelper.h" + +/* ============================================================================================== */ +/* Helper functions */ +/* ============================================================================================== */ + +/** + * @brief Appends formatted text to the given `string`. + * + * @param string A pointer to the string. + * @param format The format string. + * + * @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 text. + */ +ZYDIS_INLINE ZydisStatus ZydisStringAppendFormatC(ZydisString* string, const char* format, ...) +{ + if (!string || !string->buffer || !format) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + va_list arglist; + va_start(arglist, format); + const int w = vsnprintf(string->buffer + string->length, string->capacity - string->length, + format, arglist); + if ((w < 0) || ((size_t)w > string->capacity - string->length)) + { + va_end(arglist); + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + string->length += w; + va_end(arglist); + return ZYDIS_STATUS_SUCCESS; +} /* ============================================================================================== */ /* Static data */ @@ -100,8 +136,7 @@ typedef struct ZydisCustomUserData_ ZydisFormatterFormatFunc defaultPrintMnemonic; static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, - ZydisCustomUserData* userData) + ZydisString* string, const ZydisDecodedInstruction* instruction, ZydisCustomUserData* userData) { // We use the user-data to pass data to the @c ZydisFormatterFormatOperandImm function. userData->ommitImmediate = ZYDIS_TRUE; @@ -109,40 +144,36 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, // Rewrite the instruction-mnemonic for the given instructions if (instruction->operands[instruction->operandCount - 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) { - uint8_t conditionCode = + const uint8_t conditionCode = (uint8_t)instruction->operands[instruction->operandCount - 1].imm.value.u; switch (instruction->mnemonic) { case ZYDIS_MNEMONIC_CMPPS: if (conditionCode < 0x08) { - return ZydisStringBufferAppendFormat(buffer, bufferLen, - ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%sps", - conditionCodeStrings[conditionCode]); + return ZydisStringAppendFormatC( + string, "cmp%sps", conditionCodeStrings[conditionCode]); } break; case ZYDIS_MNEMONIC_CMPPD: if (conditionCode < 0x08) { - return ZydisStringBufferAppendFormat(buffer, bufferLen, - ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%spd", - conditionCodeStrings[conditionCode]); + return ZydisStringAppendFormatC( + string, "cmp%spd", conditionCodeStrings[conditionCode]); } break; case ZYDIS_MNEMONIC_VCMPPS: if (conditionCode < 0x20) { - return ZydisStringBufferAppendFormat(buffer, bufferLen, - ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%sps", - conditionCodeStrings[conditionCode]); + return ZydisStringAppendFormatC( + string, "vcmp%sps", conditionCodeStrings[conditionCode]); } break; case ZYDIS_MNEMONIC_VCMPPD: if (conditionCode < 0x20) { - return ZydisStringBufferAppendFormat(buffer, bufferLen, - ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%spd", - conditionCodeStrings[conditionCode]); + return ZydisStringAppendFormatC( + string, "vcmp%spd", conditionCodeStrings[conditionCode]); } break; default: @@ -155,7 +186,7 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, userData->ommitImmediate = ZYDIS_FALSE; // Default mnemonic printing - return defaultPrintMnemonic(formatter, buffer, bufferLen, instruction, userData); + return defaultPrintMnemonic(formatter, string, instruction, userData); } /* ---------------------------------------------------------------------------------------------- */ @@ -163,7 +194,7 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter, ZydisFormatterFormatOperandFunc defaultFormatOperandImm; static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter, - char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisCustomUserData* userData) { // The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code) @@ -176,7 +207,7 @@ static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatte } // Default immediate formatting - return defaultFormatOperandImm(formatter, buffer, bufferLen, instruction, operand, userData); + return defaultFormatOperandImm(formatter, string, instruction, operand, userData); } /* ---------------------------------------------------------------------------------------------- */ diff --git a/include/Zydis/Defines.h b/include/Zydis/Defines.h index 44341cd..7b92399 100644 --- a/include/Zydis/Defines.h +++ b/include/Zydis/Defines.h @@ -178,6 +178,11 @@ */ #define ZYDIS_BITFIELD(x) : x +/** + * @brief Marks the specified parameter as unused. + */ +#define ZYDIS_UNUSED_PARAMETER(x) (void)(x) + /** * @brief Calculates the size of an array. */ diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index 8b29588..dfd2dc4 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -404,6 +404,7 @@ typedef struct ZydisFormatter_ ZydisFormatter; * @brief Defines the @c ZydisFormatterNotifyFunc function pointer. * * @param formatter A pointer to the @c ZydisFormatter instance. + * @param string A pointer to the string. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param userData A pointer to user-defined data. * @@ -414,33 +415,30 @@ typedef struct ZydisFormatter_ ZydisFormatter; * @c ZYDIS_FORMATTER_HOOK_POST hook-types. */ typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData); + ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData); /** * @brief Defines the @c ZydisFormatterFormatFunc function pointer. * * @param formatter A pointer to the @c ZydisFormatter instance. - * @param str A pointer to the string buffer. + * @param string A pointer to the string. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param userData A pointer to user-defined data. * * @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the * 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. Not increasing the buffer-pointer will cause unexpected behavior. * * This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION, * @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types. */ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData); + ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData); /** * @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer. * * @param formatter A pointer to the @c ZydisFormatter instance. - * @param str A pointer to the string buffer. + * @param string A pointer to the string. * @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. @@ -448,19 +446,14 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, * @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 in one of the @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_X hooks - * without increasing the buffer-pointer is valid and will cause the formatter to omit the current + * without writing to the string is valid and will cause the formatter to omit the current * operand. * * Returning @c ZYDIS_STATUS_SUCCESS in @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE, * @c ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT or @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR without - * increasing the buffer-pointer is valid and signals that the corresponding element should not be + * writing to the string is valid and signals that the corresponding element should not be * printed for the current operand. - * - * Not increasing the buffer-pointer for any other hook-type will cause unexpected behavior. * * This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG, * @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM, @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR, @@ -470,36 +463,32 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter, * hook-types. */ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, 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 str A pointer to the string buffer. + * @param string A pointer to the string. * @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. * * @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. - * Not increasing the buffer-pointer will cause unexpected behavior. * * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type. */ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, 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 str A pointer to the string buffer. + * @param string A pointer to the string. * @param instruction A pointer to the @c ZydisDecodedInstruction struct. * @param operand A pointer to the @c ZydisDecodedOperand struct. * @param type The decorator type. @@ -508,16 +497,13 @@ typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* for * @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 the current decorator. + * Returning @c ZYDIS_STATUS_SUCCESS without writing to the string is valid and will cause the + * formatter to omit the current decorator. * * This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type. */ typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData); /* ---------------------------------------------------------------------------------------------- */ @@ -536,8 +522,10 @@ struct ZydisFormatter_ ZydisU8 displacementFormat; ZydisU8 immediateFormat; ZydisBool hexUppercase; - char* hexPrefix; - char* hexSuffix; + ZydisString* hexPrefix; + ZydisString hexPrefixData; + ZydisString* hexSuffix; + ZydisString hexSuffixData; ZydisU8 hexPaddingAddress; ZydisU8 hexPaddingDisplacement; ZydisU8 hexPaddingImmediate; diff --git a/src/LibC.h b/include/Zydis/Internal/LibC.h similarity index 100% rename from src/LibC.h rename to include/Zydis/Internal/LibC.h diff --git a/include/Zydis/Mnemonic.h b/include/Zydis/Mnemonic.h index 527532e..6afcf99 100644 --- a/include/Zydis/Mnemonic.h +++ b/include/Zydis/Mnemonic.h @@ -32,8 +32,9 @@ #ifndef ZYDIS_MNEMONIC_H #define ZYDIS_MNEMONIC_H -#include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -58,6 +59,15 @@ extern "C" { */ ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic); +/** + * @brief Returns the specified instruction mnemonic as `ZydisString`. + * + * @param mnemonic The mnemonic. + * + * @return The instruction mnemonic string or @c NULL, if an invalid mnemonic was passed. + */ +ZYDIS_EXPORT const ZydisString* ZydisMnemonicGetStringEx(ZydisMnemonic mnemonic); + /* ============================================================================================== */ #ifdef __cplusplus diff --git a/include/Zydis/Status.h b/include/Zydis/Status.h index aec256e..fa5abb3 100644 --- a/include/Zydis/Status.h +++ b/include/Zydis/Status.h @@ -164,10 +164,10 @@ enum ZydisStatusCodes #define ZYDIS_CHECK(status) \ do \ { \ - ZydisStatus status_w4587ntvmEgDG = status; \ - if (!ZYDIS_SUCCESS(status_w4587ntvmEgDG)) \ + ZydisStatus status_038560234 = status; \ + if (!ZYDIS_SUCCESS(status_038560234)) \ { \ - return status_w4587ntvmEgDG; \ + return status_038560234; \ } \ } while (0) diff --git a/include/Zydis/String.h b/include/Zydis/String.h index bb18e77..a5855bf 100644 --- a/include/Zydis/String.h +++ b/include/Zydis/String.h @@ -2,7 +2,7 @@ Zyan Disassembler Library (Zydis) - Original Author : Joel Höner + Original Author : Florian Bernd, 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 @@ -28,18 +28,284 @@ #define ZYDIS_STRING_H #include +#include +#include /* ============================================================================================== */ -/* String struct */ +/* Enums and types */ /* ============================================================================================== */ +/* ---------------------------------------------------------------------------------------------- */ +/* String */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @brief Defines the `ZydisString` struct. + */ typedef struct ZydisString_ { - char *s; // NOT always 0-terminated! + /** + * @brief The buffer that contains the actual string (0-termination is optional!). + */ + char *buffer; + /** + * @brief The length of the string (without any optional 0). + */ ZydisUSize length; - ZydisUSize capacity; // always -1 for 0 byte + /** + * @brief The total buffer capacity. + */ + ZydisUSize capacity; } ZydisString; + +/* ---------------------------------------------------------------------------------------------- */ +/* Letter Case */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @brief Defines the `ZydisLetterCase` datatype. + */ +typedef ZydisU8 ZydisLetterCase; + +/** + * @brief Values that represent letter cases. + */ +enum ZydisLetterCases +{ + /** + * @brief Uses the given text "as it is". + */ + ZYDIS_LETTER_CASE_DEFAULT, + /** + * @brief Converts the given text to lowercase letters. + */ + ZYDIS_LETTER_CASE_LOWER, + /** + * @brief Converts the given text to uppercase letters. + */ + ZYDIS_LETTER_CASE_UPPER, + + /** + * @brief Maximum value of this enum. + */ + ZYDIS_LETTER_CASE_MAX_VALUE = ZYDIS_LETTER_CASE_UPPER +}; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Macros */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Helper Macros */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @brief Creates a `ZydisString` struct from a constant C-string. + * + * @param string The C-string constant. + */ +#define ZYDIS_MAKE_STRING(string) \ + { (char*)string, sizeof(string) - 1, sizeof(string) - 1 } + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Basic Operations */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @brief Initializes a `ZydisString` struct with a C-string. + * + * @param string The string to initialize. + * @param value The C-string constant. + * + * @return A zydis status code. + */ +ZYDIS_NO_EXPORT ZYDIS_INLINE ZydisStatus ZydisStringInit(ZydisString* string, char* value) +{ + if (!string || !value) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + string->buffer = value; + string->length = ZydisStrLen(value); + string->capacity = ZydisStrLen(value); + + return ZYDIS_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @brief Appends a `ZydisString` to another `ZydisString` after converting it to the specified + * letter-case. + * + * @param string The string to append to. + * @param text The string to append. + * @param letterCase The letter case to use. + * + * @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 ZydisStringAppendEx(ZydisString* string, const ZydisString* text, + ZydisLetterCase letterCase); + +/** + * @brief Appends the given C-string to a `ZydisString` after converting it to the specified + * letter-case. + * + * @param string The string to append to. + * @param text The C-string to append. + * @param letterCase The letter case to use. + * + * @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 ZYDIS_INLINE ZydisStatus ZydisStringAppendExC(ZydisString* string, + const char* text, ZydisLetterCase letterCase) +{ + ZydisString other; + ZYDIS_CHECK(ZydisStringInit(&other, (char*)text)); + + return ZydisStringAppendEx(string, &other, letterCase); +} + +/** + * @brief Appends a `ZydisString` to another `ZydisString`. + * + * @param string The string to append to. + * @param text The string to append. + * + * @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 ZYDIS_INLINE ZydisStatus ZydisStringAppend(ZydisString* string, + const ZydisString* text) +{ + return ZydisStringAppendEx(string, text, ZYDIS_LETTER_CASE_DEFAULT); +} + +/** + * @brief Appends the given C-string to a `ZydisString`. + * + * @param string The string to append to. + * @param text The C-string to append. + * + * @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 ZYDIS_INLINE ZydisStatus ZydisStringAppendC(ZydisString* string, const char* text) +{ + ZydisString other; + ZYDIS_CHECK(ZydisStringInit(&other, (char*)text)); + + return ZydisStringAppend(string, &other); +} + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatting */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * @brief Formats the given unsigned ordinal @c value to its decimal text-representation and + * appends it to @c s. + * + * @param string 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. + * + * @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 value. + * + * The string-buffer pointer is increased by the number of chars written, if the call was + * successfull. + */ +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecU(ZydisString* string, ZydisU64 value, + ZydisU8 paddingLength); + +/** + * @brief Formats the given signed ordinal @c value to its decimal text-representation and + * appends it to @c s. + * + * @param string 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). + * + * @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 value. + * + * The string-buffer pointer is increased by the number of chars written, if the call was + * successfull. + */ +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(ZydisString* string, ZydisI64 value, + ZydisU8 paddingLength); + +/** + * @brief Formats the given unsigned ordinal @c value to its hexadecimal text-representation and + * appends it to the @c buffer. + * + * @param string 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. + * @param uppercase Set @c TRUE to print the hexadecimal value in uppercase letters instead + * of lowercase ones. + * @param prefix The string to use as prefix or `NULL`, if not needed. + * @param suffix The string to use as suffix or `NULL`, if not needed. + * + * @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 value. + * + * The string-buffer pointer is increased by the number of chars written, if the call was + * successfull. + */ +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexU(ZydisString* string, ZydisU64 value, + ZydisU8 paddingLength, ZydisBool uppercase, const ZydisString* prefix, + const ZydisString* suffix); + +/** + * @brief Formats the given signed ordinal @c value to its hexadecimal text-representation and + * appends it to the @c buffer. + * + * @param string 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). + * @param uppercase Set @c TRUE to print the hexadecimal value in uppercase letters instead + * of lowercase ones. + * @param prefix The string to use as prefix or `NULL`, if not needed. + * @param suffix The string to use as suffix or `NULL`, if not needed. + * + * @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 value. + * + * The string-buffer pointer is increased by the number of chars written, if the call was + * successfull. + */ +ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexS(ZydisString* string, ZydisI64 value, + ZydisU8 paddingLength, ZydisBool uppercase, const ZydisString* prefix, + const ZydisString* suffix); + +/* ---------------------------------------------------------------------------------------------- */ + /* ============================================================================================== */ #endif // ZYDIS_STRING_H diff --git a/include/Zydis/Zydis.h b/include/Zydis/Zydis.h index 67d6f52..417c3cd 100644 --- a/include/Zydis/Zydis.h +++ b/include/Zydis/Zydis.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #ifdef __cplusplus diff --git a/src/Decoder.c b/src/Decoder.c index 2a64174..752fbde 100644 --- a/src/Decoder.c +++ b/src/Decoder.c @@ -26,9 +26,9 @@ #include #include +#include #include #include -#include /* ============================================================================================== */ /* Internal enums and types */ diff --git a/src/DecoderData.c b/src/DecoderData.c index f65f2d4..c0d9b91 100644 --- a/src/DecoderData.c +++ b/src/DecoderData.c @@ -368,7 +368,7 @@ void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node, const ZydisInstructionEncodingInfo** info) { ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK); - ZydisU8 class = (node->type) & 0x7F; + const ZydisU8 class = (node->type) & 0x7F; ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(instructionEncodings)); *info = &instructionEncodings[class]; } diff --git a/src/FormatHelper.c b/src/FormatHelper.c deleted file mode 100644 index b9e4250..0000000 --- a/src/FormatHelper.c +++ /dev/null @@ -1,302 +0,0 @@ -/*************************************************************************************************** - - Zyan Disassembler Library (Zydis) - - Original Author : Florian Bernd, 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. - -***************************************************************************************************/ - -#include - -/* ============================================================================================== */ -/* Constants */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Defines */ -/* ---------------------------------------------------------------------------------------------- */ - -#define ZYDIS_MAXCHARS_DEC_32 10 -#define ZYDIS_MAXCHARS_DEC_64 20 -#define ZYDIS_MAXCHARS_HEX_32 8 -#define ZYDIS_MAXCHARS_HEX_64 16 - -/* ---------------------------------------------------------------------------------------------- */ -/* Lookup Tables */ -/* ---------------------------------------------------------------------------------------------- */ - -static const char* decimalLookup = - "00010203040506070809" - "10111213141516171819" - "20212223242526272829" - "30313233343536373839" - "40414243444546474849" - "50515253545556575859" - "60616263646566676869" - "70717273747576777879" - "80818283848586878889" - "90919293949596979899"; - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ -/* Functions */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Internal Functions */ -/* ---------------------------------------------------------------------------------------------- */ - -void ZydisToLowerCase(char* buffer, ZydisUSize bufferLen) -{ - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen); - - const signed char rebase = 'a' - 'A'; - for (ZydisUSize i = 0; i < bufferLen; ++i) - { - char* c = buffer + i; - if ((*c >= 'A') && (*c <= 'Z')) - { - *c += rebase; - } - } -} - -void ZydisToUpperCase(char* buffer, ZydisUSize bufferLen) -{ - ZYDIS_ASSERT(buffer); - ZYDIS_ASSERT(bufferLen); - - const signed char rebase = 'A' - 'a'; - for (ZydisUSize i = 0; i < bufferLen; ++i) - { - char* c = buffer + i; - if ((*c >= 'a') && (*c <= 'z')) - { - *c += rebase; - } - } -} - -ZydisStatus ZydisPrintDecU64(ZydisString* s, ZydisU64 value, ZydisU8 paddingLength) -{ - ZYDIS_ASSERT(s); - - char temp[ZYDIS_MAXCHARS_DEC_64 + 1]; - char *p = &temp[ZYDIS_MAXCHARS_DEC_64]; - - while (value >= 100) - { - const ZydisU64 old = value; - p -= 2; - value /= 100; - ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], 2); - } - p -= 2; - ZydisMemoryCopy(p, &decimalLookup[value * 2], 2); - - const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_64] - p; - if ((s->capacity - s->length < (ZydisUSize)(n + 1)) || - (s->capacity - s->length < (ZydisUSize)(paddingLength + 1))) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - - ZydisUSize offset = 0; - if (n <= paddingLength) - { - offset = paddingLength - n + 1; - ZydisMemorySet(s->s + s->length, '0', offset); - } - - ZydisMemoryCopy(s->s + s->length + offset, &p[value < 10], n + 1); - s->length += n + offset - (ZydisU8)(value < 10); - - 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 ZydisStringAppend(ZydisString* s, const ZydisString* text, ZydisLetterCase letterCase) -{ - ZYDIS_ASSERT(s); - ZYDIS_ASSERT(s->capacity >= s->length); - ZYDIS_ASSERT(text); - ZYDIS_ASSERT(text->capacity >= s->length); - - if (s->length + text->length >= s->capacity) - { - return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; - } - - ZydisMemoryCopy(s->s + s->length, text->s, text->length); - - switch (letterCase) - { - case ZYDIS_LETTER_CASE_DEFAULT: - break; - case ZYDIS_LETTER_CASE_LOWER: - ZydisToLowerCase(s->s + s->length, text->length); - break; - case ZYDIS_LETTER_CASE_UPPER: - ZydisToUpperCase(s->s + s->length, text->length); - break; - default: - ZYDIS_UNREACHABLE; - } - - s->length += text->length; - return ZYDIS_STATUS_SUCCESS; -} - -ZydisStatus ZydisPrintDecU(ZydisString *s, ZydisU64 value, ZydisU8 paddingLength) -{ -#if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64) - return ZydisPrintDecU64(s, value, paddingLength); -#else - if (value & 0xFFFFFFFF00000000) - { - return ZydisPrintDecU64(s, value, paddingLength); - } else - { - return ZydisPrintDecU32(s, (ZydisU32)value, paddingLength); - } -#endif -} - -ZydisStatus ZydisPrintDecS(ZydisString *s, ZydisI64 value, ZydisU8 paddingLength) -{ - if (value < 0) - { - ZYDIS_CHECK(ZydisStringAppendC(s, "-", ZYDIS_LETTER_CASE_DEFAULT)); - return ZydisPrintDecU(s, -value, paddingLength); - } - return ZydisPrintDecU(s, value, 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(s, value, paddingLength, uppercase, prefix, suffix); -#else - if (value & 0xFFFFFFFF00000000) - { - return ZydisPrintHexU64(s, value, paddingLength, uppercase, prefix, suffix); - } else - { - return ZydisPrintHexU32(s, (ZydisU32)value, paddingLength, uppercase, prefix, suffix); - } -#endif -} - -ZydisStatus ZydisPrintHexS(ZydisString *s, ZydisI64 value, ZydisU8 paddingLength, - ZydisBool uppercase, const char* prefix, const char* suffix) -{ - if (value < 0) - { - ZYDIS_CHECK(ZydisStringAppendC(s, "-", ZYDIS_LETTER_CASE_DEFAULT)); - if (prefix) - { - ZYDIS_CHECK(ZydisStringAppendC(s, prefix, ZYDIS_LETTER_CASE_DEFAULT)); - } - return ZydisPrintHexU(s, -value, paddingLength, uppercase, ZYDIS_NULL, suffix); - } - return ZydisPrintHexU(s, value, paddingLength, uppercase, prefix, suffix); -} - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ diff --git a/src/FormatHelper.h b/src/FormatHelper.h deleted file mode 100644 index b6133bb..0000000 --- a/src/FormatHelper.h +++ /dev/null @@ -1,220 +0,0 @@ -/*************************************************************************************************** - - Zyan Disassembler Library (Zydis) - - Original Author : Florian Bernd, 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_FORMATHELPER_H -#define ZYDIS_FORMATHELPER_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* ============================================================================================== */ -/* Enums and types */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* Letter Case */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Defines the `ZydisLetterCase` datatype. - */ -typedef ZydisU8 ZydisLetterCase; - -/** - * @brief Values that represent letter cases. - */ -enum ZydisLetterCases -{ - /** - * @brief Prints the given text "as it is". - */ - ZYDIS_LETTER_CASE_DEFAULT, - /** - * @brief Prints the given text in lowercase letters. - */ - ZYDIS_LETTER_CASE_LOWER, - /** - * @brief Prints the given text in uppercase letters. - */ - ZYDIS_LETTER_CASE_UPPER -}; - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ -/* Functions */ -/* ============================================================================================== */ - -/* ---------------------------------------------------------------------------------------------- */ -/* String */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Appends the @c ZydisString to another @c ZydisString. - * - * @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. - */ -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 */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Formats the given unsigned ordinal @c value to its decimal text-representation and - * appends it to @c s. - * - * @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. - * - * @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 value. - * - * The string-buffer pointer is increased by the number of chars written, if the call was - * successfull. - */ -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 @c s. - * - * @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). - * - * @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 value. - * - * The string-buffer pointer is increased by the number of chars written, if the call was - * successfull. - */ -ZYDIS_NO_EXPORT ZydisStatus ZydisPrintDecS(ZydisString* s, ZydisI64 value, - ZydisU8 paddingLength); - -/* ---------------------------------------------------------------------------------------------- */ -/* Hexadecimal values */ -/* ---------------------------------------------------------------------------------------------- */ - -/** - * @brief Formats the given unsigned ordinal @c value to its hexadecimal text-representation and - * appends it to the @c 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. - * @param uppercase Set @c TRUE to print the hexadecimal value in uppercase letters instead - * of lowercase ones. - * @param prefix The string to use as prefix or `NULL`, if not needed. - * @param suffix The string to use as suffix or `NULL`, if not needed. - * - * @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 value. - * - * The string-buffer pointer is increased by the number of chars written, if the call was - * successfull. - */ -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 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). - * @param uppercase Set @c TRUE to print the hexadecimal value in uppercase letters instead - * of lowercase ones. - * @param prefix The string to use as prefix or `NULL`, if not needed. - * @param suffix The string to use as suffix or `NULL`, if not needed. - * - * @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 value. - * - * The string-buffer pointer is increased by the number of chars written, if the call was - * successfull. - */ -ZYDIS_NO_EXPORT ZydisStatus ZydisPrintHexS(ZydisString* s, ZydisI64 value, - ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix); - -/* ---------------------------------------------------------------------------------------------- */ - -/* ============================================================================================== */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZYDIS_FORMATHELPER_H */ diff --git a/src/Formatter.c b/src/Formatter.c index c719b0e..6fa78fb 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -2,7 +2,7 @@ Zyan Disassembler Library (Zydis) - Original Author : Florian Bernd + Original Author : Florian Bernd, 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 @@ -27,8 +27,6 @@ #include #include #include -#include -#include /* ============================================================================================== */ /* Instruction formatter */ @@ -39,70 +37,70 @@ /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData) + ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction) + if (!formatter || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK) { - return ZydisStringAppendC(buffer, "lock ", formatter->letterCase); + return ZydisStringAppendExC(string, "lock ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REP) { - return ZydisStringAppendC(buffer, "rep ", formatter->letterCase); + return ZydisStringAppendExC(string, "rep ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPE) { - return ZydisStringAppendC(buffer, "repe ", formatter->letterCase); + return ZydisStringAppendExC(string, "repe ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE) { - return ZydisStringAppendC(buffer, "repne ", formatter->letterCase); + return ZydisStringAppendExC(string, "repne ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_BOUND) { - return ZydisStringAppendC(buffer, "bnd ", formatter->letterCase); + return ZydisStringAppendExC(string, "bnd ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE) { - return ZydisStringAppendC(buffer, "xacquire ", formatter->letterCase); + return ZydisStringAppendExC(string, "xacquire ", formatter->letterCase); } if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE) { - return ZydisStringAppendC(buffer, "xrelease ", formatter->letterCase); + return ZydisStringAppendExC(string, "xrelease ", formatter->letterCase); } return ZYDIS_STATUS_SUCCESS; } static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData) + ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction) + if (!formatter || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } - const char* mnemonic = ZydisMnemonicGetString(instruction->mnemonic); + const ZydisString* mnemonic = ZydisMnemonicGetStringEx(instruction->mnemonic); if (!mnemonic) { - mnemonic = "invalid"; + return ZydisStringAppendExC(string, "invalid", formatter->letterCase); } - ZYDIS_CHECK(ZydisStringAppendC(buffer, mnemonic, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendEx(string, mnemonic, formatter->letterCase)); if (instruction->attributes & ZYDIS_ATTRIB_IS_FAR_BRANCH) { - return ZydisStringAppendC(buffer, " far", formatter->letterCase); + return ZydisStringAppendExC(string, " far", formatter->letterCase); } return ZYDIS_STATUS_SUCCESS; @@ -111,12 +109,12 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -129,22 +127,21 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for const char* reg = ZydisRegisterGetString(operand->reg.value); if (!reg) { - reg = "invalid"; + return ZydisStringAppendExC(string, "invalid", formatter->letterCase); } - - return ZydisStringAppendC(buffer, reg, formatter->letterCase); + return ZydisStringAppendExC(string, reg, formatter->letterCase); } static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZYDIS_CHECK(ZydisStringAppendC(buffer, "[", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, "[")); if (operand->mem.disp.hasDisplacement && ( (operand->mem.base == ZYDIS_REGISTER_NONE) || @@ -158,13 +155,13 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for { ZydisU64 address; ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); - ZYDIS_CHECK(formatter->funcPrintAddress(formatter, buffer, instruction, operand, + ZYDIS_CHECK(formatter->funcPrintAddress(formatter, string, instruction, operand, address, userData)); } else { - ZYDIS_CHECK(ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.base), + ZYDIS_CHECK(ZydisStringAppendExC(string, ZydisRegisterGetString(operand->mem.base), formatter->letterCase)); - ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, instruction, operand, + ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, string, instruction, operand, userData)); } } else @@ -177,7 +174,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendExC(string, reg, formatter->letterCase)); } if ((operand->mem.index != ZYDIS_REGISTER_NONE) && (operand->mem.type != ZYDIS_MEMOP_TYPE_MIB)) @@ -189,47 +186,45 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for } if (operand->mem.base != ZYDIS_REGISTER_NONE) { - ZYDIS_CHECK( - ZydisStringAppendC(buffer, "+", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, "+")); } - ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendExC(string, reg, formatter->letterCase)); if (operand->mem.scale) { - ZYDIS_CHECK( - ZydisStringAppendC(buffer, "*", ZYDIS_LETTER_CASE_DEFAULT)); - ZYDIS_CHECK(ZydisPrintDecU(buffer, operand->mem.scale, 0)); + ZYDIS_CHECK(ZydisStringAppendC(string, "*")); + ZYDIS_CHECK(ZydisPrintDecU(string, operand->mem.scale, 0)); } } - ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, - instruction, operand, userData)); + ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, string, instruction, operand, + userData)); } - return ZydisStringAppendC(buffer, "]", ZYDIS_LETTER_CASE_DEFAULT); + return ZydisStringAppendC(string, "]"); } static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZYDIS_CHECK(ZydisPrintHexU(buffer, operand->ptr.segment, 4, + ZYDIS_CHECK(ZydisPrintHexU(string, operand->ptr.segment, 4, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix)); - ZYDIS_CHECK(ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT)); - return ZydisPrintHexU(buffer, operand->ptr.offset, 8, + ZYDIS_CHECK(ZydisStringAppendC(string, ":")); + return ZydisPrintHexU(string, operand->ptr.offset, 8, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -244,8 +239,8 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for { ZydisU64 address; ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address)); - return formatter->funcPrintAddress(formatter, buffer, instruction, operand, - address, userData); + return formatter->funcPrintAddress(formatter, string, instruction, operand, address, + userData); } case ZYDIS_ADDR_FORMAT_RELATIVE_SIGNED: printSignedHEX = ZYDIS_TRUE; @@ -258,29 +253,28 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for if (printSignedHEX) { - return ZydisPrintHexS(buffer, (ZydisI32)operand->imm.value.s, + return ZydisPrintHexS(string, (ZydisI32)operand->imm.value.s, formatter->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } - return ZydisPrintHexU(buffer, operand->imm.value.u, + return ZydisPrintHexU(string, 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, instruction, operand, userData); + return formatter->funcPrintImmediate(formatter, string, instruction, operand, userData); } /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisU64 address, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -288,13 +282,13 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt switch (instruction->stackWidth) { case 16: - return ZydisPrintHexU(buffer, (ZydisU16)address, 4, + return ZydisPrintHexU(string, (ZydisU16)address, 4, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexU(buffer, (ZydisU32)address, 8, + return ZydisPrintHexU(string, (ZydisU32)address, 8, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexU(buffer, address, 16, + return ZydisPrintHexU(string, address, 16, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -302,12 +296,12 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt } static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -322,16 +316,16 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo (operand->mem.base != ZYDIS_REGISTER_NONE) || (operand->mem.index != ZYDIS_REGISTER_NONE))) { - return ZydisPrintHexS(buffer, operand->mem.disp.value, + return ZydisPrintHexS(string, operand->mem.disp.value, formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } if ((operand->mem.base != ZYDIS_REGISTER_NONE) || (operand->mem.index != ZYDIS_REGISTER_NONE)) { - ZYDIS_CHECK(ZydisStringAppendC(buffer, "+", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, "+")); } - return ZydisPrintHexU(buffer, (ZydisU64)operand->mem.disp.value, + return ZydisPrintHexU(string, (ZydisU64)operand->mem.disp.value, formatter->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); } @@ -339,12 +333,12 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo } static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -360,19 +354,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma switch (operand->size) { case 8: - return ZydisPrintHexS(buffer, (ZydisI8)operand->imm.value.s, + return ZydisPrintHexS(string, (ZydisI8)operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 16: - return ZydisPrintHexS(buffer, (ZydisI16)operand->imm.value.s, + return ZydisPrintHexS(string, (ZydisI16)operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexS(buffer, (ZydisI32)operand->imm.value.s, + return ZydisPrintHexS(string, (ZydisI32)operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexS(buffer, operand->imm.value.s, + return ZydisPrintHexS(string, operand->imm.value.s, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: @@ -382,19 +376,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma switch (instruction->operandWidth) { case 8: - return ZydisPrintHexU(buffer, (ZydisU8)operand->imm.value.u, + return ZydisPrintHexU(string, (ZydisU8)operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 16: - return ZydisPrintHexU(buffer, (ZydisU16)operand->imm.value.u, + return ZydisPrintHexU(string, (ZydisU16)operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 32: - return ZydisPrintHexU(buffer, (ZydisU32)operand->imm.value.u, + return ZydisPrintHexU(string, (ZydisU32)operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); case 64: - return ZydisPrintHexU(buffer, operand->imm.value.u, + return ZydisPrintHexU(string, operand->imm.value.u, formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix); default: @@ -405,12 +399,12 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma /* ---------------------------------------------------------------------------------------------- */ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -505,19 +499,20 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for if (str) { - return ZydisStringAppendC(buffer, str, formatter->letterCase); + return ZydisStringAppendExC(string, str, formatter->letterCase); } } + return ZYDIS_STATUS_SUCCESS; } static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -528,43 +523,41 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt case ZYDIS_REGISTER_CS: case ZYDIS_REGISTER_FS: case ZYDIS_REGISTER_GS: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment), - formatter->letterCase)); - return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); + ZYDIS_CHECK(ZydisStringAppendExC(string, + ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); + return ZydisStringAppendC(string, ":"); case ZYDIS_REGISTER_SS: if ((formatter->forceSegments) || (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS)) { - ZYDIS_CHECK( - ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment), - formatter->letterCase)); - return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); + ZYDIS_CHECK(ZydisStringAppendExC(string, + ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); + return ZydisStringAppendC(string, ":"); } break; case ZYDIS_REGISTER_DS: if ((formatter->forceSegments) || (instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS)) { - ZYDIS_CHECK( - ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment), - formatter->letterCase)); - return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT); + ZYDIS_CHECK(ZydisStringAppendExC(string, + ZydisRegisterGetString(operand->mem.segment), formatter->letterCase)); + return ZydisStringAppendC(string, ":"); } break; default: break; } + return ZYDIS_STATUS_SUCCESS; } static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, + ZydisString* string, const ZydisDecodedInstruction* instruction, const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData) { - (void)userData; + ZYDIS_UNUSED_PARAMETER(userData); - if (!formatter || !buffer || !instruction || !operand) + if (!formatter || !instruction || !operand) { return ZYDIS_STATUS_INVALID_PARAMETER; } @@ -580,13 +573,12 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZYDIS_CHECK(ZydisStringAppendC(buffer, " {", ZYDIS_LETTER_CASE_DEFAULT)); - ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase)); - ZYDIS_CHECK(ZydisStringAppendC(buffer, "}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {")); + ZYDIS_CHECK(ZydisStringAppendExC(string, reg, formatter->letterCase)); + ZYDIS_CHECK(ZydisStringAppendC(string, "}")); if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO) { - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {z}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {z}")); } } break; @@ -599,28 +591,22 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma case ZYDIS_BROADCAST_MODE_INVALID: break; case ZYDIS_BROADCAST_MODE_1_TO_2: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {1to2}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {1to2}")); break; case ZYDIS_BROADCAST_MODE_1_TO_4: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {1to4}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {1to4}")); break; case ZYDIS_BROADCAST_MODE_1_TO_8: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {1to8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {1to8}")); break; case ZYDIS_BROADCAST_MODE_1_TO_16: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {1to16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {1to16}")); break; case ZYDIS_BROADCAST_MODE_4_TO_8: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {4to8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {4to8}")); break; case ZYDIS_BROADCAST_MODE_4_TO_16: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {4to16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {4to16}")); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -635,20 +621,16 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma case ZYDIS_ROUNDING_MODE_INVALID: break; case ZYDIS_ROUNDING_MODE_RN: - ZYDIS_CHECK(ZydisStringAppendC( - buffer, " {rn-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {rn-sae}")); break; case ZYDIS_ROUNDING_MODE_RD: - ZYDIS_CHECK(ZydisStringAppendC( - buffer, " {rd-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {rd-sae}")); break; case ZYDIS_ROUNDING_MODE_RU: - ZYDIS_CHECK(ZydisStringAppendC( - buffer, " {ru-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {ru-sae}")); break; case ZYDIS_ROUNDING_MODE_RZ: - ZYDIS_CHECK(ZydisStringAppendC( - buffer, " {rz-sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {rz-sae}")); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -660,20 +642,16 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma case ZYDIS_ROUNDING_MODE_INVALID: break; case ZYDIS_ROUNDING_MODE_RN: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {rn}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {rn}")); break; case ZYDIS_ROUNDING_MODE_RD: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {rd}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {rd}")); break; case ZYDIS_ROUNDING_MODE_RU: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {ru}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {ru}")); break; case ZYDIS_ROUNDING_MODE_RZ: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {rz}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {rz}")); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -683,8 +661,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma case ZYDIS_DECORATOR_TYPE_SAE: if (instruction->avx.hasSAE && !instruction->avx.rounding.mode) { - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {sae}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {sae}")); } break; case ZYDIS_DECORATOR_TYPE_SWIZZLE: @@ -695,32 +672,25 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma // Nothing to do here break; case ZYDIS_SWIZZLE_MODE_CDAB: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {cdab}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {cdab}")); break; case ZYDIS_SWIZZLE_MODE_BADC: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {badc}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {badc}")); break; case ZYDIS_SWIZZLE_MODE_DACB: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {dacb}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {dacb}")); break; case ZYDIS_SWIZZLE_MODE_AAAA: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {aaaa}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {aaaa}")); break; case ZYDIS_SWIZZLE_MODE_BBBB: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {bbbb}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {bbbb}")); break; case ZYDIS_SWIZZLE_MODE_CCCC: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {cccc}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {cccc}")); break; case ZYDIS_SWIZZLE_MODE_DDDD: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {dddd}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {dddd}")); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -732,24 +702,19 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma case ZYDIS_CONVERSION_MODE_INVALID: break; case ZYDIS_CONVERSION_MODE_FLOAT16: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {float16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {float16}")); break; case ZYDIS_CONVERSION_MODE_SINT8: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {sint8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {sint8}")); break; case ZYDIS_CONVERSION_MODE_UINT8: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {uint8}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {uint8}")); break; case ZYDIS_CONVERSION_MODE_SINT16: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {sint16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {sint16}")); break; case ZYDIS_CONVERSION_MODE_UINT16: - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {uint16}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {uint16}")); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; @@ -758,8 +723,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma case ZYDIS_DECORATOR_TYPE_EVICTION_HINT: if (instruction->avx.hasEvictionHint) { - ZYDIS_CHECK( - ZydisStringAppendC(buffer, " {eh}", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " {eh}")); } break; default: @@ -770,19 +734,16 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma } static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter, - ZydisString* buffer, const ZydisDecodedInstruction* instruction, void* userData) + ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData) { - if (!formatter || !buffer || !instruction) + if (!formatter || !string || !instruction) { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZYDIS_CHECK( - formatter->funcPrintPrefixes(formatter, buffer, instruction, userData)); - ZYDIS_CHECK( - formatter->funcPrintMnemonic(formatter, buffer, instruction, userData)); + ZYDIS_CHECK(formatter->funcPrintPrefixes(formatter, string, instruction, userData)); + ZYDIS_CHECK(formatter->funcPrintMnemonic(formatter, string, instruction, userData)); - ZydisUSize lenRestore = buffer->length; for (ZydisU8 i = 0; i < instruction->operandCount; ++i) { if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN) @@ -790,97 +751,91 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte break; } + const ZydisUSize strLenRestore = string->length; if (i == 0) { - ZYDIS_CHECK(ZydisStringAppendC(buffer, " ", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, " ")); } else { - lenRestore = buffer->length; - ZYDIS_CHECK(ZydisStringAppendC(buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT)); + ZYDIS_CHECK(ZydisStringAppendC(string, ", ")); } - ZydisUSize bufPreOperandLen = buffer->length; + const ZydisUSize strLenPreOperand = string->length; switch (instruction->operands[i].type) { case ZYDIS_OPERAND_TYPE_REGISTER: - ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer, - instruction, &instruction->operands[i], userData)); + ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, string, instruction, + &instruction->operands[i], userData)); break; case ZYDIS_OPERAND_TYPE_MEMORY: { - ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer, - instruction, &instruction->operands[i], userData)); - ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer, - instruction, &instruction->operands[i], userData)); - ZydisUSize lenTemp = buffer->length; - ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer, - instruction, &instruction->operands[i], userData)); - if (lenTemp == buffer->length) + ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, string, instruction, + &instruction->operands[i], userData)); + ZYDIS_CHECK(formatter->funcPrintSegment(formatter, string, instruction, + &instruction->operands[i], userData)); + const ZydisUSize strLenTemp = string->length; + ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, string, instruction, + &instruction->operands[i], userData)); + if (strLenTemp == string->length) { - buffer->length = bufPreOperandLen; + string->length = strLenPreOperand; } break; } case ZYDIS_OPERAND_TYPE_POINTER: - ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer, - instruction, &instruction->operands[i], userData)); + ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, string, instruction, + &instruction->operands[i], userData)); break; case ZYDIS_OPERAND_TYPE_IMMEDIATE: - ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer, - instruction, &instruction->operands[i], userData)); + ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, string, instruction, + &instruction->operands[i], userData)); break; default: return ZYDIS_STATUS_INVALID_PARAMETER; } - if (lenRestore == buffer->length) + if (strLenPreOperand == string->length) { - // Omit whole operand, if the buffer did not change during the formatting-callback - buffer->length = lenRestore; - } else + // Omit whole operand, if the string did not change during the formatting-callback + string->length = strLenRestore; + continue; + } + + if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || + (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) { - if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) || - (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)) + if ((i == 0) && + (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)) { - if ((i == 0) && - (instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK)) + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_MASK, userData)); + } + if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY) + { + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_BROADCAST, userData)); + if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_MASK, userData)); + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_CONVERSION, userData)); + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_EVICTION_HINT, userData)); } - if (instruction->operands[i].type == ZYDIS_OPERAND_TYPE_MEMORY) - { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_BROADCAST, userData)); + } else + { + if ((i == (instruction->operandCount - 1)) || + (instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) + { if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_CONVERSION, userData)); - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_EVICTION_HINT, userData)); - } - } else - { - if ((i == (instruction->operandCount - 1)) || - (instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)) - { - if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX) - { - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_SWIZZLE, userData)); - } - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, userData)); - ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer, - instruction, &instruction->operands[i], - ZYDIS_DECORATOR_TYPE_SAE, userData)); + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SWIZZLE, userData)); } + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL, + userData)); + ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction, + &instruction->operands[i], ZYDIS_DECORATOR_TYPE_SAE, userData)); } } } @@ -900,6 +855,8 @@ ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle st return ZYDIS_STATUS_INVALID_PARAMETER; } + static ZydisString hexPrefixDefault = ZYDIS_MAKE_STRING("0x"); + ZydisMemorySet(formatter, 0, sizeof(ZydisFormatter)); formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT; formatter->forceSegments = ZYDIS_FALSE; @@ -908,7 +865,7 @@ ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle st formatter->displacementFormat = ZYDIS_DISP_FORMAT_HEX_SIGNED; formatter->immediateFormat = ZYDIS_IMM_FORMAT_HEX_UNSIGNED; formatter->hexUppercase = ZYDIS_TRUE; - formatter->hexPrefix = "0x"; + formatter->hexPrefix = &hexPrefixDefault; formatter->hexSuffix = ZYDIS_NULL; formatter->hexPaddingAddress = 2; formatter->hexPaddingDisplacement = 2; @@ -982,10 +939,18 @@ ZydisStatus ZydisFormatterSetProperty(ZydisFormatter* formatter, formatter->hexUppercase = (value) ? ZYDIS_TRUE : ZYDIS_FALSE; break; case ZYDIS_FORMATTER_PROP_HEX_PREFIX: - formatter->hexPrefix = (char*)value; + formatter->hexPrefix = (value) ? &formatter->hexPrefixData : ZYDIS_NULL; + if (value) + { + return ZydisStringInit(&formatter->hexPrefixData, (char*)value); + } break; case ZYDIS_FORMATTER_PROP_HEX_SUFFIX: - formatter->hexSuffix = (char*)value; + formatter->hexSuffix = (value) ? &formatter->hexSuffixData : ZYDIS_NULL; + if (value) + { + return ZydisStringInit(&formatter->hexSuffixData, (char*)value); + } break; case ZYDIS_FORMATTER_PROP_HEX_PADDING_ADDR: if (value > 20) @@ -1147,30 +1112,28 @@ ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter, const ZydisDecodedInstruction* instruction, char* buffer, ZydisUSize bufferLen, void* userData) { - if (!formatter || !instruction || !buffer || !bufferLen) + if (!formatter || !instruction || !buffer || (bufferLen == 0)) { return ZYDIS_STATUS_INVALID_PARAMETER; } - ZydisString str = { - .s = buffer, - .length = 0, - .capacity = bufferLen - 1 - }; + ZydisString string; + string.buffer = buffer; + string.length = 0; + string.capacity = bufferLen; if (formatter->funcPre) { - ZYDIS_CHECK(formatter->funcPre(formatter, &str, instruction, userData)); + ZYDIS_CHECK(formatter->funcPre(formatter, &string, instruction, userData)); } - - ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, &str, instruction, userData)); - + ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, &string, instruction, userData)); if (formatter->funcPost) { - ZYDIS_CHECK(formatter->funcPost(formatter, &str, instruction, userData)); + return formatter->funcPost(formatter, &string, instruction, userData); } - str.s[str.length] = 0; + buffer[string.length] = 0; + return ZYDIS_STATUS_SUCCESS; } diff --git a/src/Generated/EnumMnemonic.inc b/src/Generated/EnumMnemonic.inc index 2220841..682b3e0 100644 --- a/src/Generated/EnumMnemonic.inc +++ b/src/Generated/EnumMnemonic.inc @@ -1,1578 +1,1578 @@ -static const char* zydisMnemonicStrings[] = +static const ZydisInternalString zydisMnemonicStrings[] = { - "invalid", - "aaa", - "aad", - "aam", - "aas", - "adc", - "adcx", - "add", - "addpd", - "addps", - "addsd", - "addss", - "addsubpd", - "addsubps", - "adox", - "aesdec", - "aesdeclast", - "aesenc", - "aesenclast", - "aesimc", - "aeskeygenassist", - "and", - "andn", - "andnpd", - "andnps", - "andpd", - "andps", - "arpl", - "bextr", - "blcfill", - "blci", - "blcic", - "blcmsk", - "blcs", - "blendpd", - "blendps", - "blendvpd", - "blendvps", - "blsfill", - "blsi", - "blsic", - "blsmsk", - "blsr", - "bndcl", - "bndcn", - "bndcu", - "bndldx", - "bndmk", - "bndmov", - "bndstx", - "bound", - "bsf", - "bsr", - "bswap", - "bt", - "btc", - "btr", - "bts", - "bzhi", - "call", - "cbw", - "cdq", - "cdqe", - "clac", - "clc", - "cld", - "clevict0", - "clevict1", - "clflush", - "clflushopt", - "clgi", - "cli", - "clrssbsy", - "clts", - "clwb", - "clzero", - "cmc", - "cmovb", - "cmovbe", - "cmovl", - "cmovle", - "cmovnb", - "cmovnbe", - "cmovnl", - "cmovnle", - "cmovno", - "cmovnp", - "cmovns", - "cmovnz", - "cmovo", - "cmovp", - "cmovs", - "cmovz", - "cmp", - "cmppd", - "cmpps", - "cmpsb", - "cmpsd", - "cmpsq", - "cmpss", - "cmpsw", - "cmpxchg", - "cmpxchg16b", - "cmpxchg8b", - "comisd", - "comiss", - "cpuid", - "cqo", - "crc32", - "cvtdq2pd", - "cvtdq2ps", - "cvtpd2dq", - "cvtpd2pi", - "cvtpd2ps", - "cvtpi2pd", - "cvtpi2ps", - "cvtps2dq", - "cvtps2pd", - "cvtps2pi", - "cvtsd2si", - "cvtsd2ss", - "cvtsi2sd", - "cvtsi2ss", - "cvtss2sd", - "cvtss2si", - "cvttpd2dq", - "cvttpd2pi", - "cvttps2dq", - "cvttps2pi", - "cvttsd2si", - "cvttss2si", - "cwd", - "cwde", - "daa", - "das", - "dec", - "delay", - "div", - "divpd", - "divps", - "divsd", - "divss", - "dppd", - "dpps", - "emms", - "encls", - "enclu", - "endbr32", - "endbr64", - "enter", - "extractps", - "f2xm1", - "fabs", - "fadd", - "faddp", - "fbld", - "fbstp", - "fchs", - "fcmovb", - "fcmovbe", - "fcmove", - "fcmovnb", - "fcmovnbe", - "fcmovne", - "fcmovnu", - "fcmovu", - "fcom", - "fcomi", - "fcomip", - "fcomp", - "fcompp", - "fcos", - "fdecstp", - "fdisi8087_nop", - "fdiv", - "fdivp", - "fdivr", - "fdivrp", - "femms", - "feni8087_nop", - "ffree", - "ffreep", - "fiadd", - "ficom", - "ficomp", - "fidiv", - "fidivr", - "fild", - "fimul", - "fincstp", - "fist", - "fistp", - "fisttp", - "fisub", - "fisubr", - "fld", - "fld1", - "fldcw", - "fldenv", - "fldl2e", - "fldl2t", - "fldlg2", - "fldln2", - "fldpi", - "fldz", - "fmul", - "fmulp", - "fnclex", - "fninit", - "fnop", - "fnsave", - "fnstcw", - "fnstenv", - "fnstsw", - "fpatan", - "fprem", - "fprem1", - "fptan", - "frndint", - "frstor", - "fscale", - "fsetpm287_nop", - "fsin", - "fsincos", - "fsqrt", - "fst", - "fstp", - "fstpnce", - "fsub", - "fsubp", - "fsubr", - "fsubrp", - "ftst", - "fucom", - "fucomi", - "fucomip", - "fucomp", - "fucompp", - "fwait", - "fxam", - "fxch", - "fxrstor", - "fxrstor64", - "fxsave", - "fxsave64", - "fxtract", - "fyl2x", - "fyl2xp1", - "getsec", - "gf2p8affineinvqb", - "gf2p8affineqb", - "gf2p8mulb", - "haddpd", - "haddps", - "hlt", - "hsubpd", - "hsubps", - "idiv", - "imul", - "in", - "inc", - "incsspd", - "incsspq", - "insb", - "insd", - "insertps", - "insw", - "int", - "int1", - "int3", - "into", - "invd", - "invept", - "invlpg", - "invlpga", - "invpcid", - "invvpid", - "iret", - "iretd", - "iretq", - "jb", - "jbe", - "jcxz", - "jecxz", - "jknzd", - "jkzd", - "jl", - "jle", - "jmp", - "jnb", - "jnbe", - "jnl", - "jnle", - "jno", - "jnp", - "jns", - "jnz", - "jo", - "jp", - "jrcxz", - "js", - "jz", - "kaddb", - "kaddd", - "kaddq", - "kaddw", - "kand", - "kandb", - "kandd", - "kandn", - "kandnb", - "kandnd", - "kandnq", - "kandnr", - "kandnw", - "kandq", - "kandw", - "kconcath", - "kconcatl", - "kextract", - "kmerge2l1h", - "kmerge2l1l", - "kmov", - "kmovb", - "kmovd", - "kmovq", - "kmovw", - "knot", - "knotb", - "knotd", - "knotq", - "knotw", - "kor", - "korb", - "kord", - "korq", - "kortest", - "kortestb", - "kortestd", - "kortestq", - "kortestw", - "korw", - "kshiftlb", - "kshiftld", - "kshiftlq", - "kshiftlw", - "kshiftrb", - "kshiftrd", - "kshiftrq", - "kshiftrw", - "ktestb", - "ktestd", - "ktestq", - "ktestw", - "kunpckbw", - "kunpckdq", - "kunpckwd", - "kxnor", - "kxnorb", - "kxnord", - "kxnorq", - "kxnorw", - "kxor", - "kxorb", - "kxord", - "kxorq", - "kxorw", - "lahf", - "lar", - "lddqu", - "ldmxcsr", - "lds", - "lea", - "leave", - "les", - "lfence", - "lfs", - "lgdt", - "lgs", - "lidt", - "lldt", - "llwpcb", - "lmsw", - "lodsb", - "lodsd", - "lodsq", - "lodsw", - "loop", - "loope", - "loopne", - "lsl", - "lss", - "ltr", - "lwpins", - "lwpval", - "lzcnt", - "maskmovdqu", - "maskmovq", - "maxpd", - "maxps", - "maxsd", - "maxss", - "mfence", - "minpd", - "minps", - "minsd", - "minss", - "monitor", - "mov", - "movapd", - "movaps", - "movbe", - "movd", - "movddup", - "movdq2q", - "movdqa", - "movdqu", - "movhlps", - "movhpd", - "movhps", - "movlhps", - "movlpd", - "movlps", - "movmskpd", - "movmskps", - "movntdq", - "movntdqa", - "movnti", - "movntpd", - "movntps", - "movntq", - "movq", - "movq2dq", - "movsb", - "movsd", - "movshdup", - "movsldup", - "movsq", - "movss", - "movsw", - "movsx", - "movsxd", - "movupd", - "movups", - "movzx", - "mpsadbw", - "mul", - "mulpd", - "mulps", - "mulsd", - "mulss", - "mulx", - "mwait", - "neg", - "nop", - "not", - "or", - "orpd", - "orps", - "out", - "outsb", - "outsd", - "outsw", - "pabsb", - "pabsd", - "pabsw", - "packssdw", - "packsswb", - "packusdw", - "packuswb", - "paddb", - "paddd", - "paddq", - "paddsb", - "paddsw", - "paddusb", - "paddusw", - "paddw", - "palignr", - "pand", - "pandn", - "pause", - "pavgb", - "pavgusb", - "pavgw", - "pblendvb", - "pblendw", - "pclmulqdq", - "pcmpeqb", - "pcmpeqd", - "pcmpeqq", - "pcmpeqw", - "pcmpestri", - "pcmpestrm", - "pcmpgtb", - "pcmpgtd", - "pcmpgtq", - "pcmpgtw", - "pcmpistri", - "pcmpistrm", - "pdep", - "pext", - "pextrb", - "pextrd", - "pextrq", - "pextrw", - "pf2id", - "pf2iw", - "pfacc", - "pfadd", - "pfcmpeq", - "pfcmpge", - "pfcmpgt", - "pfcpit1", - "pfmax", - "pfmin", - "pfmul", - "pfnacc", - "pfpnacc", - "pfrcp", - "pfrcpit2", - "pfrsqit1", - "pfsqrt", - "pfsub", - "pfsubr", - "phaddd", - "phaddsw", - "phaddw", - "phminposuw", - "phsubd", - "phsubsw", - "phsubw", - "pi2fd", - "pi2fw", - "pinsrb", - "pinsrd", - "pinsrq", - "pinsrw", - "pmaddubsw", - "pmaddwd", - "pmaxsb", - "pmaxsd", - "pmaxsw", - "pmaxub", - "pmaxud", - "pmaxuw", - "pminsb", - "pminsd", - "pminsw", - "pminub", - "pminud", - "pminuw", - "pmovmskb", - "pmovsxbd", - "pmovsxbq", - "pmovsxbw", - "pmovsxdq", - "pmovsxwd", - "pmovsxwq", - "pmovzxbd", - "pmovzxbq", - "pmovzxbw", - "pmovzxdq", - "pmovzxwd", - "pmovzxwq", - "pmuldq", - "pmulhrsw", - "pmulhrw", - "pmulhuw", - "pmulhw", - "pmulld", - "pmullw", - "pmuludq", - "pop", - "popa", - "popad", - "popcnt", - "popf", - "popfd", - "popfq", - "por", - "prefetch", - "prefetchnta", - "prefetcht0", - "prefetcht1", - "prefetcht2", - "prefetchw", - "prefetchwt1", - "psadbw", - "pshufb", - "pshufd", - "pshufhw", - "pshuflw", - "pshufw", - "psignb", - "psignd", - "psignw", - "pslld", - "pslldq", - "psllq", - "psllw", - "psrad", - "psraw", - "psrld", - "psrldq", - "psrlq", - "psrlw", - "psubb", - "psubd", - "psubq", - "psubsb", - "psubsw", - "psubusb", - "psubusw", - "psubw", - "pswapd", - "ptest", - "ptwrite", - "punpckhbw", - "punpckhdq", - "punpckhqdq", - "punpckhwd", - "punpcklbw", - "punpckldq", - "punpcklqdq", - "punpcklwd", - "push", - "pusha", - "pushad", - "pushf", - "pushfd", - "pushfq", - "pxor", - "rcl", - "rcpps", - "rcpss", - "rcr", - "rdfsbase", - "rdgsbase", - "rdmsr", - "rdpid", - "rdpkru", - "rdpmc", - "rdrand", - "rdseed", - "rdsspd", - "rdsspq", - "rdtsc", - "rdtscp", - "ret", - "rol", - "ror", - "rorx", - "roundpd", - "roundps", - "roundsd", - "roundss", - "rsm", - "rsqrtps", - "rsqrtss", - "rstorssp", - "sahf", - "salc", - "sar", - "sarx", - "savessp", - "sbb", - "scasb", - "scasd", - "scasq", - "scasw", - "setb", - "setbe", - "setl", - "setle", - "setnb", - "setnbe", - "setnl", - "setnle", - "setno", - "setnp", - "setns", - "setnz", - "seto", - "setp", - "sets", - "setssbsy", - "setz", - "sfence", - "sgdt", - "sha1msg1", - "sha1msg2", - "sha1nexte", - "sha1rnds4", - "sha256msg1", - "sha256msg2", - "sha256rnds2", - "shl", - "shld", - "shlx", - "shr", - "shrd", - "shrx", - "shufpd", - "shufps", - "sidt", - "skinit", - "sldt", - "slwpcb", - "smsw", - "spflt", - "sqrtpd", - "sqrtps", - "sqrtsd", - "sqrtss", - "stac", - "stc", - "std", - "stgi", - "sti", - "stmxcsr", - "stosb", - "stosd", - "stosq", - "stosw", - "str", - "sub", - "subpd", - "subps", - "subsd", - "subss", - "swapgs", - "syscall", - "sysenter", - "sysexit", - "sysret", - "t1mskc", - "test", - "tzcnt", - "tzcnti", - "tzmsk", - "ucomisd", - "ucomiss", - "ud0", - "ud1", - "ud2", - "unpckhpd", - "unpckhps", - "unpcklpd", - "unpcklps", - "v4fmaddps", - "v4fmaddss", - "v4fnmaddps", - "v4fnmaddss", - "vaddnpd", - "vaddnps", - "vaddpd", - "vaddps", - "vaddsd", - "vaddsetsps", - "vaddss", - "vaddsubpd", - "vaddsubps", - "vaesdec", - "vaesdeclast", - "vaesenc", - "vaesenclast", - "vaesimc", - "vaeskeygenassist", - "valignd", - "valignq", - "vandnpd", - "vandnps", - "vandpd", - "vandps", - "vblendmpd", - "vblendmps", - "vblendpd", - "vblendps", - "vblendvpd", - "vblendvps", - "vbroadcastf128", - "vbroadcastf32x2", - "vbroadcastf32x4", - "vbroadcastf32x8", - "vbroadcastf64x2", - "vbroadcastf64x4", - "vbroadcasti128", - "vbroadcasti32x2", - "vbroadcasti32x4", - "vbroadcasti32x8", - "vbroadcasti64x2", - "vbroadcasti64x4", - "vbroadcastsd", - "vbroadcastss", - "vcmppd", - "vcmpps", - "vcmpsd", - "vcmpss", - "vcomisd", - "vcomiss", - "vcompresspd", - "vcompressps", - "vcvtdq2pd", - "vcvtdq2ps", - "vcvtfxpntdq2ps", - "vcvtfxpntpd2dq", - "vcvtfxpntpd2udq", - "vcvtfxpntps2dq", - "vcvtfxpntps2udq", - "vcvtfxpntudq2ps", - "vcvtpd2dq", - "vcvtpd2ps", - "vcvtpd2qq", - "vcvtpd2udq", - "vcvtpd2uqq", - "vcvtph2ps", - "vcvtps2dq", - "vcvtps2pd", - "vcvtps2ph", - "vcvtps2qq", - "vcvtps2udq", - "vcvtps2uqq", - "vcvtqq2pd", - "vcvtqq2ps", - "vcvtsd2si", - "vcvtsd2ss", - "vcvtsd2usi", - "vcvtsi2sd", - "vcvtsi2ss", - "vcvtss2sd", - "vcvtss2si", - "vcvtss2usi", - "vcvttpd2dq", - "vcvttpd2qq", - "vcvttpd2udq", - "vcvttpd2uqq", - "vcvttps2dq", - "vcvttps2qq", - "vcvttps2udq", - "vcvttps2uqq", - "vcvttsd2si", - "vcvttsd2usi", - "vcvttss2si", - "vcvttss2usi", - "vcvtudq2pd", - "vcvtudq2ps", - "vcvtuqq2pd", - "vcvtuqq2ps", - "vcvtusi2sd", - "vcvtusi2ss", - "vdbpsadbw", - "vdivpd", - "vdivps", - "vdivsd", - "vdivss", - "vdppd", - "vdpps", - "verr", - "verw", - "vexp223ps", - "vexp2pd", - "vexp2ps", - "vexpandpd", - "vexpandps", - "vextractf128", - "vextractf32x4", - "vextractf32x8", - "vextractf64x2", - "vextractf64x4", - "vextracti128", - "vextracti32x4", - "vextracti32x8", - "vextracti64x2", - "vextracti64x4", - "vextractps", - "vfixupimmpd", - "vfixupimmps", - "vfixupimmsd", - "vfixupimmss", - "vfixupnanpd", - "vfixupnanps", - "vfmadd132pd", - "vfmadd132ps", - "vfmadd132sd", - "vfmadd132ss", - "vfmadd213pd", - "vfmadd213ps", - "vfmadd213sd", - "vfmadd213ss", - "vfmadd231pd", - "vfmadd231ps", - "vfmadd231sd", - "vfmadd231ss", - "vfmadd233ps", - "vfmaddpd", - "vfmaddps", - "vfmaddsd", - "vfmaddss", - "vfmaddsub132pd", - "vfmaddsub132ps", - "vfmaddsub213pd", - "vfmaddsub213ps", - "vfmaddsub231pd", - "vfmaddsub231ps", - "vfmaddsubpd", - "vfmaddsubps", - "vfmsub132pd", - "vfmsub132ps", - "vfmsub132sd", - "vfmsub132ss", - "vfmsub213pd", - "vfmsub213ps", - "vfmsub213sd", - "vfmsub213ss", - "vfmsub231pd", - "vfmsub231ps", - "vfmsub231sd", - "vfmsub231ss", - "vfmsubadd132pd", - "vfmsubadd132ps", - "vfmsubadd213pd", - "vfmsubadd213ps", - "vfmsubadd231pd", - "vfmsubadd231ps", - "vfmsubaddpd", - "vfmsubaddps", - "vfmsubpd", - "vfmsubps", - "vfmsubsd", - "vfmsubss", - "vfnmadd132pd", - "vfnmadd132ps", - "vfnmadd132sd", - "vfnmadd132ss", - "vfnmadd213pd", - "vfnmadd213ps", - "vfnmadd213sd", - "vfnmadd213ss", - "vfnmadd231pd", - "vfnmadd231ps", - "vfnmadd231sd", - "vfnmadd231ss", - "vfnmaddpd", - "vfnmaddps", - "vfnmaddsd", - "vfnmaddss", - "vfnmsub132pd", - "vfnmsub132ps", - "vfnmsub132sd", - "vfnmsub132ss", - "vfnmsub213pd", - "vfnmsub213ps", - "vfnmsub213sd", - "vfnmsub213ss", - "vfnmsub231pd", - "vfnmsub231ps", - "vfnmsub231sd", - "vfnmsub231ss", - "vfnmsubpd", - "vfnmsubps", - "vfnmsubsd", - "vfnmsubss", - "vfpclasspd", - "vfpclassps", - "vfpclasssd", - "vfpclassss", - "vfrczpd", - "vfrczps", - "vfrczsd", - "vfrczss", - "vgatherdpd", - "vgatherdps", - "vgatherpf0dpd", - "vgatherpf0dps", - "vgatherpf0hintdpd", - "vgatherpf0hintdps", - "vgatherpf0qpd", - "vgatherpf0qps", - "vgatherpf1dpd", - "vgatherpf1dps", - "vgatherpf1qpd", - "vgatherpf1qps", - "vgatherqpd", - "vgatherqps", - "vgetexppd", - "vgetexpps", - "vgetexpsd", - "vgetexpss", - "vgetmantpd", - "vgetmantps", - "vgetmantsd", - "vgetmantss", - "vgf2p8affineinvqb", - "vgf2p8affineqb", - "vgf2p8mulb", - "vgmaxabsps", - "vgmaxpd", - "vgmaxps", - "vgminpd", - "vgminps", - "vhaddpd", - "vhaddps", - "vhsubpd", - "vhsubps", - "vinsertf128", - "vinsertf32x4", - "vinsertf32x8", - "vinsertf64x2", - "vinsertf64x4", - "vinserti128", - "vinserti32x4", - "vinserti32x8", - "vinserti64x2", - "vinserti64x4", - "vinsertps", - "vlddqu", - "vldmxcsr", - "vloadunpackhd", - "vloadunpackhpd", - "vloadunpackhps", - "vloadunpackhq", - "vloadunpackld", - "vloadunpacklpd", - "vloadunpacklps", - "vloadunpacklq", - "vlog2ps", - "vmaskmovdqu", - "vmaskmovpd", - "vmaskmovps", - "vmaxpd", - "vmaxps", - "vmaxsd", - "vmaxss", - "vmcall", - "vmclear", - "vmfunc", - "vminpd", - "vminps", - "vminsd", - "vminss", - "vmlaunch", - "vmload", - "vmmcall", - "vmovapd", - "vmovaps", - "vmovd", - "vmovddup", - "vmovdqa", - "vmovdqa32", - "vmovdqa64", - "vmovdqu", - "vmovdqu16", - "vmovdqu32", - "vmovdqu64", - "vmovdqu8", - "vmovhlps", - "vmovhpd", - "vmovhps", - "vmovlhps", - "vmovlpd", - "vmovlps", - "vmovmskpd", - "vmovmskps", - "vmovnrapd", - "vmovnraps", - "vmovnrngoapd", - "vmovnrngoaps", - "vmovntdq", - "vmovntdqa", - "vmovntpd", - "vmovntps", - "vmovq", - "vmovsd", - "vmovshdup", - "vmovsldup", - "vmovss", - "vmovupd", - "vmovups", - "vmpsadbw", - "vmptrld", - "vmptrst", - "vmread", - "vmresume", - "vmrun", - "vmsave", - "vmulpd", - "vmulps", - "vmulsd", - "vmulss", - "vmwrite", - "vmxoff", - "vmxon", - "vorpd", - "vorps", - "vp4dpwssd", - "vp4dpwssds", - "vpabsb", - "vpabsd", - "vpabsq", - "vpabsw", - "vpackssdw", - "vpacksswb", - "vpackstorehd", - "vpackstorehpd", - "vpackstorehps", - "vpackstorehq", - "vpackstoreld", - "vpackstorelpd", - "vpackstorelps", - "vpackstorelq", - "vpackusdw", - "vpackuswb", - "vpadcd", - "vpaddb", - "vpaddd", - "vpaddq", - "vpaddsb", - "vpaddsetcd", - "vpaddsetsd", - "vpaddsw", - "vpaddusb", - "vpaddusw", - "vpaddw", - "vpalignr", - "vpand", - "vpandd", - "vpandn", - "vpandnd", - "vpandnq", - "vpandq", - "vpavgb", - "vpavgw", - "vpblendd", - "vpblendmb", - "vpblendmd", - "vpblendmq", - "vpblendmw", - "vpblendvb", - "vpblendw", - "vpbroadcastb", - "vpbroadcastd", - "vpbroadcastmb2q", - "vpbroadcastmw2d", - "vpbroadcastq", - "vpbroadcastw", - "vpclmulqdq", - "vpcmov", - "vpcmpb", - "vpcmpd", - "vpcmpeqb", - "vpcmpeqd", - "vpcmpeqq", - "vpcmpeqw", - "vpcmpestri", - "vpcmpestrm", - "vpcmpgtb", - "vpcmpgtd", - "vpcmpgtq", - "vpcmpgtw", - "vpcmpistri", - "vpcmpistrm", - "vpcmpltd", - "vpcmpq", - "vpcmpub", - "vpcmpud", - "vpcmpuq", - "vpcmpuw", - "vpcmpw", - "vpcomb", - "vpcomd", - "vpcompressb", - "vpcompressd", - "vpcompressq", - "vpcompressw", - "vpcomq", - "vpcomub", - "vpcomud", - "vpcomuq", - "vpcomuw", - "vpcomw", - "vpconflictd", - "vpconflictq", - "vpdpbusd", - "vpdpbusds", - "vpdpwssd", - "vpdpwssds", - "vperm2f128", - "vperm2i128", - "vpermb", - "vpermd", - "vpermf32x4", - "vpermi2b", - "vpermi2d", - "vpermi2pd", - "vpermi2ps", - "vpermi2q", - "vpermi2w", - "vpermil2pd", - "vpermil2ps", - "vpermilpd", - "vpermilps", - "vpermpd", - "vpermps", - "vpermq", - "vpermt2b", - "vpermt2d", - "vpermt2pd", - "vpermt2ps", - "vpermt2q", - "vpermt2w", - "vpermw", - "vpexpandb", - "vpexpandd", - "vpexpandq", - "vpexpandw", - "vpextrb", - "vpextrd", - "vpextrq", - "vpextrw", - "vpgatherdd", - "vpgatherdq", - "vpgatherqd", - "vpgatherqq", - "vphaddbd", - "vphaddbq", - "vphaddbw", - "vphaddd", - "vphadddq", - "vphaddsw", - "vphaddubd", - "vphaddubq", - "vphaddubw", - "vphaddudq", - "vphadduwd", - "vphadduwq", - "vphaddw", - "vphaddwd", - "vphaddwq", - "vphminposuw", - "vphsubbw", - "vphsubd", - "vphsubdq", - "vphsubsw", - "vphsubw", - "vphsubwd", - "vpinsrb", - "vpinsrd", - "vpinsrq", - "vpinsrw", - "vplzcntd", - "vplzcntq", - "vpmacsdd", - "vpmacsdqh", - "vpmacsdql", - "vpmacssdd", - "vpmacssdqh", - "vpmacssdql", - "vpmacsswd", - "vpmacssww", - "vpmacswd", - "vpmacsww", - "vpmadcsswd", - "vpmadcswd", - "vpmadd231d", - "vpmadd233d", - "vpmadd52huq", - "vpmadd52luq", - "vpmaddubsw", - "vpmaddwd", - "vpmaskmovd", - "vpmaskmovq", - "vpmaxsb", - "vpmaxsd", - "vpmaxsq", - "vpmaxsw", - "vpmaxub", - "vpmaxud", - "vpmaxuq", - "vpmaxuw", - "vpminsb", - "vpminsd", - "vpminsq", - "vpminsw", - "vpminub", - "vpminud", - "vpminuq", - "vpminuw", - "vpmovb2m", - "vpmovd2m", - "vpmovdb", - "vpmovdw", - "vpmovm2b", - "vpmovm2d", - "vpmovm2q", - "vpmovm2w", - "vpmovmskb", - "vpmovq2m", - "vpmovqb", - "vpmovqd", - "vpmovqw", - "vpmovsdb", - "vpmovsdw", - "vpmovsqb", - "vpmovsqd", - "vpmovsqw", - "vpmovswb", - "vpmovsxbd", - "vpmovsxbq", - "vpmovsxbw", - "vpmovsxdq", - "vpmovsxwd", - "vpmovsxwq", - "vpmovusdb", - "vpmovusdw", - "vpmovusqb", - "vpmovusqd", - "vpmovusqw", - "vpmovuswb", - "vpmovw2m", - "vpmovwb", - "vpmovzxbd", - "vpmovzxbq", - "vpmovzxbw", - "vpmovzxdq", - "vpmovzxwd", - "vpmovzxwq", - "vpmuldq", - "vpmulhd", - "vpmulhrsw", - "vpmulhud", - "vpmulhuw", - "vpmulhw", - "vpmulld", - "vpmullq", - "vpmullw", - "vpmultishiftqb", - "vpmuludq", - "vpopcntb", - "vpopcntd", - "vpopcntq", - "vpopcntw", - "vpor", - "vpord", - "vporq", - "vpperm", - "vprefetch0", - "vprefetch1", - "vprefetch2", - "vprefetche0", - "vprefetche1", - "vprefetche2", - "vprefetchenta", - "vprefetchnta", - "vprold", - "vprolq", - "vprolvd", - "vprolvq", - "vprord", - "vprorq", - "vprorvd", - "vprorvq", - "vprotb", - "vprotd", - "vprotq", - "vprotw", - "vpsadbw", - "vpsbbd", - "vpsbbrd", - "vpscatterdd", - "vpscatterdq", - "vpscatterqd", - "vpscatterqq", - "vpshab", - "vpshad", - "vpshaq", - "vpshaw", - "vpshlb", - "vpshld", - "vpshldd", - "vpshldq", - "vpshldvd", - "vpshldvq", - "vpshldvw", - "vpshldw", - "vpshlq", - "vpshlw", - "vpshrdd", - "vpshrdq", - "vpshrdvd", - "vpshrdvq", - "vpshrdvw", - "vpshrdw", - "vpshufb", - "vpshufbitqmb", - "vpshufd", - "vpshufhw", - "vpshuflw", - "vpsignb", - "vpsignd", - "vpsignw", - "vpslld", - "vpslldq", - "vpsllq", - "vpsllvd", - "vpsllvq", - "vpsllvw", - "vpsllw", - "vpsrad", - "vpsraq", - "vpsravd", - "vpsravq", - "vpsravw", - "vpsraw", - "vpsrld", - "vpsrldq", - "vpsrlq", - "vpsrlvd", - "vpsrlvq", - "vpsrlvw", - "vpsrlw", - "vpsubb", - "vpsubd", - "vpsubq", - "vpsubrd", - "vpsubrsetbd", - "vpsubsb", - "vpsubsetbd", - "vpsubsw", - "vpsubusb", - "vpsubusw", - "vpsubw", - "vpternlogd", - "vpternlogq", - "vptest", - "vptestmb", - "vptestmd", - "vptestmq", - "vptestmw", - "vptestnmb", - "vptestnmd", - "vptestnmq", - "vptestnmw", - "vpunpckhbw", - "vpunpckhdq", - "vpunpckhqdq", - "vpunpckhwd", - "vpunpcklbw", - "vpunpckldq", - "vpunpcklqdq", - "vpunpcklwd", - "vpxor", - "vpxord", - "vpxorq", - "vrangepd", - "vrangeps", - "vrangesd", - "vrangess", - "vrcp14pd", - "vrcp14ps", - "vrcp14sd", - "vrcp14ss", - "vrcp23ps", - "vrcp28pd", - "vrcp28ps", - "vrcp28sd", - "vrcp28ss", - "vrcpps", - "vrcpss", - "vreducepd", - "vreduceps", - "vreducesd", - "vreducess", - "vrndfxpntpd", - "vrndfxpntps", - "vrndscalepd", - "vrndscaleps", - "vrndscalesd", - "vrndscaless", - "vroundpd", - "vroundps", - "vroundsd", - "vroundss", - "vrsqrt14pd", - "vrsqrt14ps", - "vrsqrt14sd", - "vrsqrt14ss", - "vrsqrt23ps", - "vrsqrt28pd", - "vrsqrt28ps", - "vrsqrt28sd", - "vrsqrt28ss", - "vrsqrtps", - "vrsqrtss", - "vscalefpd", - "vscalefps", - "vscalefsd", - "vscalefss", - "vscaleps", - "vscatterdpd", - "vscatterdps", - "vscatterpf0dpd", - "vscatterpf0dps", - "vscatterpf0hintdpd", - "vscatterpf0hintdps", - "vscatterpf0qpd", - "vscatterpf0qps", - "vscatterpf1dpd", - "vscatterpf1dps", - "vscatterpf1qpd", - "vscatterpf1qps", - "vscatterqpd", - "vscatterqps", - "vshuff32x4", - "vshuff64x2", - "vshufi32x4", - "vshufi64x2", - "vshufpd", - "vshufps", - "vsqrtpd", - "vsqrtps", - "vsqrtsd", - "vsqrtss", - "vstmxcsr", - "vsubpd", - "vsubps", - "vsubrpd", - "vsubrps", - "vsubsd", - "vsubss", - "vtestpd", - "vtestps", - "vucomisd", - "vucomiss", - "vunpckhpd", - "vunpckhps", - "vunpcklpd", - "vunpcklps", - "vxorpd", - "vxorps", - "vzeroall", - "vzeroupper", - "wbinvd", - "wrfsbase", - "wrgsbase", - "wrmsr", - "wrpkru", - "wrssd", - "wrssq", - "wrussd", - "wrussq", - "xabort", - "xadd", - "xbegin", - "xchg", - "xend", - "xgetbv", - "xlat", - "xor", - "xorpd", - "xorps", - "xrstor", - "xrstor64", - "xrstors", - "xrstors64", - "xsave", - "xsave64", - "xsavec", - "xsavec64", - "xsaveopt", - "xsaveopt64", - "xsaves", - "xsaves64", - "xsetbv", - "xtest" + { "invalid", 0x07 }, + { "aaa", 0x03 }, + { "aad", 0x03 }, + { "aam", 0x03 }, + { "aas", 0x03 }, + { "adc", 0x03 }, + { "adcx", 0x04 }, + { "add", 0x03 }, + { "addpd", 0x05 }, + { "addps", 0x05 }, + { "addsd", 0x05 }, + { "addss", 0x05 }, + { "addsubpd", 0x08 }, + { "addsubps", 0x08 }, + { "adox", 0x04 }, + { "aesdec", 0x06 }, + { "aesdeclast", 0x0A }, + { "aesenc", 0x06 }, + { "aesenclast", 0x0A }, + { "aesimc", 0x06 }, + { "aeskeygenassist", 0x0F }, + { "and", 0x03 }, + { "andn", 0x04 }, + { "andnpd", 0x06 }, + { "andnps", 0x06 }, + { "andpd", 0x05 }, + { "andps", 0x05 }, + { "arpl", 0x04 }, + { "bextr", 0x05 }, + { "blcfill", 0x07 }, + { "blci", 0x04 }, + { "blcic", 0x05 }, + { "blcmsk", 0x06 }, + { "blcs", 0x04 }, + { "blendpd", 0x07 }, + { "blendps", 0x07 }, + { "blendvpd", 0x08 }, + { "blendvps", 0x08 }, + { "blsfill", 0x07 }, + { "blsi", 0x04 }, + { "blsic", 0x05 }, + { "blsmsk", 0x06 }, + { "blsr", 0x04 }, + { "bndcl", 0x05 }, + { "bndcn", 0x05 }, + { "bndcu", 0x05 }, + { "bndldx", 0x06 }, + { "bndmk", 0x05 }, + { "bndmov", 0x06 }, + { "bndstx", 0x06 }, + { "bound", 0x05 }, + { "bsf", 0x03 }, + { "bsr", 0x03 }, + { "bswap", 0x05 }, + { "bt", 0x02 }, + { "btc", 0x03 }, + { "btr", 0x03 }, + { "bts", 0x03 }, + { "bzhi", 0x04 }, + { "call", 0x04 }, + { "cbw", 0x03 }, + { "cdq", 0x03 }, + { "cdqe", 0x04 }, + { "clac", 0x04 }, + { "clc", 0x03 }, + { "cld", 0x03 }, + { "clevict0", 0x08 }, + { "clevict1", 0x08 }, + { "clflush", 0x07 }, + { "clflushopt", 0x0A }, + { "clgi", 0x04 }, + { "cli", 0x03 }, + { "clrssbsy", 0x08 }, + { "clts", 0x04 }, + { "clwb", 0x04 }, + { "clzero", 0x06 }, + { "cmc", 0x03 }, + { "cmovb", 0x05 }, + { "cmovbe", 0x06 }, + { "cmovl", 0x05 }, + { "cmovle", 0x06 }, + { "cmovnb", 0x06 }, + { "cmovnbe", 0x07 }, + { "cmovnl", 0x06 }, + { "cmovnle", 0x07 }, + { "cmovno", 0x06 }, + { "cmovnp", 0x06 }, + { "cmovns", 0x06 }, + { "cmovnz", 0x06 }, + { "cmovo", 0x05 }, + { "cmovp", 0x05 }, + { "cmovs", 0x05 }, + { "cmovz", 0x05 }, + { "cmp", 0x03 }, + { "cmppd", 0x05 }, + { "cmpps", 0x05 }, + { "cmpsb", 0x05 }, + { "cmpsd", 0x05 }, + { "cmpsq", 0x05 }, + { "cmpss", 0x05 }, + { "cmpsw", 0x05 }, + { "cmpxchg", 0x07 }, + { "cmpxchg16b", 0x0A }, + { "cmpxchg8b", 0x09 }, + { "comisd", 0x06 }, + { "comiss", 0x06 }, + { "cpuid", 0x05 }, + { "cqo", 0x03 }, + { "crc32", 0x05 }, + { "cvtdq2pd", 0x08 }, + { "cvtdq2ps", 0x08 }, + { "cvtpd2dq", 0x08 }, + { "cvtpd2pi", 0x08 }, + { "cvtpd2ps", 0x08 }, + { "cvtpi2pd", 0x08 }, + { "cvtpi2ps", 0x08 }, + { "cvtps2dq", 0x08 }, + { "cvtps2pd", 0x08 }, + { "cvtps2pi", 0x08 }, + { "cvtsd2si", 0x08 }, + { "cvtsd2ss", 0x08 }, + { "cvtsi2sd", 0x08 }, + { "cvtsi2ss", 0x08 }, + { "cvtss2sd", 0x08 }, + { "cvtss2si", 0x08 }, + { "cvttpd2dq", 0x09 }, + { "cvttpd2pi", 0x09 }, + { "cvttps2dq", 0x09 }, + { "cvttps2pi", 0x09 }, + { "cvttsd2si", 0x09 }, + { "cvttss2si", 0x09 }, + { "cwd", 0x03 }, + { "cwde", 0x04 }, + { "daa", 0x03 }, + { "das", 0x03 }, + { "dec", 0x03 }, + { "delay", 0x05 }, + { "div", 0x03 }, + { "divpd", 0x05 }, + { "divps", 0x05 }, + { "divsd", 0x05 }, + { "divss", 0x05 }, + { "dppd", 0x04 }, + { "dpps", 0x04 }, + { "emms", 0x04 }, + { "encls", 0x05 }, + { "enclu", 0x05 }, + { "endbr32", 0x07 }, + { "endbr64", 0x07 }, + { "enter", 0x05 }, + { "extractps", 0x09 }, + { "f2xm1", 0x05 }, + { "fabs", 0x04 }, + { "fadd", 0x04 }, + { "faddp", 0x05 }, + { "fbld", 0x04 }, + { "fbstp", 0x05 }, + { "fchs", 0x04 }, + { "fcmovb", 0x06 }, + { "fcmovbe", 0x07 }, + { "fcmove", 0x06 }, + { "fcmovnb", 0x07 }, + { "fcmovnbe", 0x08 }, + { "fcmovne", 0x07 }, + { "fcmovnu", 0x07 }, + { "fcmovu", 0x06 }, + { "fcom", 0x04 }, + { "fcomi", 0x05 }, + { "fcomip", 0x06 }, + { "fcomp", 0x05 }, + { "fcompp", 0x06 }, + { "fcos", 0x04 }, + { "fdecstp", 0x07 }, + { "fdisi8087_nop", 0x0D }, + { "fdiv", 0x04 }, + { "fdivp", 0x05 }, + { "fdivr", 0x05 }, + { "fdivrp", 0x06 }, + { "femms", 0x05 }, + { "feni8087_nop", 0x0C }, + { "ffree", 0x05 }, + { "ffreep", 0x06 }, + { "fiadd", 0x05 }, + { "ficom", 0x05 }, + { "ficomp", 0x06 }, + { "fidiv", 0x05 }, + { "fidivr", 0x06 }, + { "fild", 0x04 }, + { "fimul", 0x05 }, + { "fincstp", 0x07 }, + { "fist", 0x04 }, + { "fistp", 0x05 }, + { "fisttp", 0x06 }, + { "fisub", 0x05 }, + { "fisubr", 0x06 }, + { "fld", 0x03 }, + { "fld1", 0x04 }, + { "fldcw", 0x05 }, + { "fldenv", 0x06 }, + { "fldl2e", 0x06 }, + { "fldl2t", 0x06 }, + { "fldlg2", 0x06 }, + { "fldln2", 0x06 }, + { "fldpi", 0x05 }, + { "fldz", 0x04 }, + { "fmul", 0x04 }, + { "fmulp", 0x05 }, + { "fnclex", 0x06 }, + { "fninit", 0x06 }, + { "fnop", 0x04 }, + { "fnsave", 0x06 }, + { "fnstcw", 0x06 }, + { "fnstenv", 0x07 }, + { "fnstsw", 0x06 }, + { "fpatan", 0x06 }, + { "fprem", 0x05 }, + { "fprem1", 0x06 }, + { "fptan", 0x05 }, + { "frndint", 0x07 }, + { "frstor", 0x06 }, + { "fscale", 0x06 }, + { "fsetpm287_nop", 0x0D }, + { "fsin", 0x04 }, + { "fsincos", 0x07 }, + { "fsqrt", 0x05 }, + { "fst", 0x03 }, + { "fstp", 0x04 }, + { "fstpnce", 0x07 }, + { "fsub", 0x04 }, + { "fsubp", 0x05 }, + { "fsubr", 0x05 }, + { "fsubrp", 0x06 }, + { "ftst", 0x04 }, + { "fucom", 0x05 }, + { "fucomi", 0x06 }, + { "fucomip", 0x07 }, + { "fucomp", 0x06 }, + { "fucompp", 0x07 }, + { "fwait", 0x05 }, + { "fxam", 0x04 }, + { "fxch", 0x04 }, + { "fxrstor", 0x07 }, + { "fxrstor64", 0x09 }, + { "fxsave", 0x06 }, + { "fxsave64", 0x08 }, + { "fxtract", 0x07 }, + { "fyl2x", 0x05 }, + { "fyl2xp1", 0x07 }, + { "getsec", 0x06 }, + { "gf2p8affineinvqb", 0x10 }, + { "gf2p8affineqb", 0x0D }, + { "gf2p8mulb", 0x09 }, + { "haddpd", 0x06 }, + { "haddps", 0x06 }, + { "hlt", 0x03 }, + { "hsubpd", 0x06 }, + { "hsubps", 0x06 }, + { "idiv", 0x04 }, + { "imul", 0x04 }, + { "in", 0x02 }, + { "inc", 0x03 }, + { "incsspd", 0x07 }, + { "incsspq", 0x07 }, + { "insb", 0x04 }, + { "insd", 0x04 }, + { "insertps", 0x08 }, + { "insw", 0x04 }, + { "int", 0x03 }, + { "int1", 0x04 }, + { "int3", 0x04 }, + { "into", 0x04 }, + { "invd", 0x04 }, + { "invept", 0x06 }, + { "invlpg", 0x06 }, + { "invlpga", 0x07 }, + { "invpcid", 0x07 }, + { "invvpid", 0x07 }, + { "iret", 0x04 }, + { "iretd", 0x05 }, + { "iretq", 0x05 }, + { "jb", 0x02 }, + { "jbe", 0x03 }, + { "jcxz", 0x04 }, + { "jecxz", 0x05 }, + { "jknzd", 0x05 }, + { "jkzd", 0x04 }, + { "jl", 0x02 }, + { "jle", 0x03 }, + { "jmp", 0x03 }, + { "jnb", 0x03 }, + { "jnbe", 0x04 }, + { "jnl", 0x03 }, + { "jnle", 0x04 }, + { "jno", 0x03 }, + { "jnp", 0x03 }, + { "jns", 0x03 }, + { "jnz", 0x03 }, + { "jo", 0x02 }, + { "jp", 0x02 }, + { "jrcxz", 0x05 }, + { "js", 0x02 }, + { "jz", 0x02 }, + { "kaddb", 0x05 }, + { "kaddd", 0x05 }, + { "kaddq", 0x05 }, + { "kaddw", 0x05 }, + { "kand", 0x04 }, + { "kandb", 0x05 }, + { "kandd", 0x05 }, + { "kandn", 0x05 }, + { "kandnb", 0x06 }, + { "kandnd", 0x06 }, + { "kandnq", 0x06 }, + { "kandnr", 0x06 }, + { "kandnw", 0x06 }, + { "kandq", 0x05 }, + { "kandw", 0x05 }, + { "kconcath", 0x08 }, + { "kconcatl", 0x08 }, + { "kextract", 0x08 }, + { "kmerge2l1h", 0x0A }, + { "kmerge2l1l", 0x0A }, + { "kmov", 0x04 }, + { "kmovb", 0x05 }, + { "kmovd", 0x05 }, + { "kmovq", 0x05 }, + { "kmovw", 0x05 }, + { "knot", 0x04 }, + { "knotb", 0x05 }, + { "knotd", 0x05 }, + { "knotq", 0x05 }, + { "knotw", 0x05 }, + { "kor", 0x03 }, + { "korb", 0x04 }, + { "kord", 0x04 }, + { "korq", 0x04 }, + { "kortest", 0x07 }, + { "kortestb", 0x08 }, + { "kortestd", 0x08 }, + { "kortestq", 0x08 }, + { "kortestw", 0x08 }, + { "korw", 0x04 }, + { "kshiftlb", 0x08 }, + { "kshiftld", 0x08 }, + { "kshiftlq", 0x08 }, + { "kshiftlw", 0x08 }, + { "kshiftrb", 0x08 }, + { "kshiftrd", 0x08 }, + { "kshiftrq", 0x08 }, + { "kshiftrw", 0x08 }, + { "ktestb", 0x06 }, + { "ktestd", 0x06 }, + { "ktestq", 0x06 }, + { "ktestw", 0x06 }, + { "kunpckbw", 0x08 }, + { "kunpckdq", 0x08 }, + { "kunpckwd", 0x08 }, + { "kxnor", 0x05 }, + { "kxnorb", 0x06 }, + { "kxnord", 0x06 }, + { "kxnorq", 0x06 }, + { "kxnorw", 0x06 }, + { "kxor", 0x04 }, + { "kxorb", 0x05 }, + { "kxord", 0x05 }, + { "kxorq", 0x05 }, + { "kxorw", 0x05 }, + { "lahf", 0x04 }, + { "lar", 0x03 }, + { "lddqu", 0x05 }, + { "ldmxcsr", 0x07 }, + { "lds", 0x03 }, + { "lea", 0x03 }, + { "leave", 0x05 }, + { "les", 0x03 }, + { "lfence", 0x06 }, + { "lfs", 0x03 }, + { "lgdt", 0x04 }, + { "lgs", 0x03 }, + { "lidt", 0x04 }, + { "lldt", 0x04 }, + { "llwpcb", 0x06 }, + { "lmsw", 0x04 }, + { "lodsb", 0x05 }, + { "lodsd", 0x05 }, + { "lodsq", 0x05 }, + { "lodsw", 0x05 }, + { "loop", 0x04 }, + { "loope", 0x05 }, + { "loopne", 0x06 }, + { "lsl", 0x03 }, + { "lss", 0x03 }, + { "ltr", 0x03 }, + { "lwpins", 0x06 }, + { "lwpval", 0x06 }, + { "lzcnt", 0x05 }, + { "maskmovdqu", 0x0A }, + { "maskmovq", 0x08 }, + { "maxpd", 0x05 }, + { "maxps", 0x05 }, + { "maxsd", 0x05 }, + { "maxss", 0x05 }, + { "mfence", 0x06 }, + { "minpd", 0x05 }, + { "minps", 0x05 }, + { "minsd", 0x05 }, + { "minss", 0x05 }, + { "monitor", 0x07 }, + { "mov", 0x03 }, + { "movapd", 0x06 }, + { "movaps", 0x06 }, + { "movbe", 0x05 }, + { "movd", 0x04 }, + { "movddup", 0x07 }, + { "movdq2q", 0x07 }, + { "movdqa", 0x06 }, + { "movdqu", 0x06 }, + { "movhlps", 0x07 }, + { "movhpd", 0x06 }, + { "movhps", 0x06 }, + { "movlhps", 0x07 }, + { "movlpd", 0x06 }, + { "movlps", 0x06 }, + { "movmskpd", 0x08 }, + { "movmskps", 0x08 }, + { "movntdq", 0x07 }, + { "movntdqa", 0x08 }, + { "movnti", 0x06 }, + { "movntpd", 0x07 }, + { "movntps", 0x07 }, + { "movntq", 0x06 }, + { "movq", 0x04 }, + { "movq2dq", 0x07 }, + { "movsb", 0x05 }, + { "movsd", 0x05 }, + { "movshdup", 0x08 }, + { "movsldup", 0x08 }, + { "movsq", 0x05 }, + { "movss", 0x05 }, + { "movsw", 0x05 }, + { "movsx", 0x05 }, + { "movsxd", 0x06 }, + { "movupd", 0x06 }, + { "movups", 0x06 }, + { "movzx", 0x05 }, + { "mpsadbw", 0x07 }, + { "mul", 0x03 }, + { "mulpd", 0x05 }, + { "mulps", 0x05 }, + { "mulsd", 0x05 }, + { "mulss", 0x05 }, + { "mulx", 0x04 }, + { "mwait", 0x05 }, + { "neg", 0x03 }, + { "nop", 0x03 }, + { "not", 0x03 }, + { "or", 0x02 }, + { "orpd", 0x04 }, + { "orps", 0x04 }, + { "out", 0x03 }, + { "outsb", 0x05 }, + { "outsd", 0x05 }, + { "outsw", 0x05 }, + { "pabsb", 0x05 }, + { "pabsd", 0x05 }, + { "pabsw", 0x05 }, + { "packssdw", 0x08 }, + { "packsswb", 0x08 }, + { "packusdw", 0x08 }, + { "packuswb", 0x08 }, + { "paddb", 0x05 }, + { "paddd", 0x05 }, + { "paddq", 0x05 }, + { "paddsb", 0x06 }, + { "paddsw", 0x06 }, + { "paddusb", 0x07 }, + { "paddusw", 0x07 }, + { "paddw", 0x05 }, + { "palignr", 0x07 }, + { "pand", 0x04 }, + { "pandn", 0x05 }, + { "pause", 0x05 }, + { "pavgb", 0x05 }, + { "pavgusb", 0x07 }, + { "pavgw", 0x05 }, + { "pblendvb", 0x08 }, + { "pblendw", 0x07 }, + { "pclmulqdq", 0x09 }, + { "pcmpeqb", 0x07 }, + { "pcmpeqd", 0x07 }, + { "pcmpeqq", 0x07 }, + { "pcmpeqw", 0x07 }, + { "pcmpestri", 0x09 }, + { "pcmpestrm", 0x09 }, + { "pcmpgtb", 0x07 }, + { "pcmpgtd", 0x07 }, + { "pcmpgtq", 0x07 }, + { "pcmpgtw", 0x07 }, + { "pcmpistri", 0x09 }, + { "pcmpistrm", 0x09 }, + { "pdep", 0x04 }, + { "pext", 0x04 }, + { "pextrb", 0x06 }, + { "pextrd", 0x06 }, + { "pextrq", 0x06 }, + { "pextrw", 0x06 }, + { "pf2id", 0x05 }, + { "pf2iw", 0x05 }, + { "pfacc", 0x05 }, + { "pfadd", 0x05 }, + { "pfcmpeq", 0x07 }, + { "pfcmpge", 0x07 }, + { "pfcmpgt", 0x07 }, + { "pfcpit1", 0x07 }, + { "pfmax", 0x05 }, + { "pfmin", 0x05 }, + { "pfmul", 0x05 }, + { "pfnacc", 0x06 }, + { "pfpnacc", 0x07 }, + { "pfrcp", 0x05 }, + { "pfrcpit2", 0x08 }, + { "pfrsqit1", 0x08 }, + { "pfsqrt", 0x06 }, + { "pfsub", 0x05 }, + { "pfsubr", 0x06 }, + { "phaddd", 0x06 }, + { "phaddsw", 0x07 }, + { "phaddw", 0x06 }, + { "phminposuw", 0x0A }, + { "phsubd", 0x06 }, + { "phsubsw", 0x07 }, + { "phsubw", 0x06 }, + { "pi2fd", 0x05 }, + { "pi2fw", 0x05 }, + { "pinsrb", 0x06 }, + { "pinsrd", 0x06 }, + { "pinsrq", 0x06 }, + { "pinsrw", 0x06 }, + { "pmaddubsw", 0x09 }, + { "pmaddwd", 0x07 }, + { "pmaxsb", 0x06 }, + { "pmaxsd", 0x06 }, + { "pmaxsw", 0x06 }, + { "pmaxub", 0x06 }, + { "pmaxud", 0x06 }, + { "pmaxuw", 0x06 }, + { "pminsb", 0x06 }, + { "pminsd", 0x06 }, + { "pminsw", 0x06 }, + { "pminub", 0x06 }, + { "pminud", 0x06 }, + { "pminuw", 0x06 }, + { "pmovmskb", 0x08 }, + { "pmovsxbd", 0x08 }, + { "pmovsxbq", 0x08 }, + { "pmovsxbw", 0x08 }, + { "pmovsxdq", 0x08 }, + { "pmovsxwd", 0x08 }, + { "pmovsxwq", 0x08 }, + { "pmovzxbd", 0x08 }, + { "pmovzxbq", 0x08 }, + { "pmovzxbw", 0x08 }, + { "pmovzxdq", 0x08 }, + { "pmovzxwd", 0x08 }, + { "pmovzxwq", 0x08 }, + { "pmuldq", 0x06 }, + { "pmulhrsw", 0x08 }, + { "pmulhrw", 0x07 }, + { "pmulhuw", 0x07 }, + { "pmulhw", 0x06 }, + { "pmulld", 0x06 }, + { "pmullw", 0x06 }, + { "pmuludq", 0x07 }, + { "pop", 0x03 }, + { "popa", 0x04 }, + { "popad", 0x05 }, + { "popcnt", 0x06 }, + { "popf", 0x04 }, + { "popfd", 0x05 }, + { "popfq", 0x05 }, + { "por", 0x03 }, + { "prefetch", 0x08 }, + { "prefetchnta", 0x0B }, + { "prefetcht0", 0x0A }, + { "prefetcht1", 0x0A }, + { "prefetcht2", 0x0A }, + { "prefetchw", 0x09 }, + { "prefetchwt1", 0x0B }, + { "psadbw", 0x06 }, + { "pshufb", 0x06 }, + { "pshufd", 0x06 }, + { "pshufhw", 0x07 }, + { "pshuflw", 0x07 }, + { "pshufw", 0x06 }, + { "psignb", 0x06 }, + { "psignd", 0x06 }, + { "psignw", 0x06 }, + { "pslld", 0x05 }, + { "pslldq", 0x06 }, + { "psllq", 0x05 }, + { "psllw", 0x05 }, + { "psrad", 0x05 }, + { "psraw", 0x05 }, + { "psrld", 0x05 }, + { "psrldq", 0x06 }, + { "psrlq", 0x05 }, + { "psrlw", 0x05 }, + { "psubb", 0x05 }, + { "psubd", 0x05 }, + { "psubq", 0x05 }, + { "psubsb", 0x06 }, + { "psubsw", 0x06 }, + { "psubusb", 0x07 }, + { "psubusw", 0x07 }, + { "psubw", 0x05 }, + { "pswapd", 0x06 }, + { "ptest", 0x05 }, + { "ptwrite", 0x07 }, + { "punpckhbw", 0x09 }, + { "punpckhdq", 0x09 }, + { "punpckhqdq", 0x0A }, + { "punpckhwd", 0x09 }, + { "punpcklbw", 0x09 }, + { "punpckldq", 0x09 }, + { "punpcklqdq", 0x0A }, + { "punpcklwd", 0x09 }, + { "push", 0x04 }, + { "pusha", 0x05 }, + { "pushad", 0x06 }, + { "pushf", 0x05 }, + { "pushfd", 0x06 }, + { "pushfq", 0x06 }, + { "pxor", 0x04 }, + { "rcl", 0x03 }, + { "rcpps", 0x05 }, + { "rcpss", 0x05 }, + { "rcr", 0x03 }, + { "rdfsbase", 0x08 }, + { "rdgsbase", 0x08 }, + { "rdmsr", 0x05 }, + { "rdpid", 0x05 }, + { "rdpkru", 0x06 }, + { "rdpmc", 0x05 }, + { "rdrand", 0x06 }, + { "rdseed", 0x06 }, + { "rdsspd", 0x06 }, + { "rdsspq", 0x06 }, + { "rdtsc", 0x05 }, + { "rdtscp", 0x06 }, + { "ret", 0x03 }, + { "rol", 0x03 }, + { "ror", 0x03 }, + { "rorx", 0x04 }, + { "roundpd", 0x07 }, + { "roundps", 0x07 }, + { "roundsd", 0x07 }, + { "roundss", 0x07 }, + { "rsm", 0x03 }, + { "rsqrtps", 0x07 }, + { "rsqrtss", 0x07 }, + { "rstorssp", 0x08 }, + { "sahf", 0x04 }, + { "salc", 0x04 }, + { "sar", 0x03 }, + { "sarx", 0x04 }, + { "savessp", 0x07 }, + { "sbb", 0x03 }, + { "scasb", 0x05 }, + { "scasd", 0x05 }, + { "scasq", 0x05 }, + { "scasw", 0x05 }, + { "setb", 0x04 }, + { "setbe", 0x05 }, + { "setl", 0x04 }, + { "setle", 0x05 }, + { "setnb", 0x05 }, + { "setnbe", 0x06 }, + { "setnl", 0x05 }, + { "setnle", 0x06 }, + { "setno", 0x05 }, + { "setnp", 0x05 }, + { "setns", 0x05 }, + { "setnz", 0x05 }, + { "seto", 0x04 }, + { "setp", 0x04 }, + { "sets", 0x04 }, + { "setssbsy", 0x08 }, + { "setz", 0x04 }, + { "sfence", 0x06 }, + { "sgdt", 0x04 }, + { "sha1msg1", 0x08 }, + { "sha1msg2", 0x08 }, + { "sha1nexte", 0x09 }, + { "sha1rnds4", 0x09 }, + { "sha256msg1", 0x0A }, + { "sha256msg2", 0x0A }, + { "sha256rnds2", 0x0B }, + { "shl", 0x03 }, + { "shld", 0x04 }, + { "shlx", 0x04 }, + { "shr", 0x03 }, + { "shrd", 0x04 }, + { "shrx", 0x04 }, + { "shufpd", 0x06 }, + { "shufps", 0x06 }, + { "sidt", 0x04 }, + { "skinit", 0x06 }, + { "sldt", 0x04 }, + { "slwpcb", 0x06 }, + { "smsw", 0x04 }, + { "spflt", 0x05 }, + { "sqrtpd", 0x06 }, + { "sqrtps", 0x06 }, + { "sqrtsd", 0x06 }, + { "sqrtss", 0x06 }, + { "stac", 0x04 }, + { "stc", 0x03 }, + { "std", 0x03 }, + { "stgi", 0x04 }, + { "sti", 0x03 }, + { "stmxcsr", 0x07 }, + { "stosb", 0x05 }, + { "stosd", 0x05 }, + { "stosq", 0x05 }, + { "stosw", 0x05 }, + { "str", 0x03 }, + { "sub", 0x03 }, + { "subpd", 0x05 }, + { "subps", 0x05 }, + { "subsd", 0x05 }, + { "subss", 0x05 }, + { "swapgs", 0x06 }, + { "syscall", 0x07 }, + { "sysenter", 0x08 }, + { "sysexit", 0x07 }, + { "sysret", 0x06 }, + { "t1mskc", 0x06 }, + { "test", 0x04 }, + { "tzcnt", 0x05 }, + { "tzcnti", 0x06 }, + { "tzmsk", 0x05 }, + { "ucomisd", 0x07 }, + { "ucomiss", 0x07 }, + { "ud0", 0x03 }, + { "ud1", 0x03 }, + { "ud2", 0x03 }, + { "unpckhpd", 0x08 }, + { "unpckhps", 0x08 }, + { "unpcklpd", 0x08 }, + { "unpcklps", 0x08 }, + { "v4fmaddps", 0x09 }, + { "v4fmaddss", 0x09 }, + { "v4fnmaddps", 0x0A }, + { "v4fnmaddss", 0x0A }, + { "vaddnpd", 0x07 }, + { "vaddnps", 0x07 }, + { "vaddpd", 0x06 }, + { "vaddps", 0x06 }, + { "vaddsd", 0x06 }, + { "vaddsetsps", 0x0A }, + { "vaddss", 0x06 }, + { "vaddsubpd", 0x09 }, + { "vaddsubps", 0x09 }, + { "vaesdec", 0x07 }, + { "vaesdeclast", 0x0B }, + { "vaesenc", 0x07 }, + { "vaesenclast", 0x0B }, + { "vaesimc", 0x07 }, + { "vaeskeygenassist", 0x10 }, + { "valignd", 0x07 }, + { "valignq", 0x07 }, + { "vandnpd", 0x07 }, + { "vandnps", 0x07 }, + { "vandpd", 0x06 }, + { "vandps", 0x06 }, + { "vblendmpd", 0x09 }, + { "vblendmps", 0x09 }, + { "vblendpd", 0x08 }, + { "vblendps", 0x08 }, + { "vblendvpd", 0x09 }, + { "vblendvps", 0x09 }, + { "vbroadcastf128", 0x0E }, + { "vbroadcastf32x2", 0x0F }, + { "vbroadcastf32x4", 0x0F }, + { "vbroadcastf32x8", 0x0F }, + { "vbroadcastf64x2", 0x0F }, + { "vbroadcastf64x4", 0x0F }, + { "vbroadcasti128", 0x0E }, + { "vbroadcasti32x2", 0x0F }, + { "vbroadcasti32x4", 0x0F }, + { "vbroadcasti32x8", 0x0F }, + { "vbroadcasti64x2", 0x0F }, + { "vbroadcasti64x4", 0x0F }, + { "vbroadcastsd", 0x0C }, + { "vbroadcastss", 0x0C }, + { "vcmppd", 0x06 }, + { "vcmpps", 0x06 }, + { "vcmpsd", 0x06 }, + { "vcmpss", 0x06 }, + { "vcomisd", 0x07 }, + { "vcomiss", 0x07 }, + { "vcompresspd", 0x0B }, + { "vcompressps", 0x0B }, + { "vcvtdq2pd", 0x09 }, + { "vcvtdq2ps", 0x09 }, + { "vcvtfxpntdq2ps", 0x0E }, + { "vcvtfxpntpd2dq", 0x0E }, + { "vcvtfxpntpd2udq", 0x0F }, + { "vcvtfxpntps2dq", 0x0E }, + { "vcvtfxpntps2udq", 0x0F }, + { "vcvtfxpntudq2ps", 0x0F }, + { "vcvtpd2dq", 0x09 }, + { "vcvtpd2ps", 0x09 }, + { "vcvtpd2qq", 0x09 }, + { "vcvtpd2udq", 0x0A }, + { "vcvtpd2uqq", 0x0A }, + { "vcvtph2ps", 0x09 }, + { "vcvtps2dq", 0x09 }, + { "vcvtps2pd", 0x09 }, + { "vcvtps2ph", 0x09 }, + { "vcvtps2qq", 0x09 }, + { "vcvtps2udq", 0x0A }, + { "vcvtps2uqq", 0x0A }, + { "vcvtqq2pd", 0x09 }, + { "vcvtqq2ps", 0x09 }, + { "vcvtsd2si", 0x09 }, + { "vcvtsd2ss", 0x09 }, + { "vcvtsd2usi", 0x0A }, + { "vcvtsi2sd", 0x09 }, + { "vcvtsi2ss", 0x09 }, + { "vcvtss2sd", 0x09 }, + { "vcvtss2si", 0x09 }, + { "vcvtss2usi", 0x0A }, + { "vcvttpd2dq", 0x0A }, + { "vcvttpd2qq", 0x0A }, + { "vcvttpd2udq", 0x0B }, + { "vcvttpd2uqq", 0x0B }, + { "vcvttps2dq", 0x0A }, + { "vcvttps2qq", 0x0A }, + { "vcvttps2udq", 0x0B }, + { "vcvttps2uqq", 0x0B }, + { "vcvttsd2si", 0x0A }, + { "vcvttsd2usi", 0x0B }, + { "vcvttss2si", 0x0A }, + { "vcvttss2usi", 0x0B }, + { "vcvtudq2pd", 0x0A }, + { "vcvtudq2ps", 0x0A }, + { "vcvtuqq2pd", 0x0A }, + { "vcvtuqq2ps", 0x0A }, + { "vcvtusi2sd", 0x0A }, + { "vcvtusi2ss", 0x0A }, + { "vdbpsadbw", 0x09 }, + { "vdivpd", 0x06 }, + { "vdivps", 0x06 }, + { "vdivsd", 0x06 }, + { "vdivss", 0x06 }, + { "vdppd", 0x05 }, + { "vdpps", 0x05 }, + { "verr", 0x04 }, + { "verw", 0x04 }, + { "vexp223ps", 0x09 }, + { "vexp2pd", 0x07 }, + { "vexp2ps", 0x07 }, + { "vexpandpd", 0x09 }, + { "vexpandps", 0x09 }, + { "vextractf128", 0x0C }, + { "vextractf32x4", 0x0D }, + { "vextractf32x8", 0x0D }, + { "vextractf64x2", 0x0D }, + { "vextractf64x4", 0x0D }, + { "vextracti128", 0x0C }, + { "vextracti32x4", 0x0D }, + { "vextracti32x8", 0x0D }, + { "vextracti64x2", 0x0D }, + { "vextracti64x4", 0x0D }, + { "vextractps", 0x0A }, + { "vfixupimmpd", 0x0B }, + { "vfixupimmps", 0x0B }, + { "vfixupimmsd", 0x0B }, + { "vfixupimmss", 0x0B }, + { "vfixupnanpd", 0x0B }, + { "vfixupnanps", 0x0B }, + { "vfmadd132pd", 0x0B }, + { "vfmadd132ps", 0x0B }, + { "vfmadd132sd", 0x0B }, + { "vfmadd132ss", 0x0B }, + { "vfmadd213pd", 0x0B }, + { "vfmadd213ps", 0x0B }, + { "vfmadd213sd", 0x0B }, + { "vfmadd213ss", 0x0B }, + { "vfmadd231pd", 0x0B }, + { "vfmadd231ps", 0x0B }, + { "vfmadd231sd", 0x0B }, + { "vfmadd231ss", 0x0B }, + { "vfmadd233ps", 0x0B }, + { "vfmaddpd", 0x08 }, + { "vfmaddps", 0x08 }, + { "vfmaddsd", 0x08 }, + { "vfmaddss", 0x08 }, + { "vfmaddsub132pd", 0x0E }, + { "vfmaddsub132ps", 0x0E }, + { "vfmaddsub213pd", 0x0E }, + { "vfmaddsub213ps", 0x0E }, + { "vfmaddsub231pd", 0x0E }, + { "vfmaddsub231ps", 0x0E }, + { "vfmaddsubpd", 0x0B }, + { "vfmaddsubps", 0x0B }, + { "vfmsub132pd", 0x0B }, + { "vfmsub132ps", 0x0B }, + { "vfmsub132sd", 0x0B }, + { "vfmsub132ss", 0x0B }, + { "vfmsub213pd", 0x0B }, + { "vfmsub213ps", 0x0B }, + { "vfmsub213sd", 0x0B }, + { "vfmsub213ss", 0x0B }, + { "vfmsub231pd", 0x0B }, + { "vfmsub231ps", 0x0B }, + { "vfmsub231sd", 0x0B }, + { "vfmsub231ss", 0x0B }, + { "vfmsubadd132pd", 0x0E }, + { "vfmsubadd132ps", 0x0E }, + { "vfmsubadd213pd", 0x0E }, + { "vfmsubadd213ps", 0x0E }, + { "vfmsubadd231pd", 0x0E }, + { "vfmsubadd231ps", 0x0E }, + { "vfmsubaddpd", 0x0B }, + { "vfmsubaddps", 0x0B }, + { "vfmsubpd", 0x08 }, + { "vfmsubps", 0x08 }, + { "vfmsubsd", 0x08 }, + { "vfmsubss", 0x08 }, + { "vfnmadd132pd", 0x0C }, + { "vfnmadd132ps", 0x0C }, + { "vfnmadd132sd", 0x0C }, + { "vfnmadd132ss", 0x0C }, + { "vfnmadd213pd", 0x0C }, + { "vfnmadd213ps", 0x0C }, + { "vfnmadd213sd", 0x0C }, + { "vfnmadd213ss", 0x0C }, + { "vfnmadd231pd", 0x0C }, + { "vfnmadd231ps", 0x0C }, + { "vfnmadd231sd", 0x0C }, + { "vfnmadd231ss", 0x0C }, + { "vfnmaddpd", 0x09 }, + { "vfnmaddps", 0x09 }, + { "vfnmaddsd", 0x09 }, + { "vfnmaddss", 0x09 }, + { "vfnmsub132pd", 0x0C }, + { "vfnmsub132ps", 0x0C }, + { "vfnmsub132sd", 0x0C }, + { "vfnmsub132ss", 0x0C }, + { "vfnmsub213pd", 0x0C }, + { "vfnmsub213ps", 0x0C }, + { "vfnmsub213sd", 0x0C }, + { "vfnmsub213ss", 0x0C }, + { "vfnmsub231pd", 0x0C }, + { "vfnmsub231ps", 0x0C }, + { "vfnmsub231sd", 0x0C }, + { "vfnmsub231ss", 0x0C }, + { "vfnmsubpd", 0x09 }, + { "vfnmsubps", 0x09 }, + { "vfnmsubsd", 0x09 }, + { "vfnmsubss", 0x09 }, + { "vfpclasspd", 0x0A }, + { "vfpclassps", 0x0A }, + { "vfpclasssd", 0x0A }, + { "vfpclassss", 0x0A }, + { "vfrczpd", 0x07 }, + { "vfrczps", 0x07 }, + { "vfrczsd", 0x07 }, + { "vfrczss", 0x07 }, + { "vgatherdpd", 0x0A }, + { "vgatherdps", 0x0A }, + { "vgatherpf0dpd", 0x0D }, + { "vgatherpf0dps", 0x0D }, + { "vgatherpf0hintdpd", 0x11 }, + { "vgatherpf0hintdps", 0x11 }, + { "vgatherpf0qpd", 0x0D }, + { "vgatherpf0qps", 0x0D }, + { "vgatherpf1dpd", 0x0D }, + { "vgatherpf1dps", 0x0D }, + { "vgatherpf1qpd", 0x0D }, + { "vgatherpf1qps", 0x0D }, + { "vgatherqpd", 0x0A }, + { "vgatherqps", 0x0A }, + { "vgetexppd", 0x09 }, + { "vgetexpps", 0x09 }, + { "vgetexpsd", 0x09 }, + { "vgetexpss", 0x09 }, + { "vgetmantpd", 0x0A }, + { "vgetmantps", 0x0A }, + { "vgetmantsd", 0x0A }, + { "vgetmantss", 0x0A }, + { "vgf2p8affineinvqb", 0x11 }, + { "vgf2p8affineqb", 0x0E }, + { "vgf2p8mulb", 0x0A }, + { "vgmaxabsps", 0x0A }, + { "vgmaxpd", 0x07 }, + { "vgmaxps", 0x07 }, + { "vgminpd", 0x07 }, + { "vgminps", 0x07 }, + { "vhaddpd", 0x07 }, + { "vhaddps", 0x07 }, + { "vhsubpd", 0x07 }, + { "vhsubps", 0x07 }, + { "vinsertf128", 0x0B }, + { "vinsertf32x4", 0x0C }, + { "vinsertf32x8", 0x0C }, + { "vinsertf64x2", 0x0C }, + { "vinsertf64x4", 0x0C }, + { "vinserti128", 0x0B }, + { "vinserti32x4", 0x0C }, + { "vinserti32x8", 0x0C }, + { "vinserti64x2", 0x0C }, + { "vinserti64x4", 0x0C }, + { "vinsertps", 0x09 }, + { "vlddqu", 0x06 }, + { "vldmxcsr", 0x08 }, + { "vloadunpackhd", 0x0D }, + { "vloadunpackhpd", 0x0E }, + { "vloadunpackhps", 0x0E }, + { "vloadunpackhq", 0x0D }, + { "vloadunpackld", 0x0D }, + { "vloadunpacklpd", 0x0E }, + { "vloadunpacklps", 0x0E }, + { "vloadunpacklq", 0x0D }, + { "vlog2ps", 0x07 }, + { "vmaskmovdqu", 0x0B }, + { "vmaskmovpd", 0x0A }, + { "vmaskmovps", 0x0A }, + { "vmaxpd", 0x06 }, + { "vmaxps", 0x06 }, + { "vmaxsd", 0x06 }, + { "vmaxss", 0x06 }, + { "vmcall", 0x06 }, + { "vmclear", 0x07 }, + { "vmfunc", 0x06 }, + { "vminpd", 0x06 }, + { "vminps", 0x06 }, + { "vminsd", 0x06 }, + { "vminss", 0x06 }, + { "vmlaunch", 0x08 }, + { "vmload", 0x06 }, + { "vmmcall", 0x07 }, + { "vmovapd", 0x07 }, + { "vmovaps", 0x07 }, + { "vmovd", 0x05 }, + { "vmovddup", 0x08 }, + { "vmovdqa", 0x07 }, + { "vmovdqa32", 0x09 }, + { "vmovdqa64", 0x09 }, + { "vmovdqu", 0x07 }, + { "vmovdqu16", 0x09 }, + { "vmovdqu32", 0x09 }, + { "vmovdqu64", 0x09 }, + { "vmovdqu8", 0x08 }, + { "vmovhlps", 0x08 }, + { "vmovhpd", 0x07 }, + { "vmovhps", 0x07 }, + { "vmovlhps", 0x08 }, + { "vmovlpd", 0x07 }, + { "vmovlps", 0x07 }, + { "vmovmskpd", 0x09 }, + { "vmovmskps", 0x09 }, + { "vmovnrapd", 0x09 }, + { "vmovnraps", 0x09 }, + { "vmovnrngoapd", 0x0C }, + { "vmovnrngoaps", 0x0C }, + { "vmovntdq", 0x08 }, + { "vmovntdqa", 0x09 }, + { "vmovntpd", 0x08 }, + { "vmovntps", 0x08 }, + { "vmovq", 0x05 }, + { "vmovsd", 0x06 }, + { "vmovshdup", 0x09 }, + { "vmovsldup", 0x09 }, + { "vmovss", 0x06 }, + { "vmovupd", 0x07 }, + { "vmovups", 0x07 }, + { "vmpsadbw", 0x08 }, + { "vmptrld", 0x07 }, + { "vmptrst", 0x07 }, + { "vmread", 0x06 }, + { "vmresume", 0x08 }, + { "vmrun", 0x05 }, + { "vmsave", 0x06 }, + { "vmulpd", 0x06 }, + { "vmulps", 0x06 }, + { "vmulsd", 0x06 }, + { "vmulss", 0x06 }, + { "vmwrite", 0x07 }, + { "vmxoff", 0x06 }, + { "vmxon", 0x05 }, + { "vorpd", 0x05 }, + { "vorps", 0x05 }, + { "vp4dpwssd", 0x09 }, + { "vp4dpwssds", 0x0A }, + { "vpabsb", 0x06 }, + { "vpabsd", 0x06 }, + { "vpabsq", 0x06 }, + { "vpabsw", 0x06 }, + { "vpackssdw", 0x09 }, + { "vpacksswb", 0x09 }, + { "vpackstorehd", 0x0C }, + { "vpackstorehpd", 0x0D }, + { "vpackstorehps", 0x0D }, + { "vpackstorehq", 0x0C }, + { "vpackstoreld", 0x0C }, + { "vpackstorelpd", 0x0D }, + { "vpackstorelps", 0x0D }, + { "vpackstorelq", 0x0C }, + { "vpackusdw", 0x09 }, + { "vpackuswb", 0x09 }, + { "vpadcd", 0x06 }, + { "vpaddb", 0x06 }, + { "vpaddd", 0x06 }, + { "vpaddq", 0x06 }, + { "vpaddsb", 0x07 }, + { "vpaddsetcd", 0x0A }, + { "vpaddsetsd", 0x0A }, + { "vpaddsw", 0x07 }, + { "vpaddusb", 0x08 }, + { "vpaddusw", 0x08 }, + { "vpaddw", 0x06 }, + { "vpalignr", 0x08 }, + { "vpand", 0x05 }, + { "vpandd", 0x06 }, + { "vpandn", 0x06 }, + { "vpandnd", 0x07 }, + { "vpandnq", 0x07 }, + { "vpandq", 0x06 }, + { "vpavgb", 0x06 }, + { "vpavgw", 0x06 }, + { "vpblendd", 0x08 }, + { "vpblendmb", 0x09 }, + { "vpblendmd", 0x09 }, + { "vpblendmq", 0x09 }, + { "vpblendmw", 0x09 }, + { "vpblendvb", 0x09 }, + { "vpblendw", 0x08 }, + { "vpbroadcastb", 0x0C }, + { "vpbroadcastd", 0x0C }, + { "vpbroadcastmb2q", 0x0F }, + { "vpbroadcastmw2d", 0x0F }, + { "vpbroadcastq", 0x0C }, + { "vpbroadcastw", 0x0C }, + { "vpclmulqdq", 0x0A }, + { "vpcmov", 0x06 }, + { "vpcmpb", 0x06 }, + { "vpcmpd", 0x06 }, + { "vpcmpeqb", 0x08 }, + { "vpcmpeqd", 0x08 }, + { "vpcmpeqq", 0x08 }, + { "vpcmpeqw", 0x08 }, + { "vpcmpestri", 0x0A }, + { "vpcmpestrm", 0x0A }, + { "vpcmpgtb", 0x08 }, + { "vpcmpgtd", 0x08 }, + { "vpcmpgtq", 0x08 }, + { "vpcmpgtw", 0x08 }, + { "vpcmpistri", 0x0A }, + { "vpcmpistrm", 0x0A }, + { "vpcmpltd", 0x08 }, + { "vpcmpq", 0x06 }, + { "vpcmpub", 0x07 }, + { "vpcmpud", 0x07 }, + { "vpcmpuq", 0x07 }, + { "vpcmpuw", 0x07 }, + { "vpcmpw", 0x06 }, + { "vpcomb", 0x06 }, + { "vpcomd", 0x06 }, + { "vpcompressb", 0x0B }, + { "vpcompressd", 0x0B }, + { "vpcompressq", 0x0B }, + { "vpcompressw", 0x0B }, + { "vpcomq", 0x06 }, + { "vpcomub", 0x07 }, + { "vpcomud", 0x07 }, + { "vpcomuq", 0x07 }, + { "vpcomuw", 0x07 }, + { "vpcomw", 0x06 }, + { "vpconflictd", 0x0B }, + { "vpconflictq", 0x0B }, + { "vpdpbusd", 0x08 }, + { "vpdpbusds", 0x09 }, + { "vpdpwssd", 0x08 }, + { "vpdpwssds", 0x09 }, + { "vperm2f128", 0x0A }, + { "vperm2i128", 0x0A }, + { "vpermb", 0x06 }, + { "vpermd", 0x06 }, + { "vpermf32x4", 0x0A }, + { "vpermi2b", 0x08 }, + { "vpermi2d", 0x08 }, + { "vpermi2pd", 0x09 }, + { "vpermi2ps", 0x09 }, + { "vpermi2q", 0x08 }, + { "vpermi2w", 0x08 }, + { "vpermil2pd", 0x0A }, + { "vpermil2ps", 0x0A }, + { "vpermilpd", 0x09 }, + { "vpermilps", 0x09 }, + { "vpermpd", 0x07 }, + { "vpermps", 0x07 }, + { "vpermq", 0x06 }, + { "vpermt2b", 0x08 }, + { "vpermt2d", 0x08 }, + { "vpermt2pd", 0x09 }, + { "vpermt2ps", 0x09 }, + { "vpermt2q", 0x08 }, + { "vpermt2w", 0x08 }, + { "vpermw", 0x06 }, + { "vpexpandb", 0x09 }, + { "vpexpandd", 0x09 }, + { "vpexpandq", 0x09 }, + { "vpexpandw", 0x09 }, + { "vpextrb", 0x07 }, + { "vpextrd", 0x07 }, + { "vpextrq", 0x07 }, + { "vpextrw", 0x07 }, + { "vpgatherdd", 0x0A }, + { "vpgatherdq", 0x0A }, + { "vpgatherqd", 0x0A }, + { "vpgatherqq", 0x0A }, + { "vphaddbd", 0x08 }, + { "vphaddbq", 0x08 }, + { "vphaddbw", 0x08 }, + { "vphaddd", 0x07 }, + { "vphadddq", 0x08 }, + { "vphaddsw", 0x08 }, + { "vphaddubd", 0x09 }, + { "vphaddubq", 0x09 }, + { "vphaddubw", 0x09 }, + { "vphaddudq", 0x09 }, + { "vphadduwd", 0x09 }, + { "vphadduwq", 0x09 }, + { "vphaddw", 0x07 }, + { "vphaddwd", 0x08 }, + { "vphaddwq", 0x08 }, + { "vphminposuw", 0x0B }, + { "vphsubbw", 0x08 }, + { "vphsubd", 0x07 }, + { "vphsubdq", 0x08 }, + { "vphsubsw", 0x08 }, + { "vphsubw", 0x07 }, + { "vphsubwd", 0x08 }, + { "vpinsrb", 0x07 }, + { "vpinsrd", 0x07 }, + { "vpinsrq", 0x07 }, + { "vpinsrw", 0x07 }, + { "vplzcntd", 0x08 }, + { "vplzcntq", 0x08 }, + { "vpmacsdd", 0x08 }, + { "vpmacsdqh", 0x09 }, + { "vpmacsdql", 0x09 }, + { "vpmacssdd", 0x09 }, + { "vpmacssdqh", 0x0A }, + { "vpmacssdql", 0x0A }, + { "vpmacsswd", 0x09 }, + { "vpmacssww", 0x09 }, + { "vpmacswd", 0x08 }, + { "vpmacsww", 0x08 }, + { "vpmadcsswd", 0x0A }, + { "vpmadcswd", 0x09 }, + { "vpmadd231d", 0x0A }, + { "vpmadd233d", 0x0A }, + { "vpmadd52huq", 0x0B }, + { "vpmadd52luq", 0x0B }, + { "vpmaddubsw", 0x0A }, + { "vpmaddwd", 0x08 }, + { "vpmaskmovd", 0x0A }, + { "vpmaskmovq", 0x0A }, + { "vpmaxsb", 0x07 }, + { "vpmaxsd", 0x07 }, + { "vpmaxsq", 0x07 }, + { "vpmaxsw", 0x07 }, + { "vpmaxub", 0x07 }, + { "vpmaxud", 0x07 }, + { "vpmaxuq", 0x07 }, + { "vpmaxuw", 0x07 }, + { "vpminsb", 0x07 }, + { "vpminsd", 0x07 }, + { "vpminsq", 0x07 }, + { "vpminsw", 0x07 }, + { "vpminub", 0x07 }, + { "vpminud", 0x07 }, + { "vpminuq", 0x07 }, + { "vpminuw", 0x07 }, + { "vpmovb2m", 0x08 }, + { "vpmovd2m", 0x08 }, + { "vpmovdb", 0x07 }, + { "vpmovdw", 0x07 }, + { "vpmovm2b", 0x08 }, + { "vpmovm2d", 0x08 }, + { "vpmovm2q", 0x08 }, + { "vpmovm2w", 0x08 }, + { "vpmovmskb", 0x09 }, + { "vpmovq2m", 0x08 }, + { "vpmovqb", 0x07 }, + { "vpmovqd", 0x07 }, + { "vpmovqw", 0x07 }, + { "vpmovsdb", 0x08 }, + { "vpmovsdw", 0x08 }, + { "vpmovsqb", 0x08 }, + { "vpmovsqd", 0x08 }, + { "vpmovsqw", 0x08 }, + { "vpmovswb", 0x08 }, + { "vpmovsxbd", 0x09 }, + { "vpmovsxbq", 0x09 }, + { "vpmovsxbw", 0x09 }, + { "vpmovsxdq", 0x09 }, + { "vpmovsxwd", 0x09 }, + { "vpmovsxwq", 0x09 }, + { "vpmovusdb", 0x09 }, + { "vpmovusdw", 0x09 }, + { "vpmovusqb", 0x09 }, + { "vpmovusqd", 0x09 }, + { "vpmovusqw", 0x09 }, + { "vpmovuswb", 0x09 }, + { "vpmovw2m", 0x08 }, + { "vpmovwb", 0x07 }, + { "vpmovzxbd", 0x09 }, + { "vpmovzxbq", 0x09 }, + { "vpmovzxbw", 0x09 }, + { "vpmovzxdq", 0x09 }, + { "vpmovzxwd", 0x09 }, + { "vpmovzxwq", 0x09 }, + { "vpmuldq", 0x07 }, + { "vpmulhd", 0x07 }, + { "vpmulhrsw", 0x09 }, + { "vpmulhud", 0x08 }, + { "vpmulhuw", 0x08 }, + { "vpmulhw", 0x07 }, + { "vpmulld", 0x07 }, + { "vpmullq", 0x07 }, + { "vpmullw", 0x07 }, + { "vpmultishiftqb", 0x0E }, + { "vpmuludq", 0x08 }, + { "vpopcntb", 0x08 }, + { "vpopcntd", 0x08 }, + { "vpopcntq", 0x08 }, + { "vpopcntw", 0x08 }, + { "vpor", 0x04 }, + { "vpord", 0x05 }, + { "vporq", 0x05 }, + { "vpperm", 0x06 }, + { "vprefetch0", 0x0A }, + { "vprefetch1", 0x0A }, + { "vprefetch2", 0x0A }, + { "vprefetche0", 0x0B }, + { "vprefetche1", 0x0B }, + { "vprefetche2", 0x0B }, + { "vprefetchenta", 0x0D }, + { "vprefetchnta", 0x0C }, + { "vprold", 0x06 }, + { "vprolq", 0x06 }, + { "vprolvd", 0x07 }, + { "vprolvq", 0x07 }, + { "vprord", 0x06 }, + { "vprorq", 0x06 }, + { "vprorvd", 0x07 }, + { "vprorvq", 0x07 }, + { "vprotb", 0x06 }, + { "vprotd", 0x06 }, + { "vprotq", 0x06 }, + { "vprotw", 0x06 }, + { "vpsadbw", 0x07 }, + { "vpsbbd", 0x06 }, + { "vpsbbrd", 0x07 }, + { "vpscatterdd", 0x0B }, + { "vpscatterdq", 0x0B }, + { "vpscatterqd", 0x0B }, + { "vpscatterqq", 0x0B }, + { "vpshab", 0x06 }, + { "vpshad", 0x06 }, + { "vpshaq", 0x06 }, + { "vpshaw", 0x06 }, + { "vpshlb", 0x06 }, + { "vpshld", 0x06 }, + { "vpshldd", 0x07 }, + { "vpshldq", 0x07 }, + { "vpshldvd", 0x08 }, + { "vpshldvq", 0x08 }, + { "vpshldvw", 0x08 }, + { "vpshldw", 0x07 }, + { "vpshlq", 0x06 }, + { "vpshlw", 0x06 }, + { "vpshrdd", 0x07 }, + { "vpshrdq", 0x07 }, + { "vpshrdvd", 0x08 }, + { "vpshrdvq", 0x08 }, + { "vpshrdvw", 0x08 }, + { "vpshrdw", 0x07 }, + { "vpshufb", 0x07 }, + { "vpshufbitqmb", 0x0C }, + { "vpshufd", 0x07 }, + { "vpshufhw", 0x08 }, + { "vpshuflw", 0x08 }, + { "vpsignb", 0x07 }, + { "vpsignd", 0x07 }, + { "vpsignw", 0x07 }, + { "vpslld", 0x06 }, + { "vpslldq", 0x07 }, + { "vpsllq", 0x06 }, + { "vpsllvd", 0x07 }, + { "vpsllvq", 0x07 }, + { "vpsllvw", 0x07 }, + { "vpsllw", 0x06 }, + { "vpsrad", 0x06 }, + { "vpsraq", 0x06 }, + { "vpsravd", 0x07 }, + { "vpsravq", 0x07 }, + { "vpsravw", 0x07 }, + { "vpsraw", 0x06 }, + { "vpsrld", 0x06 }, + { "vpsrldq", 0x07 }, + { "vpsrlq", 0x06 }, + { "vpsrlvd", 0x07 }, + { "vpsrlvq", 0x07 }, + { "vpsrlvw", 0x07 }, + { "vpsrlw", 0x06 }, + { "vpsubb", 0x06 }, + { "vpsubd", 0x06 }, + { "vpsubq", 0x06 }, + { "vpsubrd", 0x07 }, + { "vpsubrsetbd", 0x0B }, + { "vpsubsb", 0x07 }, + { "vpsubsetbd", 0x0A }, + { "vpsubsw", 0x07 }, + { "vpsubusb", 0x08 }, + { "vpsubusw", 0x08 }, + { "vpsubw", 0x06 }, + { "vpternlogd", 0x0A }, + { "vpternlogq", 0x0A }, + { "vptest", 0x06 }, + { "vptestmb", 0x08 }, + { "vptestmd", 0x08 }, + { "vptestmq", 0x08 }, + { "vptestmw", 0x08 }, + { "vptestnmb", 0x09 }, + { "vptestnmd", 0x09 }, + { "vptestnmq", 0x09 }, + { "vptestnmw", 0x09 }, + { "vpunpckhbw", 0x0A }, + { "vpunpckhdq", 0x0A }, + { "vpunpckhqdq", 0x0B }, + { "vpunpckhwd", 0x0A }, + { "vpunpcklbw", 0x0A }, + { "vpunpckldq", 0x0A }, + { "vpunpcklqdq", 0x0B }, + { "vpunpcklwd", 0x0A }, + { "vpxor", 0x05 }, + { "vpxord", 0x06 }, + { "vpxorq", 0x06 }, + { "vrangepd", 0x08 }, + { "vrangeps", 0x08 }, + { "vrangesd", 0x08 }, + { "vrangess", 0x08 }, + { "vrcp14pd", 0x08 }, + { "vrcp14ps", 0x08 }, + { "vrcp14sd", 0x08 }, + { "vrcp14ss", 0x08 }, + { "vrcp23ps", 0x08 }, + { "vrcp28pd", 0x08 }, + { "vrcp28ps", 0x08 }, + { "vrcp28sd", 0x08 }, + { "vrcp28ss", 0x08 }, + { "vrcpps", 0x06 }, + { "vrcpss", 0x06 }, + { "vreducepd", 0x09 }, + { "vreduceps", 0x09 }, + { "vreducesd", 0x09 }, + { "vreducess", 0x09 }, + { "vrndfxpntpd", 0x0B }, + { "vrndfxpntps", 0x0B }, + { "vrndscalepd", 0x0B }, + { "vrndscaleps", 0x0B }, + { "vrndscalesd", 0x0B }, + { "vrndscaless", 0x0B }, + { "vroundpd", 0x08 }, + { "vroundps", 0x08 }, + { "vroundsd", 0x08 }, + { "vroundss", 0x08 }, + { "vrsqrt14pd", 0x0A }, + { "vrsqrt14ps", 0x0A }, + { "vrsqrt14sd", 0x0A }, + { "vrsqrt14ss", 0x0A }, + { "vrsqrt23ps", 0x0A }, + { "vrsqrt28pd", 0x0A }, + { "vrsqrt28ps", 0x0A }, + { "vrsqrt28sd", 0x0A }, + { "vrsqrt28ss", 0x0A }, + { "vrsqrtps", 0x08 }, + { "vrsqrtss", 0x08 }, + { "vscalefpd", 0x09 }, + { "vscalefps", 0x09 }, + { "vscalefsd", 0x09 }, + { "vscalefss", 0x09 }, + { "vscaleps", 0x08 }, + { "vscatterdpd", 0x0B }, + { "vscatterdps", 0x0B }, + { "vscatterpf0dpd", 0x0E }, + { "vscatterpf0dps", 0x0E }, + { "vscatterpf0hintdpd", 0x12 }, + { "vscatterpf0hintdps", 0x12 }, + { "vscatterpf0qpd", 0x0E }, + { "vscatterpf0qps", 0x0E }, + { "vscatterpf1dpd", 0x0E }, + { "vscatterpf1dps", 0x0E }, + { "vscatterpf1qpd", 0x0E }, + { "vscatterpf1qps", 0x0E }, + { "vscatterqpd", 0x0B }, + { "vscatterqps", 0x0B }, + { "vshuff32x4", 0x0A }, + { "vshuff64x2", 0x0A }, + { "vshufi32x4", 0x0A }, + { "vshufi64x2", 0x0A }, + { "vshufpd", 0x07 }, + { "vshufps", 0x07 }, + { "vsqrtpd", 0x07 }, + { "vsqrtps", 0x07 }, + { "vsqrtsd", 0x07 }, + { "vsqrtss", 0x07 }, + { "vstmxcsr", 0x08 }, + { "vsubpd", 0x06 }, + { "vsubps", 0x06 }, + { "vsubrpd", 0x07 }, + { "vsubrps", 0x07 }, + { "vsubsd", 0x06 }, + { "vsubss", 0x06 }, + { "vtestpd", 0x07 }, + { "vtestps", 0x07 }, + { "vucomisd", 0x08 }, + { "vucomiss", 0x08 }, + { "vunpckhpd", 0x09 }, + { "vunpckhps", 0x09 }, + { "vunpcklpd", 0x09 }, + { "vunpcklps", 0x09 }, + { "vxorpd", 0x06 }, + { "vxorps", 0x06 }, + { "vzeroall", 0x08 }, + { "vzeroupper", 0x0A }, + { "wbinvd", 0x06 }, + { "wrfsbase", 0x08 }, + { "wrgsbase", 0x08 }, + { "wrmsr", 0x05 }, + { "wrpkru", 0x06 }, + { "wrssd", 0x05 }, + { "wrssq", 0x05 }, + { "wrussd", 0x06 }, + { "wrussq", 0x06 }, + { "xabort", 0x06 }, + { "xadd", 0x04 }, + { "xbegin", 0x06 }, + { "xchg", 0x04 }, + { "xend", 0x04 }, + { "xgetbv", 0x06 }, + { "xlat", 0x04 }, + { "xor", 0x03 }, + { "xorpd", 0x05 }, + { "xorps", 0x05 }, + { "xrstor", 0x06 }, + { "xrstor64", 0x08 }, + { "xrstors", 0x07 }, + { "xrstors64", 0x09 }, + { "xsave", 0x05 }, + { "xsave64", 0x07 }, + { "xsavec", 0x06 }, + { "xsavec64", 0x08 }, + { "xsaveopt", 0x08 }, + { "xsaveopt64", 0x0A }, + { "xsaves", 0x06 }, + { "xsaves64", 0x08 }, + { "xsetbv", 0x06 }, + { "xtest", 0x05 } }; diff --git a/src/Mnemonic.c b/src/Mnemonic.c index 7a11f90..e659ce0 100644 --- a/src/Mnemonic.c +++ b/src/Mnemonic.c @@ -30,8 +30,35 @@ /* Mnemonic strings */ /* ============================================================================================== */ +#pragma pack(push, 1) + +/** + * @brief Defines the `ZydisInternalString` struct. + */ +typedef struct ZydisInternalString_ +{ + /** + * @brief Contains the actual string. + */ + char* buffer; + /** + * @brief The length of the string (without 0-termination). + */ + ZydisU8 length; +} ZydisInternalString; + +#pragma pack(pop) + #include +/** + * @brief Contains all strings that were accessed by `ZydisMnemonicGetStringEx`. + * + * We could store `ZydisString` structs instead of `ZydisInternalString` ones in the + * `zydisMnemonicStrings` array, but this would significantly increase the table-size. + */ +static ZydisString stringTable[ZYDIS_MNEMONIC_MAX_VALUE + 1]; + /* ============================================================================================== */ /* Exported functions */ /* ============================================================================================== */ @@ -42,7 +69,22 @@ const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic) { return ZYDIS_NULL; } - return zydisMnemonicStrings[mnemonic]; + return (const char*)zydisMnemonicStrings[mnemonic].buffer; +} + +const ZydisString* ZydisMnemonicGetStringEx(ZydisMnemonic mnemonic) +{ + if (mnemonic > ZYDIS_ARRAY_SIZE(zydisMnemonicStrings) - 1) + { + return ZYDIS_NULL; + } + if (!stringTable[mnemonic].buffer) + { + stringTable[mnemonic].buffer = zydisMnemonicStrings[mnemonic].buffer; + stringTable[mnemonic].length = zydisMnemonicStrings[mnemonic].length; + stringTable[mnemonic].capacity = zydisMnemonicStrings[mnemonic].length; + } + return &stringTable[mnemonic]; } /* ============================================================================================== */ diff --git a/src/String.c b/src/String.c new file mode 100644 index 0000000..41b4bdf --- /dev/null +++ b/src/String.c @@ -0,0 +1,416 @@ +/*************************************************************************************************** + + Zyan Disassembler Library (Zydis) + + Original Author : Florian Bernd, 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. + +***************************************************************************************************/ + +#include + +/* ============================================================================================== */ +/* Constants */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Defines */ +/* ---------------------------------------------------------------------------------------------- */ + +#define ZYDIS_MAXCHARS_DEC_32 10 +#define ZYDIS_MAXCHARS_DEC_64 20 +#define ZYDIS_MAXCHARS_HEX_32 8 +#define ZYDIS_MAXCHARS_HEX_64 16 + +/* ---------------------------------------------------------------------------------------------- */ +/* Lookup Tables */ +/* ---------------------------------------------------------------------------------------------- */ + +static const char* decimalLookup = + "00010203040506070809" + "10111213141516171819" + "20212223242526272829" + "30313233343536373839" + "40414243444546474849" + "50515253545556575859" + "60616263646566676869" + "70717273747576777879" + "80818283848586878889" + "90919293949596979899"; + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Internal Functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatting */ +/* ---------------------------------------------------------------------------------------------- */ + +#if defined(ZYDIS_X86) || defined(ZYDIS_ARM) +ZydisStatus ZydisPrintDecU32(ZydisString* string, ZydisU32 value, ZydisU8 paddingLength) +{ + ZYDIS_ASSERT(string); + ZYDIS_ASSERT(string->buffer); + + char temp[ZYDIS_MAXCHARS_DEC_32 + 1]; + char *p = &temp[ZYDIS_MAXCHARS_DEC_32]; + 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 ((string->capacity - string->length < (ZydisUSize)(n + 1)) || + (string->capacity - string->length < (ZydisUSize)(paddingLength + 1))) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZydisUSize offset = 0; + if (n <= paddingLength) + { + offset = paddingLength - n + 1; + ZydisMemorySet(string->buffer + string->length, '0', offset); + } + + ZydisMemoryCopy(string->buffer + string->length + offset, &p[value < 10], n + 1); + string->length += n + offset - (ZydisU8)(value < 10); + + return ZYDIS_STATUS_SUCCESS; +} + +ZydisStatus ZydisPrintHexU32(ZydisString* string, ZydisU32 value, ZydisU8 paddingLength, + ZydisBool uppercase, const ZydisString* prefix, const ZydisString* suffix) +{ + ZYDIS_ASSERT(string); + ZYDIS_ASSERT(string->buffer); + + if (prefix) + { + ZYDIS_CHECK(ZydisStringAppend(string, prefix)); + } + + char* buffer = string->buffer + string->length; + const ZydisUSize remaining = string->capacity - string->length; + + if (remaining < (ZydisUSize)paddingLength) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + if (!value) + { + const ZydisU8 n = (paddingLength ? paddingLength : 1); + + if (remaining < (ZydisUSize)n) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZydisMemorySet(buffer, '0', n); + string->length += 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 (remaining <= (ZydisU8)(i + 1)) // TODO: +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]; + } + } + string->length += n; + + if (suffix) + { + ZYDIS_CHECK(ZydisStringAppend(string, suffix)); + } + + return ZYDIS_STATUS_SUCCESS; +} +#endif + +ZydisStatus ZydisPrintDecU64(ZydisString* string, ZydisU64 value, ZydisU8 paddingLength) +{ + ZYDIS_ASSERT(string); + ZYDIS_ASSERT(string->buffer); + + char temp[ZYDIS_MAXCHARS_DEC_64 + 1]; + char *p = &temp[ZYDIS_MAXCHARS_DEC_64]; + while (value >= 100) + { + ZydisU64 const old = value; + p -= 2; + value /= 100; + ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], 2); + } + p -= 2; + ZydisMemoryCopy(p, &decimalLookup[value * 2], sizeof(ZydisU16)); + + const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_64] - p; + if ((string->capacity - string->length < (ZydisUSize)(n + 1)) || + (string->capacity - string->length < (ZydisUSize)(paddingLength + 1))) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZydisUSize offset = 0; + if (n <= paddingLength) + { + offset = paddingLength - n + 1; + ZydisMemorySet(string->buffer + string->length, '0', offset); + } + + ZydisMemoryCopy(string->buffer + string->length + offset, &p[value < 10], n + 1); + string->length += n + offset - (ZydisU8)(value < 10); + + return ZYDIS_STATUS_SUCCESS; +} + +ZydisStatus ZydisPrintHexU64(ZydisString* string, ZydisU64 value, ZydisU8 paddingLength, + ZydisBool uppercase, const ZydisString* prefix, const ZydisString* suffix) +{ + ZYDIS_ASSERT(string); + ZYDIS_ASSERT(string->buffer); + + if (prefix) + { + ZYDIS_CHECK(ZydisStringAppend(string, prefix)); + } + + char* buffer = string->buffer + string->length; + const ZydisUSize remaining = string->capacity - string->length; + + if (remaining < (ZydisUSize)paddingLength) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + if (!value) + { + const ZydisU8 n = (paddingLength ? paddingLength : 1); + + if (remaining < (ZydisUSize)n) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZydisMemorySet(buffer, '0', n); + string->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 (remaining <= (ZydisU8)(i + 1)) // TODO: +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]; + } + } + string->length += n; + + if (suffix) + { + ZYDIS_CHECK(ZydisStringAppend(string, suffix)); + } + + return ZYDIS_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */ +/* Public Functions */ +/* ============================================================================================== */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Basic Operations */ +/* ---------------------------------------------------------------------------------------------- */ + +ZydisStatus ZydisStringAppendEx(ZydisString* string, const ZydisString* text, + ZydisLetterCase letterCase) +{ + if (!string || !text) + { + return ZYDIS_STATUS_INVALID_PARAMETER; + } + + if (string->length + text->length >= string->capacity) + { + return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE; + } + + ZydisMemoryCopy(string->buffer + string->length, text->buffer, text->length); + switch (letterCase) + { + case ZYDIS_LETTER_CASE_DEFAULT: + break; + case ZYDIS_LETTER_CASE_LOWER: + { + const signed char rebase = 'a' - 'A'; + char* c = string->buffer + string->length; + for (ZydisUSize i = 0; i < text->length; ++i) + { + if ((*c >= 'A') && (*c <= 'Z')) + { + *c += rebase; + } + ++c; + } + break; + } + case ZYDIS_LETTER_CASE_UPPER: + { + const signed char rebase = 'A' - 'a'; + char* c = string->buffer + string->length; + for (ZydisUSize i = 0; i < text->length; ++i) + { + if ((*c >= 'a') && (*c <= 'z')) + { + *c += rebase; + } + ++c; + } + break; + } + default: + return ZYDIS_STATUS_INVALID_PARAMETER; + } + string->length += text->length; + + return ZYDIS_STATUS_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ +/* Formatting */ +/* ---------------------------------------------------------------------------------------------- */ + +ZydisStatus ZydisPrintDecU(ZydisString* string, ZydisU64 value, ZydisU8 paddingLength) +{ +#if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64) + return ZydisPrintDecU64(string, value, paddingLength); +#else + if (value & 0xFFFFFFFF00000000) + { + return ZydisPrintDecU64(string, value, paddingLength); + } else + { + return ZydisPrintDecU32(string, (ZydisU32)value, paddingLength); + } +#endif +} + +ZydisStatus ZydisPrintDecS(ZydisString* string, ZydisI64 value, ZydisU8 paddingLength) +{ + if (value < 0) + { + ZYDIS_CHECK(ZydisStringAppendC(string, "-")); + return ZydisPrintDecU(string, -value, paddingLength); + } + return ZydisPrintDecU(string, value, paddingLength); +} + +ZydisStatus ZydisPrintHexU(ZydisString* string, ZydisU64 value, ZydisU8 paddingLength, + ZydisBool uppercase, const ZydisString* prefix, const ZydisString* suffix) +{ +#if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64) + return ZydisPrintHexU64(string, value, paddingLength, uppercase, prefix, suffix); +#else + if (value & 0xFFFFFFFF00000000) + { + return ZydisPrintHexU64(string, value, paddingLength, uppercase, prefix, suffix); + } else + { + return ZydisPrintHexU32(string, (ZydisU32)value, paddingLength, uppercase, prefix, suffix); + } +#endif +} + +ZydisStatus ZydisPrintHexS(ZydisString* string, ZydisI64 value, ZydisU8 paddingLength, + ZydisBool uppercase, const ZydisString* prefix, const ZydisString* suffix) +{ + if (value < 0) + { + ZYDIS_CHECK(ZydisStringAppendC(string, "-")); + if (prefix) + { + ZYDIS_CHECK(ZydisStringAppend(string, prefix)); + } + return ZydisPrintHexU(string, -value, paddingLength, uppercase, ZYDIS_NULL, suffix); + } + return ZydisPrintHexU(string, value, paddingLength, uppercase, prefix, suffix); +} + +/* ---------------------------------------------------------------------------------------------- */ + +/* ============================================================================================== */