Improved C-bindings again

* Implemented API for custom data souces
* Internal changes
This commit is contained in:
flobernd 2015-05-19 21:45:53 +02:00
parent c4cb49faa7
commit 7caec91207
6 changed files with 437 additions and 161 deletions

View File

@ -76,8 +76,13 @@ include_directories(${PROJECT_BINARY_DIR})
if (BUILD_EXAMPLES) if (BUILD_EXAMPLES)
include_directories("Zydis") include_directories("Zydis")
add_executable("C_SimpleDemo" "Examples/C/SimpleDemo/SimpleDemo.c") add_executable("SimpleDemo_CPP" "Examples/CPP/SimpleDemo/SimpleDemo.cpp")
target_link_libraries("C_SimpleDemo" "Zydis") target_link_libraries("SimpleDemo_CPP" "Zydis")
if (BUILD_C_BINDINGS)
add_executable("SimpleDemo_C" "Examples/C/SimpleDemo/SimpleDemo.c")
target_link_libraries("SimpleDemo_C" "Zydis")
endif ()
endif () endif ()
set(CONFIGURED_ONCE TRUE CACHE INTERNAL "CMake has configured at least once.") set(CONFIGURED_ONCE TRUE CACHE INTERNAL "CMake has configured at least once.")

View File

@ -92,24 +92,24 @@ int main()
decoder = ZydisCreateInstructionDecoder(); decoder = ZydisCreateInstructionDecoder();
if (!decoder) if (!decoder)
{ {
goto FreeZydisDecoder; goto ZydisError;
} }
formatter = ZydisCreateIntelInstructionFormatter(); formatter = ZydisCreateIntelInstructionFormatter();
if (!formatter) if (!formatter)
{ {
goto FreeZydisFormatter; goto FreeZydisDecoder;
} }
// Create memory data sources // Create memory data sources
input32 = ZydisCreateMemoryInput(&data32[0], sizeof(data32)); input32 = ZydisCreateMemoryInput(&data32[0], sizeof(data32));
if (!input32) if (!input32)
{ {
goto FreeZydisInput32; goto FreeZydisFormatter;
} }
input64 = ZydisCreateMemoryInput(&data64[0], sizeof(data64)); input64 = ZydisCreateMemoryInput(&data64[0], sizeof(data64));
if (!input64) if (!input64)
{ {
goto FreeZydisInput64; goto FreeZydisInput32;
} }
// Set decoder properties // Set decoder properties
@ -148,6 +148,8 @@ int main()
ZydisSetDisassemblerMode(decoder, ZYDIS_DM_M64BIT); ZydisSetDisassemblerMode(decoder, ZYDIS_DM_M64BIT);
ZydisSetDataSource(decoder, input64); ZydisSetDataSource(decoder, input64);
ZydisSetInstructionPointer(decoder, 0x00007FFA39A81930ull); ZydisSetInstructionPointer(decoder, 0x00007FFA39A81930ull);
// Decode and format all instructions
puts("64 bit test ...\n\n"); puts("64 bit test ...\n\n");
while (ZydisDecodeInstruction(decoder, &info)) while (ZydisDecodeInstruction(decoder, &info))
{ {
@ -181,6 +183,7 @@ FreeZydisFormatter:
ZydisFreeInstructionFormatter(formatter); ZydisFreeInstructionFormatter(formatter);
FreeZydisDecoder: FreeZydisDecoder:
ZydisFreeInstructionDecoder(decoder); ZydisFreeInstructionDecoder(decoder);
ZydisError:
if (ZydisGetLastError() != ZYDIS_ERROR_SUCCESS) if (ZydisGetLastError() != ZYDIS_ERROR_SUCCESS)
{ {

View File

@ -0,0 +1,109 @@
/***************************************************************************************************
Zyan Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications : 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 <stdint.h>
#include <iostream>
#include <iomanip>
#include <Zydis.hpp>
int main()
{
uint8_t data32[] =
{
0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x6A, 0xFE, 0x68, 0xD8, 0x18, 0x09, 0x77, 0x68, 0x85, 0xD2,
0x09, 0x77, 0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0xEC, 0x14, 0x53, 0x56, 0x57,
0xA1, 0x68, 0xEE, 0x13, 0x77, 0x31, 0x45, 0xF8, 0x33, 0xC5, 0x50, 0x8D, 0x45, 0xF0, 0x64,
0xA3, 0x00, 0x00, 0x00, 0x00, 0x89, 0x65, 0xE8, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x5D, 0x08, 0xF6, 0xC3, 0x04, 0x0F, 0x85, 0x57, 0x74, 0x00, 0x00, 0x53, 0x6A, 0x00,
0xFF, 0x35, 0xA0, 0xE3, 0x13, 0x77, 0xFF, 0x15, 0x00, 0x10, 0x14, 0x77, 0x85, 0xC0, 0x0F,
0x84, 0xC6, 0x48, 0x04, 0x00, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xFC,
0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0xC0, 0x8B, 0x4D, 0xF0, 0x64, 0x89, 0x0D, 0x00, 0x00, 0x00,
0x00, 0x59, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00
};
uint8_t data64[] =
{
0x48, 0x89, 0x5C, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 0x89, 0x4C, 0x24, 0x08, 0x57,
0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x83, 0xEC, 0x40, 0x4C, 0x8B, 0xF2,
0x8B, 0xD9, 0x48, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x33, 0xF6, 0x48, 0x89,
0x74, 0x24, 0x30, 0x45, 0x33, 0xFF, 0xF7, 0xC1, 0x8D, 0xF0, 0xFF, 0xFF, 0x0F, 0x85, 0xAA,
0x53, 0x08, 0x00, 0xF6, 0xC1, 0x40, 0x8B, 0xFE, 0x41, 0xBD, 0x08, 0x00, 0x00, 0x00, 0x41,
0x0F, 0x45, 0xFD, 0xF6, 0xC1, 0x02, 0x48, 0x8B, 0x0D, 0x10, 0xD4, 0x0E, 0x00, 0x0F, 0x85,
0x40, 0xE1, 0x01, 0x00, 0x8B, 0x15, 0x4C, 0xD5, 0x0E, 0x00, 0x81, 0xC2, 0x00, 0x00, 0x14,
0x00, 0x0B, 0xD7, 0x4D, 0x8B, 0xC6, 0xFF, 0x15, 0x3B, 0x2F, 0x10, 0x00, 0x48, 0x8B, 0xD8,
0x48, 0x85, 0xC0, 0x0F, 0x84, 0x93, 0x78, 0x0A, 0x00, 0x48, 0x8B, 0xC3, 0x48, 0x8B, 0x5C,
0x24, 0x78, 0x48, 0x8B, 0xB4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83, 0xC4, 0x40, 0x41,
0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x5F, 0xC3
};
Zydis::InstructionInfo info;
Zydis::InstructionDecoder decoder;
Zydis::IntelInstructionFormatter formatter;
Zydis::MemoryInput input32(&data32[0], sizeof(data32));
Zydis::MemoryInput input64(&data64[0], sizeof(data64));
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
decoder.setDataSource(&input32);
decoder.setInstructionPointer(0x77091852);
std::cout << "32 bit test ..." << std::endl << std::endl;
while (decoder.decodeInstruction(info))
{
std::cout << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
<< info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << info.data[0];
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;
}
}
std::cout << std::endl;
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M64BIT);
decoder.setDataSource(&input64);
decoder.setInstructionPointer(0x00007FFA39A81930ull);
std::cout << "64 bit test ..." << std::endl << std::endl;
while (decoder.decodeInstruction(info))
{
std::cout << std::hex << std::setw(16) << std::setfill('0') << std::uppercase
<< info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << info.data[0];
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;
}
}
std::cin.get();
return 0;
}

View File

@ -48,8 +48,7 @@ int _tmain(int argc, _TCHAR* argv[])
## Compilation ## ## Compilation ##
- While Zydis supports other compilers in theory, compilation has not been tested with any compiler other than MSVC12 (Visual Studio 2013) Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C++14 compiler.
- Multi-compiler support might be added in the future
## License ## ## License ##
Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses. Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses.

View File

@ -32,6 +32,8 @@
#include "ZydisInstructionDecoder.hpp" #include "ZydisInstructionDecoder.hpp"
#include "ZydisInstructionFormatter.hpp" #include "ZydisInstructionFormatter.hpp"
/* Static Checks ================================================================================ */
static_assert( static_assert(
sizeof(ZydisOperandInfo) == sizeof(Zydis::OperandInfo), sizeof(ZydisOperandInfo) == sizeof(Zydis::OperandInfo),
"struct size mismatch"); "struct size mismatch");
@ -56,81 +58,229 @@ void ZydisSetLastError(uint32_t errorCode)
/* Conversion Helper ============================================================================ */ /* Conversion Helper ============================================================================ */
template <typename ContextT, typename InstanceT, typename... InstanceCtorArgsT> typedef enum _ZydisClassType
ContextT* ZydisCreateContextInplace(uint8_t contextType, InstanceCtorArgsT... args)
{ {
ContextT* context = new (std::nothrow) ContextT; ZYDIS_CONTEXT_INPUT = 0x00000080,
if (!context) ZYDIS_CONTEXT_INPUT_CUSTOM = ZYDIS_CONTEXT_INPUT | 0x00000001,
ZYDIS_CONTEXT_INPUT_MEMORY = ZYDIS_CONTEXT_INPUT | 0x00000002,
ZYDIS_CONTEXT_INSTRUCTIONDECODER = 0x00000040,
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER = 0x00000020,
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_CUSTOM = ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | 0x00000001,
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL = ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | 0x00000002,
ZYDIS_CONTEXT_SYMBOLRESOLVER = 0x00000010,
ZYDIS_CONTEXT_SYMBOLRESOLVER_CUSTOM = ZYDIS_CONTEXT_SYMBOLRESOLVER | 0x00000001,
ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT = ZYDIS_CONTEXT_SYMBOLRESOLVER | 0x00000002
} ZydisClassType;
/**
* @brief This helper class extends a zydis class with a type field. It is used by the C-bindings
* to check type correctness for input parameters.
* @param ZydisClassT The zydis class type.
*/
#pragma pack(push, 1)
template <typename ZydisClassT>
class ZydisClassEx final
{
private:
using FullClassT = ZydisClassEx<ZydisClassT>;
public:
uint32_t type;
std::conditional_t<std::is_abstract<ZydisClassT>::value, char, ZydisClassT> instance;
public:
/**
* @brief Constructor
* @param InstanceCtorArgsT The argument types for the constructor of the zydis class.
* @param classType The type of the zydis class.
* @param args... The arguments for the constructor of the zydis class.
*/
template<
typename ZydisClassTT=ZydisClassT,
std::enable_if_t<!std::is_abstract<ZydisClassTT>::value, int> = 0,
typename... InstanceCtorArgsT>
ZydisClassEx(uint32_t classType, InstanceCtorArgsT... args)
: type(classType)
, instance(args...) { };
public:
/**
* @brief Returns the class type.
* @return The assigned class type.
*/
uint32_t getClassType() const
{
return type;
}
/**
* @brief Returns the zydis class instance.
* @return Pointer to the zydis class instance.
*/
ZydisClassT* getInstance()
{
return reinterpret_cast<ZydisClassT*>(&instance);
}
public:
/**
* @brief Casts the given instance to @c ZydisClassEx.
* @param instance The zydis class instance.
* @return Pointer to the @c ZydisClassEx instance.
*/
static FullClassT* fromInstance(ZydisClassT* instance)
{
return reinterpret_cast<FullClassT*>(
reinterpret_cast<uintptr_t>(instance) - offsetof(FullClassT, instance));
}
};
#pragma pack(pop)
/**
* @brief Creates a context by constructing a new wrapped zydis class instance.
* @param ContextClassT The context class.
* @param ZydisClassT The zydis class type.
* @param ZydisClassCtorArgsT The argument types for the constructor of the zydis class.
* @param classType The type of the zydis class.
* @param args... The arguments for the constructor of the zydis class.
*/
template <typename ContextClassT, typename ZydisClassT, typename... ZydisClassCtorArgsT>
ContextClassT* ZydisCreateContext(uint32_t classType, ZydisClassCtorArgsT... args)
{
auto instanceEx = new (std::nothrow) ZydisClassEx<ZydisClassT>(classType, args...);
if (!instanceEx)
{ {
ZydisSetLastError(ZYDIS_ERROR_NOT_ENOUGH_MEMORY); ZydisSetLastError(ZYDIS_ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
context->type = contextType; // Return the original instance as context.
context->object = new (std::nothrow) InstanceT(args...); return reinterpret_cast<ContextClassT*>(instanceEx->getInstance());
if (!context->object)
{
delete context;
ZydisSetLastError(ZYDIS_ERROR_NOT_ENOUGH_MEMORY);
return nullptr;
}
return context;
} }
template <typename ContextT, typename InstanceT> /**
ContextT* ZydisCreateContext(uint8_t contextType, InstanceT* instance) * @brief Retrieves the zydis class instance of the given context.
* @param ContextClassT The context class.
* @param ZydisClassT The zydis class type.
* @param expectedType The expected type of the zydis class.
*/
template <typename ContextClassT, typename ZydisClassT>
ZydisClassT* ZydisRetrieveInstance(uint32_t expectedType, const ContextClassT* context)
{ {
ContextT* context = new (std::nothrow) ContextT; auto instanceEx = ZydisClassEx<ZydisClassT>::fromInstance(
if (!context) reinterpret_cast<ZydisClassT*>(const_cast<ContextClassT*>(context)));
{ if ((instanceEx->getClassType() & expectedType) != expectedType)
ZydisSetLastError(ZYDIS_ERROR_NOT_ENOUGH_MEMORY);
return nullptr;
}
context->type = contextType;
context->object = instance;
return context;
}
template <typename ContextT, typename InstanceT>
bool ZydisFreeContext(const ContextT* context, uint8_t expectedType)
{
InstanceT* instance = ZydisCast<ContextT, InstanceT>(context, expectedType);
if (!instance)
{
return false;
}
delete instance;
delete context;
return true;
}
template <typename ContextT, typename InstanceT>
InstanceT* ZydisCast(const ContextT* input, uint8_t expectedType)
{
if (!input || !input->object || ((input->type & expectedType) != expectedType))
{ {
ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER); ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
return reinterpret_cast<InstanceT*>(input->object); // The context points to the same address as the instance. We just need to cast it.
return reinterpret_cast<ZydisClassT*>(const_cast<ContextClassT*>(context));
}
/**
* @brief Creates a context by constructing a new wrapped zydis instance.
* @param ContextClassT The context class.
* @param ZydisClassT The zydis class type.
* @param expectedType The expected type of the zydis class.
*/
template <typename ContextClassT, typename ZydisClassT>
bool ZydisFreeContext(uint32_t expectedType, const ContextClassT* context)
{
auto instanceEx = ZydisClassEx<ZydisClassT>::fromInstance(
reinterpret_cast<ZydisClassT*>(const_cast<ContextClassT*>(context)));
if ((instanceEx->getClassType() & expectedType) != expectedType)
{
ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER);
return false;
}
delete instanceEx;
return true;
} }
/* Input ======================================================================================== */ /* Input ======================================================================================== */
ZydisInputContext* ZydisCreateCustomInput(/* TODO */) /**
* @brief Helper class for custom input implementations.
*/
class ZydisCustomInput : public Zydis::BaseInput
{ {
private:
void* m_userData;
ZydisCustomDestructorT m_cbDestructor;
ZydisCustomInputPeekT m_cbPeek;
ZydisCustomInputNextT m_cbNext;
ZydisCustomInputIsEndOfInputT m_cbIsEndOfInput;
ZydisCustomInputGetPositionT m_cbGetPosition;
ZydisCustomInputSetPositionT m_cbSetPosition;
protected:
uint8_t internalInputPeek() override
{
return m_cbPeek(m_userData);
}
uint8_t internalInputNext() override
{
return m_cbNext(m_userData);
}
public:
ZydisCustomInput(void* userData,
ZydisCustomInputPeekT cbPeek, ZydisCustomInputNextT cbNext,
ZydisCustomInputIsEndOfInputT cbIsEndOfInput, ZydisCustomInputGetPositionT cbGetPosition,
ZydisCustomInputSetPositionT cbSetPosition, ZydisCustomDestructorT cbDestructor)
: m_userData(userData)
, m_cbDestructor(cbDestructor)
, m_cbPeek(cbPeek)
, m_cbNext(cbNext)
, m_cbIsEndOfInput(cbIsEndOfInput)
, m_cbGetPosition(cbGetPosition)
, m_cbSetPosition(cbSetPosition)
{
}
~ZydisCustomInput() override
{
if (m_cbDestructor)
{
m_cbDestructor(m_userData);
}
}
public:
bool isEndOfInput() const override
{
return m_cbIsEndOfInput(m_userData);
}
uint64_t getPosition() const override
{
return m_cbGetPosition(m_userData);
}
bool setPosition(uint64_t position) override
{
return m_cbSetPosition(m_userData, position);
}
};
ZydisInputContext* ZydisCreateCustomInput(void* userData,
ZydisCustomInputPeekT cbPeek, ZydisCustomInputNextT cbNext,
ZydisCustomInputIsEndOfInputT cbIsEndOfInput, ZydisCustomInputGetPositionT cbGetPosition,
ZydisCustomInputSetPositionT cbSetPosition, ZydisCustomDestructorT cbDestructor)
{
if (!cbPeek || !cbNext || !cbIsEndOfInput || !cbGetPosition || !cbSetPosition)
{
ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
}
return ZydisCreateContext<ZydisInputContext, ZydisCustomInput>(ZYDIS_CONTEXT_INPUT_CUSTOM,
userData, cbPeek, cbNext, cbIsEndOfInput, cbGetPosition, cbSetPosition, cbDestructor);
} }
ZydisInputContext* ZydisCreateMemoryInput(const void* buffer, size_t bufferLen) ZydisInputContext* ZydisCreateMemoryInput(const void* buffer, size_t bufferLen)
{ {
return ZydisCreateContextInplace<ZydisInputContext, Zydis::MemoryInput>( return ZydisCreateContext<ZydisInputContext, Zydis::MemoryInput>(
ZYDIS_CONTEXT_INPUT | ZYDIS_CONTEXT_INPUT_MEMORY, buffer, bufferLen); ZYDIS_CONTEXT_INPUT_MEMORY, buffer, bufferLen);
} }
bool ZydisIsEndOfInput(const ZydisInputContext* input, bool* isEndOfInput) bool ZydisIsEndOfInput(const ZydisInputContext* input, bool* isEndOfInput)
{ {
Zydis::BaseInput* instance = Zydis::BaseInput* instance =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT); ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!instance) if (!instance)
{ {
return false; return false;
@ -142,7 +292,7 @@ bool ZydisIsEndOfInput(const ZydisInputContext* input, bool* isEndOfInput)
bool ZydisGetInputPosition(const ZydisInputContext* input, uint64_t* position) bool ZydisGetInputPosition(const ZydisInputContext* input, uint64_t* position)
{ {
Zydis::BaseInput* instance = Zydis::BaseInput* instance =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT); ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!instance) if (!instance)
{ {
return false; return false;
@ -154,7 +304,7 @@ bool ZydisGetInputPosition(const ZydisInputContext* input, uint64_t* position)
bool ZydisSetInputPosition(const ZydisInputContext* input, uint64_t position) bool ZydisSetInputPosition(const ZydisInputContext* input, uint64_t position)
{ {
Zydis::BaseInput* instance = Zydis::BaseInput* instance =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT); ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!instance) if (!instance)
{ {
return false; return false;
@ -165,23 +315,39 @@ bool ZydisSetInputPosition(const ZydisInputContext* input, uint64_t position)
bool ZydisFreeInput(const ZydisInputContext* input) bool ZydisFreeInput(const ZydisInputContext* input)
{ {
return ZydisFreeContext<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT); return ZydisFreeContext<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
} }
/* InstructionDecoder =========================================================================== */ /* InstructionDecoder =========================================================================== */
ZydisInstructionDecoderContext* ZydisCreateInstructionDecoder() ZydisInstructionDecoderContext* ZydisCreateInstructionDecoder()
{ {
return ZydisCreateContextInplace<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>( return ZydisCreateContext<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
ZYDIS_CONTEXT_INSTRUCTIONDECODER); ZYDIS_CONTEXT_INSTRUCTIONDECODER);
} }
ZydisInstructionDecoderContext* ZydisCreateInstructionDecoderEx(
const ZydisInputContext* input, ZydisDisassemblerMode disassemblerMode,
ZydisInstructionSetVendor preferredVendor, uint64_t instructionPointer)
{
Zydis::BaseInput* object =
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!object)
{
return nullptr;
}
return ZydisCreateContext<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
ZYDIS_CONTEXT_INSTRUCTIONDECODER, object,
static_cast<Zydis::DisassemblerMode>(disassemblerMode),
static_cast<Zydis::InstructionSetVendor>(preferredVendor), instructionPointer);
}
bool ZydisDecodeInstruction(const ZydisInstructionDecoderContext* decoder, bool ZydisDecodeInstruction(const ZydisInstructionDecoderContext* decoder,
ZydisInstructionInfo* info) ZydisInstructionInfo* info)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
@ -194,14 +360,13 @@ bool ZydisGetDataSource(const ZydisInstructionDecoderContext* decoder,
ZydisInputContext** input) ZydisInputContext** input)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
} }
*input = ZydisCreateContext<ZydisInputContext, *input = reinterpret_cast<ZydisInputContext*>(instance->getDataSource());
Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, instance->getDataSource());
if (!input) if (!input)
{ {
return false; return false;
@ -213,14 +378,14 @@ bool ZydisSetDataSource(const ZydisInstructionDecoderContext* decoder,
ZydisInputContext* input) ZydisInputContext* input)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
} }
Zydis::BaseInput* object = Zydis::BaseInput* object =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT); ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!object) if (!object)
{ {
return false; return false;
@ -233,8 +398,8 @@ bool ZydisGetDisassemblerMode(const ZydisInstructionDecoderContext* decoder,
ZydisDisassemblerMode* disassemblerMode) ZydisDisassemblerMode* disassemblerMode)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
@ -247,8 +412,8 @@ bool ZydisSetDisassemblerMode(const ZydisInstructionDecoderContext* decoder,
ZydisDisassemblerMode disassemblerMode) ZydisDisassemblerMode disassemblerMode)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
@ -261,8 +426,8 @@ bool ZydisGetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
ZydisInstructionSetVendor* preferredVendor) ZydisInstructionSetVendor* preferredVendor)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
@ -275,8 +440,8 @@ bool ZydisSetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
ZydisInstructionSetVendor preferredVendor) ZydisInstructionSetVendor preferredVendor)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
@ -289,8 +454,8 @@ bool ZydisSetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
uint64_t* instructionPointer) uint64_t* instructionPointer)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
@ -303,8 +468,8 @@ bool ZydisSetInstructionPointer(const ZydisInstructionDecoderContext* decoder,
uint64_t instructionPointer) uint64_t instructionPointer)
{ {
Zydis::InstructionDecoder* instance = Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext, ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER); Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance) if (!instance)
{ {
return false; return false;
@ -315,9 +480,8 @@ bool ZydisSetInstructionPointer(const ZydisInstructionDecoderContext* decoder,
bool ZydisFreeInstructionDecoder(const ZydisInstructionDecoderContext* decoder) bool ZydisFreeInstructionDecoder(const ZydisInstructionDecoderContext* decoder)
{ {
return ZydisFreeContext< return ZydisFreeContext<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
ZydisInstructionDecoderContext, Zydis::InstructionDecoder>( ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
} }
/* InstructionFormatter ========================================================================= */ /* InstructionFormatter ========================================================================= */
@ -329,17 +493,16 @@ ZydisInstructionFormatterContext* ZydisCreateCustomInstructionFormatter(/* TODO
ZydisInstructionFormatterContext* ZydisCreateIntelInstructionFormatter() ZydisInstructionFormatterContext* ZydisCreateIntelInstructionFormatter()
{ {
return ZydisCreateContextInplace<ZydisInstructionFormatterContext, return ZydisCreateContext<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>( Zydis::IntelInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL);
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL);
} }
bool ZydisFormatInstruction(const ZydisInstructionFormatterContext* formatter, bool ZydisFormatInstruction(const ZydisInstructionFormatterContext* formatter,
const ZydisInstructionInfo* info, const char** instructionText) const ZydisInstructionInfo* info, const char** instructionText)
{ {
Zydis::IntelInstructionFormatter* instance = Zydis::BaseInstructionFormatter* instance =
ZydisCast<ZydisInstructionFormatterContext, ZydisRetrieveInstance<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER); Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
if (!instance) if (!instance)
{ {
return false; return false;
@ -352,15 +515,14 @@ bool ZydisFormatInstruction(const ZydisInstructionFormatterContext* formatter,
bool ZydisGetSymbolResolver(const ZydisInstructionFormatterContext* formatter, bool ZydisGetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
ZydisSymbolResolverContext** resolver) ZydisSymbolResolverContext** resolver)
{ {
Zydis::IntelInstructionFormatter* instance = Zydis::BaseInstructionFormatter* instance =
ZydisCast<ZydisInstructionFormatterContext, ZydisRetrieveInstance<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER); Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
if (!instance) if (!instance)
{ {
return false; return false;
} }
*resolver = ZydisCreateContext<ZydisSymbolResolverContext, *resolver = reinterpret_cast<ZydisSymbolResolverContext*>(instance->getSymbolResolver());
Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, instance->getSymbolResolver());
if (!resolver) if (!resolver)
{ {
return false; return false;
@ -371,16 +533,16 @@ bool ZydisGetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
bool ZydisSetSymbolResolver(const ZydisInstructionFormatterContext* formatter, bool ZydisSetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
ZydisSymbolResolverContext* resolver) ZydisSymbolResolverContext* resolver)
{ {
Zydis::IntelInstructionFormatter* instance = Zydis::BaseInstructionFormatter* instance =
ZydisCast<ZydisInstructionFormatterContext, ZydisRetrieveInstance<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER); Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
if (!instance) if (!instance)
{ {
return false; return false;
} }
Zydis::BaseSymbolResolver* object = Zydis::BaseSymbolResolver* object =
ZydisCast<ZydisSymbolResolverContext, ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::BaseSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER); Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
if (!object) if (!object)
{ {
return false; return false;
@ -391,9 +553,8 @@ bool ZydisSetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
bool ZydisFreeInstructionFormatter(const ZydisInstructionFormatterContext* formatter) bool ZydisFreeInstructionFormatter(const ZydisInstructionFormatterContext* formatter)
{ {
return ZydisFreeContext< return ZydisFreeContext<ZydisInstructionFormatterContext, Zydis::BaseInstructionFormatter>(
ZydisInstructionFormatterContext, Zydis::BaseInstructionFormatter>( ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER);
} }
/* SymbolResolver =============================================================================== */ /* SymbolResolver =============================================================================== */
@ -405,16 +566,16 @@ ZydisSymbolResolverContext* ZydisCreateCustomSymbolResolver(/*TODO*/)
ZydisSymbolResolverContext* ZydisCreateExactSymbolResolver() ZydisSymbolResolverContext* ZydisCreateExactSymbolResolver()
{ {
return ZydisCreateContextInplace<ZydisSymbolResolverContext, Zydis::ExactSymbolResolver>( return ZydisCreateContext<ZydisSymbolResolverContext, Zydis::ExactSymbolResolver>(
ZYDIS_CONTEXT_SYMBOLRESOLVER | ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT); ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
} }
bool ZydisResolveSymbol(const ZydisSymbolResolverContext* resolver, bool ZydisResolveSymbol(const ZydisSymbolResolverContext* resolver,
const ZydisInstructionInfo* info, uint64_t address, const char** symbol, uint64_t* offset) const ZydisInstructionInfo* info, uint64_t address, const char** symbol, uint64_t* offset)
{ {
Zydis::BaseSymbolResolver* instance = Zydis::BaseSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext, ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::BaseSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER); Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
if (!instance) if (!instance)
{ {
return false; return false;
@ -428,8 +589,8 @@ bool ZydisExactSymbolResolverContainsSymbol(
const ZydisSymbolResolverContext* resolver, uint64_t address, bool* containsSymbol) const ZydisSymbolResolverContext* resolver, uint64_t address, bool* containsSymbol)
{ {
Zydis::ExactSymbolResolver* instance = Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext, ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT); Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance) if (!instance)
{ {
return false; return false;
@ -442,8 +603,8 @@ bool ZydisExactSymbolResolverSetSymbol(const ZydisSymbolResolverContext* resolve
uint64_t address, const char* name) uint64_t address, const char* name)
{ {
Zydis::ExactSymbolResolver* instance = Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext, ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT); Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance) if (!instance)
{ {
return false; return false;
@ -456,8 +617,8 @@ bool ZydisExactSymbolResolverRemoveSymbol(const ZydisSymbolResolverContext* reso
uint64_t address) uint64_t address)
{ {
Zydis::ExactSymbolResolver* instance = Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext, ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT); Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance) if (!instance)
{ {
return false; return false;
@ -469,8 +630,8 @@ bool ZydisExactSymbolResolverRemoveSymbol(const ZydisSymbolResolverContext* reso
bool ZydisExactSymbolResolverClear(const ZydisSymbolResolverContext* resolver) bool ZydisExactSymbolResolverClear(const ZydisSymbolResolverContext* resolver)
{ {
Zydis::ExactSymbolResolver* instance = Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext, ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT); Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance) if (!instance)
{ {
return false; return false;
@ -482,7 +643,7 @@ bool ZydisExactSymbolResolverClear(const ZydisSymbolResolverContext* resolver)
bool ZydisFreeSymbolResolver(const ZydisSymbolResolverContext* resolver) bool ZydisFreeSymbolResolver(const ZydisSymbolResolverContext* resolver)
{ {
return ZydisFreeContext<ZydisSymbolResolverContext, Zydis::BaseSymbolResolver>( return ZydisFreeContext<ZydisSymbolResolverContext, Zydis::BaseSymbolResolver>(
resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER); ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
} }
/* ============================================================================================== */ /* ============================================================================================== */

View File

@ -42,7 +42,7 @@ extern "C"
{ {
#endif #endif
/* Types ======================================================================================== */ /* Zydis Types ================================================================================== */
/** /**
* @brief Values that represent additional flags of a decoded instruction. * @brief Values that represent additional flags of a decoded instruction.
@ -543,45 +543,37 @@ typedef struct _ZydisInstructionInfo
uint64_t instrPointer; uint64_t instrPointer;
} ZydisInstructionInfo; } ZydisInstructionInfo;
/* Context Types ================================================================================ */ /* Context Declarations ========================================================================= */
typedef enum _ZydisContextType typedef struct _ZydisInputContext { int dummy; } ZydisInputContext;
{
ZYDIS_CONTEXT_INPUT = 0x0080,
ZYDIS_CONTEXT_INPUT_CUSTOM = ZYDIS_CONTEXT_INPUT | 0x0001,
ZYDIS_CONTEXT_INPUT_MEMORY = ZYDIS_CONTEXT_INPUT | 0x0002,
ZYDIS_CONTEXT_INSTRUCTIONDECODER = 0x0040,
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER = 0x0020,
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_CUSTOM = ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | 0x0001,
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL = ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | 0x0002,
ZYDIS_CONTEXT_SYMBOLRESOLVER = 0x0010,
ZYDIS_CONTEXT_SYMBOLRESOLVER_CUSTOM = ZYDIS_CONTEXT_SYMBOLRESOLVER | 0x0001,
ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT = ZYDIS_CONTEXT_SYMBOLRESOLVER | 0x0002
} ZydisContextType;
typedef struct _ZydisInputContext typedef struct _ZydisInstructionDecoderContext { int dummy; } ZydisInstructionDecoderContext;
{
uint8_t type;
void* object;
} ZydisInputContext;
typedef struct _ZydisInstructionDecoderContext typedef struct _ZydisInstructionFormatterContext { int dummy; } ZydisInstructionFormatterContext;
{
uint8_t type;
void* object;
} ZydisInstructionDecoderContext;
typedef struct _ZydisInstructionFormatterContext typedef struct _ZydisSymbolResolverContext { int dummy; } ZydisSymbolResolverContext;
{
uint8_t type;
void* object;
} ZydisInstructionFormatterContext;
typedef struct _ZydisSymbolResolverContext /* Callback Declarations ======================================================================== */
{
uint8_t type; /* General -------------------------------------------------------------------------------------- */
void* object;
} ZydisSymbolResolverContext; typedef void (*ZydisCustomDestructorT)(void* userData);
/* Input ---------------------------------------------------------------------------------------- */
typedef uint8_t (*ZydisCustomInputPeekT)(void* userData);
typedef uint8_t (*ZydisCustomInputNextT)(void* userData);
typedef bool (*ZydisCustomInputIsEndOfInputT)(void* userData);
typedef uint64_t (*ZydisCustomInputGetPositionT)(void* userData);
typedef bool (*ZydisCustomInputSetPositionT)(void* userData, uint64_t position);
/* InstructionFormatter ------------------------------------------------------------------------- */
// TODO:
/* SymbolResolver ------------------------------------------------------------------------------- */
// TODO:
/* Error Handling =============================================================================== */ /* Error Handling =============================================================================== */
@ -597,7 +589,10 @@ ZYDIS_EXPORT uint32_t ZydisGetLastError();
/* Input ======================================================================================== */ /* Input ======================================================================================== */
ZYDIS_EXPORT ZydisInputContext* ZydisCreateCustomInput(/* TODO */); ZYDIS_EXPORT ZydisInputContext* ZydisCreateCustomInput(void* userData,
ZydisCustomInputPeekT cbPeek, ZydisCustomInputNextT cbNext,
ZydisCustomInputIsEndOfInputT cbIsEndOfInput, ZydisCustomInputGetPositionT cbGetPosition,
ZydisCustomInputSetPositionT cbSetPosition, ZydisCustomDestructorT cbDestructor);
ZYDIS_EXPORT ZydisInputContext* ZydisCreateMemoryInput(const void* buffer, size_t bufferLen); ZYDIS_EXPORT ZydisInputContext* ZydisCreateMemoryInput(const void* buffer, size_t bufferLen);
@ -633,6 +628,10 @@ typedef enum _ZydisInstructionSetVendor /* : uint8_t */
ZYDIS_EXPORT ZydisInstructionDecoderContext* ZydisCreateInstructionDecoder(); ZYDIS_EXPORT ZydisInstructionDecoderContext* ZydisCreateInstructionDecoder();
ZYDIS_EXPORT ZydisInstructionDecoderContext* ZydisCreateInstructionDecoderEx(
const ZydisInputContext* input, ZydisDisassemblerMode disassemblerMode,
ZydisInstructionSetVendor preferredVendor, uint64_t instructionPointer);
ZYDIS_EXPORT bool ZydisDecodeInstruction(const ZydisInstructionDecoderContext* decoder, ZYDIS_EXPORT bool ZydisDecodeInstruction(const ZydisInstructionDecoderContext* decoder,
ZydisInstructionInfo* info); ZydisInstructionInfo* info);