Merge branch 'feature/zydis-string' into develop

# Conflicts:
#	include/Zydis/Formatter.h
#	src/Formatter.c
This commit is contained in:
Joel Höner 2017-12-03 22:47:01 +01:00
commit 31c369d3f1
31 changed files with 3593 additions and 3389 deletions

View File

@ -104,15 +104,18 @@ target_sources("Zydis"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Mnemonic.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Register.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/SharedTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Status.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/String.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Utils.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Zydis.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/LibC.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/SharedData.h"
PRIVATE
"src/MetaInfo.c"
"src/Mnemonic.c"
"src/Register.c"
"src/SharedData.h"
"src/SharedData.c"
"src/String.c"
"src/Utils.c"
"src/Zydis.c")
@ -122,13 +125,11 @@ if (ZYDIS_FEATURE_DECODER)
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Decoder.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/DecoderTypes.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Internal/DecoderData.h"
PRIVATE
"src/DecoderData.h"
"src/FormatHelper.h"
"src/Decoder.c"
"src/DecoderData.c"
"src/Formatter.c"
"src/FormatHelper.c")
"src/Formatter.c")
endif ()
if (BUILD_SHARED_LIBS AND WIN32)
@ -148,9 +149,7 @@ install(DIRECTORY "include" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if (ZYDIS_BUILD_EXAMPLES)
if (ZYDIS_FEATURE_DECODER)
add_executable("FormatterHooks"
"examples/FormatterHooks.c"
"examples/FormatHelper.h")
add_executable("FormatterHooks" "examples/FormatterHooks.c")
target_link_libraries("FormatterHooks" "Zydis")
set_target_properties("FormatterHooks" PROPERTIES FOLDER "Examples/Formatter")
target_compile_definitions("FormatterHooks" PRIVATE "_CRT_SECURE_NO_WARNINGS")

View File

@ -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 */

View File

@ -33,10 +33,46 @@
* the condition encoded in the immediate operand).
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <inttypes.h>
#include <Zydis/Zydis.h>
#include "FormatHelper.h"
/* ============================================================================================== */
/* Helper functions */
/* ============================================================================================== */
/**
* @brief Appends formatted text to the given `string`.
*
* @param string A pointer to the string.
* @param format The format string.
*
* @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or
* @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not
* sufficient to append the given text.
*/
ZYDIS_INLINE ZydisStatus ZydisStringAppendFormatC(ZydisString* string, const char* format, ...)
{
if (!string || !string->buffer || !format)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
va_list arglist;
va_start(arglist, format);
const int w = vsnprintf(string->buffer + string->length, string->capacity - string->length,
format, arglist);
if ((w < 0) || ((size_t)w > string->capacity - string->length))
{
va_end(arglist);
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
string->length += w;
va_end(arglist);
return ZYDIS_STATUS_SUCCESS;
}
/* ============================================================================================== */
/* Static data */
@ -100,8 +136,7 @@ typedef struct ZydisCustomUserData_
ZydisFormatterFunc defaultPrintMnemonic;
static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisCustomUserData* userData)
ZydisString* string, const ZydisDecodedInstruction* instruction, ZydisCustomUserData* userData)
{
// We use the user-data to pass data to the @c ZydisFormatterFormatOperandImm function.
userData->ommitImmediate = ZYDIS_TRUE;
@ -109,40 +144,36 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
// Rewrite the instruction-mnemonic for the given instructions
if (instruction->operands[instruction->operandCount - 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
uint8_t conditionCode =
const uint8_t conditionCode =
(uint8_t)instruction->operands[instruction->operandCount - 1].imm.value.u;
switch (instruction->mnemonic)
{
case ZYDIS_MNEMONIC_CMPPS:
if (conditionCode < 0x08)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%sps",
conditionCodeStrings[conditionCode]);
return ZydisStringAppendFormatC(
string, "cmp%sps", conditionCodeStrings[conditionCode]);
}
break;
case ZYDIS_MNEMONIC_CMPPD:
if (conditionCode < 0x08)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%spd",
conditionCodeStrings[conditionCode]);
return ZydisStringAppendFormatC(
string, "cmp%spd", conditionCodeStrings[conditionCode]);
}
break;
case ZYDIS_MNEMONIC_VCMPPS:
if (conditionCode < 0x20)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%sps",
conditionCodeStrings[conditionCode]);
return ZydisStringAppendFormatC(
string, "vcmp%sps", conditionCodeStrings[conditionCode]);
}
break;
case ZYDIS_MNEMONIC_VCMPPD:
if (conditionCode < 0x20)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%spd",
conditionCodeStrings[conditionCode]);
return ZydisStringAppendFormatC(
string, "vcmp%spd", conditionCodeStrings[conditionCode]);
}
break;
default:
@ -155,7 +186,7 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
userData->ommitImmediate = ZYDIS_FALSE;
// Default mnemonic printing
return defaultPrintMnemonic(formatter, buffer, bufferLen, instruction, userData);
return defaultPrintMnemonic(formatter, string, instruction, userData);
}
/* ---------------------------------------------------------------------------------------------- */
@ -163,7 +194,7 @@ static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
ZydisFormatterOperandFunc defaultFormatOperandImm;
static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* string, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisCustomUserData* userData)
{
// The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code)
@ -176,7 +207,7 @@ static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatte
}
// Default immediate formatting
return defaultFormatOperandImm(formatter, buffer, bufferLen, instruction, operand, userData);
return defaultFormatOperandImm(formatter, string, instruction, operand, userData);
}
/* ---------------------------------------------------------------------------------------------- */
@ -189,8 +220,8 @@ void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, Zydi
{
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE);
ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE);
ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE);
ZydisFormatterSetProperty(&formatter, ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE);
if (installHooks)
{

View File

@ -174,9 +174,9 @@ uint64_t processBuffer(const char* buffer, size_t length, ZydisBool minimalMode,
{
if (!ZYDIS_SUCCESS(ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL)) ||
!ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter,
ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE)) ||
ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE)) ||
!ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter,
ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE)))
ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE)))
{
fputs("Failed to initialize instruction-formatter\n", stderr);
exit(EXIT_FAILURE);

View File

@ -1,127 +1,137 @@
/***************************************************************************************************
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.
***************************************************************************************************/
/**
* @file
* @brief Includes and defines some default datatypes.
*/
#ifndef ZYDIS_COMMONTYPES_H
#define ZYDIS_COMMONTYPES_H
#include <Zydis/Defines.h>
/* ============================================================================================== */
/* Integer types */
/* ============================================================================================== */
#if !defined(ZYDIS_NO_LIBC)
// If is LibC present, we use stdint types.
# include <stdint.h>
# include <stddef.h>
typedef uint8_t ZydisU8;
typedef uint16_t ZydisU16;
typedef uint32_t ZydisU32;
typedef uint64_t ZydisU64;
typedef int8_t ZydisI8;
typedef int16_t ZydisI16;
typedef int32_t ZydisI32;
typedef int64_t ZydisI64;
typedef size_t ZydisUSize;
typedef ptrdiff_t ZydisISize;
#else
// No LibC, use compiler built-in types / macros.
# if defined(ZYDIS_MSVC)
typedef unsigned __int8 ZydisU8;
typedef unsigned __int16 ZydisU16;
typedef unsigned __int32 ZydisU32;
typedef unsigned __int64 ZydisU64;
typedef signed __int8 ZydisI8;
typedef signed __int16 ZydisI16;
typedef signed __int32 ZydisI32;
typedef signed __int64 ZydisI64;
/***************************************************************************************************
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.
***************************************************************************************************/
/**
* @file
* @brief Includes and defines some default datatypes.
*/
#ifndef ZYDIS_COMMONTYPES_H
#define ZYDIS_COMMONTYPES_H
#include <Zydis/Defines.h>
/* ============================================================================================== */
/* Integer types */
/* ============================================================================================== */
#if !defined(ZYDIS_NO_LIBC)
// If is LibC present, we use stdint types.
# include <stdint.h>
# include <stddef.h>
typedef uint8_t ZydisU8;
typedef uint16_t ZydisU16;
typedef uint32_t ZydisU32;
typedef uint64_t ZydisU64;
typedef int8_t ZydisI8;
typedef int16_t ZydisI16;
typedef int32_t ZydisI32;
typedef int64_t ZydisI64;
typedef size_t ZydisUSize;
typedef ptrdiff_t ZydisISize;
typedef uintptr_t ZydisUPointer;
typedef intptr_t ZydisIPointer;
#else
// No LibC, use compiler built-in types / macros.
# if defined(ZYDIS_MSVC)
typedef unsigned __int8 ZydisU8;
typedef unsigned __int16 ZydisU16;
typedef unsigned __int32 ZydisU32;
typedef unsigned __int64 ZydisU64;
typedef signed __int8 ZydisI8;
typedef signed __int16 ZydisI16;
typedef signed __int32 ZydisI32;
typedef signed __int64 ZydisI64;
# if _WIN64
typedef ZydisU64 ZydisUSize;
typedef ZydisI64 ZydisISize;
typedef ZydisU64 ZydisUPointer;
typedef ZydisI64 ZydisIPointer;
# else
typedef ZydisU32 ZydisUSize;
typedef ZydisI32 ZydisISize;
# endif
# elif defined(ZYDIS_GNUC)
typedef __UINT8_TYPE__ ZydisU8;
typedef __UINT16_TYPE__ ZydisU16;
typedef __UINT32_TYPE__ ZydisU32;
typedef __UINT64_TYPE__ ZydisU64;
typedef __INT8_TYPE__ ZydisI8;
typedef __INT16_TYPE__ ZydisI16;
typedef __INT32_TYPE__ ZydisI32;
typedef __INT64_TYPE__ ZydisI64;
typedef __SIZE_TYPE__ ZydisUSize;
typedef __PTRDIFF_TYPE__ ZydisISize;
# else
# error "Unsupported compiler for no-libc mode."
# endif
#endif
// Verify size assumptions.
ZYDIS_STATIC_ASSERT(sizeof(ZydisU8 ) == 1 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisU16 ) == 2 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisU32 ) == 4 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisU64 ) == 8 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI8 ) == 1 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI16 ) == 2 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI32 ) == 4 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI64 ) == 8 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisUSize) == sizeof(void*));
ZYDIS_STATIC_ASSERT(sizeof(ZydisISize) == sizeof(void*));
// Verify signedness assumptions (relies on size checks above).
ZYDIS_STATIC_ASSERT((ZydisI8 )-1 >> 1 < (ZydisI8 )((ZydisU8 )-1 >> 1));
ZYDIS_STATIC_ASSERT((ZydisI16)-1 >> 1 < (ZydisI16)((ZydisU16)-1 >> 1));
ZYDIS_STATIC_ASSERT((ZydisI32)-1 >> 1 < (ZydisI32)((ZydisU32)-1 >> 1));
ZYDIS_STATIC_ASSERT((ZydisI64)-1 >> 1 < (ZydisI64)((ZydisU64)-1 >> 1));
/* ============================================================================================== */
/* NULL */
/* ============================================================================================== */
#define ZYDIS_NULL ((void*)0)
/* ============================================================================================== */
/* Boolean */
/* ============================================================================================== */
#define ZYDIS_FALSE 0
#define ZYDIS_TRUE 1
/**
* @briefs Defines the @c ZydisBool datatype.
*/
typedef ZydisU8 ZydisBool;
/* ============================================================================================== */
#endif /* ZYDIS_COMMONTYPES_H */
typedef ZydisU32 ZydisUPointer;
typedef ZydisI32 ZydisIPointer;
# endif
# elif defined(ZYDIS_GNUC)
typedef __UINT8_TYPE__ ZydisU8;
typedef __UINT16_TYPE__ ZydisU16;
typedef __UINT32_TYPE__ ZydisU32;
typedef __UINT64_TYPE__ ZydisU64;
typedef __INT8_TYPE__ ZydisI8;
typedef __INT16_TYPE__ ZydisI16;
typedef __INT32_TYPE__ ZydisI32;
typedef __INT64_TYPE__ ZydisI64;
typedef __SIZE_TYPE__ ZydisUSize;
typedef __PTRDIFF_TYPE__ ZydisISize;
typedef __UINTPTR_TYPE__ ZydisUPointer;
typedef __INTPTR_TYPE__ ZydisIPointer;
# else
# error "Unsupported compiler for no-libc mode."
# endif
#endif
// Verify size assumptions.
ZYDIS_STATIC_ASSERT(sizeof(ZydisU8 ) == 1 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisU16 ) == 2 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisU32 ) == 4 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisU64 ) == 8 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI8 ) == 1 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI16 ) == 2 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI32 ) == 4 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisI64 ) == 8 );
ZYDIS_STATIC_ASSERT(sizeof(ZydisUSize ) == sizeof(void*)); // TODO: This one is incorrect!
ZYDIS_STATIC_ASSERT(sizeof(ZydisISize ) == sizeof(void*)); // TODO: This one is incorrect!
ZYDIS_STATIC_ASSERT(sizeof(ZydisUPointer) == sizeof(void*));
ZYDIS_STATIC_ASSERT(sizeof(ZydisIPointer) == sizeof(void*));
// Verify signedness assumptions (relies on size checks above).
ZYDIS_STATIC_ASSERT((ZydisI8 )-1 >> 1 < (ZydisI8 )((ZydisU8 )-1 >> 1));
ZYDIS_STATIC_ASSERT((ZydisI16)-1 >> 1 < (ZydisI16)((ZydisU16)-1 >> 1));
ZYDIS_STATIC_ASSERT((ZydisI32)-1 >> 1 < (ZydisI32)((ZydisU32)-1 >> 1));
ZYDIS_STATIC_ASSERT((ZydisI64)-1 >> 1 < (ZydisI64)((ZydisU64)-1 >> 1));
/* ============================================================================================== */
/* NULL */
/* ============================================================================================== */
#define ZYDIS_NULL ((void*)0)
/* ============================================================================================== */
/* Boolean */
/* ============================================================================================== */
#define ZYDIS_FALSE 0
#define ZYDIS_TRUE 1
/**
* @briefs Defines the @c ZydisBool datatype.
*/
typedef ZydisU8 ZydisBool;
/* ============================================================================================== */
#endif /* ZYDIS_COMMONTYPES_H */

