mirror of https://github.com/x64dbg/zydis
Improved no-libc support
- Added `ZYDIS_NO_LIBC` CMake switch - When enabled, removes dependency on `memset`, `memcpy` and `strlen`
This commit is contained in:
parent
eefeb6c18d
commit
df949a5eb0
|
@ -15,26 +15,20 @@ option(ZYDIS_FEATURE_DECODER
|
||||||
option(ZYDIS_FEATURE_FORMATTER
|
option(ZYDIS_FEATURE_FORMATTER
|
||||||
"Enable instruction formatting functionality"
|
"Enable instruction formatting functionality"
|
||||||
ON)
|
ON)
|
||||||
#option(ZYDIS_FEATURE_ENCODER
|
|
||||||
# "Enable instruction encoding functionality"
|
|
||||||
# OFF)
|
|
||||||
option(ZYDIS_FEATURE_EVEX
|
option(ZYDIS_FEATURE_EVEX
|
||||||
"Enable support for EVEX instructions"
|
"Enable support for EVEX instructions"
|
||||||
ON)
|
ON)
|
||||||
option(ZYDIS_FEATURE_MVEX
|
option(ZYDIS_FEATURE_MVEX
|
||||||
"Enable support for MVEX instructions"
|
"Enable support for MVEX instructions"
|
||||||
ON)
|
ON)
|
||||||
option(ZYDIS_FEATURE_FLAGS
|
|
||||||
"Include information about affected flags"
|
|
||||||
ON)
|
|
||||||
option(ZYDIS_FEATURE_CPUID
|
|
||||||
"Include information about CPUID feature-flags"
|
|
||||||
OFF)
|
|
||||||
|
|
||||||
# Build configuration
|
# Build configuration
|
||||||
option(BUILD_SHARED_LIBS
|
option(BUILD_SHARED_LIBS
|
||||||
"Build shared libraries"
|
"Build shared libraries"
|
||||||
OFF)
|
OFF)
|
||||||
|
option(ZYDIS_NO_LIBC
|
||||||
|
"Don't use any C standard library functions (for exotic build-envs like kernel drivers)"
|
||||||
|
OFF)
|
||||||
option(ZYDIS_BUILD_EXAMPLES
|
option(ZYDIS_BUILD_EXAMPLES
|
||||||
"Build examples"
|
"Build examples"
|
||||||
ON)
|
ON)
|
||||||
|
@ -95,6 +89,9 @@ endif ()
|
||||||
if (NOT ZYDIS_FEATURE_MVEX)
|
if (NOT ZYDIS_FEATURE_MVEX)
|
||||||
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_MVEX")
|
target_compile_definitions("Zydis" PUBLIC "ZYDIS_DISABLE_MVEX")
|
||||||
endif ()
|
endif ()
|
||||||
|
if (ZYDIS_NO_LIBC)
|
||||||
|
target_compile_definitions("Zydis" PUBLIC "ZYDIS_NO_LIBC")
|
||||||
|
endif ()
|
||||||
|
|
||||||
target_sources("Zydis"
|
target_sources("Zydis"
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <Zydis/Status.h>
|
#include <Zydis/Status.h>
|
||||||
#include <DecoderData.h>
|
#include <DecoderData.h>
|
||||||
#include <SharedData.h>
|
#include <SharedData.h>
|
||||||
|
#include <LibC.h>
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Internal enums and types */
|
/* Internal enums and types */
|
||||||
|
@ -327,10 +328,10 @@ static ZydisStatus ZydisInputNextBytes(ZydisDecoderContext* context,
|
||||||
|
|
||||||
if (context->bufferLen >= numberOfBytes)
|
if (context->bufferLen >= numberOfBytes)
|
||||||
{
|
{
|
||||||
memcpy(&instruction->data[instruction->length], context->buffer, numberOfBytes);
|
ZydisMemoryCopy(&instruction->data[instruction->length], context->buffer, numberOfBytes);
|
||||||
instruction->length += numberOfBytes;
|
instruction->length += numberOfBytes;
|
||||||
|
|
||||||
memcpy(value, context->buffer, numberOfBytes);
|
ZydisMemoryCopy(value, context->buffer, numberOfBytes);
|
||||||
context->buffer += numberOfBytes;
|
context->buffer += numberOfBytes;
|
||||||
context->bufferLen -= numberOfBytes;
|
context->bufferLen -= numberOfBytes;
|
||||||
|
|
||||||
|
@ -2243,7 +2244,7 @@ static void ZydisSetAccessedFlags(ZydisDecodedInstruction* instruction,
|
||||||
|
|
||||||
ZYDIS_ASSERT(ZYDIS_ARRAY_SIZE(instruction->accessedFlags) == ZYDIS_ARRAY_SIZE(flags->action));
|
ZYDIS_ASSERT(ZYDIS_ARRAY_SIZE(instruction->accessedFlags) == ZYDIS_ARRAY_SIZE(flags->action));
|
||||||
|
|
||||||
memcpy(&instruction->accessedFlags, &flags->action, ZYDIS_ARRAY_SIZE(flags->action));
|
ZydisMemoryCopy(&instruction->accessedFlags, &flags->action, ZYDIS_ARRAY_SIZE(flags->action));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4447,7 +4448,7 @@ ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode
|
||||||
|
|
||||||
decoder->machineMode = machineMode;
|
decoder->machineMode = machineMode;
|
||||||
decoder->addressWidth = addressWidth;
|
decoder->addressWidth = addressWidth;
|
||||||
memcpy(&decoder->decoderMode, &decoderModes, sizeof(decoderModes));
|
ZydisMemoryCopy(&decoder->decoderMode, &decoderModes, sizeof(decoderModes));
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -4478,14 +4479,14 @@ ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder, const void* bu
|
||||||
}
|
}
|
||||||
|
|
||||||
ZydisDecoderContext context;
|
ZydisDecoderContext context;
|
||||||
memset(&context.cache, 0, sizeof(context.cache));
|
ZydisMemorySet(&context.cache, 0, sizeof(context.cache));
|
||||||
context.decoder = decoder;
|
context.decoder = decoder;
|
||||||
context.buffer = (uint8_t*)buffer;
|
context.buffer = (uint8_t*)buffer;
|
||||||
context.bufferLen = bufferLen;
|
context.bufferLen = bufferLen;
|
||||||
context.lastSegmentPrefix = 0;
|
context.lastSegmentPrefix = 0;
|
||||||
context.mandatoryCandidate = 0;
|
context.mandatoryCandidate = 0;
|
||||||
|
|
||||||
memset(instruction, 0, sizeof(*instruction));
|
ZydisMemorySet(instruction, 0, sizeof(*instruction));
|
||||||
instruction->machineMode = decoder->machineMode;
|
instruction->machineMode = decoder->machineMode;
|
||||||
instruction->stackWidth = decoder->addressWidth;
|
instruction->stackWidth = decoder->addressWidth;
|
||||||
instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT;
|
instruction->encoding = ZYDIS_INSTRUCTION_ENCODING_DEFAULT;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <FormatHelper.h>
|
#include <FormatHelper.h>
|
||||||
|
#include <LibC.h>
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Constants */
|
/* Constants */
|
||||||
|
@ -113,10 +114,10 @@ ZydisStatus ZydisPrintDecU32(char** buffer, size_t bufferLen, uint32_t value, ui
|
||||||
uint32_t const old = value;
|
uint32_t const old = value;
|
||||||
p -= 2;
|
p -= 2;
|
||||||
value /= 100;
|
value /= 100;
|
||||||
memcpy(p, &decimalLookup[(old - (value * 100)) * 2], sizeof(uint16_t));
|
ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
p -= 2;
|
p -= 2;
|
||||||
memcpy(p, &decimalLookup[value * 2], sizeof(uint16_t));
|
ZydisMemoryCopy(p, &decimalLookup[value * 2], sizeof(uint16_t));
|
||||||
|
|
||||||
const size_t n = &temp[ZYDIS_MAXCHARS_DEC_32] - p;
|
const size_t n = &temp[ZYDIS_MAXCHARS_DEC_32] - p;
|
||||||
if ((bufferLen < (size_t)(n + 1)) || (bufferLen < (size_t)(paddingLength + 1)))
|
if ((bufferLen < (size_t)(n + 1)) || (bufferLen < (size_t)(paddingLength + 1)))
|
||||||
|
@ -128,10 +129,10 @@ ZydisStatus ZydisPrintDecU32(char** buffer, size_t bufferLen, uint32_t value, ui
|
||||||
if (n <= paddingLength)
|
if (n <= paddingLength)
|
||||||
{
|
{
|
||||||
offset = paddingLength - n + 1;
|
offset = paddingLength - n + 1;
|
||||||
memset(*buffer, '0', offset);
|
ZydisMemorySet(*buffer, '0', offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&(*buffer)[offset], &p[value < 10], n + 1);
|
ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1);
|
||||||
*buffer += n + offset - (uint8_t)(value < 10);
|
*buffer += n + offset - (uint8_t)(value < 10);
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
@ -163,7 +164,7 @@ ZydisStatus ZydisPrintHexU32(char** buffer, size_t bufferLen, uint32_t value, ui
|
||||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(*buffer, '0', n);
|
ZydisMemorySet(*buffer, '0', n);
|
||||||
(*buffer)[n] = '\0';
|
(*buffer)[n] = '\0';
|
||||||
*buffer += n;
|
*buffer += n;
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
@ -186,7 +187,7 @@ ZydisStatus ZydisPrintHexU32(char** buffer, size_t bufferLen, uint32_t value, ui
|
||||||
if (paddingLength > i)
|
if (paddingLength > i)
|
||||||
{
|
{
|
||||||
n = paddingLength - i - 1;
|
n = paddingLength - i - 1;
|
||||||
memset(*buffer, '0', n);
|
ZydisMemorySet(*buffer, '0', n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (uppercase)
|
if (uppercase)
|
||||||
|
@ -222,10 +223,10 @@ ZydisStatus ZydisPrintDecU64(char** buffer, size_t bufferLen, uint64_t value, ui
|
||||||
uint64_t const old = value;
|
uint64_t const old = value;
|
||||||
p -= 2;
|
p -= 2;
|
||||||
value /= 100;
|
value /= 100;
|
||||||
memcpy(p, &decimalLookup[(old - (value * 100)) * 2], 2);
|
ZydisMemoryCopy(p, &decimalLookup[(old - (value * 100)) * 2], 2);
|
||||||
}
|
}
|
||||||
p -= 2;
|
p -= 2;
|
||||||
memcpy(p, &decimalLookup[value * 2], 2);
|
ZydisMemoryCopy(p, &decimalLookup[value * 2], 2);
|
||||||
|
|
||||||
const size_t n = &temp[ZYDIS_MAXCHARS_DEC_64] - p;
|
const size_t n = &temp[ZYDIS_MAXCHARS_DEC_64] - p;
|
||||||
if ((bufferLen < (size_t)(n + 1)) || (bufferLen < (size_t)(paddingLength + 1)))
|
if ((bufferLen < (size_t)(n + 1)) || (bufferLen < (size_t)(paddingLength + 1)))
|
||||||
|
@ -237,10 +238,10 @@ ZydisStatus ZydisPrintDecU64(char** buffer, size_t bufferLen, uint64_t value, ui
|
||||||
if (n <= paddingLength)
|
if (n <= paddingLength)
|
||||||
{
|
{
|
||||||
offset = paddingLength - n + 1;
|
offset = paddingLength - n + 1;
|
||||||
memset(*buffer, '0', offset);
|
ZydisMemorySet(*buffer, '0', offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&(*buffer)[offset], &p[value < 10], n + 1);
|
ZydisMemoryCopy(&(*buffer)[offset], &p[value < 10], n + 1);
|
||||||
*buffer += n + offset - (uint8_t)(value < 10);
|
*buffer += n + offset - (uint8_t)(value < 10);
|
||||||
|
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
@ -272,7 +273,7 @@ ZydisStatus ZydisPrintHexU64(char** buffer, size_t bufferLen, uint64_t value, ui
|
||||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(*buffer, '0', n);
|
ZydisMemorySet(*buffer, '0', n);
|
||||||
(*buffer)[n] = '\0';
|
(*buffer)[n] = '\0';
|
||||||
*buffer += n;
|
*buffer += n;
|
||||||
return ZYDIS_STATUS_SUCCESS;
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
@ -296,7 +297,7 @@ ZydisStatus ZydisPrintHexU64(char** buffer, size_t bufferLen, uint64_t value, ui
|
||||||
if (paddingLength > i)
|
if (paddingLength > i)
|
||||||
{
|
{
|
||||||
n = paddingLength - i - 1;
|
n = paddingLength - i - 1;
|
||||||
memset(*buffer, '0', n);
|
ZydisMemorySet(*buffer, '0', n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (uppercase)
|
if (uppercase)
|
||||||
|
@ -329,13 +330,13 @@ ZydisStatus ZydisPrintStr(char** buffer, size_t bufferLen, const char* text,
|
||||||
ZYDIS_ASSERT(bufferLen > 0);
|
ZYDIS_ASSERT(bufferLen > 0);
|
||||||
ZYDIS_ASSERT(text);
|
ZYDIS_ASSERT(text);
|
||||||
|
|
||||||
const size_t strLen = strlen(text);
|
const size_t strLen = ZydisStrLen(text);
|
||||||
if (strLen >= bufferLen)
|
if (strLen >= bufferLen)
|
||||||
{
|
{
|
||||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(*buffer, text, strLen + 1);
|
ZydisMemoryCopy(*buffer, text, strLen + 1);
|
||||||
switch (letterCase)
|
switch (letterCase)
|
||||||
{
|
{
|
||||||
case ZYDIS_LETTER_CASE_DEFAULT:
|
case ZYDIS_LETTER_CASE_DEFAULT:
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <Zydis/Formatter.h>
|
#include <Zydis/Formatter.h>
|
||||||
#include <Zydis/Utils.h>
|
#include <Zydis/Utils.h>
|
||||||
#include <FormatHelper.h>
|
#include <FormatHelper.h>
|
||||||
|
#include <LibC.h>
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Instruction formatter */
|
/* Instruction formatter */
|
||||||
|
@ -909,7 +910,7 @@ ZydisStatus ZydisFormatterInit(ZydisFormatter* formatter, ZydisFormatterStyle st
|
||||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(formatter, 0, sizeof(ZydisFormatter));
|
ZydisMemorySet(formatter, 0, sizeof(ZydisFormatter));
|
||||||
formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT;
|
formatter->letterCase = ZYDIS_LETTER_CASE_DEFAULT;
|
||||||
formatter->forceSegments = ZYDIS_FALSE;
|
formatter->forceSegments = ZYDIS_FALSE;
|
||||||
formatter->forceOperandSize = ZYDIS_FALSE;
|
formatter->forceOperandSize = ZYDIS_FALSE;
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Disassembler Library (Zydis)
|
||||||
|
|
||||||
|
Original Author : 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_LIBC_H
|
||||||
|
#define ZYDIS_LIBC_H
|
||||||
|
|
||||||
|
#include <Zydis/Defines.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef ZYDIS_NO_LIBC
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* LibC is available */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
# define ZydisMemoryCopy memcpy
|
||||||
|
# define ZydisMemorySet memset
|
||||||
|
# define ZydisStrLen strlen
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* No LibC available, use our own functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These implementations are by no means optimized and will be outperformed by pretty much any
|
||||||
|
* libc implementation out there. We do not aim towards providing competetive implementations here,
|
||||||
|
* but towards providing a last resort fallback for environments without a working libc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ZYDIS_INLINE void* ZydisMemorySet(void* ptr, int value, size_t num)
|
||||||
|
{
|
||||||
|
uint8_t c = value & 0xff;
|
||||||
|
for (uint8_t* p = (uint8_t*)ptr; *p; ++p) *p = c;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZYDIS_INLINE void* ZydisMemoryCopy(void* dst, const void* src, size_t num)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < num; ++i)
|
||||||
|
{
|
||||||
|
((uint8_t*)dst)[i] = ((const uint8_t*)src)[i];
|
||||||
|
}
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZYDIS_INLINE size_t ZydisStrLen(const char* str)
|
||||||
|
{
|
||||||
|
const char *s;
|
||||||
|
for (s = str; *s; ++s);
|
||||||
|
return s - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZYDIS_LIBC_H */
|
Loading…
Reference in New Issue