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
|
@ -105,14 +105,17 @@ target_sources("Zydis"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h"
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/SharedTypes.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/Utils.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h"
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h"
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
"src/LibC.h"
|
||||||
"src/MetaInfo.c"
|
"src/MetaInfo.c"
|
||||||
"src/Mnemonic.c"
|
"src/Mnemonic.c"
|
||||||
"src/Register.c"
|
"src/Register.c"
|
||||||
"src/SharedData.h"
|
"src/SharedData.h"
|
||||||
"src/SharedData.c"
|
"src/SharedData.c"
|
||||||
|
"src/String.c"
|
||||||
"src/Utils.c"
|
"src/Utils.c"
|
||||||
"src/Zydis.c")
|
"src/Zydis.c")
|
||||||
|
|
||||||
|
@ -124,11 +127,9 @@ if (ZYDIS_FEATURE_DECODER)
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h"
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h"
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"src/DecoderData.h"
|
"src/DecoderData.h"
|
||||||
"src/FormatHelper.h"
|
|
||||||
"src/Decoder.c"
|
"src/Decoder.c"
|
||||||
"src/DecoderData.c"
|
"src/DecoderData.c"
|
||||||
"src/Formatter.c"
|
"src/Formatter.c")
|
||||||
"src/FormatHelper.c")
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (BUILD_SHARED_LIBS AND WIN32)
|
if (BUILD_SHARED_LIBS AND WIN32)
|
||||||
|
@ -148,9 +149,7 @@ install(DIRECTORY "include" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
if (ZYDIS_BUILD_EXAMPLES)
|
if (ZYDIS_BUILD_EXAMPLES)
|
||||||
if (ZYDIS_FEATURE_DECODER)
|
if (ZYDIS_FEATURE_DECODER)
|
||||||
add_executable("FormatterHooks"
|
add_executable("FormatterHooks" "examples/FormatterHooks.c")
|
||||||
"examples/FormatterHooks.c"
|
|
||||||
"examples/FormatHelper.h")
|
|
||||||
target_link_libraries("FormatterHooks" "Zydis")
|
target_link_libraries("FormatterHooks" "Zydis")
|
||||||
set_target_properties("FormatterHooks" PROPERTIES FOLDER "Examples/Formatter")
|
set_target_properties("FormatterHooks" PROPERTIES FOLDER "Examples/Formatter")
|
||||||
target_compile_definitions("FormatterHooks" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
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).
|
* the condition encoded in the immediate operand).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <Zydis/Zydis.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 */
|
/* Static data */
|
||||||
|
@ -100,8 +136,7 @@ typedef struct ZydisCustomUserData_
|
||||||
ZydisFormatterFormatFunc defaultPrintMnemonic;
|
ZydisFormatterFormatFunc defaultPrintMnemonic;
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
|
||||||
char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction, ZydisCustomUserData* userData)
|
||||||
ZydisCustomUserData* userData)
|
|
||||||
{
|
{
|
||||||
// We use the user-data to pass data to the @c ZydisFormatterFormatOperandImm function.
|
// We use the user-data to pass data to the @c ZydisFormatterFormatOperandImm function.
|
||||||
userData->ommitImmediate = ZYDIS_TRUE;
|
userData->ommitImmediate = ZYDIS_TRUE;
|
||||||
|
@ -109,40 +144,36 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
|
||||||
// Rewrite the instruction-mnemonic for the given instructions
|
// Rewrite the instruction-mnemonic for the given instructions
|
||||||
if (instruction->operands[instruction->operandCount - 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
|
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;
|
(uint8_t)instruction->operands[instruction->operandCount - 1].imm.value.u;
|
||||||
switch (instruction->mnemonic)
|
switch (instruction->mnemonic)
|
||||||
{
|
{
|
||||||
case ZYDIS_MNEMONIC_CMPPS:
|
case ZYDIS_MNEMONIC_CMPPS:
|
||||||
if (conditionCode < 0x08)
|
if (conditionCode < 0x08)
|
||||||
{
|
{
|
||||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
return ZydisStringAppendFormatC(
|
||||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%sps",
|
string, "cmp%sps", conditionCodeStrings[conditionCode]);
|
||||||
conditionCodeStrings[conditionCode]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_MNEMONIC_CMPPD:
|
case ZYDIS_MNEMONIC_CMPPD:
|
||||||
if (conditionCode < 0x08)
|
if (conditionCode < 0x08)
|
||||||
{
|
{
|
||||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
return ZydisStringAppendFormatC(
|
||||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%spd",
|
string, "cmp%spd", conditionCodeStrings[conditionCode]);
|
||||||
conditionCodeStrings[conditionCode]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_MNEMONIC_VCMPPS:
|
case ZYDIS_MNEMONIC_VCMPPS:
|
||||||
if (conditionCode < 0x20)
|
if (conditionCode < 0x20)
|
||||||
{
|
{
|
||||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
return ZydisStringAppendFormatC(
|
||||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%sps",
|
string, "vcmp%sps", conditionCodeStrings[conditionCode]);
|
||||||
conditionCodeStrings[conditionCode]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_MNEMONIC_VCMPPD:
|
case ZYDIS_MNEMONIC_VCMPPD:
|
||||||
if (conditionCode < 0x20)
|
if (conditionCode < 0x20)
|
||||||
{
|
{
|
||||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
return ZydisStringAppendFormatC(
|
||||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%spd",
|
string, "vcmp%spd", conditionCodeStrings[conditionCode]);
|
||||||
conditionCodeStrings[conditionCode]);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -155,7 +186,7 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
|
||||||
userData->ommitImmediate = ZYDIS_FALSE;
|
userData->ommitImmediate = ZYDIS_FALSE;
|
||||||
|
|
||||||
// Default mnemonic printing
|
// 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;
|
ZydisFormatterFormatOperandFunc defaultFormatOperandImm;
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter,
|
||||||
char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, ZydisCustomUserData* userData)
|
const ZydisDecodedOperand* operand, ZydisCustomUserData* userData)
|
||||||
{
|
{
|
||||||
// The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code)
|
// The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code)
|
||||||
|
@ -176,7 +207,7 @@ static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default immediate formatting
|
// 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
|
#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.
|
* @brief Calculates the size of an array.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -404,6 +404,7 @@ typedef struct ZydisFormatter_ ZydisFormatter;
|
||||||
* @brief Defines the @c ZydisFormatterNotifyFunc function pointer.
|
* @brief Defines the @c ZydisFormatterNotifyFunc function pointer.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the @c ZydisFormatter instance.
|
* @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 instruction A pointer to the @c ZydisDecodedInstruction struct.
|
||||||
* @param userData A pointer to user-defined data.
|
* @param userData A pointer to user-defined data.
|
||||||
*
|
*
|
||||||
|
@ -414,33 +415,30 @@ typedef struct ZydisFormatter_ ZydisFormatter;
|
||||||
* @c ZYDIS_FORMATTER_HOOK_POST hook-types.
|
* @c ZYDIS_FORMATTER_HOOK_POST hook-types.
|
||||||
*/
|
*/
|
||||||
typedef ZydisStatus (*ZydisFormatterNotifyFunc)(const ZydisFormatter* formatter,
|
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.
|
* @brief Defines the @c ZydisFormatterFormatFunc function pointer.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the @c ZydisFormatter instance.
|
* @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 instruction A pointer to the @c ZydisDecodedInstruction struct.
|
||||||
* @param userData A pointer to user-defined data.
|
* @param userData A pointer to user-defined data.
|
||||||
*
|
*
|
||||||
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
* formatting process to fail.
|
* 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,
|
* 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.
|
* @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types.
|
||||||
*/
|
*/
|
||||||
typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter,
|
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.
|
* @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the @c ZydisFormatter instance.
|
* @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 instruction A pointer to the @c ZydisDecodedInstruction struct.
|
||||||
* @param operand A pointer to the @c ZydisDecodedOperand struct.
|
* @param operand A pointer to the @c ZydisDecodedOperand struct.
|
||||||
* @param userData A pointer to user-defined data.
|
* @param userData A pointer to user-defined data.
|
||||||
|
@ -448,20 +446,15 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter,
|
||||||
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
* formatting process to fail.
|
* 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
|
* 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.
|
* operand.
|
||||||
*
|
*
|
||||||
* Returning @c ZYDIS_STATUS_SUCCESS in @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
|
* 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
|
* @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.
|
* 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,
|
* 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,
|
* @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM, @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR,
|
||||||
* @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
|
* @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
|
||||||
|
@ -470,14 +463,14 @@ typedef ZydisStatus (*ZydisFormatterFormatFunc)(const ZydisFormatter* formatter,
|
||||||
* hook-types.
|
* hook-types.
|
||||||
*/
|
*/
|
||||||
typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter,
|
typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData);
|
const ZydisDecodedOperand* operand, void* userData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer.
|
* @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the @c ZydisFormatter instance.
|
* @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 instruction A pointer to the @c ZydisDecodedInstruction struct.
|
||||||
* @param operand A pointer to the @c ZydisDecodedOperand struct.
|
* @param operand A pointer to the @c ZydisDecodedOperand struct.
|
||||||
* @param userData A pointer to user-defined data.
|
* @param userData A pointer to user-defined data.
|
||||||
|
@ -485,21 +478,17 @@ typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(const ZydisFormatter* for
|
||||||
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
* formatting process to fail.
|
* 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.
|
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type.
|
||||||
*/
|
*/
|
||||||
typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter,
|
typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, ZydisU64 address, void* userData);
|
const ZydisDecodedOperand* operand, ZydisU64 address, void* userData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer.
|
* @brief Defines the @c ZydisFormatterFormatDecoratorFunc function pointer.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the @c ZydisFormatter instance.
|
* @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 instruction A pointer to the @c ZydisDecodedInstruction struct.
|
||||||
* @param operand A pointer to the @c ZydisDecodedOperand struct.
|
* @param operand A pointer to the @c ZydisDecodedOperand struct.
|
||||||
* @param type The decorator type.
|
* @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
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
* formatting process to fail.
|
* formatting process to fail.
|
||||||
*
|
*
|
||||||
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
|
* Returning @c ZYDIS_STATUS_SUCCESS without writing to the string is valid and will cause the
|
||||||
* number of chars written.
|
* formatter to omit the current decorator.
|
||||||
*
|
|
||||||
* Returning @c ZYDIS_STATUS_SUCCESS without increasing the buffer-pointer 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.
|
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type.
|
||||||
*/
|
*/
|
||||||
typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter,
|
typedef ZydisStatus (*ZydisFormatterFormatDecoratorFunc)(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData);
|
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData);
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
@ -536,8 +522,10 @@ struct ZydisFormatter_
|
||||||
ZydisU8 displacementFormat;
|
ZydisU8 displacementFormat;
|
||||||
ZydisU8 immediateFormat;
|
ZydisU8 immediateFormat;
|
||||||
ZydisBool hexUppercase;
|
ZydisBool hexUppercase;
|
||||||
char* hexPrefix;
|
ZydisString* hexPrefix;
|
||||||
char* hexSuffix;
|
ZydisString hexPrefixData;
|
||||||
|
ZydisString* hexSuffix;
|
||||||
|
ZydisString hexSuffixData;
|
||||||
ZydisU8 hexPaddingAddress;
|
ZydisU8 hexPaddingAddress;
|
||||||
ZydisU8 hexPaddingDisplacement;
|
ZydisU8 hexPaddingDisplacement;
|
||||||
ZydisU8 hexPaddingImmediate;
|
ZydisU8 hexPaddingImmediate;
|
||||||
|
|
|
@ -32,8 +32,9 @@
|
||||||
#ifndef ZYDIS_MNEMONIC_H
|
#ifndef ZYDIS_MNEMONIC_H
|
||||||
#define ZYDIS_MNEMONIC_H
|
#define ZYDIS_MNEMONIC_H
|
||||||
|
|
||||||
#include <Zydis/Defines.h>
|
|
||||||
#include <Zydis/CommonTypes.h>
|
#include <Zydis/CommonTypes.h>
|
||||||
|
#include <Zydis/Defines.h>
|
||||||
|
#include <Zydis/String.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -58,6 +59,15 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic);
|
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
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -164,10 +164,10 @@ enum ZydisStatusCodes
|
||||||
#define ZYDIS_CHECK(status) \
|
#define ZYDIS_CHECK(status) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
ZydisStatus status_w4587ntvmEgDG = status; \
|
ZydisStatus status_038560234 = status; \
|
||||||
if (!ZYDIS_SUCCESS(status_w4587ntvmEgDG)) \
|
if (!ZYDIS_SUCCESS(status_038560234)) \
|
||||||
{ \
|
{ \
|
||||||
return status_w4587ntvmEgDG; \
|
return status_038560234; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Zyan Disassembler Library (Zydis)
|
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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -28,18 +28,284 @@
|
||||||
#define ZYDIS_STRING_H
|
#define ZYDIS_STRING_H
|
||||||
|
|
||||||
#include <Zydis/CommonTypes.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_
|
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 length;
|
||||||
ZydisUSize capacity; // always -1 for 0 byte
|
/**
|
||||||
|
* @brief The total buffer capacity.
|
||||||
|
*/
|
||||||
|
ZydisUSize capacity;
|
||||||
} ZydisString;
|
} 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
|
#endif // ZYDIS_STRING_H
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <Zydis/Register.h>
|
#include <Zydis/Register.h>
|
||||||
#include <Zydis/SharedTypes.h>
|
#include <Zydis/SharedTypes.h>
|
||||||
#include <Zydis/Status.h>
|
#include <Zydis/Status.h>
|
||||||
|
#include <Zydis/String.h>
|
||||||
#include <Zydis/Utils.h>
|
#include <Zydis/Utils.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
|
|
||||||
#include <Zydis/Decoder.h>
|
#include <Zydis/Decoder.h>
|
||||||
#include <Zydis/Status.h>
|
#include <Zydis/Status.h>
|
||||||
|
#include <Zydis/Internal/LibC.h>
|
||||||
#include <DecoderData.h>
|
#include <DecoderData.h>
|
||||||
#include <SharedData.h>
|
#include <SharedData.h>
|
||||||
#include <LibC.h>
|
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Internal enums and types */
|
/* Internal enums and types */
|
||||||
|
|
|
@ -368,7 +368,7 @@ void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node,
|
||||||
const ZydisInstructionEncodingInfo** info)
|
const ZydisInstructionEncodingInfo** info)
|
||||||
{
|
{
|
||||||
ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK);
|
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));
|
ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(instructionEncodings));
|
||||||
*info = &instructionEncodings[class];
|
*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 */
|
|
447
src/Formatter.c
447
src/Formatter.c
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
Zyan Disassembler Library (Zydis)
|
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
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -27,8 +27,6 @@
|
||||||
#include <Zydis/CommonTypes.h>
|
#include <Zydis/CommonTypes.h>
|
||||||
#include <Zydis/Formatter.h>
|
#include <Zydis/Formatter.h>
|
||||||
#include <Zydis/Utils.h>
|
#include <Zydis/Utils.h>
|
||||||
#include <FormatHelper.h>
|
|
||||||
#include <LibC.h>
|
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Instruction formatter */
|
/* Instruction formatter */
|
||||||
|
@ -39,70 +37,70 @@
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* formatter,
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE)
|
||||||
{
|
{
|
||||||
return ZydisStringAppendC(buffer, "xrelease ", formatter->letterCase);
|
return ZydisStringAppendExC(string, "xrelease ", formatter->letterCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* formatter,
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* mnemonic = ZydisMnemonicGetString(instruction->mnemonic);
|
const ZydisString* mnemonic = ZydisMnemonicGetStringEx(instruction->mnemonic);
|
||||||
if (!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)
|
if (instruction->attributes & ZYDIS_ATTRIB_IS_FAR_BRANCH)
|
||||||
{
|
{
|
||||||
return ZydisStringAppendC(buffer, " far", formatter->letterCase);
|
return ZydisStringAppendExC(string, " far", formatter->letterCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
@ -111,12 +109,12 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -129,22 +127,21 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for
|
||||||
const char* reg = ZydisRegisterGetString(operand->reg.value);
|
const char* reg = ZydisRegisterGetString(operand->reg.value);
|
||||||
if (!reg)
|
if (!reg)
|
||||||
{
|
{
|
||||||
reg = "invalid";
|
return ZydisStringAppendExC(string, "invalid", formatter->letterCase);
|
||||||
}
|
}
|
||||||
|
return ZydisStringAppendExC(string, reg, formatter->letterCase);
|
||||||
return ZydisStringAppendC(buffer, reg, formatter->letterCase);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
const ZydisDecodedOperand* operand, void* userData)
|
||||||
{
|
{
|
||||||
if (!formatter || !buffer || !instruction || !operand)
|
if (!formatter || !instruction || !operand)
|
||||||
{
|
{
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(buffer, "[", ZYDIS_LETTER_CASE_DEFAULT));
|
ZYDIS_CHECK(ZydisStringAppendC(string, "["));
|
||||||
|
|
||||||
if (operand->mem.disp.hasDisplacement && (
|
if (operand->mem.disp.hasDisplacement && (
|
||||||
(operand->mem.base == ZYDIS_REGISTER_NONE) ||
|
(operand->mem.base == ZYDIS_REGISTER_NONE) ||
|
||||||
|
@ -158,13 +155,13 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
|
||||||
{
|
{
|
||||||
ZydisU64 address;
|
ZydisU64 address;
|
||||||
ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &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));
|
address, userData));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.base),
|
ZYDIS_CHECK(ZydisStringAppendExC(string, ZydisRegisterGetString(operand->mem.base),
|
||||||
formatter->letterCase));
|
formatter->letterCase));
|
||||||
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, instruction, operand,
|
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, string, instruction, operand,
|
||||||
userData));
|
userData));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -177,7 +174,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
|
||||||
{
|
{
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
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) &&
|
if ((operand->mem.index != ZYDIS_REGISTER_NONE) &&
|
||||||
(operand->mem.type != ZYDIS_MEMOP_TYPE_MIB))
|
(operand->mem.type != ZYDIS_MEMOP_TYPE_MIB))
|
||||||
|
@ -189,47 +186,45 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
|
||||||
}
|
}
|
||||||
if (operand->mem.base != ZYDIS_REGISTER_NONE)
|
if (operand->mem.base != ZYDIS_REGISTER_NONE)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, "+"));
|
||||||
ZydisStringAppendC(buffer, "+", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
}
|
}
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(buffer, reg, formatter->letterCase));
|
ZYDIS_CHECK(ZydisStringAppendExC(string, reg, formatter->letterCase));
|
||||||
if (operand->mem.scale)
|
if (operand->mem.scale)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, "*"));
|
||||||
ZydisStringAppendC(buffer, "*", ZYDIS_LETTER_CASE_DEFAULT));
|
ZYDIS_CHECK(ZydisPrintDecU(string, operand->mem.scale, 0));
|
||||||
ZYDIS_CHECK(ZydisPrintDecU(buffer, operand->mem.scale, 0));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, string, instruction, operand,
|
||||||
instruction, operand, userData));
|
userData));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZydisStringAppendC(buffer, "]", ZYDIS_LETTER_CASE_DEFAULT);
|
return ZydisStringAppendC(string, "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
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;
|
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));
|
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix));
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT));
|
ZYDIS_CHECK(ZydisStringAppendC(string, ":"));
|
||||||
return ZydisPrintHexU(buffer, operand->ptr.offset, 8,
|
return ZydisPrintHexU(string, operand->ptr.offset, 8,
|
||||||
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
const ZydisDecodedOperand* operand, void* userData)
|
||||||
{
|
{
|
||||||
if (!formatter || !buffer || !instruction || !operand)
|
if (!formatter || !instruction || !operand)
|
||||||
{
|
{
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -244,8 +239,8 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for
|
||||||
{
|
{
|
||||||
ZydisU64 address;
|
ZydisU64 address;
|
||||||
ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address));
|
ZYDIS_CHECK(ZydisCalcAbsoluteAddress(instruction, operand, &address));
|
||||||
return formatter->funcPrintAddress(formatter, buffer, instruction, operand,
|
return formatter->funcPrintAddress(formatter, string, instruction, operand, address,
|
||||||
address, userData);
|
userData);
|
||||||
}
|
}
|
||||||
case ZYDIS_ADDR_FORMAT_RELATIVE_SIGNED:
|
case ZYDIS_ADDR_FORMAT_RELATIVE_SIGNED:
|
||||||
printSignedHEX = ZYDIS_TRUE;
|
printSignedHEX = ZYDIS_TRUE;
|
||||||
|
@ -258,29 +253,28 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for
|
||||||
|
|
||||||
if (printSignedHEX)
|
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->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
}
|
}
|
||||||
return ZydisPrintHexU(buffer, operand->imm.value.u,
|
return ZydisPrintHexU(string, operand->imm.value.u,
|
||||||
formatter->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix,
|
formatter->hexPaddingAddress, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The immediate operand contains an actual ordinal value
|
// The immediate operand contains an actual ordinal value
|
||||||
return formatter->funcPrintImmediate(
|
return formatter->funcPrintImmediate(formatter, string, instruction, operand, userData);
|
||||||
formatter, buffer, instruction, operand, userData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, ZydisU64 address, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -288,13 +282,13 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt
|
||||||
switch (instruction->stackWidth)
|
switch (instruction->stackWidth)
|
||||||
{
|
{
|
||||||
case 16:
|
case 16:
|
||||||
return ZydisPrintHexU(buffer, (ZydisU16)address, 4,
|
return ZydisPrintHexU(string, (ZydisU16)address, 4,
|
||||||
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
||||||
case 32:
|
case 32:
|
||||||
return ZydisPrintHexU(buffer, (ZydisU32)address, 8,
|
return ZydisPrintHexU(string, (ZydisU32)address, 8,
|
||||||
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
||||||
case 64:
|
case 64:
|
||||||
return ZydisPrintHexU(buffer, address, 16,
|
return ZydisPrintHexU(string, address, 16,
|
||||||
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
formatter->hexUppercase, formatter->hexPrefix, formatter->hexSuffix);
|
||||||
default:
|
default:
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
|
@ -302,12 +296,12 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -322,16 +316,16 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo
|
||||||
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
|
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
|
||||||
(operand->mem.index != 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->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
}
|
}
|
||||||
if ((operand->mem.base != ZYDIS_REGISTER_NONE) ||
|
if ((operand->mem.base != ZYDIS_REGISTER_NONE) ||
|
||||||
(operand->mem.index != 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->hexPaddingDisplacement, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
}
|
}
|
||||||
|
@ -339,12 +333,12 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -360,19 +354,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
|
||||||
switch (operand->size)
|
switch (operand->size)
|
||||||
{
|
{
|
||||||
case 8:
|
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->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
case 16:
|
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->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
case 32:
|
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->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
case 64:
|
case 64:
|
||||||
return ZydisPrintHexS(buffer, operand->imm.value.s,
|
return ZydisPrintHexS(string, operand->imm.value.s,
|
||||||
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
default:
|
default:
|
||||||
|
@ -382,19 +376,19 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
|
||||||
switch (instruction->operandWidth)
|
switch (instruction->operandWidth)
|
||||||
{
|
{
|
||||||
case 8:
|
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->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
case 16:
|
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->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
case 32:
|
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->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
case 64:
|
case 64:
|
||||||
return ZydisPrintHexU(buffer, operand->imm.value.u,
|
return ZydisPrintHexU(string, operand->imm.value.u,
|
||||||
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
formatter->hexPaddingImmediate, formatter->hexUppercase, formatter->hexPrefix,
|
||||||
formatter->hexSuffix);
|
formatter->hexSuffix);
|
||||||
default:
|
default:
|
||||||
|
@ -405,12 +399,12 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -505,19 +499,20 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
|
||||||
|
|
||||||
if (str)
|
if (str)
|
||||||
{
|
{
|
||||||
return ZydisStringAppendC(buffer, str, formatter->letterCase);
|
return ZydisStringAppendExC(string, str, formatter->letterCase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -528,43 +523,41 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
|
||||||
case ZYDIS_REGISTER_CS:
|
case ZYDIS_REGISTER_CS:
|
||||||
case ZYDIS_REGISTER_FS:
|
case ZYDIS_REGISTER_FS:
|
||||||
case ZYDIS_REGISTER_GS:
|
case ZYDIS_REGISTER_GS:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendExC(string,
|
||||||
ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment),
|
ZydisRegisterGetString(operand->mem.segment), formatter->letterCase));
|
||||||
formatter->letterCase));
|
return ZydisStringAppendC(string, ":");
|
||||||
return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
|
|
||||||
case ZYDIS_REGISTER_SS:
|
case ZYDIS_REGISTER_SS:
|
||||||
if ((formatter->forceSegments) ||
|
if ((formatter->forceSegments) ||
|
||||||
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS))
|
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS))
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendExC(string,
|
||||||
ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment),
|
ZydisRegisterGetString(operand->mem.segment), formatter->letterCase));
|
||||||
formatter->letterCase));
|
return ZydisStringAppendC(string, ":");
|
||||||
return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_REGISTER_DS:
|
case ZYDIS_REGISTER_DS:
|
||||||
if ((formatter->forceSegments) ||
|
if ((formatter->forceSegments) ||
|
||||||
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS))
|
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS))
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendExC(string,
|
||||||
ZydisStringAppendC(buffer, ZydisRegisterGetString(operand->mem.segment),
|
ZydisRegisterGetString(operand->mem.segment), formatter->letterCase));
|
||||||
formatter->letterCase));
|
return ZydisStringAppendC(string, ":");
|
||||||
return ZydisStringAppendC(buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
|
static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* formatter,
|
||||||
ZydisString* buffer, const ZydisDecodedInstruction* instruction,
|
ZydisString* string, const ZydisDecodedInstruction* instruction,
|
||||||
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
@ -580,13 +573,12 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
{
|
{
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
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));
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(buffer, "}", ZYDIS_LETTER_CASE_DEFAULT));
|
ZYDIS_CHECK(ZydisStringAppendC(string, "}"));
|
||||||
if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO)
|
if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {z}"));
|
||||||
ZydisStringAppendC(buffer, " {z}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -599,28 +591,22 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
case ZYDIS_BROADCAST_MODE_INVALID:
|
case ZYDIS_BROADCAST_MODE_INVALID:
|
||||||
break;
|
break;
|
||||||
case ZYDIS_BROADCAST_MODE_1_TO_2:
|
case ZYDIS_BROADCAST_MODE_1_TO_2:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {1to2}"));
|
||||||
ZydisStringAppendC(buffer, " {1to2}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_BROADCAST_MODE_1_TO_4:
|
case ZYDIS_BROADCAST_MODE_1_TO_4:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {1to4}"));
|
||||||
ZydisStringAppendC(buffer, " {1to4}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_BROADCAST_MODE_1_TO_8:
|
case ZYDIS_BROADCAST_MODE_1_TO_8:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {1to8}"));
|
||||||
ZydisStringAppendC(buffer, " {1to8}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_BROADCAST_MODE_1_TO_16:
|
case ZYDIS_BROADCAST_MODE_1_TO_16:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {1to16}"));
|
||||||
ZydisStringAppendC(buffer, " {1to16}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_BROADCAST_MODE_4_TO_8:
|
case ZYDIS_BROADCAST_MODE_4_TO_8:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {4to8}"));
|
||||||
ZydisStringAppendC(buffer, " {4to8}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_BROADCAST_MODE_4_TO_16:
|
case ZYDIS_BROADCAST_MODE_4_TO_16:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {4to16}"));
|
||||||
ZydisStringAppendC(buffer, " {4to16}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
|
@ -635,20 +621,16 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
case ZYDIS_ROUNDING_MODE_INVALID:
|
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RN:
|
case ZYDIS_ROUNDING_MODE_RN:
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {rn-sae}"));
|
||||||
buffer, " {rn-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RD:
|
case ZYDIS_ROUNDING_MODE_RD:
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {rd-sae}"));
|
||||||
buffer, " {rd-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RU:
|
case ZYDIS_ROUNDING_MODE_RU:
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {ru-sae}"));
|
||||||
buffer, " {ru-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RZ:
|
case ZYDIS_ROUNDING_MODE_RZ:
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {rz-sae}"));
|
||||||
buffer, " {rz-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
|
@ -660,20 +642,16 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
case ZYDIS_ROUNDING_MODE_INVALID:
|
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RN:
|
case ZYDIS_ROUNDING_MODE_RN:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {rn}"));
|
||||||
ZydisStringAppendC(buffer, " {rn}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RD:
|
case ZYDIS_ROUNDING_MODE_RD:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {rd}"));
|
||||||
ZydisStringAppendC(buffer, " {rd}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RU:
|
case ZYDIS_ROUNDING_MODE_RU:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {ru}"));
|
||||||
ZydisStringAppendC(buffer, " {ru}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_ROUNDING_MODE_RZ:
|
case ZYDIS_ROUNDING_MODE_RZ:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {rz}"));
|
||||||
ZydisStringAppendC(buffer, " {rz}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
|
@ -683,8 +661,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
case ZYDIS_DECORATOR_TYPE_SAE:
|
case ZYDIS_DECORATOR_TYPE_SAE:
|
||||||
if (instruction->avx.hasSAE && !instruction->avx.rounding.mode)
|
if (instruction->avx.hasSAE && !instruction->avx.rounding.mode)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {sae}"));
|
||||||
ZydisStringAppendC(buffer, " {sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZYDIS_DECORATOR_TYPE_SWIZZLE:
|
case ZYDIS_DECORATOR_TYPE_SWIZZLE:
|
||||||
|
@ -695,32 +672,25 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
// Nothing to do here
|
// Nothing to do here
|
||||||
break;
|
break;
|
||||||
case ZYDIS_SWIZZLE_MODE_CDAB:
|
case ZYDIS_SWIZZLE_MODE_CDAB:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {cdab}"));
|
||||||
ZydisStringAppendC(buffer, " {cdab}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_SWIZZLE_MODE_BADC:
|
case ZYDIS_SWIZZLE_MODE_BADC:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {badc}"));
|
||||||
ZydisStringAppendC(buffer, " {badc}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_SWIZZLE_MODE_DACB:
|
case ZYDIS_SWIZZLE_MODE_DACB:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {dacb}"));
|
||||||
ZydisStringAppendC(buffer, " {dacb}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_SWIZZLE_MODE_AAAA:
|
case ZYDIS_SWIZZLE_MODE_AAAA:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {aaaa}"));
|
||||||
ZydisStringAppendC(buffer, " {aaaa}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_SWIZZLE_MODE_BBBB:
|
case ZYDIS_SWIZZLE_MODE_BBBB:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {bbbb}"));
|
||||||
ZydisStringAppendC(buffer, " {bbbb}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_SWIZZLE_MODE_CCCC:
|
case ZYDIS_SWIZZLE_MODE_CCCC:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {cccc}"));
|
||||||
ZydisStringAppendC(buffer, " {cccc}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_SWIZZLE_MODE_DDDD:
|
case ZYDIS_SWIZZLE_MODE_DDDD:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {dddd}"));
|
||||||
ZydisStringAppendC(buffer, " {dddd}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
|
@ -732,24 +702,19 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
case ZYDIS_CONVERSION_MODE_INVALID:
|
case ZYDIS_CONVERSION_MODE_INVALID:
|
||||||
break;
|
break;
|
||||||
case ZYDIS_CONVERSION_MODE_FLOAT16:
|
case ZYDIS_CONVERSION_MODE_FLOAT16:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {float16}"));
|
||||||
ZydisStringAppendC(buffer, " {float16}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_CONVERSION_MODE_SINT8:
|
case ZYDIS_CONVERSION_MODE_SINT8:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {sint8}"));
|
||||||
ZydisStringAppendC(buffer, " {sint8}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_CONVERSION_MODE_UINT8:
|
case ZYDIS_CONVERSION_MODE_UINT8:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {uint8}"));
|
||||||
ZydisStringAppendC(buffer, " {uint8}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_CONVERSION_MODE_SINT16:
|
case ZYDIS_CONVERSION_MODE_SINT16:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {sint16}"));
|
||||||
ZydisStringAppendC(buffer, " {sint16}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
case ZYDIS_CONVERSION_MODE_UINT16:
|
case ZYDIS_CONVERSION_MODE_UINT16:
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {uint16}"));
|
||||||
ZydisStringAppendC(buffer, " {uint16}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
|
@ -758,8 +723,7 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
case ZYDIS_DECORATOR_TYPE_EVICTION_HINT:
|
case ZYDIS_DECORATOR_TYPE_EVICTION_HINT:
|
||||||
if (instruction->avx.hasEvictionHint)
|
if (instruction->avx.hasEvictionHint)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(ZydisStringAppendC(string, " {eh}"));
|
||||||
ZydisStringAppendC(buffer, " {eh}", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -770,19 +734,16 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatter,
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZYDIS_CHECK(
|
ZYDIS_CHECK(formatter->funcPrintPrefixes(formatter, string, instruction, userData));
|
||||||
formatter->funcPrintPrefixes(formatter, buffer, instruction, userData));
|
ZYDIS_CHECK(formatter->funcPrintMnemonic(formatter, string, instruction, userData));
|
||||||
ZYDIS_CHECK(
|
|
||||||
formatter->funcPrintMnemonic(formatter, buffer, instruction, userData));
|
|
||||||
|
|
||||||
ZydisUSize lenRestore = buffer->length;
|
|
||||||
for (ZydisU8 i = 0; i < instruction->operandCount; ++i)
|
for (ZydisU8 i = 0; i < instruction->operandCount; ++i)
|
||||||
{
|
{
|
||||||
if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN)
|
if (instruction->operands[i].visibility == ZYDIS_OPERAND_VISIBILITY_HIDDEN)
|
||||||
|
@ -790,97 +751,91 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ZydisUSize strLenRestore = string->length;
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(buffer, " ", ZYDIS_LETTER_CASE_DEFAULT));
|
ZYDIS_CHECK(ZydisStringAppendC(string, " "));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
lenRestore = buffer->length;
|
ZYDIS_CHECK(ZydisStringAppendC(string, ", "));
|
||||||
ZYDIS_CHECK(ZydisStringAppendC(buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZydisUSize bufPreOperandLen = buffer->length;
|
const ZydisUSize strLenPreOperand = string->length;
|
||||||
switch (instruction->operands[i].type)
|
switch (instruction->operands[i].type)
|
||||||
{
|
{
|
||||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||||
ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcFormatOperandReg(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i], userData));
|
&instruction->operands[i], userData));
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcPrintOperandSize(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i], userData));
|
&instruction->operands[i], userData));
|
||||||
ZYDIS_CHECK(formatter->funcPrintSegment(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcPrintSegment(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i], userData));
|
&instruction->operands[i], userData));
|
||||||
ZydisUSize lenTemp = buffer->length;
|
const ZydisUSize strLenTemp = string->length;
|
||||||
ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcFormatOperandMem(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i], userData));
|
&instruction->operands[i], userData));
|
||||||
if (lenTemp == buffer->length)
|
if (strLenTemp == string->length)
|
||||||
{
|
{
|
||||||
buffer->length = bufPreOperandLen;
|
string->length = strLenPreOperand;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ZYDIS_OPERAND_TYPE_POINTER:
|
case ZYDIS_OPERAND_TYPE_POINTER:
|
||||||
ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcFormatOperandPtr(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i], userData));
|
&instruction->operands[i], userData));
|
||||||
break;
|
break;
|
||||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||||
ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcFormatOperandImm(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i], userData));
|
&instruction->operands[i], userData));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
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
|
// Omit whole operand, if the string did not change during the formatting-callback
|
||||||
buffer->length = lenRestore;
|
string->length = strLenRestore;
|
||||||
} else
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
|
||||||
|
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
|
||||||
{
|
{
|
||||||
if ((instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX) ||
|
if ((i == 0) &&
|
||||||
(instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX))
|
(instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK))
|
||||||
{
|
{
|
||||||
if ((i == 0) &&
|
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction,
|
||||||
(instruction->operands[i + 1].encoding == ZYDIS_OPERAND_ENCODING_MASK))
|
&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,
|
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i],
|
&instruction->operands[i], ZYDIS_DECORATOR_TYPE_CONVERSION, userData));
|
||||||
ZYDIS_DECORATOR_TYPE_MASK, 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)
|
} else
|
||||||
|
{
|
||||||
|
if ((i == (instruction->operandCount - 1)) ||
|
||||||
|
(instruction->operands[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
|
||||||
instruction, &instruction->operands[i],
|
|
||||||
ZYDIS_DECORATOR_TYPE_BROADCAST, userData));
|
|
||||||
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
|
if (instruction->encoding == ZYDIS_INSTRUCTION_ENCODING_MVEX)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, buffer,
|
ZYDIS_CHECK(formatter->funcPrintDecorator(formatter, string, instruction,
|
||||||
instruction, &instruction->operands[i],
|
&instruction->operands[i], ZYDIS_DECORATOR_TYPE_SWIZZLE, userData));
|
||||||
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_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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ZydisString hexPrefixDefault = ZYDIS_MAKE_STRING("0x");
|
||||||
|
|
||||||
ZydisMemorySet(formatter, 0, sizeof(ZydisFormatter));
|
ZydisMemorySet(formatter, 0, sizeof(ZydisFormatter));
|
||||||
formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT;
|
formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT;
|
||||||
formatter->forceSegments = ZYDIS_FALSE;
|
formatter->forceSegments = ZYDIS_FALSE;
|
||||||
|
@ -908,7 +865,7 @@ ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle st
|
||||||
formatter->displacementFormat = ZYDIS_DISP_FORMAT_HEX_SIGNED;
|
formatter->displacementFormat = ZYDIS_DISP_FORMAT_HEX_SIGNED;
|
||||||
formatter->immediateFormat = ZYDIS_IMM_FORMAT_HEX_UNSIGNED;
|
formatter->immediateFormat = ZYDIS_IMM_FORMAT_HEX_UNSIGNED;
|
||||||
formatter->hexUppercase = ZYDIS_TRUE;
|
formatter->hexUppercase = ZYDIS_TRUE;
|
||||||
formatter->hexPrefix = "0x";
|
formatter->hexPrefix = &hexPrefixDefault;
|
||||||
formatter->hexSuffix = ZYDIS_NULL;
|
formatter->hexSuffix = ZYDIS_NULL;
|
||||||
formatter->hexPaddingAddress = 2;
|
formatter->hexPaddingAddress = 2;
|
||||||
formatter->hexPaddingDisplacement = 2;
|
formatter->hexPaddingDisplacement = 2;
|
||||||
|
@ -982,10 +939,18 @@ ZydisStatus ZydisFormatterSetProperty(ZydisFormatter* formatter,
|
||||||
formatter->hexUppercase = (value) ? ZYDIS_TRUE : ZYDIS_FALSE;
|
formatter->hexUppercase = (value) ? ZYDIS_TRUE : ZYDIS_FALSE;
|
||||||
break;
|
break;
|
||||||
case ZYDIS_FORMATTER_PROP_HEX_PREFIX:
|
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;
|
break;
|
||||||
case ZYDIS_FORMATTER_PROP_HEX_SUFFIX:
|
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;
|
break;
|
||||||
case ZYDIS_FORMATTER_PROP_HEX_PADDING_ADDR:
|
case ZYDIS_FORMATTER_PROP_HEX_PADDING_ADDR:
|
||||||
if (value > 20)
|
if (value > 20)
|
||||||
|
@ -1147,30 +1112,28 @@ ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter,
|
||||||
ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter,
|
ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter,
|
||||||
const ZydisDecodedInstruction* instruction, char* buffer, ZydisUSize bufferLen, void* userData)
|
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;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZydisString str = {
|
ZydisString string;
|
||||||
.s = buffer,
|
string.buffer = buffer;
|
||||||
.length = 0,
|
string.length = 0;
|
||||||
.capacity = bufferLen - 1
|
string.capacity = bufferLen;
|
||||||
};
|
|
||||||
|
|
||||||
if (formatter->funcPre)
|
if (formatter->funcPre)
|
||||||
{
|
{
|
||||||
ZYDIS_CHECK(formatter->funcPre(formatter, &str, instruction, userData));
|
ZYDIS_CHECK(formatter->funcPre(formatter, &string, instruction, userData));
|
||||||
}
|
}
|
||||||
|
ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, &string, instruction, userData));
|
||||||
ZYDIS_CHECK(formatter->funcFormatInstruction(formatter, &str, instruction, userData));
|
|
||||||
|
|
||||||
if (formatter->funcPost)
|
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;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,8 +30,35 @@
|
||||||
/* Mnemonic strings */
|
/* 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>
|
#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 */
|
/* Exported functions */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
@ -42,7 +69,22 @@ const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic)
|
||||||
{
|
{
|
||||||
return ZYDIS_NULL;
|
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