View File

@ -178,6 +178,11 @@
*/
#define ZYDIS_BITFIELD(x) : x
/**
* @brief Marks the specified parameter as unused.
*/
#define ZYDIS_UNUSED_PARAMETER(x) (void)(x)
/**
* @brief Calculates the size of an array.
*/

View File

@ -35,6 +35,7 @@
#include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h>
#include <Zydis/Status.h>
#include <Zydis/String.h>
#ifdef __cplusplus
extern "C" {
@ -49,7 +50,7 @@ extern "C" {
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisFormatterStyle datatype.
* @brief Defines the `ZydisFormatterStyle` datatype.
*/
typedef ZydisU8 ZydisFormatterStyle;
@ -62,6 +63,7 @@ enum ZydisFormatterStyles
* @brief Generates intel-style disassembly.
*/
ZYDIS_FORMATTER_STYLE_INTEL,
/**
* @brief Maximum value of this enum.
*/
@ -73,7 +75,7 @@ enum ZydisFormatterStyles
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisFormatterProperty datatype.
* @brief Defines the `ZydisFormatterProperty` datatype.
*/
typedef ZydisU8 ZydisFormatterProperty;
@ -98,16 +100,16 @@ enum ZydisFormatterProperties
*
* The default value is `ZYDIS_FALSE`.
*/
ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS,
ZYDIS_FORMATTER_PROP_FORCE_MEMSEG,
/**
* @brief Controls the printing of operand-sizes.
* @brief Controls the printing of memory-operand sizes.
*
* Pass `ZYDIS_TRUE` as value to force the formatter to always print the size of memory-operands
* or `ZYDIS_FALSE` to only print it on demand.
*
* The default value is `ZYDIS_FALSE`.
*/
ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE,
ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE,
/**
* @brief Controls the format of addresses.
@ -139,7 +141,7 @@ enum ZydisFormatterProperties
/**
* @brief Sets the prefix for hexadecimal values.
*
* The default value is `0x`.
* The default value is `"0x"`.
*/
ZYDIS_FORMATTER_PROP_HEX_PREFIX,
/**
@ -174,7 +176,7 @@ enum ZydisFormatterProperties
};
/* ---------------------------------------------------------------------------------------------- */
/* Address format constants */
/* Address format */
/* ---------------------------------------------------------------------------------------------- */
/**
@ -184,24 +186,34 @@ enum ZydisAddressFormat
{
/**
* @brief Displays absolute addresses instead of relative ones.
*
* Using this value will cause the formatter to invoke `ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS`
* for every address.
*/
ZYDIS_ADDR_FORMAT_ABSOLUTE,
/**
* @brief Uses signed hexadecimal values to display relative addresses.
*
* Using this value will cause the formatter to either invoke
* `ZYDIS_FORMATTER_HOOK_PRINT_DISP` or `ZYDIS_FORMATTER_HOOK_PRINT_IMM` to format addresses.
*
* Examples:
* "JMP 0x20"
* "JMP -0x20"
* - `"JMP 0x20"`
* - `"JMP -0x20"`
*/
ZYDIS_ADDR_FORMAT_RELATIVE_SIGNED,
/**
* @brief Uses unsigned hexadecimal values to display relative addresses.
*
*
* Using this value will cause the formatter to either invoke
* `ZYDIS_FORMATTER_HOOK_PRINT_DISP` or `ZYDIS_FORMATTER_HOOK_PRINT_IMM` to format addresses.
*
* Examples:
* "JMP 0x20"
* "JMP 0xE0"
* - `"JMP 0x20"`
* - `"JMP 0xE0"`
*/
ZYDIS_ADDR_FORMAT_RELATIVE_UNSIGNED,
/**
* @brief Maximum value of this enum.
*/
@ -209,7 +221,7 @@ enum ZydisAddressFormat
};
/* ---------------------------------------------------------------------------------------------- */
/* Displacement formats */
/* Displacement format */
/* ---------------------------------------------------------------------------------------------- */
/**
@ -221,18 +233,19 @@ enum ZydisDisplacementFormat
* @brief Formats displacements as signed hexadecimal values.
*
* Examples:
* "MOV EAX, DWORD PTR SS:[ESP+0x400]"
* "MOV EAX, DWORD PTR SS:[ESP-0x400]"
* - `"MOV EAX, DWORD PTR SS:[ESP+0x400]"`
* - `"MOV EAX, DWORD PTR SS:[ESP-0x400]"`
*/
ZYDIS_DISP_FORMAT_HEX_SIGNED,
/**
* @brief Formats displacements as unsigned hexadecimal values.
*
* Examples:
* "MOV EAX, DWORD PTR SS:[ESP+0x400]"
* "MOV EAX, DWORD PTR SS:[ESP+0xFFFFFC00]"
* - `"MOV EAX, DWORD PTR SS:[ESP+0x400]"`
* - `"MOV EAX, DWORD PTR SS:[ESP+0xFFFFFC00]"`
*/
ZYDIS_DISP_FORMAT_HEX_UNSIGNED,
/**
* @brief Maximum value of this enum.
*/
@ -240,7 +253,7 @@ enum ZydisDisplacementFormat
};
/* ---------------------------------------------------------------------------------------------- */
/* Immediate formats */
/* Immediate format */
/* ---------------------------------------------------------------------------------------------- */
/**
@ -250,25 +263,26 @@ enum ZydisImmediateFormat
{
/**
* @brief Automatically chooses the most suitable formatting-mode based on the operands
* @c ZydisOperandInfo.imm.isSigned attribute.
* `ZydisOperandInfo.imm.isSigned` attribute.
*/
ZYDIS_IMM_FORMAT_HEX_AUTO,
/**
* @brief Formats immediates as signed hexadecimal values.
*
* Examples:
* "MOV EAX, 0x400"
* "MOV EAX, -0x400"
* - `"MOV EAX, 0x400"`
* - `"MOV EAX, -0x400"`
*/
ZYDIS_IMM_FORMAT_HEX_SIGNED,
/**
* @brief Formats immediates as unsigned hexadecimal values.
*
* Examples:
* "MOV EAX, 0x400"
* "MOV EAX, 0xFFFFFC00"
* - `"MOV EAX, 0x400"`
* - `"MOV EAX, 0xFFFFFC00"`
*/
ZYDIS_IMM_FORMAT_HEX_UNSIGNED,
/**
* @brief Maximum value of this enum.
*/
@ -280,7 +294,7 @@ enum ZydisImmediateFormat
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisFormatterHookType datatype.
* @brief Defines the `ZydisFormatterHookType` datatype.
*/
typedef ZydisU8 ZydisFormatterHookType;
@ -290,98 +304,98 @@ typedef ZydisU8 ZydisFormatterHookType;
enum ZydisFormatterHookTypes
{
/**
* @brief This function is called before the formatter starts formatting an instruction.
* @brief This function is invoked before the formatter formats an instruction.
*/
ZYDIS_FORMATTER_HOOK_PRE,
ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION,
/**
* @brief This function is called after the formatter finished formatting an instruction.
* @brief This function is invoked before the formatter formatted an instruction.
*/
ZYDIS_FORMATTER_HOOK_POST,
ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION,
/**
* @brief This function refers to the main formatting function, that internally calls all
* other function except the ones that are hooked by @c ZYDIS_FORMATTER_HOOK_PRE and
* @c ZYDIS_FORMATTER_HOOK_POST.
*
* Replacing this function allows for complete custom formatting, but indirectly disables all
* other hooks except for @c ZYDIS_FORMATTER_HOOK_PRE and @c ZYDIS_FORMATTER_HOOK_POST.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION,
/**
* @brief This function is called to print the instruction prefixes.
*/
ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES,
/**
* @brief This function is called to print the instruction mnemonic.
*/
ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC,
/**
* @brief This function is called before the formatter starts formatting an operand.
* @brief This function is invoked before the formatter formats an operand.
*/
ZYDIS_FORMATTER_HOOK_PRE_OPERAND,
/**
* @brief This function is called after the formatter finished formatting an operand.
* @brief This function is invoked before the formatter formatted an operand.
*/
ZYDIS_FORMATTER_HOOK_POST_OPERAND,
/**
* @brief This function is called to format an register operand.
* @brief This function refers to the main formatting function.
*
* Replacing this function allows for complete custom formatting, but indirectly disables all
* other hooks except for `ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION` and
* `ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION`.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION,
/**
* @brief This function is invoked to format a register operand.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG,
/**
* @brief This function is called to format an memory operand.
* @brief This function is invoked to format a memory operand.
*
* Replacing this function might indirectly disable some specific calls to the
* @c ZYDIS_FORMATTER_PRINT_ADDRESS and @c ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT functions.
* `ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS` and `ZYDIS_FORMATTER_HOOK_PRINT_DISP` functions.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM,
/**
* @brief This function is called to format an pointer operand.
* @brief This function is invoked to format a pointer operand.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR,
/**
* @brief This function is called to format an immediate operand.
* @brief This function is invoked to format an immediate operand.
*
* Replacing this function might indirectly disable some specific calls to the
* @c ZYDIS_FORMATTER_PRINT_ADDRESS and @c ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE functions.
* `ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS` and `ZYDIS_FORMATTER_HOOK_PRINT_IMM` functions.
*/
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
/**
* @brief This function is called right before formatting an memory operand to print the
* optional size-specifier.
* @brief This function is invoked to print the instruction mnemonic.
*/
ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC,
/**
* @brief This function is called right before formatting an memory operand to print the
* optional segment-register.
* @brief This function is invoked to print a register.
*/
ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT,
ZYDIS_FORMATTER_HOOK_PRINT_REGISTER,
/**
* @brief This function is called right after formatting an operand to print the optional
* EVEX/MVEX operand-decorator.
*/
ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR,
/**
* @brief This function is called to print an absolute address.
* @brief This function is invoked to print an absolute address.
*/
ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS,
/**
* @brief This function is called to print a memory displacement value.
* @brief This function is invoked to print a memory displacement value.
*/
ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT,
ZYDIS_FORMATTER_HOOK_PRINT_DISP,
/**
* @brief This function is called to print an immediate value.
* @brief This function is invoked to print an immediate value.
*/
ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE,
ZYDIS_FORMATTER_HOOK_PRINT_IMM,
/**
* @brief This function is invoked to print the size of a memory operand.
*/
ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE,
/**
* @brief This function is invoked to print the instruction prefixes.
*/
ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES,
/**
* @brief This function is invoked after formatting an operand to print a `EVEX`/`MVEX`
* decorator.
*/
ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR,
/**
* @brief Maximum value of this enum.
*/
ZYDIS_FORMATTER_HOOK_MAX_VALUE = ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE
ZYDIS_FORMATTER_HOOK_MAX_VALUE = ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR
};
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisDecoratorType datatype.
* @brief Defines the `ZydisDecoratorType` datatype.
*/
typedef ZydisU8 ZydisDecoratorType;
@ -391,17 +405,39 @@ typedef ZydisU8 ZydisDecoratorType;
enum ZydisDecoratorTypes
{
ZYDIS_DECORATOR_TYPE_INVALID,
/**
* @brief The embedded-mask decorator.
*/
ZYDIS_DECORATOR_TYPE_MASK,
ZYDIS_DECORATOR_TYPE_BROADCAST,
ZYDIS_DECORATOR_TYPE_ROUNDING_CONTROL,
/**
* @brief The broadcast decorator.
*/
ZYDIS_DECORATOR_TYPE_BC,
/**
* @brief The rounding-control decorator.
*/
ZYDIS_DECORATOR_TYPE_RC,
/**
* @brief The suppress-all-exceptions decorator.
*/
ZYDIS_DECORATOR_TYPE_SAE,
/**
* @brief The register-swizzle decorator.
*/
ZYDIS_DECORATOR_TYPE_SWIZZLE,
/**
* @brief The conversion decorator.
*/
ZYDIS_DECORATOR_TYPE_CONVERSION,
ZYDIS_DECORATOR_TYPE_EVICTION_HINT,
/**
* @brief The eviction-hint decorator.
*/
ZYDIS_DECORATOR_TYPE_EH,
/**
* @brief Maximum value of this enum.
*/
ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EVICTION_HINT
ZYDIS_DECORATOR_TYPE_MAX_VALUE = ZYDIS_DECORATOR_TYPE_EH
};
/* ---------------------------------------------------------------------------------------------- */
@ -409,113 +445,129 @@ enum ZydisDecoratorTypes
typedef struct ZydisFormatter_ ZydisFormatter;
/**
* @brief Defines the @c ZydisFormatterFunc function pointer.
* @brief Defines the `ZydisFormatterFunc` function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param string A pointer to the string.
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param userData A pointer to user-defined data.
*
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail.
* @return A zydis status code.
*
* 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.
* Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the formatting
* process to fail.
*
* Returning `ZYDIS_STATUS_SUCCESS` in `ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES` without writing to
* the string is valid and signals that the corresponding element should not be printed.
*
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRE, @c ZYDIS_FORMATTER_HOOK_POST,
* @c ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION, @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and
* @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types.
* This function type is used for:
* - `ZYDIS_FORMATTER_HOOK_PRE_INSTRUCTION`
* - `ZYDIS_FORMATTER_HOOK_POST_INSTRUCTION`
* - `ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION`
* - `ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC`
* - `ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES`
*/
typedef ZydisStatus (*ZydisFormatterFunc)(const ZydisFormatter* formatter, char** buffer,
ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction, void* userData);
typedef ZydisStatus (*ZydisFormatterFunc)(const ZydisFormatter* formatter,
ZydisString* string, const ZydisDecodedInstruction* instruction, void* userData);
/**
* @brief Defines the @c ZydisFormatterOperandFunc function pointer.
* @brief Defines the `ZydisFormatterOperandFunc` function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param string A pointer to the string.
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param operand A pointer to the `ZydisDecodedOperand` struct.
* @param userData A pointer to user-defined data.
*
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
* formatting process to fail.
* @return A zydis status code.
*
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
* number of chars written.
* Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the formatting
* process to fail.
*
* 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
* Returning `ZYDIS_STATUS_SUCCESS` in one of the `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_X` hooks
* without writing to the string is valid and will cause the formatter to omit the current
* operand.
*
* Returning @c ZYDIS_STATUS_SUCCESS in @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
* @c ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT or @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR without
* increasing the buffer-pointer is valid and signals that the corresponding element should not be
* printed for the current operand.
*
* Not increasing the buffer-pointer for any other hook-type will cause unexpected behavior.
* Returning `ZYDIS_STATUS_SUCCESS` in `ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE` or
* `ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR` without writing to the string is valid and signals that
* the corresponding element should not be printed for the current operand.
*
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRE_OPERAND,
* @c ZYDIS_FORMATTER_HOOK_POST_OPERAND, @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_IMM, @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
* @c ZYDIS_FORMATTER_HOOK_PRINT_SEGMENT, @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR,
* @c ZYDIS_FORMATTER_HOOK_PRINT_DISPLACEMENT and @c ZYDIS_FORMATTER_HOOK_PRINT_IMMEDIATE
* hook-types.
* This function type is used for:
* - `ZYDIS_FORMATTER_HOOK_PRE_OPERAND`
* - `ZYDIS_FORMATTER_HOOK_POST_OPERAND`
* - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG`
* - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM`
* - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR`
* - `ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM`
* - `ZYDIS_FORMATTER_HOOK_PRINT_DISP`
* - `ZYDIS_FORMATTER_HOOK_PRINT_IMM`
* - `ZYDIS_FORMATTER_HOOK_PRINT_MEMSIZE`
*/
typedef ZydisStatus (*ZydisFormatterOperandFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* string, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, void* userData);
/**
* @brief Defines the @c ZydisFormatterAddressFunc function pointer.
* @brief Defines the `ZydisFormatterRegisterFunc` function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param string A pointer to the string.
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param operand A pointer to the `ZydisDecodedOperand` struct.
* @param reg The register.
* @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 `ZYDIS_STATUS_SUCCESS` will immediately cause the
* formatting process to fail.
*
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
* number of chars written.
* Not increasing the buffer-pointer will cause unexpected behavior.
*
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type.
* This function type is used for:
* - `ZYDIS_FORMATTER_HOOK_PRINT_REGISTER`.
*/
typedef ZydisStatus (*ZydisFormatterRegisterFunc)(const ZydisFormatter* formatter,
ZydisString* string, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisRegister reg, void* userData);
/**
* @brief Defines the `ZydisFormatterAddressFunc` function pointer.
*
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param string A pointer to the string.
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param operand A pointer to the `ZydisDecodedOperand` struct.
* @param address The address.
* @param userData A pointer to user-defined data.
*
* @return Returning a status code other than `ZYDIS_STATUS_SUCCESS` will immediately cause the
* formatting process to fail.
*
* This function type is used for:
* - `ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS`
*/
typedef ZydisStatus (*ZydisFormatterAddressFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* string, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisU64 address, void* userData);
/**
* @brief Defines the @c ZydisFormatterDecoratorFunc function pointer.
* @brief Defines the `ZydisFormatterDecoratorFunc` function pointer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param string A pointer to the string.
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param operand A pointer to the `ZydisDecodedOperand` struct.
* @param type The decorator type.
* @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 `ZYDIS_STATUS_SUCCESS` will immediately cause the
* formatting process to fail.
*
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
* number of chars written.
*
* Returning @c ZYDIS_STATUS_SUCCESS without increasing the buffer-pointer is valid and will cause
* the formatter to omit the current decorator.
* Returning `ZYDIS_STATUS_SUCCESS` without writing to the string is valid and will cause the
* formatter to omit the current decorator.
*
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-type.
* This function type is used for:
* - `ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR`
*/
typedef ZydisStatus (*ZydisFormatterDecoratorFunc)(const ZydisFormatter* formatter,
char** buffer, ZydisUSize bufferLen, const ZydisDecodedInstruction* instruction,
ZydisString* string, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisDecoratorType type, void* userData);
/* ---------------------------------------------------------------------------------------------- */
@ -523,39 +575,41 @@ typedef ZydisStatus (*ZydisFormatterDecoratorFunc)(const ZydisFormatter* formatt
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the @c ZydisFormatter struct.
* @brief Defines the `ZydisFormatter` struct.
*/
struct ZydisFormatter_
{
ZydisU8 letterCase;
ZydisBool forceSegments;
ZydisBool forceOperandSize;
ZydisU8 addressFormat;
ZydisU8 displacementFormat;
ZydisU8 immediateFormat;
ZydisLetterCase letterCase;
ZydisBool forceMemorySegment;
ZydisBool forceMemorySize;
ZydisU8 formatAddress;
ZydisU8 formatDisp;
ZydisU8 formatImm;
ZydisBool hexUppercase;
char* hexPrefix;
char* hexSuffix;
ZydisString* hexPrefix;
ZydisString hexPrefixData;
ZydisString* hexSuffix;
ZydisString hexSuffixData;
ZydisU8 hexPaddingAddress;
ZydisU8 hexPaddingDisplacement;
ZydisU8 hexPaddingImmediate;
ZydisFormatterFunc funcPre;
ZydisFormatterFunc funcPost;
ZydisFormatterFunc funcFormatInstruction;
ZydisFormatterFunc funcPrintPrefixes;
ZydisFormatterFunc funcPrintMnemonic;
ZydisU8 hexPaddingDisp;
ZydisU8 hexPaddingImm;
ZydisFormatterFunc funcPreInstruction;
ZydisFormatterFunc funcPostInstruction;
ZydisFormatterOperandFunc funcPreOperand;
ZydisFormatterOperandFunc funcPostOperand;
ZydisFormatterFunc funcFormatInstruction;
ZydisFormatterOperandFunc funcFormatOperandReg;
ZydisFormatterOperandFunc funcFormatOperandMem;
ZydisFormatterOperandFunc funcFormatOperandPtr;
ZydisFormatterOperandFunc funcFormatOperandImm;
ZydisFormatterOperandFunc funcPrintOperandSize;
ZydisFormatterOperandFunc funcPrintSegment;
ZydisFormatterDecoratorFunc funcPrintDecorator;
ZydisFormatterFunc funcPrintMnemonic;
ZydisFormatterRegisterFunc funcPrintRegister;
ZydisFormatterAddressFunc funcPrintAddress;
ZydisFormatterOperandFunc funcPrintDisplacement;
ZydisFormatterOperandFunc funcPrintImmediate;
ZydisFormatterOperandFunc funcPrintDisp;
ZydisFormatterOperandFunc funcPrintImm;
ZydisFormatterOperandFunc funcPrintMemSize;
ZydisFormatterFunc funcPrintPrefixes;
ZydisFormatterDecoratorFunc funcPrintDecorator;
};
/* ---------------------------------------------------------------------------------------------- */
@ -565,9 +619,9 @@ struct ZydisFormatter_
/* ============================================================================================== */
/**
* @brief Initializes the given @c ZydisFormatter instance.
* @brief Initializes the given `ZydisFormatter` instance.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param style The formatter style.
*
* @return A zydis status code.
@ -577,20 +631,20 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisForm
/**
* @brief Sets the value of the specified formatter `attribute`.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param property The id of the formatter-property.
* @param value The new value.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetProperty(ZydisFormatter* formatter,
ZydisFormatterProperty property, ZydisUSize value);
ZydisFormatterProperty property, ZydisUPointer value);
/**
* @brief Replaces a formatter function with a custom callback and/or retrieves the currently
* used function.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param hook The formatter hook-type.
* @param callback A pointer to a variable that contains the pointer of the callback function
* and receives the pointer of the currently used function.
@ -606,8 +660,8 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter,
/**
* @brief Formats the given instruction and writes it into the output buffer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param buffer A pointer to the output buffer.
* @param bufferLen The length of the output buffer.
*
@ -619,8 +673,8 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* f
/**
* @brief Formats the given instruction and writes it into the output buffer.
*
* @param formatter A pointer to the @c ZydisFormatter instance.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param formatter A pointer to the `ZydisFormatter` instance.
* @param instruction A pointer to the `ZydisDecodedInstruction` struct.
* @param buffer A pointer to the output buffer.
* @param bufferLen The length of the output buffer.
* @param userData A pointer to user-defined data which can be used in custom formatter

View File

@ -148,8 +148,7 @@ enum ZydisISAExts
ZYDIS_ISA_EXT_XSAVE,
ZYDIS_ISA_EXT_XSAVEC,
ZYDIS_ISA_EXT_XSAVEOPT,
ZYDIS_ISA_EXT_XSAVES
ZYDIS_ISA_EXT_XSAVES,
ZYDIS_ISA_EXT_MAX_VALUE = ZYDIS_ISA_EXT_XSAVES,
ZYDIS_ISA_EXT_MIN_BITS = 0x0008
};
#define ZYDIS_ISA_EXT_MAX_VALUE ZYDIS_ISA_EXT_XSAVES
#define ZYDIS_ISA_EXT_MAX_BITS 0x0008

View File

@ -71,8 +71,7 @@ enum ZydisISASets
ZYDIS_ISA_SET_XSAVE,
ZYDIS_ISA_SET_XSAVEC,
ZYDIS_ISA_SET_XSAVEOPT,
ZYDIS_ISA_SET_XSAVES
ZYDIS_ISA_SET_XSAVES,
ZYDIS_ISA_SET_MAX_VALUE = ZYDIS_ISA_SET_XSAVES,
ZYDIS_ISA_SET_MIN_BITS = 0x0006
};
#define ZYDIS_ISA_SET_MAX_VALUE ZYDIS_ISA_SET_XSAVES
#define ZYDIS_ISA_SET_MAX_BITS 0x0006

View File

@ -98,8 +98,7 @@ enum ZydisInstructionCategories
ZYDIS_CATEGORY_X87_ALU,
ZYDIS_CATEGORY_XOP,
ZYDIS_CATEGORY_XSAVE,
ZYDIS_CATEGORY_XSAVEOPT
ZYDIS_CATEGORY_XSAVEOPT,
ZYDIS_CATEGORY_MAX_VALUE = ZYDIS_CATEGORY_XSAVEOPT,
ZYDIS_CATEGORY_MIN_BITS = 0x0007
};
#define ZYDIS_CATEGORY_MAX_VALUE ZYDIS_CATEGORY_XSAVEOPT
#define ZYDIS_CATEGORY_MAX_BITS 0x0007

View File

@ -1582,8 +1582,7 @@ enum ZydisMnemonics
ZYDIS_MNEMONIC_XSAVES,
ZYDIS_MNEMONIC_XSAVES64,
ZYDIS_MNEMONIC_XSETBV,
ZYDIS_MNEMONIC_XTEST
ZYDIS_MNEMONIC_XTEST,
ZYDIS_MNEMONIC_MAX_VALUE = ZYDIS_MNEMONIC_XTEST,
ZYDIS_MNEMONIC_MIN_BITS = 0x000B
};
#define ZYDIS_MNEMONIC_MAX_VALUE ZYDIS_MNEMONIC_XTEST
#define ZYDIS_MNEMONIC_MAX_BITS 0x000B

View File

@ -24,8 +24,8 @@
***************************************************************************************************/
#ifndef ZYDIS_DECODERDATA_H
#define ZYDIS_DECODERDATA_H
#ifndef ZYDIS_INTERNAL_DECODERDATA_H
#define ZYDIS_INTERNAL_DECODERDATA_H
#include <Zydis/Defines.h>
#include <Zydis/DecoderTypes.h>
@ -311,4 +311,4 @@ ZYDIS_NO_EXPORT void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode*
}
#endif
#endif /* ZYDIS_DECODERDATA_H */
#endif /* ZYDIS_INTERNAL_DECODERDATA_H */

