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

@ -44,10 +44,10 @@ endif ()
# Library
set(headers
"Zydis/Zydis.hpp"
"Zydis/ZydisInstructionDecoder.hpp"
"Zydis/Zydis.hpp"
"Zydis/ZydisInstructionDecoder.hpp"
"Zydis/ZydisInstructionFormatter.hpp"
"Zydis/ZydisOpcodeTable.hpp"
"Zydis/ZydisOpcodeTable.hpp"
"Zydis/ZydisSymbolResolver.hpp"
"Zydis/ZydisTypes.hpp"
"Zydis/ZydisUtils.hpp")
@ -57,12 +57,12 @@ set(sources
"Zydis/ZydisOpcodeTable.cpp"
"Zydis/ZydisSymbolResolver.cpp"
"Zydis/ZydisUtils.cpp")
if (BUILD_C_BINDINGS)
set(headers ${headers}
"Zydis/ZydisAPI.h")
set(sources ${sources}
"Zydis/ZydisAPI.cpp")
set(headers ${headers}
"Zydis/ZydisAPI.h")
set(sources ${sources}
"Zydis/ZydisAPI.cpp")
endif ()
add_library("Zydis" ${headers} ${sources})
@ -76,8 +76,13 @@ include_directories(${PROJECT_BINARY_DIR})
if (BUILD_EXAMPLES)
include_directories("Zydis")
add_executable("C_SimpleDemo" "Examples/C/SimpleDemo/SimpleDemo.c")
target_link_libraries("C_SimpleDemo" "Zydis")
add_executable("SimpleDemo_CPP" "Examples/CPP/SimpleDemo/SimpleDemo.cpp")
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 ()
set(CONFIGURED_ONCE TRUE CACHE INTERNAL "CMake has configured at least once.")

View File

