mirror of https://github.com/x64dbg/zydis
Significantly improved formatter performance
- Exchanged `vsnprintf` by custom print functions
This commit is contained in:
parent
30f15afe0a
commit
01dca38516
|
@ -127,9 +127,11 @@ if (ZYDIS_FEATURE_DECODER)
|
|||
"${CMAKE_CURRENT_LIST_DIR}/include/Zydis/Formatter.h"
|
||||
PRIVATE
|
||||
"src/DecoderData.h"
|
||||
"src/FormatHelper.h"
|
||||
"src/Decoder.c"
|
||||
"src/DecoderData.c"
|
||||
"src/Formatter.c")
|
||||
"src/Formatter.c"
|
||||
"src/FormatHelper.c")
|
||||
endif ()
|
||||
|
||||
if (ZYDIS_FEATURE_ENCODER)
|
||||
|
|
|
@ -323,7 +323,7 @@ int main(int argc, char** argv)
|
|||
printf("Testing %s ...\n", tests[i].encoding);
|
||||
testPerformance(buffer, length, ZYDIS_DECODE_GRANULARITY_MINIMAL, ZYDIS_FALSE);
|
||||
testPerformance(buffer, length, ZYDIS_DECODE_GRANULARITY_FULL , ZYDIS_FALSE);
|
||||
// testPerformance(buffer, length, ZYDIS_DECODE_GRANULARITY_FULL , ZYDIS_TRUE );
|
||||
testPerformance(buffer, length, ZYDIS_DECODE_GRANULARITY_FULL , ZYDIS_TRUE );
|
||||
|
||||
puts("");
|
||||
free(buffer);
|
||||
|
|
|
@ -0,0 +1,451 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Library (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.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <FormatHelper.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Constants */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Defines */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
#define ZYDIS_MAXCHARS_DEC_32 10
|
||||
#define ZYDIS_MAXCHARS_DEC_64 20
|
||||
#define ZYDIS_MAXCHARS_HEX_32 8
|
||||
#define ZYDIS_MAXCHARS_HEX_64 16
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Lookup Tables */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
static uint16_t const decimalLookup[100] =
|
||||
{
|
||||
0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930,
|
||||
0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931,
|
||||
0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932,
|
||||
0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933,
|
||||
0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934,
|
||||
0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935,
|
||||
0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936,
|
||||
0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937,
|
||||
0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938,
|
||||
0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Public Functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZydisStatus ZydisPrintStr(char** buffer, size_t bufferLen, const char* text,
|
||||
ZydisLetterCase letterCase)
|
||||
{
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen > 0);
|
||||
ZYDIS_ASSERT(text);
|
||||
|
||||
size_t strLen = strlen(text);
|
||||
if (strLen >= bufferLen)
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
memcpy(*buffer, text, strLen + 1);
|
||||
switch (letterCase)
|
||||
{
|
||||
case ZYDIS_LETTER_CASE_LOWER:
|
||||
for (size_t i = 0; i < strLen; ++i)
|
||||
{
|
||||
(*buffer[i]) = (char)tolower((*buffer)[i]);
|
||||
}
|
||||
break;
|
||||
case ZYDIS_LETTER_CASE_UPPER:
|
||||
for (size_t i = 0; i < strLen; ++i)
|
||||
{
|
||||
(*buffer)[i] = (char)toupper((*buffer)[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*buffer += strLen;
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintDec32U(char** buffer, size_t bufferLen, uint32_t value, uint8_t paddingLength)
|
||||
{
|
||||
#ifdef ZYDIS_X64
|
||||
return ZydisPrintDec64U(buffer, bufferLen, value, paddingLength);
|
||||
#else
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen > 0);
|
||||
ZYDIS_ASSERT(paddingLength <= sizeof(ZYDIS_PADDING_STRING) / sizeof(ZYDIS_PADDING_STRING[0]));
|
||||
|
||||
char temp[ZYDIS_MAXCHARS_DEC_32 + 1];
|
||||
char *p = &temp[ZYDIS_MAXCHARS_DEC_32];
|
||||
*p = '\0';
|
||||
while(value >= 100)
|
||||
{
|
||||
uint32_t const old = value;
|
||||
p -= 2;
|
||||
value /= 100;
|
||||
memcpy(p, &decimalLookup[old - (value * 100)], sizeof(uint16_t));
|
||||
}
|
||||
p -= 2;
|
||||
memcpy(p, &decimalLookup[value], sizeof(uint16_t));
|
||||
|
||||
size_t n = &temp[ZYDIS_MAXCHARS_DEC_32] - p;
|
||||
if ((bufferLen < n + 1) || (bufferLen < paddingLength + 1))
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
uintptr_t offset = 0;
|
||||
if (n <= paddingLength)
|
||||
{
|
||||
offset = paddingLength - n + 1;
|
||||
memset((*buffer), '0', offset);
|
||||
}
|
||||
|
||||
memcpy(&(*buffer)[offset], &p[value < 10], n + 1);
|
||||
*buffer += n + offset - 1;
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintDec64U(char** buffer, size_t bufferLen, uint64_t value, uint8_t paddingLength)
|
||||
{
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen > 0);
|
||||
ZYDIS_ASSERT(paddingLength <= sizeof(ZYDIS_PADDING_STRING) / sizeof(ZYDIS_PADDING_STRING[0]));
|
||||
|
||||
char temp[ZYDIS_MAXCHARS_DEC_64 + 1];
|
||||
char *p = &temp[ZYDIS_MAXCHARS_DEC_64];
|
||||
*p = '\0';
|
||||
while(value >= 100)
|
||||
{
|
||||
uint64_t const old = value;
|
||||
p -= 2;
|
||||
value /= 100;
|
||||
memcpy(p, &decimalLookup[old - (value * 100)], sizeof(uint16_t));
|
||||
}
|
||||
p -= 2;
|
||||
memcpy(p, &decimalLookup[value], sizeof(uint16_t));
|
||||
|
||||
size_t n = &temp[ZYDIS_MAXCHARS_DEC_64] - p;
|
||||
if ((bufferLen < n + 1) || (bufferLen < paddingLength + 1))
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
uintptr_t offset = 0;
|
||||
if (n <= paddingLength)
|
||||
{
|
||||
offset = paddingLength - n + 1;
|
||||
memset((*buffer), '0', offset);
|
||||
}
|
||||
|
||||
memcpy(&(*buffer)[offset], &p[value < 20], n + 1);
|
||||
*buffer += n + offset - 1;
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintDec8S(char** buffer, size_t bufferLen, int8_t value, uint8_t paddingLength)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
return ZydisPrintDec32U(buffer, bufferLen - 1, -value, paddingLength);
|
||||
}
|
||||
return ZydisPrintDec32U(buffer, bufferLen, value, paddingLength);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintDec16S(char** buffer, size_t bufferLen, int16_t value, uint8_t paddingLength)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
return ZydisPrintDec32U(buffer, bufferLen - 1, -value, paddingLength);
|
||||
}
|
||||
return ZydisPrintDec32U(buffer, bufferLen, value, paddingLength);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintDec32S(char** buffer, size_t bufferLen, int32_t value, uint8_t paddingLength)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
return ZydisPrintDec32U(buffer, bufferLen - 1, -value, paddingLength);
|
||||
}
|
||||
return ZydisPrintDec32U(buffer, bufferLen, value, paddingLength);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintDec64S(char** buffer, size_t bufferLen, int64_t value, uint8_t paddingLength)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
return ZydisPrintDec64U(buffer, bufferLen - 1, -value, paddingLength);
|
||||
}
|
||||
return ZydisPrintDec64U(buffer, bufferLen, value, paddingLength);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintHex32U(char** buffer, size_t bufferLen, uint32_t value, uint8_t paddingLength,
|
||||
ZydisBool uppercase, ZydisBool prefix)
|
||||
{
|
||||
#ifdef ZYDIS_X64
|
||||
return ZydisPrintHex64U(buffer, bufferLen, value, paddingLength, uppercase, prefix);
|
||||
#else
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen);
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "0x", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
bufferLen -= 2;
|
||||
}
|
||||
if (bufferLen < paddingLength + 1)
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
{
|
||||
uint8_t n = (paddingLength ? paddingLength : 1);
|
||||
|
||||
if (bufferLen < n + 1)
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
memset((*buffer), '0', n);
|
||||
(*buffer)[n] = '\0';
|
||||
*buffer += n;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
char temp[ZYDIS_MAXCHARS_HEX_32];
|
||||
uint8_t n = 0;
|
||||
for (int8_t i = ZYDIS_MAXCHARS_HEX_32 - 1; i >= 0; --i)
|
||||
{
|
||||
uint8_t v = (value >> i * 4) & 0x0F;
|
||||
if (!n)
|
||||
{
|
||||
if (!v)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (bufferLen <= (uint8_t)(i + 1))
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
if (uppercase)
|
||||
{
|
||||
temp[n++] = "0123456789ABCDEF"[v];
|
||||
} else
|
||||
{
|
||||
temp[n++] = "0123456789abcdef"[v];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t offset = 0;
|
||||
if (paddingLength > n)
|
||||
{
|
||||
offset = paddingLength - n;
|
||||
memset(*buffer, '0', offset);
|
||||
}
|
||||
memcpy(&(*buffer)[offset], temp, n);
|
||||
(*buffer)[offset + n] = '\0';
|
||||
|
||||
*buffer += n + offset;
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintHex64U(char** buffer, size_t bufferLen, uint64_t value, uint8_t paddingLength,
|
||||
ZydisBool uppercase, ZydisBool prefix)
|
||||
{
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen);
|
||||
|
||||
if (prefix)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "0x", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
bufferLen -= 2;
|
||||
}
|
||||
if (bufferLen < paddingLength + 1)
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
{
|
||||
uint8_t n = (paddingLength ? paddingLength : 1);
|
||||
|
||||
if (bufferLen < n + 1)
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
memset((*buffer), '0', n);
|
||||
(*buffer)[n] = '\0';
|
||||
*buffer += n;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
char temp[ZYDIS_MAXCHARS_HEX_64];
|
||||
uint8_t n = 0;
|
||||
for (int8_t i =
|
||||
((value & 0xFFFFFFFF00000000) ? ZYDIS_MAXCHARS_HEX_64 : ZYDIS_MAXCHARS_HEX_32) - 1;
|
||||
i >= 0; --i)
|
||||
{
|
||||
uint8_t v = (value >> i * 4) & 0x0F;
|
||||
if (!n)
|
||||
{
|
||||
if (!v)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (bufferLen <= (uint8_t)(i + 1))
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
if (uppercase)
|
||||
{
|
||||
temp[n++] = "0123456789ABCDEF"[v];
|
||||
} else
|
||||
{
|
||||
temp[n++] = "0123456789abcdef"[v];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t offset = 0;
|
||||
if (paddingLength > n)
|
||||
{
|
||||
offset = paddingLength - n;
|
||||
memset(*buffer, '0', offset);
|
||||
}
|
||||
memcpy(&(*buffer)[offset], temp, n);
|
||||
(*buffer)[offset + n] = '\0';
|
||||
|
||||
*buffer += n + offset;
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintHex8S(char** buffer, size_t bufferLen, int8_t value, uint8_t paddingLength,
|
||||
ZydisBool uppercase, ZydisBool prefix)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
if (prefix)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-0x", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
bufferLen -= 3;
|
||||
} else
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
--bufferLen;
|
||||
}
|
||||
return ZydisPrintHex32U(buffer, bufferLen, -value, paddingLength, uppercase, ZYDIS_FALSE);
|
||||
}
|
||||
return ZydisPrintHex32U(buffer, bufferLen, value, paddingLength, uppercase, prefix);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintHex16S(char** buffer, size_t bufferLen, int16_t value, uint8_t paddingLength,
|
||||
ZydisBool uppercase, ZydisBool prefix)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
if (prefix)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-0x", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
bufferLen -= 3;
|
||||
} else
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
--bufferLen;
|
||||
}
|
||||
return ZydisPrintHex32U(buffer, bufferLen, -value, paddingLength, uppercase, ZYDIS_FALSE);
|
||||
}
|
||||
return ZydisPrintHex32U(buffer, bufferLen, value, paddingLength, uppercase, prefix);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintHex32S(char** buffer, size_t bufferLen, int32_t value, uint8_t paddingLength,
|
||||
ZydisBool uppercase, ZydisBool prefix)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
if (prefix)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-0x", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
bufferLen -= 3;
|
||||
} else
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
--bufferLen;
|
||||
}
|
||||
return ZydisPrintHex32U(buffer, bufferLen, -value, paddingLength, uppercase, ZYDIS_FALSE);
|
||||
}
|
||||
return ZydisPrintHex32U(buffer, bufferLen, value, paddingLength, uppercase, prefix);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisPrintHex64S(char** buffer, size_t bufferLen, int64_t value, uint8_t paddingLength,
|
||||
ZydisBool uppercase, ZydisBool prefix)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
if (prefix)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-0x", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
bufferLen -= 3;
|
||||
} else
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "-", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
--bufferLen;
|
||||
}
|
||||
return ZydisPrintHex64U(buffer, bufferLen, -value, paddingLength, uppercase, ZYDIS_FALSE);
|
||||
}
|
||||
return ZydisPrintHex64U(buffer, bufferLen, value, paddingLength, uppercase, prefix);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
|
@ -0,0 +1,371 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Library (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 <Zydis/Defines.h>
|
||||
#include <Zydis/Status.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Letter Case */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the `ZydisLetterCase` datatype.
|
||||
*/
|
||||
typedef uint8_t 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, size_t bufferLen, const char* text,
|
||||
ZydisLetterCase letterCase);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Decimal values */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Formats the given unsigned 64-bit 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 ZydisPrintDec64U(char** buffer, size_t bufferLen, uint64_t value,
|
||||
uint8_t paddingLength);
|
||||
|
||||
/**
|
||||
* @brief Formats the given unsigned 32-bit 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 ZydisPrintDec32U(char** buffer, size_t bufferLen, uint32_t value,
|
||||
uint8_t paddingLength);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 64-bit 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 ZydisPrintDec64S(char** buffer, size_t bufferLen, int64_t value,
|
||||
uint8_t paddingLength);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 32-bit 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 ZydisPrintDec32S(char** buffer, size_t bufferLen, int32_t value,
|
||||
uint8_t paddingLength);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 16-bit 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 ZydisPrintDec16S(char** buffer, size_t bufferLen, int16_t value,
|
||||
uint8_t paddingLength);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 8-bit 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 ZydisPrintDec8S(char** buffer, size_t bufferLen, int8_t value,
|
||||
uint8_t paddingLength);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Hexadecimal values */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Formats the given unsigned 64-bit 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 Set @c TRUE to add the "0x" prefix to the hexadecimal value.
|
||||
*
|
||||
* @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 ZydisPrintHex64U(char** buffer, size_t bufferLen, uint64_t value,
|
||||
uint8_t paddingLength, ZydisBool uppercase, ZydisBool prefix);
|
||||
|
||||
/**
|
||||
* @brief Formats the given unsigned 32-bit 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 Set @c TRUE to add the "0x" prefix to the hexadecimal value.
|
||||
*
|
||||
* @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 ZydisPrintHex32U(char** buffer, size_t bufferLen, uint32_t value,
|
||||
uint8_t paddingLength, ZydisBool uppercase, ZydisBool prefix);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 64-bit 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 Set @c TRUE to add the "0x" prefix to the hexadecimal value.
|
||||
*
|
||||
* @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 ZydisPrintHex64S(char** buffer, size_t bufferLen, int64_t value,
|
||||
uint8_t paddingLength, ZydisBool uppercase, ZydisBool prefix);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 32-bit 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 Set @c TRUE to add the "0x" prefix to the hexadecimal value.
|
||||
*
|
||||
* @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 ZydisPrintHex32S(char** buffer, size_t bufferLen, int32_t value,
|
||||
uint8_t paddingLength, ZydisBool uppercase, ZydisBool prefix);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 16-bit 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 Set @c TRUE to add the "0x" prefix to the hexadecimal value.
|
||||
*
|
||||
* @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 ZydisPrintHex16S(char** buffer, size_t bufferLen, int16_t value,
|
||||
uint8_t paddingLength, ZydisBool uppercase, ZydisBool prefix);
|
||||
|
||||
/**
|
||||
* @brief Formats the given signed 8-bit 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 Set @c TRUE to add the "0x" prefix to the hexadecimal value.
|
||||
*
|
||||
* @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 ZydisPrintHex8S(char** buffer, size_t bufferLen, int8_t value,
|
||||
uint8_t paddingLength, ZydisBool uppercase, ZydisBool prefix);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_FORMATHELPER_H */
|
439
src/Formatter.c
439
src/Formatter.c
|
@ -24,169 +24,11 @@
|
|||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <Zydis/CommonTypes.h>
|
||||
#include <Zydis/Formatter.h>
|
||||
#include <Zydis/Utils.h>
|
||||
#include <Zydis/CommonTypes.h>
|
||||
|
||||
#if defined(ZYDIS_WINKERNEL)
|
||||
# include <ntddk.h>
|
||||
# include <Ntstrsafe.h>
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* String formatting */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* 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
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Internal functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
#if defined(ZYDIS_WINKERNEL)
|
||||
static int ZydisVSNPrintF(char* s, size_t n, const char* format, va_list arg)
|
||||
{
|
||||
size_t bytesRemaining;
|
||||
NTSTATUS ret = RtlStringCchVPrintfExA(
|
||||
s, n, NULL, &bytesRemaining, 0, format, arg
|
||||
);
|
||||
|
||||
if (!NT_SUCCESS(ret)) return -1;
|
||||
return (int)(n - bytesRemaining);
|
||||
}
|
||||
#else
|
||||
static int ZydisVSNPrintF(char* s, size_t n, const char* format, va_list arg)
|
||||
{
|
||||
return vsnprintf(s, n, format, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
static 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.
|
||||
*/
|
||||
static 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 = ZydisVSNPrintF(*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;
|
||||
}
|
||||
#include <FormatHelper.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Instruction formatter */
|
||||
|
@ -196,9 +38,9 @@ static ZydisStatus ZydisStringBufferAppendFormat(char** buffer, size_t bufferLen
|
|||
/* Internal macros */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
#define ZYDIS_APPENDMODE \
|
||||
#define ZYDIS_LETTER_CASE \
|
||||
(formatter->flags & ZYDIS_FMTFLAG_UPPERCASE) ? \
|
||||
ZYDIS_STRBUF_APPEND_MODE_UPPERCASE : ZYDIS_STRBUF_APPEND_MODE_DEFAULT
|
||||
ZYDIS_LETTER_CASE_UPPER : ZYDIS_LETTER_CASE_DEFAULT
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Intel style */
|
||||
|
@ -214,34 +56,34 @@ static ZydisStatus ZydisFormatterPrintPrefixesIntel(const ZydisFormatter* format
|
|||
|
||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_LOCK)
|
||||
{
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "lock ");
|
||||
return ZydisPrintStr(buffer, bufferLen, "lock ", ZYDIS_LETTER_CASE);
|
||||
}
|
||||
|
||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_REP)
|
||||
{
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "rep ");
|
||||
return ZydisPrintStr(buffer, bufferLen, "rep ", ZYDIS_LETTER_CASE);
|
||||
}
|
||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPE)
|
||||
{
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "repe ");
|
||||
return ZydisPrintStr(buffer, bufferLen, "repe ", ZYDIS_LETTER_CASE);
|
||||
}
|
||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_REPNE)
|
||||
{
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "repne ");
|
||||
return ZydisPrintStr(buffer, bufferLen, "repne ", ZYDIS_LETTER_CASE);
|
||||
}
|
||||
|
||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_BOUND)
|
||||
{
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "bnd ");
|
||||
return ZydisPrintStr(buffer, bufferLen, "bnd ", ZYDIS_LETTER_CASE);
|
||||
}
|
||||
|
||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_XACQUIRE)
|
||||
{
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "xacquire ");
|
||||
return ZydisPrintStr(buffer, bufferLen, "xacquire ", ZYDIS_LETTER_CASE);
|
||||
}
|
||||
if (instruction->attributes & ZYDIS_ATTRIB_HAS_XRELEASE)
|
||||
{
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, "xrelease ");
|
||||
return ZydisPrintStr(buffer, bufferLen, "xrelease ", ZYDIS_LETTER_CASE);
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
|
@ -260,7 +102,7 @@ static ZydisStatus ZydisFormatterPrintMnemonicIntel(const ZydisFormatter* format
|
|||
{
|
||||
mnemonic = "invalid";
|
||||
}
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, mnemonic);
|
||||
return ZydisPrintStr(buffer, bufferLen, mnemonic, ZYDIS_LETTER_CASE);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
@ -284,7 +126,7 @@ static ZydisStatus ZydisFormatterFormatOperandRegIntel(const ZydisFormatter* for
|
|||
{
|
||||
reg = "invalid";
|
||||
}
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, reg);
|
||||
return ZydisPrintStr(buffer, bufferLen, reg, ZYDIS_LETTER_CASE);
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* formatter,
|
||||
|
@ -298,8 +140,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
|
|||
|
||||
char* bufEnd = *buffer + bufferLen;
|
||||
|
||||
ZYDIS_CHECK(
|
||||
ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "["));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, "[", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
|
||||
if (operand->mem.disp.hasDisplacement && (
|
||||
(operand->mem.base == ZYDIS_REGISTER_NONE) ||
|
||||
|
@ -330,7 +171,7 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
|
|||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, reg));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, ZYDIS_LETTER_CASE));
|
||||
}
|
||||
if (operand->mem.index != ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
|
@ -339,20 +180,29 @@ static ZydisStatus ZydisFormatterFormatOperandMemIntel(const ZydisFormatter* for
|
|||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
const char* c = (operand->mem.base != ZYDIS_REGISTER_NONE) ? "+" : "";
|
||||
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
|
||||
"%s%s", c, reg));
|
||||
if (operand->mem.base != ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, "+", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
}
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, ZYDIS_LETTER_CASE));
|
||||
//const char* c = (operand->mem.base != ZYDIS_REGISTER_NONE) ? "+" : "";
|
||||
//ZYDIS_CHECK(ZydisPrintStrFormat(buffer, bufEnd - *buffer, ZYDIS_APPENDMODE,
|
||||
// "%s%s", c, reg));
|
||||
if (operand->mem.scale)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppendFormat(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "*%d", operand->mem.scale));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, "*", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
ZYDIS_CHECK(ZydisPrintDec32U(buffer, bufEnd - *buffer, operand->mem.scale, 0));
|
||||
//ZYDIS_CHECK(ZydisPrintStrFormat(buffer, bufEnd - *buffer,
|
||||
// ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "*%d", operand->mem.scale));
|
||||
}
|
||||
}
|
||||
ZYDIS_CHECK(formatter->funcPrintDisplacement(formatter, buffer, bufEnd - *buffer,
|
||||
instruction, operand));
|
||||
}
|
||||
|
||||
return ZydisStringBufferAppend(buffer, bufEnd - *buffer, ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "]");
|
||||
return ZydisPrintStr(buffer, bufEnd - *buffer, "]", ZYDIS_LETTER_CASE_DEFAULT);
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* formatter,
|
||||
|
@ -364,8 +214,14 @@ static ZydisStatus ZydisFormatterFormatOperandPtrIntel(const ZydisFormatter* for
|
|||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
"0x%04"PRIX16":0x%08"PRIX32, operand->ptr.segment, operand->ptr.offset);
|
||||
char* bufEnd = *buffer + bufferLen;
|
||||
ZYDIS_CHECK(ZydisPrintHex32U(
|
||||
buffer, bufEnd - *buffer, operand->ptr.segment, 4, ZYDIS_TRUE, ZYDIS_TRUE));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
return ZydisPrintHex32U(
|
||||
buffer, bufEnd - *buffer, operand->ptr.offset, 8, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
//return ZydisPrintStrFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
// "0x%04"PRIX16":0x%08"PRIX32, operand->ptr.segment, operand->ptr.offset);
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* formatter,
|
||||
|
@ -399,13 +255,16 @@ static ZydisStatus ZydisFormatterFormatOperandImmIntel(const ZydisFormatter* for
|
|||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (printSignedHEX && (operand->imm.value.s < 0))
|
||||
|
||||
return ZydisPrintHex32S(
|
||||
buffer, bufferLen, (int32_t)operand->imm.value.s, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
/*if (printSignedHEX && (operand->imm.value.s < 0))
|
||||
{
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
return ZydisPrintStrFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX32, -(int32_t)operand->imm.value.s);
|
||||
}
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
"0x%02"PRIX32, (int32_t)operand->imm.value.s);
|
||||
return ZydisPrintStrFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
"0x%02"PRIX32, (int32_t)operand->imm.value.s);*/
|
||||
}
|
||||
|
||||
// The immediate operand contains an actual ordinal value
|
||||
|
@ -428,11 +287,13 @@ static ZydisStatus ZydisFormatterPrintAddressIntel(const ZydisFormatter* formatt
|
|||
{
|
||||
case 16:
|
||||
case 32:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
"0x%08"PRIX64, address);
|
||||
return ZydisPrintHex64U(buffer, bufferLen, address, 8, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
//return ZydisPrintStrFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
// "0x%08"PRIX64, address);
|
||||
case 64:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
"0x%016"PRIX64, address);
|
||||
return ZydisPrintHex64U(buffer, bufferLen, address, 16, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
//return ZydisPrintStrFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
// "0x%016"PRIX64, address);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -457,14 +318,17 @@ static ZydisStatus ZydisFormatterPrintDisplacementIntel(const ZydisFormatter* fo
|
|||
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
|
||||
(operand->mem.index != ZYDIS_REGISTER_NONE)))
|
||||
{
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX32, -operand->mem.disp.value);
|
||||
return ZydisPrintHex64S(
|
||||
buffer, bufferLen, operand->mem.disp.value, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
}
|
||||
const char* sign =
|
||||
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
|
||||
(operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+";
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||
"%s0x%02"PRIX32, sign, operand->mem.disp.value);
|
||||
char* bufEnd = *buffer + bufferLen;
|
||||
if ((operand->mem.base != ZYDIS_REGISTER_NONE) ||
|
||||
(operand->mem.index != ZYDIS_REGISTER_NONE))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufferLen, "+", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
}
|
||||
return ZydisPrintHex64U(
|
||||
buffer, bufEnd - *buffer, operand->mem.disp.value, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
}
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -483,22 +347,23 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
|
|||
{
|
||||
printSignedHEX = operand->imm.isSigned;
|
||||
}
|
||||
|
||||
if (printSignedHEX && (operand->imm.value.s < 0))
|
||||
{
|
||||
switch (operand->size)
|
||||
{
|
||||
case 8:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX8, -(int8_t)operand->imm.value.s);
|
||||
return ZydisPrintHex8S(
|
||||
buffer, bufferLen, (int8_t)operand->imm.value.s, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
case 16:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX16, -(int16_t)operand->imm.value.s);
|
||||
return ZydisPrintHex16S(
|
||||
buffer, bufferLen, (int16_t)operand->imm.value.s, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
case 32:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX32, -(int32_t)operand->imm.value.s);
|
||||
return ZydisPrintHex32S(
|
||||
buffer, bufferLen, (int32_t)operand->imm.value.s, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
case 64:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "-0x%02"PRIX64, -operand->imm.value.s);
|
||||
return ZydisPrintHex64S(
|
||||
buffer, bufferLen, (int64_t)operand->imm.value.s, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -506,14 +371,14 @@ static ZydisStatus ZydisFormatterPrintImmediateIntel(const ZydisFormatter* forma
|
|||
switch (instruction->operandSize)
|
||||
{
|
||||
case 16:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "0x%02"PRIX16, (uint16_t)operand->imm.value.u);
|
||||
return ZydisPrintHex32U(
|
||||
buffer, bufferLen, (uint16_t)operand->imm.value.u, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
case 32:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "0x%02"PRIX32, (uint32_t)operand->imm.value.u);
|
||||
return ZydisPrintHex32U(
|
||||
buffer, bufferLen, (int32_t)operand->imm.value.u, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
case 64:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "0x%02"PRIX64, operand->imm.value.u);
|
||||
return ZydisPrintHex64U(
|
||||
buffer, bufferLen, (int64_t)operand->imm.value.u, 2, ZYDIS_TRUE, ZYDIS_TRUE);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -614,7 +479,7 @@ static ZydisStatus ZydisFormatterPrintOperandSizeIntel(const ZydisFormatter* for
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return ZydisStringBufferAppend(buffer, bufferLen, ZYDIS_APPENDMODE, str);
|
||||
return ZydisPrintStr(buffer, bufferLen, str, ZYDIS_LETTER_CASE);
|
||||
}
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -628,28 +493,41 @@ static ZydisStatus ZydisFormatterPrintSegmentIntel(const ZydisFormatter* formatt
|
|||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
char* bufEnd = *buffer + bufferLen;
|
||||
switch (operand->mem.segment)
|
||||
{
|
||||
case ZYDIS_REGISTER_ES:
|
||||
case ZYDIS_REGISTER_CS:
|
||||
case ZYDIS_REGISTER_FS:
|
||||
case ZYDIS_REGISTER_GS:
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
|
||||
ZydisRegisterGetString(operand->mem.segment));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer,
|
||||
ZydisRegisterGetString(operand->mem.segment), ZYDIS_LETTER_CASE));
|
||||
return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
|
||||
//return ZydisPrintStrFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
|
||||
// ZydisRegisterGetString(operand->mem.segment));
|
||||
case ZYDIS_REGISTER_SS:
|
||||
if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) ||
|
||||
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_SS))
|
||||
{
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
|
||||
ZydisRegisterGetString(operand->mem.segment));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer,
|
||||
ZydisRegisterGetString(operand->mem.segment), ZYDIS_LETTER_CASE));
|
||||
return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
|
||||
//return ZydisPrintStrFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
|
||||
// ZydisRegisterGetString(operand->mem.segment));
|
||||
}
|
||||
break;
|
||||
case ZYDIS_REGISTER_DS:
|
||||
if ((formatter->flags & ZYDIS_FMTFLAG_FORCE_SEGMENTS) ||
|
||||
(instruction->attributes & ZYDIS_ATTRIB_HAS_SEGMENT_DS))
|
||||
{
|
||||
return ZydisStringBufferAppendFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
|
||||
ZydisRegisterGetString(operand->mem.segment));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer,
|
||||
ZydisRegisterGetString(operand->mem.segment), ZYDIS_LETTER_CASE));
|
||||
return ZydisPrintStr(buffer, bufEnd - *buffer, ":", ZYDIS_LETTER_CASE_DEFAULT);
|
||||
//return ZydisPrintStrFormat(buffer, bufferLen, ZYDIS_APPENDMODE, "%s:",
|
||||
// ZydisRegisterGetString(operand->mem.segment));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -679,12 +557,13 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
ZYDIS_CHECK(ZydisStringBufferAppendFormat(
|
||||
buffer, bufEnd - *buffer, ZYDIS_APPENDMODE, " {%s}", reg));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " {", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, reg, ZYDIS_LETTER_CASE));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, "}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
if (instruction->avx.mask.mode == ZYDIS_MASK_MODE_ZERO)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {z}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {z}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -697,28 +576,28 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
case ZYDIS_BROADCAST_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_2:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to2}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to2}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_4:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to4}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to4}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to8}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to8}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_1_TO_16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {1to16}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {1to16}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_4_TO_8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to8}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {4to8}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_BROADCAST_MODE_4_TO_16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {4to16}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {4to16}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
@ -733,20 +612,20 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RN:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn-sae}"));
|
||||
ZYDIS_CHECK(ZydisPrintStr(
|
||||
buffer, bufEnd - *buffer, " {rn-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd-sae}"));
|
||||
ZYDIS_CHECK(ZydisPrintStr(
|
||||
buffer, bufEnd - *buffer, " {rd-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RU:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru-sae}"));
|
||||
ZYDIS_CHECK(ZydisPrintStr(
|
||||
buffer, bufEnd - *buffer, " {ru-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RZ:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz-sae}"));
|
||||
ZYDIS_CHECK(ZydisPrintStr(
|
||||
buffer, bufEnd - *buffer, " {rz-sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
@ -758,20 +637,20 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
case ZYDIS_ROUNDING_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RN:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rn}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {rn}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rd}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {rd}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RU:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {ru}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {ru}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_ROUNDING_MODE_RZ:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {rz}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {rz}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
@ -781,8 +660,8 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
case ZYDIS_DECORATOR_TYPE_SAE:
|
||||
if (instruction->avx.hasSAE && !instruction->avx.rounding.mode)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sae}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {sae}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
}
|
||||
break;
|
||||
case ZYDIS_DECORATOR_TYPE_SWIZZLE:
|
||||
|
@ -793,32 +672,32 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
// Nothing to do here
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_CDAB:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cdab}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {cdab}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_BADC:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {badc}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {badc}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_DACB:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dacb}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {dacb}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_AAAA:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {aaaa}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {aaaa}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_BBBB:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {bbbb}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {bbbb}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_CCCC:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {cccc}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {cccc}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_SWIZZLE_MODE_DDDD:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {dddd}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {dddd}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
@ -830,24 +709,24 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
case ZYDIS_CONVERSION_MODE_INVALID:
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_FLOAT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {float16}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {float16}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_SINT8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint8}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {sint8}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_UINT8:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint8}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {uint8}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_SINT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {sint16}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {sint16}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
case ZYDIS_CONVERSION_MODE_UINT16:
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {uint16}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {uint16}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
|
@ -856,8 +735,8 @@ static ZydisStatus ZydisFormatterPrintDecoratorIntel(const ZydisFormatter* forma
|
|||
case ZYDIS_DECORATOR_TYPE_EVICTION_HINT:
|
||||
if (instruction->avx.hasEvictionHint)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer,
|
||||
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, " {eh}"));
|
||||
ZYDIS_CHECK(
|
||||
ZydisPrintStr(buffer, bufEnd - *buffer, " {eh}", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -889,11 +768,11 @@ static ZydisStatus ZydisFormatterFormatInstrIntel(const ZydisFormatter* formatte
|
|||
|
||||
if (i == 0)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, 0, " "));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, " ", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
} else
|
||||
{
|
||||
bufRestore = *buffer;
|
||||
ZYDIS_CHECK(ZydisStringBufferAppend(buffer, bufEnd - *buffer, 0, ", "));
|
||||
ZYDIS_CHECK(ZydisPrintStr(buffer, bufEnd - *buffer, ", ", ZYDIS_LETTER_CASE_DEFAULT));
|
||||
}
|
||||
|
||||
const char* bufPreOperand = *buffer;
|
||||
|
|
Loading…
Reference in New Issue