View File

@ -24,8 +24,8 @@
***************************************************************************************************/
#ifndef ZYDIS_LIBC_H
#define ZYDIS_LIBC_H
#ifndef ZYDIS_INTERNAL_LIBC_H
#define ZYDIS_INTERNAL_LIBC_H
#include <Zydis/Defines.h>
@ -79,4 +79,4 @@ ZYDIS_INLINE ZydisUSize ZydisStrLen(const char* str)
#endif
#endif /* ZYDIS_LIBC_H */
#endif /* ZYDIS_INTERNAL_LIBC_H */

View File

@ -24,8 +24,8 @@
***************************************************************************************************/
#ifndef ZYDIS_SHAREDDATA_H
#define ZYDIS_SHAREDDATA_H
#ifndef ZYDIS_INTERNAL_SHAREDDATA_H
#define ZYDIS_INTERNAL_SHAREDDATA_H
#include <Zydis/Defines.h>
#include <Zydis/Mnemonic.h>
@ -147,7 +147,7 @@ typedef struct ZydisOperandDefinition_
ZydisU8 type ZYDIS_BITFIELD(3);
union
{
ZydisRegister reg;
ZydisRegister reg ZYDIS_BITFIELD(ZYDIS_REGISTER_MIN_BITS);
ZydisU8 id ZYDIS_BITFIELD(6);
} reg;
} reg;
@ -543,16 +543,16 @@ enum ZydisMaskPolicies
/* ---------------------------------------------------------------------------------------------- */
#define ZYDIS_INSTRUCTION_DEFINITION_BASE \
ZydisMnemonic mnemonic ZYDIS_BITFIELD(ZYDIS_MNEMONIC_MAX_BITS); \
ZydisMnemonic mnemonic ZYDIS_BITFIELD(ZYDIS_MNEMONIC_MIN_BITS); \
ZydisU8 operandCount ZYDIS_BITFIELD( 4); \
ZydisU16 operandReference ZYDIS_BITFIELD(15); \
ZydisU8 operandSizeMap ZYDIS_BITFIELD( 3); \
ZydisU8 flagsReference ZYDIS_BITFIELD( 7); \
ZydisBool requiresProtectedMode ZYDIS_BITFIELD( 1); \
ZydisBool acceptsAddressSizeOverride ZYDIS_BITFIELD( 1); \
ZydisInstructionCategory category ZYDIS_BITFIELD(ZYDIS_CATEGORY_MAX_BITS); \
ZydisISASet isaSet ZYDIS_BITFIELD(ZYDIS_ISA_SET_MAX_BITS); \
ZydisISAExt isaExt ZYDIS_BITFIELD(ZYDIS_ISA_EXT_MAX_BITS); \
ZydisInstructionCategory category ZYDIS_BITFIELD(ZYDIS_CATEGORY_MIN_BITS); \
ZydisISASet isaSet ZYDIS_BITFIELD(ZYDIS_ISA_SET_MIN_BITS); \
ZydisISAExt isaExt ZYDIS_BITFIELD(ZYDIS_ISA_EXT_MIN_BITS); \
ZydisExceptionClass exceptionClass ZYDIS_BITFIELD( 6)
#define ZYDIS_INSTRUCTION_DEFINITION_BASE_VECTOR \
@ -717,4 +717,4 @@ ZYDIS_NO_EXPORT void ZydisGetAccessedFlags(const ZydisInstructionDefinition* def
}
#endif
#endif /* ZYDIS_SHAREDDATA_H */
#endif /* ZYDIS_INTERNAL_SHAREDDATA_H */