@ -92,24 +92,24 @@ int main()
decoder = ZydisCreateInstructionDecoder();
if (!decoder)
{
goto FreeZydisDecoder;
goto ZydisError;
}
formatter = ZydisCreateIntelInstructionFormatter();
if (!formatter)
{
goto FreeZydisFormatter;
goto FreeZydisDecoder;
}
// Create memory data sources
input32 = ZydisCreateMemoryInput(&data32[0], sizeof(data32));
if (!input32)
{
goto FreeZydisInput32;
goto FreeZydisFormatter;
}
input64 = ZydisCreateMemoryInput(&data64[0], sizeof(data64));
if (!input64)
{
goto FreeZydisInput64;
goto FreeZydisInput32;
}
// Set decoder properties
@ -148,6 +148,8 @@ int main()
ZydisSetDisassemblerMode(decoder, ZYDIS_DM_M64BIT);
ZydisSetDataSource(decoder, input64);
ZydisSetInstructionPointer(decoder, 0x00007FFA39A81930ull);
// Decode and format all instructions
puts("64 bit test ...\n\n");
while (ZydisDecodeInstruction(decoder, &info))
{
@ -181,6 +183,7 @@ FreeZydisFormatter:
ZydisFreeInstructionFormatter(formatter);
FreeZydisDecoder:
ZydisFreeInstructionDecoder(decoder);
ZydisError:
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 ##
- While Zydis supports other compilers in theory, compilation has not been tested with any compiler other than MSVC12 (Visual Studio 2013)
- Multi-compiler support might be added in the future
Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C++14 compiler.
## License ##
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 "ZydisInstructionFormatter.hpp"
/* Static Checks ================================================================================ */
static_assert(
sizeof(ZydisOperandInfo) == sizeof(Zydis::OperandInfo),
"struct size mismatch");
@ -56,81 +58,229 @@ void ZydisSetLastError(uint32_t errorCode)
/* Conversion Helper ============================================================================ */
template <typename ContextT, typename InstanceT, typename... InstanceCtorArgsT>
ContextT* ZydisCreateContextInplace(uint8_t contextType, InstanceCtorArgsT... args)
typedef enum _ZydisClassType
{
ContextT* context = new (std::nothrow) ContextT;
if (!context)
ZYDIS_CONTEXT_INPUT = 0x00000080,
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);
return nullptr;
}
context->type = contextType;
context->object = new (std::nothrow) InstanceT(args...);
if (!context->object)
{
delete context;
ZydisSetLastError(ZYDIS_ERROR_NOT_ENOUGH_MEMORY);
return nullptr;
}
return context;
// Return the original instance as context.
return reinterpret_cast<ContextClassT*>(instanceEx->getInstance());
}
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;
if (!context)
{
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))
auto instanceEx = ZydisClassEx<ZydisClassT>::fromInstance(
reinterpret_cast<ZydisClassT*>(const_cast<ContextClassT*>(context)));
if ((instanceEx->getClassType() & expectedType) != expectedType)
{
ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER);
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 ======================================================================================== */
ZydisInputContext* ZydisCreateCustomInput(/* TODO */)
/**
* @brief Helper class for custom input implementations.
*/
class ZydisCustomInput : public Zydis::BaseInput
{
return nullptr;
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 ZydisCreateContext<ZydisInputContext, ZydisCustomInput>(ZYDIS_CONTEXT_INPUT_CUSTOM,
userData, cbPeek, cbNext, cbIsEndOfInput, cbGetPosition, cbSetPosition, cbDestructor);
}
ZydisInputContext* ZydisCreateMemoryInput(const void* buffer, size_t bufferLen)
{
return ZydisCreateContextInplace<ZydisInputContext, Zydis::MemoryInput>(
ZYDIS_CONTEXT_INPUT | ZYDIS_CONTEXT_INPUT_MEMORY, buffer, bufferLen);
return ZydisCreateContext<ZydisInputContext, Zydis::MemoryInput>(
ZYDIS_CONTEXT_INPUT_MEMORY, buffer, bufferLen);
}
bool ZydisIsEndOfInput(const ZydisInputContext* input, bool* isEndOfInput)
{
Zydis::BaseInput* instance =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT);
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!instance)
{
return false;
@ -142,7 +292,7 @@ bool ZydisIsEndOfInput(const ZydisInputContext* input, bool* isEndOfInput)
bool ZydisGetInputPosition(const ZydisInputContext* input, uint64_t* position)
{
Zydis::BaseInput* instance =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT);
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!instance)
{
return false;
@ -154,7 +304,7 @@ bool ZydisGetInputPosition(const ZydisInputContext* input, uint64_t* position)
bool ZydisSetInputPosition(const ZydisInputContext* input, uint64_t position)
{
Zydis::BaseInput* instance =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT);
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!instance)
{
return false;
@ -165,23 +315,39 @@ bool ZydisSetInputPosition(const ZydisInputContext* input, uint64_t position)
bool ZydisFreeInput(const ZydisInputContext* input)
{
return ZydisFreeContext<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT);
return ZydisFreeContext<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
}
/* InstructionDecoder =========================================================================== */
ZydisInstructionDecoderContext* ZydisCreateInstructionDecoder()
{
return ZydisCreateContextInplace<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
return ZydisCreateContext<ZydisInstructionDecoderContext, Zydis::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,
ZydisInstructionInfo* info)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
@ -194,14 +360,13 @@ bool ZydisGetDataSource(const ZydisInstructionDecoderContext* decoder,
ZydisInputContext** input)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
}
*input = ZydisCreateContext<ZydisInputContext,
Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, instance->getDataSource());
*input = reinterpret_cast<ZydisInputContext*>(instance->getDataSource());
if (!input)
{
return false;
@ -213,14 +378,14 @@ bool ZydisSetDataSource(const ZydisInstructionDecoderContext* decoder,
ZydisInputContext* input)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
}
Zydis::BaseInput* object =
ZydisCast<ZydisInputContext, Zydis::BaseInput>(input, ZYDIS_CONTEXT_INPUT);
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
if (!object)
{
return false;
@ -233,8 +398,8 @@ bool ZydisGetDisassemblerMode(const ZydisInstructionDecoderContext* decoder,
ZydisDisassemblerMode* disassemblerMode)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
@ -247,8 +412,8 @@ bool ZydisSetDisassemblerMode(const ZydisInstructionDecoderContext* decoder,
ZydisDisassemblerMode disassemblerMode)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
@ -261,8 +426,8 @@ bool ZydisGetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
ZydisInstructionSetVendor* preferredVendor)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
@ -275,8 +440,8 @@ bool ZydisSetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
ZydisInstructionSetVendor preferredVendor)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
@ -289,8 +454,8 @@ bool ZydisSetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
uint64_t* instructionPointer)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
@ -303,8 +468,8 @@ bool ZydisSetInstructionPointer(const ZydisInstructionDecoderContext* decoder,
uint64_t instructionPointer)
{
Zydis::InstructionDecoder* instance =
ZydisCast<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
if (!instance)
{
return false;
@ -315,9 +480,8 @@ bool ZydisSetInstructionPointer(const ZydisInstructionDecoderContext* decoder,
bool ZydisFreeInstructionDecoder(const ZydisInstructionDecoderContext* decoder)
{
return ZydisFreeContext<
ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
decoder, ZYDIS_CONTEXT_INSTRUCTIONDECODER);
return ZydisFreeContext<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
}
/* InstructionFormatter ========================================================================= */
@ -329,17 +493,16 @@ ZydisInstructionFormatterContext* ZydisCreateCustomInstructionFormatter(/* TODO
ZydisInstructionFormatterContext* ZydisCreateIntelInstructionFormatter()
{
return ZydisCreateContextInplace<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL);
return ZydisCreateContext<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL);
}
bool ZydisFormatInstruction(const ZydisInstructionFormatterContext* formatter,
const ZydisInstructionInfo* info, const char** instructionText)
{
Zydis::IntelInstructionFormatter* instance =
ZydisCast<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER);
Zydis::BaseInstructionFormatter* instance =
ZydisRetrieveInstance<ZydisInstructionFormatterContext,
Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
if (!instance)
{
return false;
@ -352,15 +515,14 @@ bool ZydisFormatInstruction(const ZydisInstructionFormatterContext* formatter,
bool ZydisGetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
ZydisSymbolResolverContext** resolver)
{
Zydis::IntelInstructionFormatter* instance =
ZydisCast<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER);
Zydis::BaseInstructionFormatter* instance =
ZydisRetrieveInstance<ZydisInstructionFormatterContext,
Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
if (!instance)
{
return false;
}
*resolver = ZydisCreateContext<ZydisSymbolResolverContext,
Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, instance->getSymbolResolver());
*resolver = reinterpret_cast<ZydisSymbolResolverContext*>(instance->getSymbolResolver());
if (!resolver)
{
return false;
@ -371,16 +533,16 @@ bool ZydisGetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
bool ZydisSetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
ZydisSymbolResolverContext* resolver)
{
Zydis::IntelInstructionFormatter* instance =
ZydisCast<ZydisInstructionFormatterContext,
Zydis::IntelInstructionFormatter>(formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER);
Zydis::BaseInstructionFormatter* instance =
ZydisRetrieveInstance<ZydisInstructionFormatterContext,
Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
if (!instance)
{
return false;
}
Zydis::BaseSymbolResolver* object =
ZydisCast<ZydisSymbolResolverContext,
Zydis::BaseSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER);
ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
if (!object)
{
return false;
@ -391,9 +553,8 @@ bool ZydisSetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
bool ZydisFreeInstructionFormatter(const ZydisInstructionFormatterContext* formatter)
{
return ZydisFreeContext<
ZydisInstructionFormatterContext, Zydis::BaseInstructionFormatter>(
formatter, ZYDIS_CONTEXT_INSTRUCTIONFORMATTER);
return ZydisFreeContext<ZydisInstructionFormatterContext, Zydis::BaseInstructionFormatter>(
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
}
/* SymbolResolver =============================================================================== */
@ -405,16 +566,16 @@ ZydisSymbolResolverContext* ZydisCreateCustomSymbolResolver(/*TODO*/)
ZydisSymbolResolverContext* ZydisCreateExactSymbolResolver()
{
return ZydisCreateContextInplace<ZydisSymbolResolverContext, Zydis::ExactSymbolResolver>(
ZYDIS_CONTEXT_SYMBOLRESOLVER | ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
return ZydisCreateContext<ZydisSymbolResolverContext, Zydis::ExactSymbolResolver>(
ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
}
bool ZydisResolveSymbol(const ZydisSymbolResolverContext* resolver,
const ZydisInstructionInfo* info, uint64_t address, const char** symbol, uint64_t* offset)
{
Zydis::BaseSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext,
Zydis::BaseSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER);
ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
if (!instance)
{
return false;
@ -428,8 +589,8 @@ bool ZydisExactSymbolResolverContainsSymbol(
const ZydisSymbolResolverContext* resolver, uint64_t address, bool* containsSymbol)
{
Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance)
{
return false;
@ -442,8 +603,8 @@ bool ZydisExactSymbolResolverSetSymbol(const ZydisSymbolResolverContext* resolve
uint64_t address, const char* name)
{
Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance)
{
return false;
@ -456,8 +617,8 @@ bool ZydisExactSymbolResolverRemoveSymbol(const ZydisSymbolResolverContext* reso
uint64_t address)
{
Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance)
{
return false;
@ -469,8 +630,8 @@ bool ZydisExactSymbolResolverRemoveSymbol(const ZydisSymbolResolverContext* reso
bool ZydisExactSymbolResolverClear(const ZydisSymbolResolverContext* resolver)
{
Zydis::ExactSymbolResolver* instance =
ZydisCast<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
ZydisRetrieveInstance<ZydisSymbolResolverContext,
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
if (!instance)
{
return false;
@ -482,7 +643,7 @@ bool ZydisExactSymbolResolverClear(const ZydisSymbolResolverContext* resolver)
bool ZydisFreeSymbolResolver(const ZydisSymbolResolverContext* resolver)
{
return ZydisFreeContext<ZydisSymbolResolverContext, Zydis::BaseSymbolResolver>(
resolver, ZYDIS_CONTEXT_SYMBOLRESOLVER);
ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
}
/* ============================================================================================== */

View File

@ -42,7 +42,7 @@ extern "C"
{
#endif
/* Types ======================================================================================== */
/* Zydis Types ================================================================================== */
/**
* @brief Values that represent additional flags of a decoded instruction.
@ -543,45 +543,37 @@ typedef struct _ZydisInstructionInfo
uint64_t instrPointer;
} ZydisInstructionInfo;
/* Context Types ================================================================================ */
/* Context Declarations ========================================================================= */
typedef enum _ZydisContextType
{
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 { int dummy; } ZydisInputContext;
typedef struct _ZydisInputContext
{
uint8_t type;
void* object;
} ZydisInputContext;
typedef struct _ZydisInstructionDecoderContext { int dummy; } ZydisInstructionDecoderContext;
typedef struct _ZydisInstructionDecoderContext
{
uint8_t type;
void* object;
} ZydisInstructionDecoderContext;
typedef struct _ZydisInstructionFormatterContext { int dummy; } ZydisInstructionFormatterContext;
typedef struct _ZydisInstructionFormatterContext
{
uint8_t type;
void* object;
} ZydisInstructionFormatterContext;
typedef struct _ZydisSymbolResolverContext { int dummy; } ZydisSymbolResolverContext;
typedef struct _ZydisSymbolResolverContext
{
uint8_t type;
void* object;
} ZydisSymbolResolverContext;
/* Callback Declarations ======================================================================== */
/* General -------------------------------------------------------------------------------------- */
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 =============================================================================== */
@ -597,7 +589,10 @@ ZYDIS_EXPORT uint32_t ZydisGetLastError();
/* 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);
@ -633,6 +628,10 @@ typedef enum _ZydisInstructionSetVendor /* : uint8_t */
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,
ZydisInstructionInfo* info);