mirror of https://github.com/x64dbg/zydis
				
				
				
			Various changes and refactorings
- Moved types and functions from `FormatHelper.h/c` to `String.h/c` - Added `ZydisMnemonicGetStringEx` function that returns the mnemonic-string as `ZydisString` struct - Added `ZYDIS_UNUSED_PARAMETER` macro - Fixed omitting of operands in custom formatter-hooks - Fixed `FormatterHooks` example - Refactored some code
This commit is contained in:
		
							parent
							
								
									fa12ccb64b
								
							
						
					
					
						commit
						02030c3b92
					
				| 
						 | 
				
			
			@ -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")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 <assert.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <Zydis/Defines.h>
 | 
			
		||||
#include <Zydis/Status.h>
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
/* 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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -33,10 +33,46 @@
 | 
			
		|||
 * the condition encoded in the immediate operand).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <Zydis/Zydis.h>
 | 
			
		||||
#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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------------------------------------- */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,8 +32,9 @@
 | 
			
		|||
#ifndef ZYDIS_MNEMONIC_H
 | 
			
		||||
#define ZYDIS_MNEMONIC_H
 | 
			
		||||
 | 
			
		||||
#include <Zydis/Defines.h>
 | 
			
		||||
#include <Zydis/CommonTypes.h>
 | 
			
		||||
#include <Zydis/Defines.h>
 | 
			
		||||
#include <Zydis/String.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 <Zydis/CommonTypes.h>
 | 
			
		||||
#include <Zydis/Status.h>
 | 
			
		||||
#include <Zydis/Internal/LibC.h>
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
/* 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,7 @@
 | 
			
		|||
#include <Zydis/Register.h>   
 | 
			
		||||
#include <Zydis/SharedTypes.h>
 | 
			
		||||
#include <Zydis/Status.h>
 | 
			
		||||
#include <Zydis/String.h>
 | 
			
		||||
#include <Zydis/Utils.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,9 +26,9 @@
 | 
			
		|||
 | 
			
		||||
#include <Zydis/Decoder.h>
 | 
			
		||||
#include <Zydis/Status.h>
 | 
			
		||||
#include <Zydis/Internal/LibC.h>
 | 
			
		||||
#include <DecoderData.h>
 | 
			
		||||
#include <SharedData.h>
 | 
			
		||||
#include <LibC.h>
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
/* Internal enums and types                                                                       */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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];
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 <FormatHelper.h>
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
/* 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);  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <Zydis/Defines.h>
 | 
			
		||||
#include <Zydis/Status.h>
 | 
			
		||||
#include <Zydis/String.h>
 | 
			
		||||
#include <LibC.h>
 | 
			
		||||
 | 
			
		||||
#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 */
 | 
			
		||||
							
								
								
									
										449
									
								
								src/Formatter.c
								
								
								
								
							
							
						
						
									
										449
									
								
								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 <Zydis/CommonTypes.h>
 | 
			
		||||
#include <Zydis/Formatter.h>
 | 
			
		||||
#include <Zydis/Utils.h>
 | 
			
		||||
#include <FormatHelper.h>
 | 
			
		||||
#include <LibC.h>
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
/* 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -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 <Generated/EnumMnemonic.inc>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @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];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 <Zydis/String.h>
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
/* 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);  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
/* ============================================================================================== */
 | 
			
		||||
		Loading…
	
		Reference in New Issue