View File

@ -32,8 +32,8 @@
#ifndef ZYDIS_MNEMONIC_H
#define ZYDIS_MNEMONIC_H
#include <Zydis/Defines.h>
#include <Zydis/CommonTypes.h>
#include <Zydis/String.h>
#ifdef __cplusplus
extern "C" {
@ -58,6 +58,17 @@ extern "C" {
*/
ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic);
/**
* @brief Returns the specified instruction mnemonic as `ZydisStaticString`.
*
* @param mnemonic The mnemonic.
*
* @return The instruction mnemonic string or @c NULL, if an invalid mnemonic was passed.
*
* The `buffer` of the returned struct is guaranteed to be zero-terminated in this special case.
*/
ZYDIS_EXPORT const ZydisStaticString* ZydisMnemonicGetStaticString(ZydisMnemonic mnemonic);
/* ============================================================================================== */
#ifdef __cplusplus

View File

@ -34,7 +34,7 @@
#include <Zydis/Defines.h>
#include <Zydis/CommonTypes.h>
#include <Zydis/Status.h>
#include <Zydis/String.h>
#ifdef __cplusplus
extern "C" {
@ -59,6 +59,7 @@ typedef ZydisU8 ZydisRegister;
enum ZydisRegisters
{
ZYDIS_REGISTER_NONE,
// General purpose registers 8-bit
ZYDIS_REGISTER_AL, ZYDIS_REGISTER_CL, ZYDIS_REGISTER_DL, ZYDIS_REGISTER_BL,
ZYDIS_REGISTER_AH, ZYDIS_REGISTER_CH, ZYDIS_REGISTER_DH, ZYDIS_REGISTER_BH,
@ -86,24 +87,6 @@ enum ZydisRegisters
// Floating point multimedia registers
ZYDIS_REGISTER_MM0, ZYDIS_REGISTER_MM1, ZYDIS_REGISTER_MM2, ZYDIS_REGISTER_MM3,
ZYDIS_REGISTER_MM4, ZYDIS_REGISTER_MM5, ZYDIS_REGISTER_MM6, ZYDIS_REGISTER_MM7,
// Floating point vector registers 512-bit
ZYDIS_REGISTER_ZMM0, ZYDIS_REGISTER_ZMM1, ZYDIS_REGISTER_ZMM2, ZYDIS_REGISTER_ZMM3,
ZYDIS_REGISTER_ZMM4, ZYDIS_REGISTER_ZMM5, ZYDIS_REGISTER_ZMM6, ZYDIS_REGISTER_ZMM7,
ZYDIS_REGISTER_ZMM8, ZYDIS_REGISTER_ZMM9, ZYDIS_REGISTER_ZMM10, ZYDIS_REGISTER_ZMM11,
ZYDIS_REGISTER_ZMM12, ZYDIS_REGISTER_ZMM13, ZYDIS_REGISTER_ZMM14, ZYDIS_REGISTER_ZMM15,
ZYDIS_REGISTER_ZMM16, ZYDIS_REGISTER_ZMM17, ZYDIS_REGISTER_ZMM18, ZYDIS_REGISTER_ZMM19,
ZYDIS_REGISTER_ZMM20, ZYDIS_REGISTER_ZMM21, ZYDIS_REGISTER_ZMM22, ZYDIS_REGISTER_ZMM23,
ZYDIS_REGISTER_ZMM24, ZYDIS_REGISTER_ZMM25, ZYDIS_REGISTER_ZMM26, ZYDIS_REGISTER_ZMM27,
ZYDIS_REGISTER_ZMM28, ZYDIS_REGISTER_ZMM29, ZYDIS_REGISTER_ZMM30, ZYDIS_REGISTER_ZMM31,
// Floating point vector registers 256-bit
ZYDIS_REGISTER_YMM0, ZYDIS_REGISTER_YMM1, ZYDIS_REGISTER_YMM2, ZYDIS_REGISTER_YMM3,
ZYDIS_REGISTER_YMM4, ZYDIS_REGISTER_YMM5, ZYDIS_REGISTER_YMM6, ZYDIS_REGISTER_YMM7,
ZYDIS_REGISTER_YMM8, ZYDIS_REGISTER_YMM9, ZYDIS_REGISTER_YMM10, ZYDIS_REGISTER_YMM11,
ZYDIS_REGISTER_YMM12, ZYDIS_REGISTER_YMM13, ZYDIS_REGISTER_YMM14, ZYDIS_REGISTER_YMM15,
ZYDIS_REGISTER_YMM16, ZYDIS_REGISTER_YMM17, ZYDIS_REGISTER_YMM18, ZYDIS_REGISTER_YMM19,
ZYDIS_REGISTER_YMM20, ZYDIS_REGISTER_YMM21, ZYDIS_REGISTER_YMM22, ZYDIS_REGISTER_YMM23,
ZYDIS_REGISTER_YMM24, ZYDIS_REGISTER_YMM25, ZYDIS_REGISTER_YMM26, ZYDIS_REGISTER_YMM27,
ZYDIS_REGISTER_YMM28, ZYDIS_REGISTER_YMM29, ZYDIS_REGISTER_YMM30, ZYDIS_REGISTER_YMM31,
// Floating point vector registers 128-bit
ZYDIS_REGISTER_XMM0, ZYDIS_REGISTER_XMM1, ZYDIS_REGISTER_XMM2, ZYDIS_REGISTER_XMM3,
ZYDIS_REGISTER_XMM4, ZYDIS_REGISTER_XMM5, ZYDIS_REGISTER_XMM6, ZYDIS_REGISTER_XMM7,
@ -113,12 +96,28 @@ enum ZydisRegisters
ZYDIS_REGISTER_XMM20, ZYDIS_REGISTER_XMM21, ZYDIS_REGISTER_XMM22, ZYDIS_REGISTER_XMM23,
ZYDIS_REGISTER_XMM24, ZYDIS_REGISTER_XMM25, ZYDIS_REGISTER_XMM26, ZYDIS_REGISTER_XMM27,
ZYDIS_REGISTER_XMM28, ZYDIS_REGISTER_XMM29, ZYDIS_REGISTER_XMM30, ZYDIS_REGISTER_XMM31,
// Floating point vector registers 256-bit
ZYDIS_REGISTER_YMM0, ZYDIS_REGISTER_YMM1, ZYDIS_REGISTER_YMM2, ZYDIS_REGISTER_YMM3,
ZYDIS_REGISTER_YMM4, ZYDIS_REGISTER_YMM5, ZYDIS_REGISTER_YMM6, ZYDIS_REGISTER_YMM7,
ZYDIS_REGISTER_YMM8, ZYDIS_REGISTER_YMM9, ZYDIS_REGISTER_YMM10, ZYDIS_REGISTER_YMM11,
ZYDIS_REGISTER_YMM12, ZYDIS_REGISTER_YMM13, ZYDIS_REGISTER_YMM14, ZYDIS_REGISTER_YMM15,
ZYDIS_REGISTER_YMM16, ZYDIS_REGISTER_YMM17, ZYDIS_REGISTER_YMM18, ZYDIS_REGISTER_YMM19,
ZYDIS_REGISTER_YMM20, ZYDIS_REGISTER_YMM21, ZYDIS_REGISTER_YMM22, ZYDIS_REGISTER_YMM23,
ZYDIS_REGISTER_YMM24, ZYDIS_REGISTER_YMM25, ZYDIS_REGISTER_YMM26, ZYDIS_REGISTER_YMM27,
ZYDIS_REGISTER_YMM28, ZYDIS_REGISTER_YMM29, ZYDIS_REGISTER_YMM30, ZYDIS_REGISTER_YMM31,
// Floating point vector registers 512-bit
ZYDIS_REGISTER_ZMM0, ZYDIS_REGISTER_ZMM1, ZYDIS_REGISTER_ZMM2, ZYDIS_REGISTER_ZMM3,
ZYDIS_REGISTER_ZMM4, ZYDIS_REGISTER_ZMM5, ZYDIS_REGISTER_ZMM6, ZYDIS_REGISTER_ZMM7,
ZYDIS_REGISTER_ZMM8, ZYDIS_REGISTER_ZMM9, ZYDIS_REGISTER_ZMM10, ZYDIS_REGISTER_ZMM11,
ZYDIS_REGISTER_ZMM12, ZYDIS_REGISTER_ZMM13, ZYDIS_REGISTER_ZMM14, ZYDIS_REGISTER_ZMM15,
ZYDIS_REGISTER_ZMM16, ZYDIS_REGISTER_ZMM17, ZYDIS_REGISTER_ZMM18, ZYDIS_REGISTER_ZMM19,
ZYDIS_REGISTER_ZMM20, ZYDIS_REGISTER_ZMM21, ZYDIS_REGISTER_ZMM22, ZYDIS_REGISTER_ZMM23,
ZYDIS_REGISTER_ZMM24, ZYDIS_REGISTER_ZMM25, ZYDIS_REGISTER_ZMM26, ZYDIS_REGISTER_ZMM27,
ZYDIS_REGISTER_ZMM28, ZYDIS_REGISTER_ZMM29, ZYDIS_REGISTER_ZMM30, ZYDIS_REGISTER_ZMM31,
// Flags registers
ZYDIS_REGISTER_RFLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_FLAGS,
// Instruction-pointer registers
ZYDIS_REGISTER_RIP, ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP,
// Special registers
ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU, ZYDIS_REGISTER_XCR0,
ZYDIS_REGISTER_FLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_RFLAGS,
// IP registers
ZYDIS_REGISTER_IP, ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_RIP,
// Segment registers
ZYDIS_REGISTER_ES, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_DS,
ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS,
@ -143,15 +142,17 @@ enum ZydisRegisters
// Bound registers
ZYDIS_REGISTER_BND0, ZYDIS_REGISTER_BND1, ZYDIS_REGISTER_BND2, ZYDIS_REGISTER_BND3,
ZYDIS_REGISTER_BNDCFG, ZYDIS_REGISTER_BNDSTATUS,
// Misc registers
ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU, ZYDIS_REGISTER_XCR0,
/**
* @brief Maximum value of this enum.
*/
ZYDIS_REGISTER_MAX_VALUE = ZYDIS_REGISTER_BNDSTATUS,
ZYDIS_REGISTER_MAX_VALUE = ZYDIS_REGISTER_XCR0,
/**
* @brief Maximum amount of bits occupied by an integer from this enum.
* @brief Minimum amount of bits required to store a value of this enum.
*/
ZYDIS_REGISTER_MAX_BITS = 8
ZYDIS_REGISTER_MIN_BITS = 0x0008
};
/* ---------------------------------------------------------------------------------------------- */
@ -314,6 +315,17 @@ ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth64(ZydisRegister reg);
*/
ZYDIS_EXPORT const char* ZydisRegisterGetString(ZydisRegister reg);
/**
* @brief Returns the specified register string as `ZydisStaticString`.
*
* @param reg The register.
*
* @return The register string or @c NULL, if an invalid register was passed.
*
* The `buffer` of the returned struct is guaranteed to be zero-terminated in this special case.
*/
ZYDIS_EXPORT const ZydisStaticString* ZydisRegisterGetStaticString(ZydisRegister reg);
/* ============================================================================================== */
#ifdef __cplusplus

View File

@ -164,10 +164,10 @@ enum ZydisStatusCodes
#define ZYDIS_CHECK(status) \
do \
{ \
ZydisStatus s = status; \
if (!ZYDIS_SUCCESS(s)) \
ZydisStatus status_038560234 = status; \
if (!ZYDIS_SUCCESS(status_038560234)) \
{ \
return s; \
return status_038560234; \
} \
} while (0)

418
include/Zydis/String.h Normal file
View File

@ -0,0 +1,418 @@
/***************************************************************************************************
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_STRING_H
#define ZYDIS_STRING_H
#include <Zydis/CommonTypes.h>
#include <Zydis/Status.h>
#include <Zydis/Internal/LibC.h>
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* String */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the `ZydisString` struct.
*/
typedef struct ZydisString_
{
/**
* @brief The buffer that contains the actual string (0-termination is optional!).
*/
char *buffer;
/**
* @brief The length of the string (without 0-termination).
*/
ZydisUSize length;
/**
* @brief The total buffer capacity.
*/
ZydisUSize capacity;
} ZydisString;
/* ---------------------------------------------------------------------------------------------- */
/* Static string */
/* ---------------------------------------------------------------------------------------------- */
#pragma pack(push, 1)
/**
* @brief Defines the `ZydisStaticString` struct.
*
* This more compact struct is mainly used for internal string-tables to save up some bytes.
*/
typedef struct ZydisStaticString_
{
/**
* @brief The buffer that contains the actual string (0-termination is optional!).
*/
const char* buffer;
/**
* @brief The length of the string (without 0-termination).
*/
ZydisU8 length;
} ZydisStaticString;
#pragma pack(pop)
/* ---------------------------------------------------------------------------------------------- */
/* Letter Case */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Defines the `ZydisLetterCase` datatype.
*/
typedef ZydisU8 ZydisLetterCase;
/**
* @brief Values that represent letter cases.
*/
enum ZydisLetterCases
{
/**
* @brief Uses the given text "as 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 static C-string.
*
* @param string The C-string constant.
*/
#define ZYDIS_MAKE_STRING(string) \
{ (char*)string, sizeof(string) - 1, sizeof(string) - 1 }
/**
* @brief Creates a `ZydisStaticString` from a static C-string.
*
* @param string The C-string constant.
*/
#define ZYDIS_MAKE_STATIC_STRING(string) \
{ string, 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;
}
const ZydisUSize length = ZydisStrLen(value);
string->buffer = value;
string->length = length;
string->capacity = length;
return ZYDIS_STATUS_SUCCESS;
}
/**
* @brief Finalizes a `ZydisString` struct by adding a terminating zero byte.
*
* @param string The string to finalize.
*
* @return A zydis status code.
*/
ZYDIS_NO_EXPORT ZYDIS_INLINE ZydisStatus ZydisStringFinalize(ZydisString* string)
{
if (!string)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
if (string->length >= string->capacity)
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
string->buffer[string->length] = 0;
return ZYDIS_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Appends a `ZydisString` to another `ZydisString`, 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`, 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 the given 'ZydisStaticString' to a `ZydisString`, converting it to the
* specified letter-case.
*
* @param string The string to append to.
* @param text The static-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 ZydisStringAppendExStatic(ZydisString* string,
const ZydisStaticString* text, ZydisLetterCase letterCase)
{
if (!text || !text->buffer)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
ZydisString other;
other.buffer = (char*)text->buffer;
other.length = text->length;
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 ZydisStringAppendEx(string, &other, ZYDIS_LETTER_CASE_DEFAULT);
}
/**
* @brief Appends the given 'ZydisStaticString' to a `ZydisString`.
*
* @param string The string to append to.
* @param text The static-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 ZydisStringAppendStatic(ZydisString* string,
const ZydisStaticString* text, ZydisLetterCase letterCase)
{
if (!text || !text->buffer)
{
return ZYDIS_STATUS_INVALID_PARAMETER;
}
ZydisString other;
other.buffer = (char*)text->buffer;
other.length = text->length;
return ZydisStringAppendEx(string, &other, letterCase);
}
/* ---------------------------------------------------------------------------------------------- */
/* 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

View File

@ -42,6 +42,7 @@
#include <Zydis/Register.h>
#include <Zydis/SharedTypes.h>
#include <Zydis/Status.h>
#include <Zydis/String.h>
#include <Zydis/Utils.h>
#ifdef __cplusplus

View File

@ -26,9 +26,9 @@
#include <Zydis/Decoder.h>
#include <Zydis/Status.h>
#include <DecoderData.h>
#include <SharedData.h>
#include <LibC.h>
#include <Zydis/Internal/LibC.h>
#include <Zydis/Internal/DecoderData.h>
#include <Zydis/Internal/SharedData.h>
/* ============================================================================================== */
/* Internal enums and types */

View File

@ -24,7 +24,7 @@
***************************************************************************************************/
#include <DecoderData.h>
#include <Zydis/Internal/DecoderData.h>
/* ============================================================================================== */
/* Data tables */
@ -368,7 +368,7 @@ void ZydisGetInstructionEncodingInfo(const ZydisDecoderTreeNode* node,
const ZydisInstructionEncodingInfo** info)
{
ZYDIS_ASSERT(node->type & ZYDIS_NODETYPE_DEFINITION_MASK);
ZydisU8 class = (node->type) & 0x7F;
const ZydisU8 class = (node->type) & 0x7F;
ZYDIS_ASSERT(class < ZYDIS_ARRAY_SIZE(instructionEncodings));
*info = &instructionEncodings[class];
}

View File

@ -1,201 +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>
#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 given @c text to the @c buffer.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param text The text to append.
* @param letterCase The desired letter-case.
*
* @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or
* @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not
* sufficient to append the given @c text.
*
* The string-buffer pointer is increased by the number of chars written, if the call was
* successfull.
*/
ZYDIS_NO_EXPORT ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, const char* text,
ZydisLetterCase letterCase);
/* ---------------------------------------------------------------------------------------------- */
/* Decimal values */
/* ---------------------------------------------------------------------------------------------- */
/**
* @brief Formats the given unsigned ordinal @c value to its decimal text-representation and
* appends it to the @c buffer.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param 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(char** buffer, ZydisUSize bufferLen, ZydisU64 value,
ZydisU8 paddingLength);
/**
* @brief Formats the given signed ordinal @c value to its decimal text-representation and
* appends it to the @c buffer.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param 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(char** buffer, ZydisUSize bufferLen, 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 buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @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(char** buffer, ZydisUSize bufferLen, ZydisU64 value,
ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix);
/**
* @brief Formats the given signed ordinal @c value to its hexadecimal text-representation and
* appends it to the @c buffer.
*
* @param buffer A pointer to the string-buffer.
* @param bufferLen The length of the string-buffer.
* @param 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(char** buffer, ZydisUSize bufferLen, ZydisI64 value,
ZydisU8 paddingLength, ZydisBool uppercase, const char* prefix, const char* suffix);
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* ZYDIS_FORMATHELPER_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@
const char* ZydisCategoryGetString(ZydisInstructionCategory category)
{
if (category > ZYDIS_ARRAY_SIZE(zydisInstructionCategoryStrings) - 1)
if (category >= ZYDIS_ARRAY_SIZE(zydisInstructionCategoryStrings))
{
return ZYDIS_NULL;
}
@ -49,7 +49,7 @@ const char* ZydisCategoryGetString(ZydisInstructionCategory category)
const char* ZydisISASetGetString(ZydisISASet isaSet)
{
if (isaSet > ZYDIS_ARRAY_SIZE(zydisISASetStrings) - 1)
if (isaSet >= ZYDIS_ARRAY_SIZE(zydisISASetStrings))
{
return ZYDIS_NULL;
}
@ -58,7 +58,7 @@ const char* ZydisISASetGetString(ZydisISASet isaSet)
const char* ZydisISAExtGetString(ZydisISAExt isaExt)
{
if (isaExt > ZYDIS_ARRAY_SIZE(zydisISAExtStrings) - 1)
if (isaExt >= ZYDIS_ARRAY_SIZE(zydisISAExtStrings))
{
return ZYDIS_NULL;
}

View File

@ -25,11 +25,6 @@
***************************************************************************************************/
#include <Zydis/Mnemonic.h>
/* ============================================================================================== */
/* Mnemonic strings */
/* ============================================================================================== */
#include <Generated/EnumMnemonic.inc>
/* ============================================================================================== */
@ -38,11 +33,20 @@
const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic)
{
if (mnemonic > ZYDIS_ARRAY_SIZE(zydisMnemonicStrings) - 1)
if (mnemonic >= ZYDIS_ARRAY_SIZE(zydisMnemonicStrings))
{
return ZYDIS_NULL;
}
return zydisMnemonicStrings[mnemonic];
return (const char*)zydisMnemonicStrings[mnemonic].buffer;
}
const ZydisStaticString* ZydisMnemonicGetStaticString(ZydisMnemonic mnemonic)
{
if (mnemonic >= ZYDIS_ARRAY_SIZE(zydisMnemonicStrings))
{
return ZYDIS_NULL;
}
return &zydisMnemonicStrings[mnemonic];
}
/* ============================================================================================== */

View File

@ -30,91 +30,156 @@
/* Register strings */
/* ============================================================================================== */
const char* registerStrings[] =
static const ZydisStaticString registerStrings[] =
{
"none",
// General purpose registers 8-bit
"al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh",
"spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b",
"r12b", "r13b", "r14b", "r15b",
ZYDIS_MAKE_STATIC_STRING("none"),
// General purpose registers 8-bit
ZYDIS_MAKE_STATIC_STRING("al"), ZYDIS_MAKE_STATIC_STRING("cl"),
ZYDIS_MAKE_STATIC_STRING("dl"), ZYDIS_MAKE_STATIC_STRING("bl"),
ZYDIS_MAKE_STATIC_STRING("ah"), ZYDIS_MAKE_STATIC_STRING("ch"),
ZYDIS_MAKE_STATIC_STRING("dh"), ZYDIS_MAKE_STATIC_STRING("bh"),
ZYDIS_MAKE_STATIC_STRING("spl"), ZYDIS_MAKE_STATIC_STRING("bpl"),
ZYDIS_MAKE_STATIC_STRING("sil"), ZYDIS_MAKE_STATIC_STRING("dil"),
ZYDIS_MAKE_STATIC_STRING("r8b"), ZYDIS_MAKE_STATIC_STRING("r9b"),
ZYDIS_MAKE_STATIC_STRING("r10b"), ZYDIS_MAKE_STATIC_STRING("r11b"),
ZYDIS_MAKE_STATIC_STRING("r12b"), ZYDIS_MAKE_STATIC_STRING("r13b"),
ZYDIS_MAKE_STATIC_STRING("r14b"), ZYDIS_MAKE_STATIC_STRING("r15b"),
// General purpose registers 16-bit
"ax", "cx", "dx", "bx",
"sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w",
"r12w", "r13w", "r14w", "r15w",
ZYDIS_MAKE_STATIC_STRING("ax"), ZYDIS_MAKE_STATIC_STRING("cx"),
ZYDIS_MAKE_STATIC_STRING("dx"), ZYDIS_MAKE_STATIC_STRING("bx"),
ZYDIS_MAKE_STATIC_STRING("sp"), ZYDIS_MAKE_STATIC_STRING("bp"),
ZYDIS_MAKE_STATIC_STRING("si"), ZYDIS_MAKE_STATIC_STRING("di"),
ZYDIS_MAKE_STATIC_STRING("r8d"), ZYDIS_MAKE_STATIC_STRING("r9d"),
ZYDIS_MAKE_STATIC_STRING("r10d"), ZYDIS_MAKE_STATIC_STRING("r11d"),
ZYDIS_MAKE_STATIC_STRING("r12d"), ZYDIS_MAKE_STATIC_STRING("r13d"),
ZYDIS_MAKE_STATIC_STRING("r14d"), ZYDIS_MAKE_STATIC_STRING("r15d"),
// General purpose registers 32-bit
"eax", "ecx", "edx", "ebx",
"esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d",
"r12d", "r13d", "r14d", "r15d",
ZYDIS_MAKE_STATIC_STRING("rax"), ZYDIS_MAKE_STATIC_STRING("rcx"),
ZYDIS_MAKE_STATIC_STRING("rdx"), ZYDIS_MAKE_STATIC_STRING("rbx"),
ZYDIS_MAKE_STATIC_STRING("rsp"), ZYDIS_MAKE_STATIC_STRING("rbp"),
ZYDIS_MAKE_STATIC_STRING("rsi"), ZYDIS_MAKE_STATIC_STRING("rdi"),
ZYDIS_MAKE_STATIC_STRING("r8"), ZYDIS_MAKE_STATIC_STRING("r9"),
ZYDIS_MAKE_STATIC_STRING("r10"), ZYDIS_MAKE_STATIC_STRING("r11"),
ZYDIS_MAKE_STATIC_STRING("r12"), ZYDIS_MAKE_STATIC_STRING("r13"),
ZYDIS_MAKE_STATIC_STRING("r14"), ZYDIS_MAKE_STATIC_STRING("r15"),
// General purpose registers 64-bit
"rax", "rcx", "rdx", "rbx",
"rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11",
"r12", "r13", "r14", "r15",
ZYDIS_MAKE_STATIC_STRING("rax"), ZYDIS_MAKE_STATIC_STRING("rcx"),
ZYDIS_MAKE_STATIC_STRING("rdx"), ZYDIS_MAKE_STATIC_STRING("rbx"),
ZYDIS_MAKE_STATIC_STRING("rsp"), ZYDIS_MAKE_STATIC_STRING("rbp"),
ZYDIS_MAKE_STATIC_STRING("rsi"), ZYDIS_MAKE_STATIC_STRING("rdi"),
ZYDIS_MAKE_STATIC_STRING("r8"), ZYDIS_MAKE_STATIC_STRING("r9"),
ZYDIS_MAKE_STATIC_STRING("r10"), ZYDIS_MAKE_STATIC_STRING("r11"),
ZYDIS_MAKE_STATIC_STRING("r12"), ZYDIS_MAKE_STATIC_STRING("r13"),
ZYDIS_MAKE_STATIC_STRING("r14"), ZYDIS_MAKE_STATIC_STRING("r15"),
// Floating point legacy registers
"st0", "st1", "st2", "st3",
"st4", "st5", "st6", "st7",
ZYDIS_MAKE_STATIC_STRING("st0"), ZYDIS_MAKE_STATIC_STRING("st1"),
ZYDIS_MAKE_STATIC_STRING("st2"), ZYDIS_MAKE_STATIC_STRING("st3"),
ZYDIS_MAKE_STATIC_STRING("st4"), ZYDIS_MAKE_STATIC_STRING("st5"),
ZYDIS_MAKE_STATIC_STRING("st6"), ZYDIS_MAKE_STATIC_STRING("st7"),
// Floating point multimedia registers
"mm0", "mm1", "mm2", "mm3",
"mm4", "mm5", "mm6", "mm7",
// Floating point vector registers 512-bit
"zmm0", "zmm1", "zmm2", "zmm3",
"zmm4", "zmm5", "zmm6", "zmm7",
"zmm8", "zmm9", "zmm10", "zmm11",
"zmm12", "zmm13", "zmm14", "zmm15",
"zmm16", "zmm17", "zmm18", "zmm19",
"zmm20", "zmm21", "zmm22", "zmm23",
"zmm24", "zmm25", "zmm26", "zmm27",
"zmm28", "zmm29", "zmm30", "zmm31",
// Floating point vector registers 256-bit
"ymm0", "ymm1", "ymm2", "ymm3",
"ymm4", "ymm5", "ymm6", "ymm7",
"ymm8", "ymm9", "ymm10", "ymm11",
"ymm12", "ymm13", "ymm14", "ymm15",
"ymm16", "ymm17", "ymm18", "ymm19",
"ymm20", "ymm21", "ymm22", "ymm23",
"ymm24", "ymm25", "ymm26", "ymm27",
"ymm28", "ymm29", "ymm30", "ymm31",
ZYDIS_MAKE_STATIC_STRING("mm0"), ZYDIS_MAKE_STATIC_STRING("mm1"),
ZYDIS_MAKE_STATIC_STRING("mm2"), ZYDIS_MAKE_STATIC_STRING("mm3"),
ZYDIS_MAKE_STATIC_STRING("mm4"), ZYDIS_MAKE_STATIC_STRING("mm5"),
ZYDIS_MAKE_STATIC_STRING("mm6"), ZYDIS_MAKE_STATIC_STRING("mm7"),
// Floating point vector registers 128-bit
"xmm0", "xmm1", "xmm2", "xmm3",
"xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11",
"xmm12", "xmm13", "xmm14", "xmm15",
"xmm16", "xmm17", "xmm18", "xmm19",
"xmm20", "xmm21", "xmm22", "xmm23",
"xmm24", "xmm25", "xmm26", "xmm27",
"xmm28", "xmm29", "xmm30", "xmm31",
// Special registers
"rflags", "eflags", "flags", "rip",
"eip", "ip", "mxcsr", "pkru",
"xcr0",
ZYDIS_MAKE_STATIC_STRING("xmm0"), ZYDIS_MAKE_STATIC_STRING("xmm1"),
ZYDIS_MAKE_STATIC_STRING("xmm2"), ZYDIS_MAKE_STATIC_STRING("xmm3"),
ZYDIS_MAKE_STATIC_STRING("xmm4"), ZYDIS_MAKE_STATIC_STRING("xmm5"),
ZYDIS_MAKE_STATIC_STRING("xmm6"), ZYDIS_MAKE_STATIC_STRING("xmm7"),
ZYDIS_MAKE_STATIC_STRING("xmm8"), ZYDIS_MAKE_STATIC_STRING("xmm9"),
ZYDIS_MAKE_STATIC_STRING("xmm10"), ZYDIS_MAKE_STATIC_STRING("xmm11"),
ZYDIS_MAKE_STATIC_STRING("xmm12"), ZYDIS_MAKE_STATIC_STRING("xmm13"),
ZYDIS_MAKE_STATIC_STRING("xmm14"), ZYDIS_MAKE_STATIC_STRING("xmm15"),
ZYDIS_MAKE_STATIC_STRING("xmm16"), ZYDIS_MAKE_STATIC_STRING("xmm17"),
ZYDIS_MAKE_STATIC_STRING("xmm18"), ZYDIS_MAKE_STATIC_STRING("xmm19"),
ZYDIS_MAKE_STATIC_STRING("xmm20"), ZYDIS_MAKE_STATIC_STRING("xmm21"),
ZYDIS_MAKE_STATIC_STRING("xmm22"), ZYDIS_MAKE_STATIC_STRING("xmm23"),
ZYDIS_MAKE_STATIC_STRING("xmm24"), ZYDIS_MAKE_STATIC_STRING("xmm25"),
ZYDIS_MAKE_STATIC_STRING("xmm26"), ZYDIS_MAKE_STATIC_STRING("xmm27"),
ZYDIS_MAKE_STATIC_STRING("xmm28"), ZYDIS_MAKE_STATIC_STRING("xmm29"),
ZYDIS_MAKE_STATIC_STRING("xmm30"), ZYDIS_MAKE_STATIC_STRING("xmm31"),
// Floating point vector registers 256-bit
ZYDIS_MAKE_STATIC_STRING("ymm0"), ZYDIS_MAKE_STATIC_STRING("ymm1"),
ZYDIS_MAKE_STATIC_STRING("ymm2"), ZYDIS_MAKE_STATIC_STRING("ymm3"),
ZYDIS_MAKE_STATIC_STRING("ymm4"), ZYDIS_MAKE_STATIC_STRING("ymm5"),
ZYDIS_MAKE_STATIC_STRING("ymm6"), ZYDIS_MAKE_STATIC_STRING("ymm7"),
ZYDIS_MAKE_STATIC_STRING("ymm8"), ZYDIS_MAKE_STATIC_STRING("ymm9"),
ZYDIS_MAKE_STATIC_STRING("ymm10"), ZYDIS_MAKE_STATIC_STRING("ymm11"),
ZYDIS_MAKE_STATIC_STRING("ymm12"), ZYDIS_MAKE_STATIC_STRING("ymm13"),
ZYDIS_MAKE_STATIC_STRING("ymm14"), ZYDIS_MAKE_STATIC_STRING("ymm15"),
ZYDIS_MAKE_STATIC_STRING("ymm16"), ZYDIS_MAKE_STATIC_STRING("ymm17"),
ZYDIS_MAKE_STATIC_STRING("ymm18"), ZYDIS_MAKE_STATIC_STRING("ymm19"),
ZYDIS_MAKE_STATIC_STRING("ymm20"), ZYDIS_MAKE_STATIC_STRING("ymm21"),
ZYDIS_MAKE_STATIC_STRING("ymm22"), ZYDIS_MAKE_STATIC_STRING("ymm23"),
ZYDIS_MAKE_STATIC_STRING("ymm24"), ZYDIS_MAKE_STATIC_STRING("ymm25"),
ZYDIS_MAKE_STATIC_STRING("ymm26"), ZYDIS_MAKE_STATIC_STRING("ymm27"),
ZYDIS_MAKE_STATIC_STRING("ymm28"), ZYDIS_MAKE_STATIC_STRING("ymm29"),
ZYDIS_MAKE_STATIC_STRING("ymm30"), ZYDIS_MAKE_STATIC_STRING("ymm31"),
// Floating point vector registers 512-bit
ZYDIS_MAKE_STATIC_STRING("zmm0"), ZYDIS_MAKE_STATIC_STRING("zmm1"),
ZYDIS_MAKE_STATIC_STRING("zmm2"), ZYDIS_MAKE_STATIC_STRING("zmm3"),
ZYDIS_MAKE_STATIC_STRING("zmm4"), ZYDIS_MAKE_STATIC_STRING("zmm5"),
ZYDIS_MAKE_STATIC_STRING("zmm6"), ZYDIS_MAKE_STATIC_STRING("zmm7"),
ZYDIS_MAKE_STATIC_STRING("zmm8"), ZYDIS_MAKE_STATIC_STRING("zmm9"),
ZYDIS_MAKE_STATIC_STRING("zmm10"), ZYDIS_MAKE_STATIC_STRING("zmm11"),
ZYDIS_MAKE_STATIC_STRING("zmm12"), ZYDIS_MAKE_STATIC_STRING("zmm13"),
ZYDIS_MAKE_STATIC_STRING("zmm14"), ZYDIS_MAKE_STATIC_STRING("zmm15"),
ZYDIS_MAKE_STATIC_STRING("zmm16"), ZYDIS_MAKE_STATIC_STRING("zmm17"),
ZYDIS_MAKE_STATIC_STRING("zmm18"), ZYDIS_MAKE_STATIC_STRING("zmm19"),
ZYDIS_MAKE_STATIC_STRING("zmm20"), ZYDIS_MAKE_STATIC_STRING("zmm21"),
ZYDIS_MAKE_STATIC_STRING("zmm22"), ZYDIS_MAKE_STATIC_STRING("zmm23"),
ZYDIS_MAKE_STATIC_STRING("zmm24"), ZYDIS_MAKE_STATIC_STRING("zmm25"),
ZYDIS_MAKE_STATIC_STRING("zmm26"), ZYDIS_MAKE_STATIC_STRING("zmm27"),
ZYDIS_MAKE_STATIC_STRING("zmm28"), ZYDIS_MAKE_STATIC_STRING("zmm29"),
ZYDIS_MAKE_STATIC_STRING("zmm30"), ZYDIS_MAKE_STATIC_STRING("zmm31"),
// Flags registers
ZYDIS_MAKE_STATIC_STRING("flags"), ZYDIS_MAKE_STATIC_STRING("eflags"),
ZYDIS_MAKE_STATIC_STRING("rflags"),
// Instruction-pointer registers
ZYDIS_MAKE_STATIC_STRING("ip"), ZYDIS_MAKE_STATIC_STRING("eip"),
ZYDIS_MAKE_STATIC_STRING("rip"),
// Segment registers
"es", "cs", "ss", "ds",
"fs", "gs",
ZYDIS_MAKE_STATIC_STRING("es"), ZYDIS_MAKE_STATIC_STRING("cs"),
ZYDIS_MAKE_STATIC_STRING("ss"), ZYDIS_MAKE_STATIC_STRING("ds"),
ZYDIS_MAKE_STATIC_STRING("fs"), ZYDIS_MAKE_STATIC_STRING("gs"),
// Table registers
"gdtr", "ldtr", "idtr", "tr",
ZYDIS_MAKE_STATIC_STRING("gdtr"), ZYDIS_MAKE_STATIC_STRING("ldtr"),
ZYDIS_MAKE_STATIC_STRING("idtr"), ZYDIS_MAKE_STATIC_STRING("tr"),
// Test registers
"tr0", "tr1", "tr2", "tr3",
"tr4", "tr5", "tr6", "tr7",
ZYDIS_MAKE_STATIC_STRING("tr0"), ZYDIS_MAKE_STATIC_STRING("tr1"),
ZYDIS_MAKE_STATIC_STRING("tr2"), ZYDIS_MAKE_STATIC_STRING("tr3"),
ZYDIS_MAKE_STATIC_STRING("tr4"), ZYDIS_MAKE_STATIC_STRING("tr5"),
ZYDIS_MAKE_STATIC_STRING("tr6"), ZYDIS_MAKE_STATIC_STRING("tr7"),
// Control registers
"cr0", "cr1", "cr2", "cr3",
"cr4", "cr5", "cr6", "cr7",
"cr8", "cr9", "cr10", "cr11",
"cr12", "cr13", "cr14", "cr15",
ZYDIS_MAKE_STATIC_STRING("cr0"), ZYDIS_MAKE_STATIC_STRING("cr1"),
ZYDIS_MAKE_STATIC_STRING("cr2"), ZYDIS_MAKE_STATIC_STRING("cr3"),
ZYDIS_MAKE_STATIC_STRING("cr4"), ZYDIS_MAKE_STATIC_STRING("cr5"),
ZYDIS_MAKE_STATIC_STRING("cr6"), ZYDIS_MAKE_STATIC_STRING("cr7"),
ZYDIS_MAKE_STATIC_STRING("cr8"), ZYDIS_MAKE_STATIC_STRING("cr9"),
ZYDIS_MAKE_STATIC_STRING("cr10"), ZYDIS_MAKE_STATIC_STRING("cr11"),
ZYDIS_MAKE_STATIC_STRING("cr12"), ZYDIS_MAKE_STATIC_STRING("cr13"),
ZYDIS_MAKE_STATIC_STRING("cr14"), ZYDIS_MAKE_STATIC_STRING("cr15"),
// Debug registers
"dr0", "dr1", "dr2", "dr3",
"dr4", "dr5", "dr6", "dr7",
"dr8", "dr9", "dr10", "dr11",
"dr12", "dr13", "dr14", "dr15",
ZYDIS_MAKE_STATIC_STRING("dr0"), ZYDIS_MAKE_STATIC_STRING("dr1"),
ZYDIS_MAKE_STATIC_STRING("dr2"), ZYDIS_MAKE_STATIC_STRING("dr3"),
ZYDIS_MAKE_STATIC_STRING("dr4"), ZYDIS_MAKE_STATIC_STRING("dr5"),
ZYDIS_MAKE_STATIC_STRING("dr6"), ZYDIS_MAKE_STATIC_STRING("dr7"),
ZYDIS_MAKE_STATIC_STRING("dr8"), ZYDIS_MAKE_STATIC_STRING("dr9"),
ZYDIS_MAKE_STATIC_STRING("dr10"), ZYDIS_MAKE_STATIC_STRING("dr11"),
ZYDIS_MAKE_STATIC_STRING("dr12"), ZYDIS_MAKE_STATIC_STRING("dr13"),
ZYDIS_MAKE_STATIC_STRING("dr14"), ZYDIS_MAKE_STATIC_STRING("dr15"),
// Mask registers
"k0", "k1", "k2", "k3",
"k4", "k5", "k6", "k7",
// Bounds registers
"bnd0", "bnd1", "bnd2", "bnd3",
"bndcfg", "bndstatus"
ZYDIS_MAKE_STATIC_STRING("k0"), ZYDIS_MAKE_STATIC_STRING("k1"),
ZYDIS_MAKE_STATIC_STRING("k2"), ZYDIS_MAKE_STATIC_STRING("k3"),
ZYDIS_MAKE_STATIC_STRING("k4"), ZYDIS_MAKE_STATIC_STRING("k5"),
ZYDIS_MAKE_STATIC_STRING("k6"), ZYDIS_MAKE_STATIC_STRING("k7"),
// Bound registers
ZYDIS_MAKE_STATIC_STRING("bnd0"), ZYDIS_MAKE_STATIC_STRING("bnd1"),
ZYDIS_MAKE_STATIC_STRING("bnd2"), ZYDIS_MAKE_STATIC_STRING("bnd3"),
ZYDIS_MAKE_STATIC_STRING("bndcfg"), ZYDIS_MAKE_STATIC_STRING("bndstatus"),
// Misc registers
ZYDIS_MAKE_STATIC_STRING("mxcsr"), ZYDIS_MAKE_STATIC_STRING("pkru"),
ZYDIS_MAKE_STATIC_STRING("xcr0")
};
/* ============================================================================================== */
@ -268,11 +333,20 @@ ZydisRegisterWidth ZydisRegisterGetWidth64(ZydisRegister reg)
const char* ZydisRegisterGetString(ZydisRegister reg)
{
if (reg > (sizeof(registerStrings) / sizeof(registerStrings[0])) - 1)
if (reg >= ZYDIS_ARRAY_SIZE(registerStrings))
{
return ZYDIS_NULL;
}
return registerStrings[reg];
return registerStrings[reg].buffer;
}
const ZydisStaticString* ZydisRegisterGetStaticString(ZydisRegister reg)
{
if (reg >= ZYDIS_ARRAY_SIZE(registerStrings))
{
return ZYDIS_NULL;
}
return &registerStrings[reg];
}
/* ============================================================================================== */

View File

@ -24,7 +24,7 @@
***************************************************************************************************/
#include <SharedData.h>
#include <Zydis/Internal/SharedData.h>
/* ============================================================================================== */
/* Data tables */

View File

@ -1,416 +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 <FormatHelper.h>
#include <LibC.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;
}
}
}
#if defined(ZYDIS_X86) || defined(ZYDIS_ARM)
ZydisStatus ZydisPrintDecU32(char** buffer, ZydisUSize bufferLen, ZydisU32 value, ZydisU8 paddingLength)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen > 0);
char temp[ZYDIS_MAXCHARS_DEC_32 + 1];
char *p = &temp[ZYDIS_MAXCHARS_DEC_32];
*p = '\0';
while (value >= 100)
{
ZydisU32 const old = value;
p -= 2;
value /= 100;
ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], sizeof(ZydisU16));
}
p -= 2;
ZydisMemoryCopy(p, &decimalLookup[value * 2], sizeof(ZydisU16));
const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_32] - p;
if ((bufferLen < (ZydisUSize)(n + 1)) || (bufferLen < (ZydisUSize)(paddingLength + 1)))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisUSize offset = 0;
if (n <= paddingLength)
{
offset = paddingLength - n + 1;
ZydisMemorySet(*buffer, '0', offset);
}
ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1);
*buffer += n + offset - (ZydisU8)(value < 10);
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisPrintHexU32(char** buffer, ZydisUSize bufferLen, ZydisU32 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen);
if (prefix)
{
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, prefix, ZYDIS_LETTER_CASE_DEFAULT));
bufferLen = bufEnd - *buffer;
}
if (bufferLen < (ZydisUSize)(paddingLength + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (!value)
{
const ZydisU8 n = (paddingLength ? paddingLength : 1);
if (bufferLen < (ZydisUSize)(n + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisMemorySet(*buffer, '0', n);
(*buffer)[n] = '\0';
*buffer += n;
return ZYDIS_STATUS_SUCCESS;
}
ZydisU8 n = 0;
for (ZydisI8 i = ZYDIS_MAXCHARS_HEX_32 - 1; i >= 0; --i)
{
const ZydisU8 v = (value >> i * 4) & 0x0F;
if (!n)
{
if (!v)
{
continue;
}
if (bufferLen <= (ZydisU8)(i + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (paddingLength > i)
{
n = paddingLength - i - 1;
ZydisMemorySet(*buffer, '0', n);
}
}
if (uppercase)
{
(*buffer)[n++] = "0123456789ABCDEF"[v];
} else
{
(*buffer)[n++] = "0123456789abcdef"[v];
}
}
(*buffer)[n] = '\0';
*buffer += n;
if (suffix)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen - n, suffix, ZYDIS_LETTER_CASE_DEFAULT));
}
return ZYDIS_STATUS_SUCCESS;
}
#endif
ZydisStatus ZydisPrintDecU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen > 0);
char temp[ZYDIS_MAXCHARS_DEC_64 + 1];
char *p = &temp[ZYDIS_MAXCHARS_DEC_64];
*p = '\0';
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], 2);
const ZydisUSize n = &temp[ZYDIS_MAXCHARS_DEC_64] - p;
if ((bufferLen < (ZydisUSize)(n + 1)) || (bufferLen < (ZydisUSize)(paddingLength + 1)))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisUSize offset = 0;
if (n <= paddingLength)
{
offset = paddingLength - n + 1;
ZydisMemorySet(*buffer, '0', offset);
}
ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1);
*buffer += n + offset - (ZydisU8)(value < 10);
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisPrintHexU64(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen);
if (prefix)
{
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, prefix, ZYDIS_LETTER_CASE_DEFAULT));
bufferLen = bufEnd - *buffer;
}
if (bufferLen < (ZydisUSize)(paddingLength + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (!value)
{
const ZydisU8 n = (paddingLength ? paddingLength : 1);
if (bufferLen < (ZydisUSize)(n + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisMemorySet(*buffer, '0', n);
(*buffer)[n] = '\0';
*buffer += n;
return ZYDIS_STATUS_SUCCESS;
}
ZydisU8 n = 0;
const ZydisU8 c = ((value & 0xFFFFFFFF00000000) ? ZYDIS_MAXCHARS_HEX_64 : ZYDIS_MAXCHARS_HEX_32);
for (ZydisI8 i = c - 1; i >= 0; --i)
{
const ZydisU8 v = (value >> i * 4) & 0x0F;
if (!n)
{
if (!v)
{
continue;
}
if (bufferLen <= (ZydisU8)(i + 1))
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
if (paddingLength > i)
{
n = paddingLength - i - 1;
ZydisMemorySet(*buffer, '0', n);
}
}
if (uppercase)
{
(*buffer)[n++] = "0123456789ABCDEF"[v];
} else
{
(*buffer)[n++] = "0123456789abcdef"[v];
}
}
(*buffer)[n] = '\0';
*buffer += n;
if (suffix)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen - n, suffix, ZYDIS_LETTER_CASE_DEFAULT));
}
return ZYDIS_STATUS_SUCCESS;
}
/* ---------------------------------------------------------------------------------------------- */
/* Public Functions */
/* ---------------------------------------------------------------------------------------------- */
ZydisStatus ZydisPrintStr(char** buffer, ZydisUSize bufferLen, const char* text,
ZydisLetterCase letterCase)
{
ZYDIS_ASSERT(buffer);
ZYDIS_ASSERT(bufferLen > 0);
ZYDIS_ASSERT(text);
const ZydisUSize strLen = ZydisStrLen(text);
if (strLen >= bufferLen)
{
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
}
ZydisMemoryCopy(*buffer, text, strLen + 1);
switch (letterCase)
{
case ZYDIS_LETTER_CASE_DEFAULT:
break;
case ZYDIS_LETTER_CASE_LOWER:
ZydisToLowerCase(*buffer, strLen);
break;
case ZYDIS_LETTER_CASE_UPPER:
ZydisToUpperCase(*buffer, strLen);
break;
default:
ZYDIS_UNREACHABLE;
}
*buffer += strLen;
return ZYDIS_STATUS_SUCCESS;
}
ZydisStatus ZydisPrintDecU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength)
{
#if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64)
return ZydisPrintDecU64(buffer, bufferLen, value, paddingLength);
#else
if (value & 0xFFFFFFFF00000000)
{
return ZydisPrintDecU64(buffer, bufferLen, value, paddingLength);
} else
{
return ZydisPrintDecU32(buffer, bufferLen, (ZydisU32)value, paddingLength);
}
#endif
}
ZydisStatus ZydisPrintDecS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, ZydisU8 paddingLength)
{
if (value < 0)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
return ZydisPrintDecU(buffer, bufferLen - 1, -value, paddingLength);
}
return ZydisPrintDecU(buffer, bufferLen, value, paddingLength);
}
ZydisStatus ZydisPrintHexU(char** buffer, ZydisUSize bufferLen, ZydisU64 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
#if defined(ZYDIS_X64) || defined(ZYDIS_AARCH64)
return ZydisPrintHexU64(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix);
#else
if (value & 0xFFFFFFFF00000000)
{
return ZydisPrintHexU64(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix);
} else
{
return ZydisPrintHexU32(buffer, bufferLen, (ZydisU32)value, paddingLength, uppercase,
prefix, suffix);
}
#endif
}
ZydisStatus ZydisPrintHexS(char** buffer, ZydisUSize bufferLen, ZydisI64 value, ZydisU8 paddingLength,
ZydisBool uppercase, const char* prefix, const char* suffix)
{
if (value < 0)
{
const char* bufEnd = *buffer + bufferLen;
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
if (prefix)
{
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, prefix, ZYDIS_LETTER_CASE_DEFAULT));
}
return ZydisPrintHexU(buffer, bufEnd - *buffer, -value, paddingLength, uppercase,
ZYDIS_NULL, suffix);
}
return ZydisPrintHexU(buffer, bufferLen, value, paddingLength, uppercase, prefix, suffix);
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/***************************************************************************************************
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);
}
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */

View File

@ -69,9 +69,9 @@ int main(int argc, char** argv)
ZydisFormatter formatter;
if (!ZYDIS_SUCCESS(ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL)) ||
!ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter,
ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE)) ||
ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE)) ||
!ZYDIS_SUCCESS(ZydisFormatterSetProperty(&formatter,
ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE)))
ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE)))
{
fputs("Failed to initialized instruction-formatter\n", stderr);
return EXIT_FAILURE;

View File

@ -551,9 +551,9 @@ void printInstruction(ZydisDecodedInstruction* instruction)
ZydisFormatter formatter;
if (!ZYDIS_SUCCESS((status = ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL))) ||
!ZYDIS_SUCCESS((status = ZydisFormatterSetProperty(&formatter,
ZYDIS_FORMATTER_PROP_FORCE_SEGMENTS, ZYDIS_TRUE))) ||
ZYDIS_FORMATTER_PROP_FORCE_MEMSEG, ZYDIS_TRUE))) ||
!ZYDIS_SUCCESS((status = ZydisFormatterSetProperty(&formatter,
ZYDIS_FORMATTER_PROP_FORCE_OPERANDSIZE, ZYDIS_TRUE))))
ZYDIS_FORMATTER_PROP_FORCE_MEMSIZE, ZYDIS_TRUE))))
{
fputs("Failed to initialize instruction-formatter\n", stderr);
exit(status);