mirror of https://github.com/x64dbg/zydis
made c "bindings" independent from c++ library
This commit is contained in:
parent
a51c9085e6
commit
ff09bd32eb
|
@ -5,10 +5,10 @@
|
|||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
|
||||
Original Author : athre0z
|
||||
Modifications :
|
||||
Original Author : Florian Bernd
|
||||
Modifications : athre0z
|
||||
|
||||
Last change : 04. February 2015
|
||||
Last change : 13. March 2015
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -31,14 +31,44 @@
|
|||
**************************************************************************************************/
|
||||
|
||||
#include "VXDisassemblerUtilsC.h"
|
||||
#include "VXDisassemblerUtils.h"
|
||||
|
||||
static_assert(sizeof(VXInstructionInfo) == sizeof(Verteron::VXInstructionInfo), "struct rekt");
|
||||
static_assert(sizeof(VXOperandInfo) == sizeof(Verteron::VXOperandInfo), "struct rekt");
|
||||
#include <assert.h>
|
||||
|
||||
uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo *info, const VXOperandInfo *operand)
|
||||
uint64_t VXCalcAbsoluteTarget(const VXInstructionInfo *info, const VXOperandInfo *operand)
|
||||
{
|
||||
return Verteron::VDECalcAbsoluteTarget(
|
||||
*reinterpret_cast<const Verteron::VXInstructionInfo*>(info),
|
||||
*reinterpret_cast<const Verteron::VXOperandInfo*>(operand));
|
||||
assert((operand->type == OPTYPE_REL_IMMEDIATE) ||
|
||||
((operand->type == OPTYPE_MEMORY) && (operand->base == REG_RIP)));
|
||||
|
||||
uint64_t truncMask = 0xFFFFFFFFFFFFFFFFull;
|
||||
if (!(info->flags & IF_DISASSEMBLER_MODE_64))
|
||||
{
|
||||
truncMask >>= (64 - info->operand_mode);
|
||||
}
|
||||
|
||||
uint16_t size = operand->size;
|
||||
if ((operand->type == OPTYPE_MEMORY) && (operand->base == REG_RIP))
|
||||
{
|
||||
size = operand->offset;
|
||||
}
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 8:
|
||||
return (info->instrPointer + operand->lval.sbyte) & truncMask;
|
||||
case 16:
|
||||
{
|
||||
uint32_t delta = operand->lval.sword & truncMask;
|
||||
if ((info->instrPointer + delta) > 0xFFFF)
|
||||
{
|
||||
return (info->instrPointer & 0xF0000) + ((info->instrPointer + delta) & 0xFFFF);
|
||||
}
|
||||
return info->instrPointer + delta;
|
||||
}
|
||||
case 32:
|
||||
return (info->instrPointer + operand->lval.sdword) & truncMask;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -41,13 +41,19 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
typedef struct _VXContextDescriptor
|
||||
{
|
||||
uint8_t type;
|
||||
void *ptr;
|
||||
} VXContextDescriptor;
|
||||
|
||||
/**
|
||||
* @brief Calculates the absolute target address of a relative instruction operand.
|
||||
* @param info The instruction info.
|
||||
* @param operand The operand.
|
||||
* @return The absolute target address.
|
||||
*/
|
||||
uint64_t VDECalcAbsoluteTarget(const VXInstructionInfo *info, const VXOperandInfo *operand);
|
||||
uint64_t VXCalcAbsoluteTarget(const VXInstructionInfo *info, const VXOperandInfo *operand);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,259 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
|
||||
Verteron Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
|
||||
Original Author : athre0z
|
||||
Modifications :
|
||||
|
||||
Last change : 04. February 2015
|
||||
|
||||
* 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 "VXInstructionDecoderC.h"
|
||||
#include "VXInstructionDecoder.h"
|
||||
#include "VXDisassemblerTypes.h"
|
||||
|
||||
/* Helpers ===================================================================================== */
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
inline Verteron::VXBaseDataSource* VXBaseDataSource_CppPtr(
|
||||
VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<Verteron::VXBaseDataSource*>(ctx);
|
||||
}
|
||||
|
||||
inline const Verteron::VXBaseDataSource* VXBaseDataSource_CppPtr(
|
||||
const VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<const Verteron::VXBaseDataSource*>(ctx);
|
||||
}
|
||||
|
||||
inline VXBaseDataSourceContext* VXBaseDataSource_CPtr(
|
||||
Verteron::VXBaseDataSource *ptr)
|
||||
{
|
||||
return reinterpret_cast<VXBaseDataSourceContext*>(ptr);
|
||||
}
|
||||
|
||||
inline const VXBaseDataSourceContext* VXBaseDataSource_CPtr(
|
||||
const Verteron::VXBaseDataSource *ptr)
|
||||
{
|
||||
return reinterpret_cast<const VXBaseDataSourceContext*>(ptr);
|
||||
}
|
||||
|
||||
inline Verteron::VXInstructionInfo* VXInstructionInfo_CppPtr(
|
||||
VXInstructionInfo *ptr)
|
||||
{
|
||||
static_assert(sizeof(*ptr) == sizeof(Verteron::VXInstructionInfo), "broken struct");
|
||||
return reinterpret_cast<Verteron::VXInstructionInfo*>(ptr);
|
||||
}
|
||||
|
||||
inline const Verteron::VXInstructionInfo* VXInstructionInfo_CppPtr(
|
||||
const VXInstructionInfo *ptr)
|
||||
{
|
||||
static_assert(sizeof(*ptr) == sizeof(Verteron::VXInstructionInfo), "broken struct");
|
||||
return reinterpret_cast<const Verteron::VXInstructionInfo*>(ptr);
|
||||
}
|
||||
|
||||
inline VXInstructionDecoderContext* VXInstructionDecoder_CPtr(
|
||||
Verteron::VXInstructionDecoder *ptr)
|
||||
{
|
||||
return reinterpret_cast<VXInstructionDecoderContext*>(ptr);
|
||||
}
|
||||
|
||||
inline const VXInstructionDecoderContext* VXInstructionDecoder_CPtr(
|
||||
const Verteron::VXInstructionDecoder *ptr)
|
||||
{
|
||||
return reinterpret_cast<const VXInstructionDecoderContext*>(ptr);
|
||||
}
|
||||
|
||||
inline Verteron::VXInstructionDecoder* VXInstructionDecoder_CppPtr(
|
||||
VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<Verteron::VXInstructionDecoder*>(ctx);
|
||||
}
|
||||
|
||||
inline const Verteron::VXInstructionDecoder* VXInstructionDecoder_CppPtr(
|
||||
const VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<const Verteron::VXInstructionDecoder*>(ctx);
|
||||
}
|
||||
|
||||
inline Verteron::VXDisassemblerMode VXDisassemblerMode_CppRepr(
|
||||
VXDisassemblerMode val)
|
||||
{
|
||||
return static_cast<Verteron::VXDisassemblerMode>(val);
|
||||
}
|
||||
|
||||
inline VXDisassemblerMode VXDisassemblerMode_CRepr(
|
||||
Verteron::VXDisassemblerMode val)
|
||||
{
|
||||
return static_cast<VXDisassemblerMode>(val);
|
||||
}
|
||||
|
||||
inline Verteron::VXInstructionSetVendor VXInstructionSetVendor_CppRepr(
|
||||
VXInstructionSetVendor val)
|
||||
{
|
||||
return static_cast<Verteron::VXInstructionSetVendor>(val);
|
||||
}
|
||||
|
||||
inline VXInstructionSetVendor VXInstructionSetVendor_CRepr(
|
||||
Verteron::VXInstructionSetVendor val)
|
||||
{
|
||||
return static_cast<VXInstructionSetVendor>(val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* VXBaseDataSource ============================================================================ */
|
||||
|
||||
void VXBaseDataSource_Release(VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
delete VXBaseDataSource_CppPtr(ctx);
|
||||
}
|
||||
|
||||
uint8_t VXBaseDataSource_InputPeek(VXBaseDataSourceContext *ctx, VXInstructionInfo *info)
|
||||
{
|
||||
return VXBaseDataSource_CppPtr(ctx)->inputPeek(*VXInstructionInfo_CppPtr(info));
|
||||
}
|
||||
|
||||
uint8_t VXBaseDataSource_InputNext(VXBaseDataSourceContext *ctx, VXInstructionInfo *info)
|
||||
{
|
||||
return VXBaseDataSource_CppPtr(ctx)->inputNext(*VXInstructionInfo_CppPtr(info));
|
||||
}
|
||||
|
||||
uint8_t VXBaseDataSource_InputCurrent(const VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
return VXBaseDataSource_CppPtr(ctx)->inputCurrent();
|
||||
}
|
||||
|
||||
bool VXBaseDataSource_IsEndOfInput(const VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
return VXBaseDataSource_CppPtr(ctx)->isEndOfInput();
|
||||
}
|
||||
|
||||
uint64_t VXBaseDataSource_GetPosition(const VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
return VXBaseDataSource_CppPtr(ctx)->getPosition();
|
||||
}
|
||||
|
||||
bool VXBaseDataSource_SetPosition(VXBaseDataSourceContext *ctx, uint64_t position)
|
||||
{
|
||||
return VXBaseDataSource_CppPtr(ctx)->setPosition(position);
|
||||
}
|
||||
|
||||
/* VXMemoryDataSource ========================================================================== */
|
||||
|
||||
VXBaseDataSourceContext* VXMemoryDataSource_Create(const void* buffer, size_t bufferLen)
|
||||
{
|
||||
return reinterpret_cast<VXBaseDataSourceContext*>(
|
||||
new Verteron::VXMemoryDataSource(buffer, bufferLen));
|
||||
}
|
||||
|
||||
/* VXInstructionDecoder ======================================================================== */
|
||||
|
||||
VXInstructionDecoderContext* VXInstructionDecoder_Create()
|
||||
{
|
||||
return reinterpret_cast<VXInstructionDecoderContext*>(new Verteron::VXInstructionDecoder);
|
||||
}
|
||||
|
||||
VXInstructionDecoderContext* VXInstructionDecoder_CreateEx(
|
||||
VXBaseDataSourceContext *input,
|
||||
VXDisassemblerMode disassemblerMode,
|
||||
VXInstructionSetVendor preferredVendor,
|
||||
uint64_t instructionPointer)
|
||||
{
|
||||
return VXInstructionDecoder_CPtr(new Verteron::VXInstructionDecoder(
|
||||
VXBaseDataSource_CppPtr(input),
|
||||
VXDisassemblerMode_CppRepr(disassemblerMode),
|
||||
VXInstructionSetVendor_CppRepr(preferredVendor),
|
||||
instructionPointer));
|
||||
}
|
||||
|
||||
void VXInstructionDecoder_Release(VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
delete VXInstructionDecoder_CppPtr(ctx);
|
||||
}
|
||||
|
||||
bool VXInstructionDecoder_DecodeInstruction(
|
||||
VXInstructionDecoderContext *ctx, VXInstructionInfo *info)
|
||||
{
|
||||
return VXInstructionDecoder_CppPtr(ctx)->decodeInstruction(
|
||||
*VXInstructionInfo_CppPtr(info));
|
||||
}
|
||||
|
||||
VXBaseDataSourceContext* VXInstructionDecoder_GetDataSource(
|
||||
const VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
return VXBaseDataSource_CPtr(VXInstructionDecoder_CppPtr(ctx)->getDataSource());
|
||||
}
|
||||
|
||||
void VXInstructionDecoder_SetDataSource(
|
||||
VXInstructionDecoderContext *ctx, VXBaseDataSourceContext *input)
|
||||
{
|
||||
VXInstructionDecoder_CppPtr(ctx)->setDataSource(VXBaseDataSource_CppPtr(input));
|
||||
}
|
||||
|
||||
VXDisassemblerMode VXInstructionDecoder_GetDisassemblerMode(VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
return VXDisassemblerMode_CRepr(VXInstructionDecoder_CppPtr(ctx)->getDisassemblerMode());
|
||||
}
|
||||
|
||||
void VXInstructionDecoder_SetDisassemblerMode(
|
||||
VXInstructionDecoderContext *ctx,
|
||||
VXDisassemblerMode disassemblerMode)
|
||||
{
|
||||
VXInstructionDecoder_CppPtr(ctx)->setDisassemblerMode(
|
||||
VXDisassemblerMode_CppRepr(disassemblerMode));
|
||||
}
|
||||
|
||||
VXInstructionSetVendor VXInstructionDecoder_GetPreferredVendor(
|
||||
const VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
return VXInstructionSetVendor_CRepr(VXInstructionDecoder_CppPtr(ctx)->getPreferredVendor());
|
||||
}
|
||||
|
||||
void VXInstructionDecoder_SetPreferredVendor(
|
||||
VXInstructionDecoderContext *ctx,
|
||||
VXInstructionSetVendor preferredVendor)
|
||||
{
|
||||
return VXInstructionDecoder_CppPtr(ctx)->setPreferredVendor(
|
||||
VXInstructionSetVendor_CppRepr(preferredVendor));
|
||||
}
|
||||
|
||||
uint64_t VXInstructionDecoder_GetInstructionPointer(
|
||||
VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
return VXInstructionDecoder_CppPtr(ctx)->getInstructionPointer();
|
||||
}
|
||||
|
||||
void VXInstructionDecoder_SetInstructionPointer(
|
||||
VXInstructionDecoderContext *ctx,
|
||||
uint64_t instructionPointer)
|
||||
{
|
||||
VXInstructionDecoder_CppPtr(ctx)->setInstructionPointer(instructionPointer);
|
||||
}
|
||||
|
||||
/* ============================================================================================= */
|
|
@ -8,7 +8,7 @@
|
|||
Original Author : Florian Bernd
|
||||
Modifications : athre0z
|
||||
|
||||
Last change : 04. February 2015
|
||||
Last change : 14. March 2015
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -34,6 +34,7 @@
|
|||
#define _VDE_VXINSTRUCTIONDECODERC_H_
|
||||
|
||||
#include "VXDisassemblerTypesC.h"
|
||||
#include "VXDisassemblerUtilsC.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
@ -45,7 +46,7 @@ extern "C"
|
|||
|
||||
/* VXBaseDataSource ============================================================================ */
|
||||
|
||||
typedef struct _VXBaseDataSourceContext { int a; } VXBaseDataSourceContext;
|
||||
typedef struct _VXBaseDataSourceContext { VXContextDescriptor d; } VXBaseDataSourceContext;
|
||||
|
||||
/**
|
||||
* @brief Releases a data source.
|
||||
|
@ -79,7 +80,28 @@ uint8_t VXBaseDataSource_InputPeek(
|
|||
* parameter. This function also appends the new byte to to @c data field of the @c info
|
||||
* parameter.
|
||||
*/
|
||||
uint8_t VXBaseDataSource_InputNext(
|
||||
uint8_t VXBaseDataSource_InputNext8(
|
||||
VXBaseDataSourceContext *ctx,
|
||||
VXInstructionInfo *info);
|
||||
|
||||
/**
|
||||
* @copydoc VXBaseDataSource_InputNext8
|
||||
*/
|
||||
uint16_t VXBaseDataSource_InputNext16(
|
||||
VXBaseDataSourceContext *ctx,
|
||||
VXInstructionInfo *info);
|
||||
|
||||
/**
|
||||
* @copydoc VXBaseDataSource_InputNext8
|
||||
*/
|
||||
uint32_t VXBaseDataSource_InputNext32(
|
||||
VXBaseDataSourceContext *ctx,
|
||||
VXInstructionInfo *info);
|
||||
|
||||
/**
|
||||
* @copydoc VXBaseDataSource_InputNext8
|
||||
*/
|
||||
uint64_t VXBaseDataSource_InputNext64(
|
||||
VXBaseDataSourceContext *ctx,
|
||||
VXInstructionInfo *info);
|
||||
|
||||
|
@ -157,7 +179,10 @@ typedef enum _VXInstructionSetVendor /* : uint8_t */
|
|||
|
||||
/* VXInstructionDecoder ======================================================================== */
|
||||
|
||||
typedef struct _VXInstructionDecoderContext { int a; } VXInstructionDecoderContext;
|
||||
typedef struct _VXInstructionDecoderContext
|
||||
{
|
||||
VXContextDescriptor d;
|
||||
} VXInstructionDecoderContext;
|
||||
|
||||
/**
|
||||
* @brief Creates an instruction decoder.
|
||||
|
@ -225,7 +250,7 @@ void VXInstructionDecoder_SetDataSource(
|
|||
* @return The current disassembler mode.
|
||||
*/
|
||||
VXDisassemblerMode VXInstructionDecoder_GetDisassemblerMode(
|
||||
VXInstructionDecoderContext *ctx);
|
||||
const VXInstructionDecoderContext *ctx);
|
||||
|
||||
/**
|
||||
* @brief Sets the current disassembler mode.
|
||||
|
@ -259,7 +284,7 @@ void VXInstructionDecoder_SetPreferredVendor(
|
|||
* @return The current instruction pointer.
|
||||
*/
|
||||
uint64_t VXInstructionDecoder_GetInstructionPointer(
|
||||
VXInstructionDecoderContext *ctx);
|
||||
const VXInstructionDecoderContext *ctx);
|
||||
|
||||
/**
|
||||
* @brief Sets a new instruction pointer.
|
||||
|
|
|
@ -0,0 +1,856 @@
|
|||
/**************************************************************************************************
|
||||
|
||||
Verteron Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
|
||||
Original Author : Florian Bernd
|
||||
Modifications : athre0z
|
||||
|
||||
Last change : 14. March 2014
|
||||
|
||||
* 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 "VXInstructionFormatterC.h"
|
||||
#include "VXDisassemblerUtilsC.h"
|
||||
#include "VXInternalHelpersC.h"
|
||||
#include "VXOpcodeTableInternalC.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* Interface =================================================================================== */
|
||||
|
||||
/* VXBaseSymbolResolver ------------------------------------------------------------------------ */
|
||||
|
||||
typedef const char* (*VXBaseSymbolResolver_DestructionCallback)(
|
||||
VXBaseSymbolResolverContext *ctx);
|
||||
typedef const char* (*VXBaseSymbolResolver_ResolveSymbolCallback)(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
const VXInstructionInfo *info,
|
||||
uint64_t address, uint64_t *offset);
|
||||
|
||||
typedef struct _VXBaseSymbolResolver
|
||||
{
|
||||
VXBaseSymbolResolver_DestructionCallback destruct; // may be NULL
|
||||
VXBaseSymbolResolver_ResolveSymbolCallback resolveCallback;
|
||||
} VXBaseSymbolResolver;
|
||||
|
||||
void VXBaseSymbolResolver_Release(VXBaseSymbolResolverContext *ctx);
|
||||
const char* VXBaseSymbolResolver_ResolveSymbol(VXBaseSymbolResolverContext *ctx, const VXInstructionInfo *info, uint64_t address, uint64_t *offset);
|
||||
|
||||
/* VXBaseInstructionFormatter ------------------------------------------------------------------ */
|
||||
|
||||
typedef void(*VXBaseInstructionFormatter_DestructionCallback)(
|
||||
VXBaseInstructionFormatterContext *ctx);
|
||||
typedef void(*VXBaseInstructionFormatter_InternalFormatInstructionCallback)(
|
||||
VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info);
|
||||
|
||||
typedef struct _VXBaseInstructionFormatter
|
||||
{
|
||||
VXBaseInstructionFormatter_DestructionCallback destruct; // may be NULL
|
||||
VXBaseInstructionFormatter_InternalFormatInstructionCallback internalFormat;
|
||||
VXBaseSymbolResolverContext *symbolResolver;
|
||||
char *outputBuffer;
|
||||
size_t outputBufferCapacity;
|
||||
size_t outputStringLen;
|
||||
bool outputUppercase;
|
||||
} VXBaseInstructionFormatter;
|
||||
|
||||
void VXBaseInstructionFormatter_Construct(VXBaseInstructionFormatterContext *ctx, VXBaseSymbolResolverContext *symbolResolver);
|
||||
void VXBaseInstructionFormatter_Destruct(VXBaseInstructionFormatterContext *ctx);
|
||||
void VXBaseInstructionFormatter_Release(VXBaseInstructionFormatterContext *ctx);
|
||||
void VXBaseInstructionFormatter_OutputSetUppercase(VXBaseInstructionFormatterContext *ctx, bool uppercase);
|
||||
char const* VXBaseInstructionFormatter_RegisterToString(const VXBaseInstructionFormatterContext *ctx, VXRegister reg);
|
||||
char const* VXBaseInstructionFormatter_ResolveSymbol(const VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info, uint64_t address, uint64_t *offset);
|
||||
VXBaseSymbolResolverContext* VXBaseInstructionFormatter_GetSymbolResolver(const VXBaseInstructionFormatterContext *ctx);
|
||||
void VXBaseInstructionFormatter_SetSymbolResolver(VXBaseInstructionFormatterContext *ctx, VXBaseSymbolResolverContext *symbolResolver);
|
||||
const char* VXBaseInstructionFormatter_FormatInstruction(VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info);
|
||||
void VXBaseInstructionFormatter_OutputClear(VXBaseInstructionFormatterContext *ctx);
|
||||
char const* VXBaseInstructionFormatter_OutputString(VXBaseInstructionFormatterContext *ctx);
|
||||
void VXBaseInstructionFormatter_OutputAppend(VXBaseInstructionFormatterContext *ctx, char const *text);
|
||||
void VXBaseInstructionFormatter_OutputAppendFormatted(VXBaseInstructionFormatterContext *ctx, char const *format, ...);
|
||||
void VXBaseInstructionFormatter_OutputAppendAddress(VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info, uint64_t address, bool resolveSymbols);
|
||||
void VXBaseInstructionFormatter_OutputAppendImmediate(VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info, const VXOperandInfo *operand, bool resolveSymbols);
|
||||
void VXBaseInstructionFormatter_OutputAppendDisplacement(VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info, const VXOperandInfo *operand);
|
||||
|
||||
/* VXIntelInstructionFormatter ----------------------------------------------------------------- */
|
||||
|
||||
typedef struct _VXIntelInstructionFormatter
|
||||
{
|
||||
VXBaseInstructionFormatter super;
|
||||
} VXIntelInstructionFormatter;
|
||||
|
||||
void VXIntelInstructionFormatter_Construct(VXBaseInstructionFormatterContext *ctx, VXBaseSymbolResolverContext *symbolResolver);
|
||||
void VXIntelInstructionFormatter_Destruct(VXBaseInstructionFormatterContext *ctx);
|
||||
void VXIntelInstructionFormatter_OutputAppendOperandCast(VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info, const VXOperandInfo *operand);
|
||||
void VXIntelInstructionFormatter_FormatOperand(VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info, const VXOperandInfo *operand);
|
||||
void VXIntelInstructionFormatter_InternalFormatInstruction(VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info);
|
||||
|
||||
/* VXExactSymbolResolver ----------------------------------------------------------------------- */
|
||||
|
||||
typedef struct _VXExactSymbolResolver
|
||||
{
|
||||
VXBaseSymbolResolver super;
|
||||
} VXExactSymbolResolver;
|
||||
|
||||
// TODO
|
||||
|
||||
/* Implementation ============================================================================== */
|
||||
|
||||
/* VXBaseSymbolResolver ------------------------------------------------------------------------ */
|
||||
|
||||
void VXBaseSymbolResolver_Release(
|
||||
VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
VXBaseSymbolResolver *thiz = VXBaseSymbolResolver_thiz(ctx);
|
||||
|
||||
if (thiz->destruct)
|
||||
{
|
||||
thiz->destruct(ctx);
|
||||
}
|
||||
|
||||
free(thiz);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
const char* VXBaseSymbolResolver_ResolveSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
const VXInstructionInfo *info,
|
||||
uint64_t address,
|
||||
uint64_t *offset)
|
||||
{
|
||||
assert(VXBaseSymbolResolver_thiz(ctx)->resolveCallback);
|
||||
return VXBaseSymbolResolver_thiz(ctx)->resolveCallback(ctx, info, address, offset);
|
||||
}
|
||||
|
||||
/* VXBaseInstructionFormatter ------------------------------------------------------------------ */
|
||||
|
||||
const char* VXBaseInstructionFormatter_registerStrings[] =
|
||||
{
|
||||
/* 8 bit general purpose registers */
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh",
|
||||
"spl", "bpl", "sil", "dil",
|
||||
"r8b", "r9b", "r10b", "r11b",
|
||||
"r12b", "r13b", "r14b", "r15b",
|
||||
/* 16 bit general purpose registers */
|
||||
"ax", "cx", "dx", "bx",
|
||||
"sp", "bp", "si", "di",
|
||||
"r8w", "r9w", "r10w", "r11w",
|
||||
"r12w", "r13w", "r14w", "r15w",
|
||||
/* 32 bit general purpose registers */
|
||||
"eax", "ecx", "edx", "ebx",
|
||||
"esp", "ebp", "esi", "edi",
|
||||
"r8d", "r9d", "r10d", "r11d",
|
||||
"r12d", "r13d", "r14d", "r15d",
|
||||
/* 64 bit general purpose registers */
|
||||
"rax", "rcx", "rdx", "rbx",
|
||||
"rsp", "rbp", "rsi", "rdi",
|
||||
"r8", "r9", "r10", "r11",
|
||||
"r12", "r13", "r14", "r15",
|
||||
/* segment registers */
|
||||
"es", "cs", "ss",
|
||||
"ds", "fs", "gs",
|
||||
/* control registers */
|
||||
"cr0", "cr1", "cr2", "cr3",
|
||||
"cr4", "cr5", "cr6", "cr7",
|
||||
"cr8", "cr9", "cr10", "cr11",
|
||||
"cr12", "cr13", "cr14", "cr15",
|
||||
/* debug registers */
|
||||
"dr0", "dr1", "dr2", "dr3",
|
||||
"dr4", "dr5", "dr6", "dr7",
|
||||
"dr8", "dr9", "dr10", "dr11",
|
||||
"dr12", "dr13", "dr14", "dr15",
|
||||
/* mmx registers */
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7",
|
||||
/* x87 registers */
|
||||
"st0", "st1", "st2", "st3",
|
||||
"st4", "st5", "st6", "st7",
|
||||
/* extended multimedia registers */
|
||||
"xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7",
|
||||
"xmm8", "xmm9", "xmm10", "xmm11",
|
||||
"xmm12", "xmm13", "xmm14", "xmm15",
|
||||
/* 256 bit multimedia registers */
|
||||
"ymm0", "ymm1", "ymm2", "ymm3",
|
||||
"ymm4", "ymm5", "ymm6", "ymm7",
|
||||
"ymm8", "ymm9", "ymm10", "ymm11",
|
||||
"ymm12", "ymm13", "ymm14", "ymm15",
|
||||
/* instruction pointer register */
|
||||
"rip"
|
||||
};
|
||||
|
||||
void VXBaseInstructionFormatter_Construct(
|
||||
VXBaseInstructionFormatterContext *ctx, VXBaseSymbolResolverContext *symbolResolver)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
thiz->destruct = &VXBaseInstructionFormatter_Destruct;
|
||||
thiz->internalFormat = NULL;
|
||||
thiz->symbolResolver = symbolResolver;
|
||||
thiz->outputStringLen = 0;
|
||||
thiz->outputUppercase = false;
|
||||
thiz->outputBufferCapacity = 256;
|
||||
thiz->outputBuffer = malloc(thiz->outputBufferCapacity);
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_Destruct(VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
if (thiz->outputBuffer)
|
||||
{
|
||||
free(thiz->outputBuffer);
|
||||
thiz->outputBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_Release(
|
||||
VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
if (thiz->destruct)
|
||||
{
|
||||
thiz->destruct(ctx);
|
||||
}
|
||||
|
||||
free(thiz);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_OutputSetUppercase(VXBaseInstructionFormatterContext *ctx,
|
||||
bool uppercase)
|
||||
{
|
||||
VXBaseInstructionFormatter_thiz(ctx)->outputUppercase = uppercase;
|
||||
}
|
||||
|
||||
char const* VXBaseInstructionFormatter_RegisterToString(
|
||||
const VXBaseInstructionFormatterContext *ctx, VXRegister reg)
|
||||
{
|
||||
if (reg == REG_NONE)
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
return VXBaseInstructionFormatter_registerStrings[reg - 1];
|
||||
}
|
||||
|
||||
char const* VXBaseInstructionFormatter_ResolveSymbol(
|
||||
const VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info,
|
||||
uint64_t address, uint64_t *offset)
|
||||
{
|
||||
const VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_cthiz(ctx);
|
||||
|
||||
if (thiz->symbolResolver)
|
||||
{
|
||||
return VXBaseSymbolResolver_ResolveSymbol(
|
||||
thiz->symbolResolver, info, address, offset);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VXBaseSymbolResolverContext* VXBaseInstructionFormatter_GetSymbolResolver(
|
||||
const VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
return VXBaseInstructionFormatter_cthiz(ctx)->symbolResolver;
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_SetSymbolResolver(
|
||||
VXBaseInstructionFormatterContext *ctx, VXBaseSymbolResolverContext *symbolResolver)
|
||||
{
|
||||
VXBaseInstructionFormatter_thiz(ctx)->symbolResolver = symbolResolver;
|
||||
}
|
||||
|
||||
const char* VXBaseInstructionFormatter_FormatInstruction(
|
||||
VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
// Clears the internal string buffer
|
||||
VXBaseInstructionFormatter_OutputClear(ctx);
|
||||
|
||||
// Calls the virtual format method that actually formats the instruction
|
||||
thiz->internalFormat(ctx, info);
|
||||
|
||||
if (thiz->outputBufferCapacity == 0)
|
||||
{
|
||||
// The basic instruction formatter only returns the instruction menmonic.
|
||||
return VXGetInstructionMnemonicString(info->mnemonic);
|
||||
}
|
||||
|
||||
// Return the formatted instruction string
|
||||
return VXBaseInstructionFormatter_OutputString(ctx);
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_OutputClear(VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
VXBaseInstructionFormatter_thiz(ctx)->outputStringLen = 0;
|
||||
}
|
||||
|
||||
char const* VXBaseInstructionFormatter_OutputString(VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
return &VXBaseInstructionFormatter_thiz(ctx)->outputBuffer[0];
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_OutputAppend(
|
||||
VXBaseInstructionFormatterContext *ctx, char const *text)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
// Get the string length including the null-terminator char
|
||||
size_t strLen = strlen(text) + 1;
|
||||
|
||||
// Get the buffer size
|
||||
size_t bufLen = thiz->outputBufferCapacity;
|
||||
|
||||
// Decrease the offset by one, to exclude already existing null-terminator chars in the
|
||||
// output buffer
|
||||
size_t offset = (thiz->outputStringLen) ? thiz->outputStringLen - 1 : 0;
|
||||
|
||||
// Resize capacity of the output buffer on demand and add some extra space to improve the
|
||||
// performance
|
||||
if (bufLen <= (thiz->outputStringLen + strLen))
|
||||
{
|
||||
thiz->outputBufferCapacity = bufLen + strLen + 512;
|
||||
thiz->outputBuffer = realloc(thiz->outputBuffer, thiz->outputBufferCapacity);
|
||||
}
|
||||
|
||||
// Write the text to the output buffer
|
||||
memcpy(&thiz->outputBuffer[offset], text, strLen);
|
||||
|
||||
// Increase the string length
|
||||
thiz->outputStringLen = offset + strLen;
|
||||
|
||||
// Convert to uppercase
|
||||
if (thiz->outputUppercase)
|
||||
{
|
||||
for (size_t i = offset; i < thiz->outputStringLen - 1; ++i)
|
||||
{
|
||||
thiz->outputBuffer[i] = toupper(thiz->outputBuffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_OutputAppendFormatted(
|
||||
VXBaseInstructionFormatterContext *ctx, char const *format, ...)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
|
||||
// Get the buffer size
|
||||
size_t bufLen = thiz->outputBufferCapacity;
|
||||
|
||||
// Decrease the offset by one, to exclude already existing null-terminator chars in the
|
||||
// output buffer
|
||||
size_t offset = (thiz->outputStringLen) ? thiz->outputStringLen - 1 : 0;
|
||||
|
||||
// Resize the output buffer on demand and add some extra space to improve the performance
|
||||
if ((bufLen - thiz->outputStringLen) < 256)
|
||||
{
|
||||
bufLen = bufLen + 512;
|
||||
thiz->outputBuffer = realloc(thiz->outputBuffer, bufLen);
|
||||
thiz->outputBufferCapacity = bufLen;
|
||||
}
|
||||
|
||||
int strLen = 0;
|
||||
do
|
||||
{
|
||||
// If the formatted text did not fit in the output buffer, resize it, and try again
|
||||
if (strLen < 0)
|
||||
{
|
||||
thiz->outputBufferCapacity = bufLen + 512;
|
||||
thiz->outputBuffer = realloc(thiz->outputBuffer, thiz->outputBufferCapacity);
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, format, arguments);
|
||||
return;
|
||||
}
|
||||
// Write the formatted text to the output buffer
|
||||
assert((bufLen - offset) > 0);
|
||||
strLen = vsnprintf(&thiz->outputBuffer[offset], bufLen - offset, format, arguments);
|
||||
} while (strLen < 0);
|
||||
|
||||
// Increase the string length
|
||||
thiz->outputStringLen = offset + strLen + 1;
|
||||
|
||||
// Convert to uppercase
|
||||
if (thiz->outputUppercase)
|
||||
{
|
||||
for (size_t i = offset; i < thiz->outputStringLen - 1; ++i)
|
||||
{
|
||||
thiz->outputBuffer[i] = toupper(thiz->outputBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_OutputAppendAddress(
|
||||
VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info,
|
||||
uint64_t address, bool resolveSymbols)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
const char* name = NULL;
|
||||
|
||||
if (resolveSymbols)
|
||||
{
|
||||
name = VXBaseInstructionFormatter_ResolveSymbol(ctx, info, address, &offset);
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%s+%.2llX", name, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (info->flags & IF_DISASSEMBLER_MODE_16)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%.4X", address);
|
||||
}
|
||||
else if (info->flags & IF_DISASSEMBLER_MODE_32)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%.8lX", address);
|
||||
}
|
||||
else if (info->flags & IF_DISASSEMBLER_MODE_64)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%.16llX", address);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_OutputAppendImmediate(VXBaseInstructionFormatterContext *ctx,
|
||||
const VXInstructionInfo *info, const VXOperandInfo *operand, bool resolveSymbols)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
assert(operand->type == OPTYPE_IMMEDIATE);
|
||||
uint64_t value = 0;
|
||||
if (operand->signed_lval && (operand->size != info->operand_mode))
|
||||
{
|
||||
if (operand->size == 8)
|
||||
{
|
||||
value = (int64_t)operand->lval.sbyte;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(operand->size == 32);
|
||||
value = (int64_t)operand->lval.sdword;
|
||||
}
|
||||
|
||||
if (info->operand_mode < 64)
|
||||
{
|
||||
value = value & ((1ull << info->operand_mode) - 1ull);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (operand->size)
|
||||
{
|
||||
case 8:
|
||||
value = operand->lval.ubyte;
|
||||
break;
|
||||
case 16:
|
||||
value = operand->lval.uword;
|
||||
break;
|
||||
case 32:
|
||||
value = operand->lval.udword;
|
||||
break;
|
||||
case 64:
|
||||
value = operand->lval.uqword;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t offset = 0;
|
||||
const char* name = NULL;
|
||||
if (resolveSymbols)
|
||||
{
|
||||
name = VXBaseInstructionFormatter_ResolveSymbol(ctx, info, value, &offset);
|
||||
}
|
||||
|
||||
if (name)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%s+%.2llX", name, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%.2llX", value);
|
||||
}
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_OutputAppendDisplacement(
|
||||
VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info,
|
||||
const VXOperandInfo *operand)
|
||||
{
|
||||
VXBaseInstructionFormatter *thiz = VXBaseInstructionFormatter_thiz(ctx);
|
||||
|
||||
assert(operand->offset > 0);
|
||||
if ((operand->base == REG_NONE) && (operand->index == REG_NONE))
|
||||
{
|
||||
// Assume the displacement value is unsigned
|
||||
assert(operand->scale == 0);
|
||||
assert(operand->offset != 8);
|
||||
uint64_t value = 0;
|
||||
switch (operand->offset)
|
||||
{
|
||||
case 16:
|
||||
value = operand->lval.uword;
|
||||
break;
|
||||
case 32:
|
||||
value = operand->lval.udword;
|
||||
break;
|
||||
case 64:
|
||||
value = operand->lval.uqword;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%.2llX", value);
|
||||
} else
|
||||
{
|
||||
// The displacement value might be negative
|
||||
assert(operand->offset != 64);
|
||||
int64_t value = 0;
|
||||
switch (operand->offset)
|
||||
{
|
||||
case 8:
|
||||
value = operand->lval.sbyte;
|
||||
break;
|
||||
case 16:
|
||||
value = operand->lval.sword;
|
||||
break;
|
||||
case 32:
|
||||
value = operand->lval.sdword;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if (value < 0)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "-%.2lX", -value);
|
||||
} else
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%s%.2lX",
|
||||
(operand->base != REG_NONE || operand->index != REG_NONE) ? "+" : "", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* VXIntelInstructionFormatter ----------------------------------------------------------------- */
|
||||
|
||||
void VXIntelInstructionFormatter_Construct(VXBaseInstructionFormatterContext *ctx,
|
||||
VXBaseSymbolResolverContext* symbolResolver)
|
||||
{
|
||||
VXBaseInstructionFormatter_Construct(ctx, symbolResolver);
|
||||
VXIntelInstructionFormatter *thiz = VXIntelInstructionFormatter_thiz(ctx);
|
||||
|
||||
thiz->super.destruct = &VXIntelInstructionFormatter_Destruct;
|
||||
thiz->super.internalFormat = &VXIntelInstructionFormatter_InternalFormatInstruction;
|
||||
}
|
||||
|
||||
void VXIntelInstructionFormatter_Destruct(VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
VXBaseInstructionFormatter_Destruct(ctx);
|
||||
}
|
||||
|
||||
VXBaseInstructionFormatterContext* VXIntelInstructionFormatter_Create(void)
|
||||
{
|
||||
return VXIntelInstructionFormatter_CreateEx(NULL);
|
||||
}
|
||||
|
||||
VXBaseInstructionFormatterContext* VXIntelInstructionFormatter_CreateEx(
|
||||
VXBaseSymbolResolverContext *resolver)
|
||||
{
|
||||
VXIntelInstructionFormatter *thiz = malloc(sizeof(VXIntelInstructionFormatter));
|
||||
VXBaseInstructionFormatterContext *ctx = malloc(sizeof(VXBaseInstructionFormatterContext));
|
||||
|
||||
ctx->d.type = TYPE_INTELINSTRUCTIONFORMATTER;
|
||||
ctx->d.ptr = thiz;
|
||||
|
||||
VXIntelInstructionFormatter_Construct(ctx, resolver);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void VXIntelInstructionFormatter_OutputAppendOperandCast(
|
||||
VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info,
|
||||
const VXOperandInfo *operand)
|
||||
{
|
||||
switch(operand->size)
|
||||
{
|
||||
case 8:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "byte ptr " );
|
||||
break;
|
||||
case 16:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "word ptr " );
|
||||
break;
|
||||
case 32:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "dword ptr ");
|
||||
break;
|
||||
case 64:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "qword ptr ");
|
||||
break;
|
||||
case 80:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "tword ptr ");
|
||||
break;
|
||||
case 128:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "oword ptr ");
|
||||
break;
|
||||
case 256:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "yword ptr ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VXIntelInstructionFormatter_FormatOperand(
|
||||
VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info,
|
||||
const VXOperandInfo *operand)
|
||||
{
|
||||
switch (operand->type)
|
||||
{
|
||||
case OPTYPE_REGISTER:
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx,
|
||||
VXBaseInstructionFormatter_RegisterToString(ctx, operand->base));
|
||||
break;
|
||||
case OPTYPE_MEMORY:
|
||||
if (info->flags & IF_PREFIX_SEGMENT)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx,
|
||||
"%s:", VXBaseInstructionFormatter_RegisterToString(ctx, info->segment));
|
||||
}
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "[");
|
||||
if (operand->base == REG_RIP)
|
||||
{
|
||||
// TODO: Add option
|
||||
VXBaseInstructionFormatter_OutputAppendAddress(
|
||||
ctx, info, VXCalcAbsoluteTarget(info, operand), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (operand->base != REG_NONE)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx,
|
||||
VXBaseInstructionFormatter_RegisterToString(ctx, operand->base));
|
||||
}
|
||||
|
||||
if (operand->index != REG_NONE)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%s%s",
|
||||
operand->base != REG_NONE ? "+" : "",
|
||||
VXBaseInstructionFormatter_RegisterToString(ctx, operand->index));
|
||||
if (operand->scale)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "*%d", operand->scale);
|
||||
}
|
||||
}
|
||||
|
||||
if (operand->offset)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendDisplacement(ctx, info, operand);
|
||||
}
|
||||
}
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "]");
|
||||
break;
|
||||
case OPTYPE_POINTER:
|
||||
// TODO: resolve symbols
|
||||
switch (operand->size)
|
||||
{
|
||||
case 32:
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "word %.4X:%.4X",
|
||||
operand->lval.ptr.seg, operand->lval.ptr.off & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "dword %.4X:%.8lX",
|
||||
operand->lval.ptr.seg, operand->lval.ptr.off);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
case OPTYPE_IMMEDIATE:
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppendImmediate(ctx, info, operand, true);
|
||||
}
|
||||
break;
|
||||
case OPTYPE_REL_IMMEDIATE:
|
||||
{
|
||||
if (operand->size == 8)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "short ");
|
||||
}
|
||||
VXBaseInstructionFormatter_OutputAppendAddress(ctx, info,
|
||||
VXCalcAbsoluteTarget(info, operand), true);
|
||||
}
|
||||
break;
|
||||
case OPTYPE_CONSTANT:
|
||||
VXBaseInstructionFormatter_OutputAppendFormatted(ctx, "%.2X", operand->lval.udword);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void VXIntelInstructionFormatter_InternalFormatInstruction(
|
||||
VXBaseInstructionFormatterContext *ctx, const VXInstructionInfo *info)
|
||||
{
|
||||
// Append string prefixes
|
||||
if (info->flags & IF_PREFIX_LOCK)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "lock ");
|
||||
}
|
||||
|
||||
if (info->flags & IF_PREFIX_REP)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "rep ");
|
||||
}
|
||||
else if (info->flags & IF_PREFIX_REPNE)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, "repne ");
|
||||
}
|
||||
|
||||
// Append the instruction mnemonic
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, VXGetInstructionMnemonicString(info->mnemonic));
|
||||
|
||||
// Append the first operand
|
||||
if (info->operand[0].type != OPTYPE_NONE)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, " ");
|
||||
bool cast = false;
|
||||
if (info->operand[0].type == OPTYPE_MEMORY)
|
||||
{
|
||||
if (info->operand[1].type == OPTYPE_IMMEDIATE ||
|
||||
info->operand[1].type == OPTYPE_CONSTANT ||
|
||||
info->operand[1].type == OPTYPE_NONE ||
|
||||
(info->operand[0].size != info->operand[1].size))
|
||||
{
|
||||
cast = true;
|
||||
}
|
||||
else if (info->operand[1].type == OPTYPE_REGISTER && info->operand[1].base == REG_CL)
|
||||
{
|
||||
switch (info->mnemonic)
|
||||
{
|
||||
case MNEM_RCL:
|
||||
case MNEM_ROL:
|
||||
case MNEM_ROR:
|
||||
case MNEM_RCR:
|
||||
case MNEM_SHL:
|
||||
case MNEM_SHR:
|
||||
case MNEM_SAR:
|
||||
cast = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cast)
|
||||
{
|
||||
VXIntelInstructionFormatter_OutputAppendOperandCast(ctx, info, &info->operand[0]);
|
||||
}
|
||||
VXIntelInstructionFormatter_FormatOperand(ctx, info, &info->operand[0]);
|
||||
}
|
||||
|
||||
// Append the second operand
|
||||
if (info->operand[1].type != OPTYPE_NONE)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, ", ");
|
||||
bool cast = false;
|
||||
if (info->operand[1].type == OPTYPE_MEMORY &&
|
||||
info->operand[0].size != info->operand[1].size &&
|
||||
((info->operand[0].type != OPTYPE_REGISTER) ||
|
||||
((info->operand[0].base != REG_ES) &&
|
||||
(info->operand[0].base != REG_CS) &&
|
||||
(info->operand[0].base != REG_SS) &&
|
||||
(info->operand[0].base != REG_DS) &&
|
||||
(info->operand[0].base != REG_FS) &&
|
||||
(info->operand[0].base != REG_GS))))
|
||||
{
|
||||
cast = true;
|
||||
}
|
||||
|
||||
if (cast)
|
||||
{
|
||||
VXIntelInstructionFormatter_OutputAppendOperandCast(ctx, info, &info->operand[1]);
|
||||
}
|
||||
VXIntelInstructionFormatter_FormatOperand(ctx, info, &info->operand[1]);
|
||||
}
|
||||
|
||||
// Append the third operand
|
||||
if (info->operand[2].type != OPTYPE_NONE)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, ", ");
|
||||
bool cast = false;
|
||||
if (info->operand[2].type == OPTYPE_MEMORY &&
|
||||
(info->operand[2].size != info->operand[1].size))
|
||||
{
|
||||
cast = true;
|
||||
}
|
||||
|
||||
if (cast)
|
||||
{
|
||||
VXIntelInstructionFormatter_OutputAppendOperandCast(ctx, info, &info->operand[2]);
|
||||
}
|
||||
|
||||
VXIntelInstructionFormatter_FormatOperand(ctx, info, &info->operand[2]);
|
||||
}
|
||||
|
||||
// Append the fourth operand
|
||||
if (info->operand[3].type != OPTYPE_NONE)
|
||||
{
|
||||
VXBaseInstructionFormatter_OutputAppend(ctx, ", ");
|
||||
VXIntelInstructionFormatter_FormatOperand(ctx, info, &info->operand[3]);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================= */
|
|
@ -1,312 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
|
||||
Verteron Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
|
||||
Original Author : athre0z
|
||||
Modifications :
|
||||
|
||||
Last change : 04. February 2015
|
||||
|
||||
* 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 "VXInstructionFormatterC.h"
|
||||
#include "VXInstructionFormatter.h"
|
||||
|
||||
/* Helpers ===================================================================================== */
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
inline Verteron::VXBaseSymbolResolver* VXBaseSymbolResolver_CppPtr(
|
||||
VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<Verteron::VXBaseSymbolResolver*>(ctx);
|
||||
}
|
||||
|
||||
inline const Verteron::VXBaseSymbolResolver* VXBaseSymbolResolver_CppPtr(
|
||||
const VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<const Verteron::VXBaseSymbolResolver*>(ctx);
|
||||
}
|
||||
|
||||
inline VXBaseSymbolResolverContext* VXBaseSymbolResolver_CPtr(
|
||||
Verteron::VXBaseSymbolResolver *ptr)
|
||||
{
|
||||
return reinterpret_cast<VXBaseSymbolResolverContext*>(ptr);
|
||||
}
|
||||
|
||||
inline const VXBaseSymbolResolverContext* VXBaseSymbolResolver_CPtr(
|
||||
const Verteron::VXBaseSymbolResolver *ptr)
|
||||
{
|
||||
return reinterpret_cast<const VXBaseSymbolResolverContext*>(ptr);
|
||||
}
|
||||
|
||||
inline Verteron::VXExactSymbolResolver* VXExactSymbolResolver_CppPtr(
|
||||
VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<Verteron::VXExactSymbolResolver*>(ctx);
|
||||
}
|
||||
|
||||
inline const Verteron::VXExactSymbolResolver* VXExactSymbolResolver_CppPtr(
|
||||
const VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<const Verteron::VXExactSymbolResolver*>(ctx);
|
||||
}
|
||||
|
||||
inline VXBaseSymbolResolverContext* VXExactSymbolResolver_CPtr(
|
||||
Verteron::VXExactSymbolResolver *ptr)
|
||||
{
|
||||
return reinterpret_cast<VXBaseSymbolResolverContext*>(ptr);
|
||||
}
|
||||
|
||||
inline const VXBaseSymbolResolverContext* VXExactSymbolResolver_CPtr(
|
||||
const Verteron::VXExactSymbolResolver *ptr)
|
||||
{
|
||||
return reinterpret_cast<const VXBaseSymbolResolverContext*>(ptr);
|
||||
}
|
||||
|
||||
inline Verteron::VXInstructionInfo* VXInstructionInfo_CppPtr(
|
||||
VXInstructionInfo *ptr)
|
||||
{
|
||||
static_assert(sizeof(*ptr) == sizeof(Verteron::VXInstructionInfo), "broken struct");
|
||||
return reinterpret_cast<Verteron::VXInstructionInfo*>(ptr);
|
||||
}
|
||||
|
||||
inline const Verteron::VXInstructionInfo* VXInstructionInfo_CppPtr(
|
||||
const VXInstructionInfo *ptr)
|
||||
{
|
||||
static_assert(sizeof(*ptr) == sizeof(Verteron::VXInstructionInfo), "broken struct");
|
||||
return reinterpret_cast<const Verteron::VXInstructionInfo*>(ptr);
|
||||
}
|
||||
|
||||
inline VXInstructionInfo* VXInstructionInfo_CPtr(
|
||||
Verteron::VXInstructionInfo *ptr)
|
||||
{
|
||||
return reinterpret_cast<VXInstructionInfo*>(ptr);
|
||||
}
|
||||
|
||||
inline const VXInstructionInfo* VXInstructionInfo_CPtr(
|
||||
const Verteron::VXInstructionInfo *ptr)
|
||||
{
|
||||
return reinterpret_cast<const VXInstructionInfo*>(ptr);
|
||||
}
|
||||
|
||||
inline Verteron::VXBaseInstructionFormatter* VXBaseInstructionFormatter_CppPtr(
|
||||
VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<Verteron::VXBaseInstructionFormatter*>(ctx);
|
||||
}
|
||||
|
||||
inline const Verteron::VXBaseInstructionFormatter* VXBaseInstructionFormatter_CppPtr(
|
||||
const VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<const Verteron::VXBaseInstructionFormatter*>(ctx);
|
||||
}
|
||||
|
||||
inline Verteron::VXBaseInstructionFormatter* VXIntelInstructionFormatter_CppPtr(
|
||||
VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<Verteron::VXBaseInstructionFormatter*>(ctx);
|
||||
}
|
||||
|
||||
inline const Verteron::VXBaseInstructionFormatter* VXIntelInstructionFormatter_CppPtr(
|
||||
const VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
return reinterpret_cast<const Verteron::VXBaseInstructionFormatter*>(ctx);
|
||||
}
|
||||
|
||||
inline VXBaseInstructionFormatterContext* VXIntelInstructionFormatter_CPtr(
|
||||
Verteron::VXBaseInstructionFormatter *ctx)
|
||||
{
|
||||
return reinterpret_cast<VXBaseInstructionFormatterContext*>(ctx);
|
||||
}
|
||||
|
||||
inline const VXBaseInstructionFormatterContext* VXIntelInstructionFormatter_CPtr(
|
||||
const Verteron::VXBaseInstructionFormatter *ctx)
|
||||
{
|
||||
return reinterpret_cast<const VXBaseInstructionFormatterContext*>(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* VXBaseSymbolResolver ======================================================================== */
|
||||
|
||||
void VXBaseSymbolResolver_Release(
|
||||
VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
delete VXBaseSymbolResolver_CppPtr(ctx);
|
||||
}
|
||||
|
||||
const char* VXBaseSymbolResolver_ResolveSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
const VXInstructionInfo *info,
|
||||
uint64_t address,
|
||||
uint64_t *offset)
|
||||
{
|
||||
return VXBaseSymbolResolver_CppPtr(ctx)->resolveSymbol(
|
||||
*VXInstructionInfo_CppPtr(info),
|
||||
address,
|
||||
*offset);
|
||||
}
|
||||
|
||||
/* VXExactSymbolResolver ======================================================================= */
|
||||
|
||||
VXBaseSymbolResolverContext* VXExactSymbolResolver_Create(void)
|
||||
{
|
||||
return VXExactSymbolResolver_CPtr(new Verteron::VXExactSymbolResolver);
|
||||
}
|
||||
|
||||
bool VXExactSymbolResolver_ContainsSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
uint64_t address)
|
||||
{
|
||||
return VXExactSymbolResolver_CppPtr(ctx)->containsSymbol(address);
|
||||
}
|
||||
|
||||
void VXExactSymbolResolverContext_SetSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
uint64_t address,
|
||||
const char* name)
|
||||
{
|
||||
VXExactSymbolResolver_CppPtr(ctx)->setSymbol(address, name);
|
||||
}
|
||||
|
||||
void VXExactSymbolResolverContext_RemoveSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
uint64_t address)
|
||||
{
|
||||
VXExactSymbolResolver_CppPtr(ctx)->removeSymbol(address);
|
||||
}
|
||||
|
||||
void VXExactSymbolResolverContext_Clear(
|
||||
VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
VXExactSymbolResolver_CppPtr(ctx)->clear();
|
||||
}
|
||||
|
||||
/* VXBaseInstructionFormatter ================================================================== */
|
||||
|
||||
const char* VXBaseInstructionFormatter_FormatInstruction(
|
||||
VXBaseInstructionFormatterContext *ctx,
|
||||
const VXInstructionInfo *info)
|
||||
{
|
||||
return VXBaseInstructionFormatter_CppPtr(ctx)->formatInstruction(
|
||||
*VXInstructionInfo_CppPtr(info));
|
||||
}
|
||||
|
||||
VXBaseSymbolResolverContext* VXBaseInstructionFormatter_GetSymbolResolver(
|
||||
const VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
return VXBaseSymbolResolver_CPtr(
|
||||
VXBaseInstructionFormatter_CppPtr(ctx)->getSymbolResolver());
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_SetSymbolResolver(
|
||||
VXBaseInstructionFormatterContext *ctx,
|
||||
VXBaseSymbolResolverContext *resolver)
|
||||
{
|
||||
VXBaseInstructionFormatter_CppPtr(ctx)->setSymbolResolver(
|
||||
VXBaseSymbolResolver_CppPtr(resolver));
|
||||
}
|
||||
|
||||
void VXBaseInstructionFormatter_Release(
|
||||
VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
delete VXBaseInstructionFormatter_CppPtr(ctx);
|
||||
}
|
||||
|
||||
/* VXIntelInstructionFormatter ================================================================ */
|
||||
|
||||
VXBaseInstructionFormatterContext* VXIntelInstructionFormatter_Create(void)
|
||||
{
|
||||
return VXIntelInstructionFormatter_CPtr(new Verteron::VXIntelInstructionFormatter);
|
||||
}
|
||||
|
||||
VXBaseInstructionFormatterContext* VXIntelInstructionFormatter_CreateEx(
|
||||
VXBaseSymbolResolverContext *resolver)
|
||||
{
|
||||
return VXIntelInstructionFormatter_CPtr(new Verteron::VXIntelInstructionFormatter(
|
||||
VXBaseSymbolResolver_CppPtr(resolver)));
|
||||
}
|
||||
|
||||
/* VXCustomSymbolResolver ====================================================================== */
|
||||
|
||||
/* Internal helper class ----------------------------------------------------------------------- */
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class VXCustomSymbolResolver : public Verteron::VXBaseSymbolResolver
|
||||
{
|
||||
VXResolveSymbol_t m_resolverCb;
|
||||
void *m_userData;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param resolverCb The resolver callback.
|
||||
* @param userData User provided pointer to arbitrary data passed to resolve callback.
|
||||
*/
|
||||
VXCustomSymbolResolver(VXResolveSymbol_t resolverCb, void *userData);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
~VXCustomSymbolResolver() override = default;
|
||||
public:
|
||||
/**
|
||||
* @brief Resolves a symbol.
|
||||
* @param info The instruction info.
|
||||
* @param address The address.
|
||||
* @param offset Reference to an unsigned 64 bit integer that receives an offset
|
||||
* relative to the base address of the symbol.
|
||||
* @return The name of the symbol, if the symbol was found, @c NULL if not.
|
||||
*/
|
||||
const char* resolveSymbol(const Verteron::VXInstructionInfo &info, uint64_t address,
|
||||
uint64_t &offset) override;
|
||||
};
|
||||
|
||||
VXCustomSymbolResolver::VXCustomSymbolResolver(VXResolveSymbol_t resolverCb, void *userData)
|
||||
: m_resolverCb(resolverCb)
|
||||
, m_userData(userData)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* VXCustomSymbolResolver::resolveSymbol(
|
||||
const Verteron::VXInstructionInfo &info, uint64_t address, uint64_t &offset)
|
||||
{
|
||||
return m_resolverCb(VXInstructionInfo_CPtr(&info), address, &offset, m_userData);
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
/* C API implementation ------------------------------------------------------------------------ */
|
||||
|
||||
VXBaseSymbolResolverContext* VXCustomSymbolResolver_Create(
|
||||
VXResolveSymbol_t resolverCb,
|
||||
void *userData)
|
||||
{
|
||||
return VXBaseSymbolResolver_CPtr(new VXCustomSymbolResolver(resolverCb, userData));
|
||||
}
|
||||
|
||||
/* ============================================================================================= */
|
|
@ -8,7 +8,7 @@
|
|||
Original Author : Florian Bernd
|
||||
Modifications : athre0z
|
||||
|
||||
Last change : 04. February 2015
|
||||
Last change : 14. March 2015
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -34,6 +34,7 @@
|
|||
#define _VDE_VXINSTRUCTIONFORMATTERC_H_
|
||||
|
||||
#include "VXDisassemblerTypesC.h"
|
||||
#include "VXDisassemblerUtilsC.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
@ -42,7 +43,10 @@ extern "C"
|
|||
|
||||
/* VXBaseSymbolResolver ======================================================================== */
|
||||
|
||||
typedef struct _VXBaseSymbolResolverContext { int a; } VXBaseSymbolResolverContext;
|
||||
typedef struct _VXBaseSymbolResolverContext
|
||||
{
|
||||
VXContextDescriptor d;
|
||||
} VXBaseSymbolResolverContext;
|
||||
|
||||
/**
|
||||
* @brief Releases a symbol resolver.
|
||||
|
@ -67,55 +71,6 @@ const char* VXBaseSymbolResolver_ResolveSymbol(
|
|||
uint64_t address,
|
||||
uint64_t *offset);
|
||||
|
||||
/* VXExactSymbolResolver ======================================================================= */
|
||||
|
||||
/**
|
||||
* @brief Creates an exact symbol resolver.
|
||||
* @return @c NULL if it fails, else a symbol resolver context.
|
||||
* @see VXBaseSymbolResolver_Release
|
||||
* An exact resolver is a simple symbol resolver that only matches exact addresses.
|
||||
*/
|
||||
// TODO: verify return value
|
||||
VXBaseSymbolResolverContext* VXExactSymbolResolver_Create(void);
|
||||
|
||||
/**
|
||||
* @brief Query if the given address is a known symbol.
|
||||
* @param ctx The exact symbol resolver context.
|
||||
* @param address The address.
|
||||
* @return @c true if the address is known, @c false if not.
|
||||
*/
|
||||
bool VXExactSymbolResolver_ContainsSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
uint64_t address);
|
||||
|
||||
/**
|
||||
* @brief Adds or changes a symbol.
|
||||
* @param ctx The exact symbol resolver context.
|
||||
* @param address The address.
|
||||
* @param name The symbol name.
|
||||
*/
|
||||
void VXExactSymbolResolverContext_SetSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
uint64_t address,
|
||||
const char* name);
|
||||
|
||||
/**
|
||||
* @brief Removes the symbol described by address.
|
||||
* @param ctx The exact symbol resolver context.
|
||||
* @param address The address.
|
||||
* This will invalidate all char-pointers to the affected symbol name.
|
||||
*/
|
||||
void VXExactSymbolResolverContext_RemoveSymbol(
|
||||
VXBaseSymbolResolverContext *ctx,
|
||||
uint64_t address);
|
||||
|
||||
/**
|
||||
* @brief Clears the symbol tree.
|
||||
* @param ctx The exact symbol resolver context.
|
||||
*/
|
||||
void VXExactSymbolResolverContext_Clear(
|
||||
VXBaseSymbolResolverContext *ctx);
|
||||
|
||||
/* VXCustomSymbolResolver ====================================================================== */
|
||||
|
||||
typedef const char* (*VXResolveSymbol_t)(
|
||||
|
@ -137,7 +92,10 @@ VXBaseSymbolResolverContext* VXCustomSymbolResolver_Create(
|
|||
|
||||
/* VXBaseInstructionFormatter ================================================================== */
|
||||
|
||||
typedef struct _VXBaseInstructionFormatterContext {int a;} VXBaseInstructionFormatterContext;
|
||||
typedef struct _VXBaseInstructionFormatterContext
|
||||
{
|
||||
VXContextDescriptor d;
|
||||
} VXBaseInstructionFormatterContext;
|
||||
|
||||
/**
|
||||
* @brief Formats a decoded instruction.
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/**************************************************************************************************
|
||||
|
||||
Verteron Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
|
||||
Original Author : athre0z
|
||||
Modifications :
|
||||
|
||||
Last change : 13. March 2015
|
||||
|
||||
* 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 _VDE_VXINTERNALHELPERS_H_
|
||||
#define _VDE_VXINTERNALHELPERS_H_
|
||||
|
||||
#include "VXInstructionDecoderC.h"
|
||||
#include "VXInstructionFormatterC.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
struct _VXBaseDataSource;
|
||||
struct _VXInstructionDecoder;
|
||||
|
||||
/* Types IDs =================================================================================== */
|
||||
|
||||
typedef enum _VXTypeId
|
||||
{
|
||||
TYPE_BASEDATASOURCE,
|
||||
TYPE_MEMORYDATASOURCE,
|
||||
TYPE_INSTRUCTIONDECODER,
|
||||
TYPE_BASESYMBOLRESOLVER,
|
||||
TYPE_EXACTSYMBOLRESOLVER,
|
||||
TYPE_BASEINSTRUCTIONFORMATTER,
|
||||
TYPE_INTELINSTRUCTIONFORMATTER,
|
||||
} VXTypeId;
|
||||
|
||||
/* Context conversion helpers ================================================================== */
|
||||
|
||||
// TODO: don't use __inline
|
||||
|
||||
__inline struct _VXBaseDataSource* VXBaseDataSource_thiz(
|
||||
VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_BASEDATASOURCE
|
||||
|| ctx->d.type == TYPE_MEMORYDATASOURCE);
|
||||
return (struct _VXBaseDataSource*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline const struct _VXBaseDataSource* VXBaseDataSource_cthiz(
|
||||
const VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_BASEDATASOURCE
|
||||
|| ctx->d.type == TYPE_MEMORYDATASOURCE);
|
||||
return (const struct _VXBaseDataSource*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline struct _VXMemoryDataSource* VXMemoryDataSource_thiz(
|
||||
VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_MEMORYDATASOURCE);
|
||||
return (struct _VXMemoryDataSource*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline const struct _VXMemoryDataSource* VXMemoryDataSource_cthiz(
|
||||
const VXBaseDataSourceContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_MEMORYDATASOURCE);
|
||||
return (const struct _VXMemoryDataSource*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline struct _VXInstructionDecoder* VXInstructionDecoder_thiz(
|
||||
VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_INSTRUCTIONDECODER);
|
||||
return (struct _VXInstructionDecoder*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline const struct _VXInstructionDecoder* VXInstructionDecoder_cthiz(
|
||||
const VXInstructionDecoderContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_INSTRUCTIONDECODER);
|
||||
return (const struct _VXInstructionDecoder*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline struct _VXBaseSymbolResolver* VXBaseSymbolResolver_thiz(
|
||||
VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_BASESYMBOLRESOLVER);
|
||||
return (struct _VXBaseSymbolResolver*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline const struct _VXBaseSymbolResolver* VXBaseSymbolResolver_cthiz(
|
||||
const VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_BASESYMBOLRESOLVER);
|
||||
return (const struct _VXBaseSymbolResolver*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline struct _VXExactSymbolResolver* VXExactSymbolResolver_thiz(
|
||||
VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_EXACTSYMBOLRESOLVER);
|
||||
return (struct _VXExactSymbolResolver*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline const struct _VXExactSymbolResolver* VXExactSymbolResolver_cthiz(
|
||||
const VXBaseSymbolResolverContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_EXACTSYMBOLRESOLVER);
|
||||
return (const struct _VXExactSymbolResolver*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline struct _VXBaseInstructionFormatter* VXBaseInstructionFormatter_thiz(
|
||||
VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_BASEINSTRUCTIONFORMATTER
|
||||
|| ctx->d.type == TYPE_INTELINSTRUCTIONFORMATTER);
|
||||
return (struct _VXBaseInstructionFormatter*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline const struct _VXBaseInstructionFormatter* VXBaseInstructionFormatter_cthiz(
|
||||
const VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_BASEINSTRUCTIONFORMATTER
|
||||
|| ctx->d.type == TYPE_INTELINSTRUCTIONFORMATTER);
|
||||
return (const struct _VXBaseInstructionFormatter*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline struct _VXIntelInstructionFormatter* VXIntelInstructionFormatter_thiz(
|
||||
VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_INTELINSTRUCTIONFORMATTER);
|
||||
return (struct _VXIntelInstructionFormatter*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
__inline const struct _VXIntelInstructionFormatter* VXIntelInstructionFormatter_cthiz(
|
||||
const VXBaseInstructionFormatterContext *ctx)
|
||||
{
|
||||
assert(ctx->d.type == TYPE_INTELINSTRUCTIONFORMATTER);
|
||||
return (const struct _VXIntelInstructionFormatter*)ctx->d.ptr;
|
||||
}
|
||||
|
||||
/* ============================================================================================= */
|
||||
|
||||
#endif /* _VDE_VXINTERNALHELPERS_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,35 +0,0 @@
|
|||
/**************************************************************************************************
|
||||
|
||||
Verteron Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
|
||||
Original Author : athre0z
|
||||
Modifications :
|
||||
|
||||
Last change : 04. February 2015
|
||||
|
||||
* 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 "VXOpcodeTableC.h"
|
||||
#include "VXOpcodeTable.h"
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
#define _VDE_VXOPCODETABLEC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
|
|
@ -0,0 +1,313 @@
|
|||
/**************************************************************************************************
|
||||
|
||||
Verteron Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
|
||||
Original Author : athre0z
|
||||
Modifications :
|
||||
|
||||
Last change : 14. March 2015
|
||||
|
||||
* 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 _VDE_VXOPCODETABLEINTERNAL_H_
|
||||
#define _VDE_VXOPCODETABLEINTERNAL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "VXOpcodeTableC.h"
|
||||
|
||||
/**
|
||||
* @brief Contains all opcode tables.
|
||||
* Indexed by the numeric value of the opcode.
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeTable[][256];
|
||||
|
||||
/**
|
||||
* @brief Contains all modrm_mod switch tables.
|
||||
* Index values:
|
||||
* 0 = [modrm_mod == !11]
|
||||
* 1 = [modrm_mod == 11]
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeModrmMod[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all modrm_reg switch tables.
|
||||
* Indexed by the numeric value of the modrm_reg field.
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeModrmReg[][8];
|
||||
|
||||
/**
|
||||
* @brief Contains all modrm_rm switch tables.
|
||||
* Indexed by the numeric value of the modrm_rm field.
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeModrmRm[][8];
|
||||
|
||||
/**
|
||||
* @brief Contains all mandatory-prefix switch tables.
|
||||
* Index values:
|
||||
* 0 = none
|
||||
* 1 = F2
|
||||
* 2 = F3
|
||||
* 3 = 66
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeMandatory[][4];
|
||||
|
||||
/**
|
||||
* @brief Contains all x87 opcode tables.
|
||||
* Indexed by the numeric value of the 6 lowest bits of the modrm byte (modrm_mod should
|
||||
* always be 11).
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeX87[][64];
|
||||
|
||||
/**
|
||||
* @brief Contains all address-size switch tables.
|
||||
* Index values:
|
||||
* 0 = 16
|
||||
* 1 = 32
|
||||
* 2 = 64
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeAddressSize[][3];
|
||||
|
||||
/**
|
||||
* @brief Contains all operand-size switch tables.
|
||||
* Index values:
|
||||
* 0 = 16
|
||||
* 1 = 32
|
||||
* 2 = 64
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeOperandSize[][3];
|
||||
|
||||
/**
|
||||
* @brief Contains all cpu-mode switch tables.
|
||||
* Index values:
|
||||
* 0 = [!= 64]
|
||||
* 1 = 64
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeMode[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all vendor switch tables.
|
||||
* Index values:
|
||||
* 0 = AMD
|
||||
* 1 = Intel
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeVendor[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all 3DNow! switch tables.
|
||||
* Indexed by the numeric value of the 3DNow! opcode.
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptree3dnow[][256];
|
||||
|
||||
/**
|
||||
* @brief Contains all vex switch tables.
|
||||
* Index values:
|
||||
* 0 = none
|
||||
* 1 = 0F
|
||||
* 2 = 0F38
|
||||
* 3 = 0F3A
|
||||
* 4 = 66
|
||||
* 5 = 66_0F
|
||||
* 6 = 66_0F38
|
||||
* 7 = 66_0F3A
|
||||
* 8 = F3
|
||||
* 9 = F3_0F
|
||||
* A = F3_0F38
|
||||
* B = F3_0F3A
|
||||
* C = F2
|
||||
* D = F2_0F
|
||||
* E = F2_0F38
|
||||
* F = F2_0F3A
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeVex[][16];
|
||||
|
||||
/**
|
||||
* @brief Contains all vex_w switch tables.
|
||||
* Indexed by the numeric value of the vex_w field.
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeVexW[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all vex_l switch tables.
|
||||
* Indexed by the numeric value of the vex_l field.
|
||||
*/
|
||||
extern const VXOpcodeTreeNode vxOptreeVexL[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all instruction definitions.
|
||||
*/
|
||||
extern const VXInstructionDefinition vxInstrDefinitions[];
|
||||
|
||||
/**
|
||||
* @brief Contains all instruction mnemonic strings.
|
||||
*/
|
||||
extern const char* vxInstrMnemonicStrings[];
|
||||
|
||||
/**
|
||||
* @brief Returns the type of the specified opcode tree node.
|
||||
* @param node The node.
|
||||
* @return The type of the specified opcode tree node.
|
||||
*/
|
||||
__inline VXOpcodeTreeNodeType VXGetOpcodeNodeType(VXOpcodeTreeNode node)
|
||||
{
|
||||
return (VXOpcodeTreeNodeType)((node >> 12) & 0x0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the value of the specified opcode tree node.
|
||||
* @param node The node.
|
||||
* @return The value of the specified opcode tree node.
|
||||
*/
|
||||
__inline uint16_t VXGetOpcodeNodeValue(VXOpcodeTreeNode node)
|
||||
{
|
||||
return (node & 0x0FFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the root node of the opcode tree.
|
||||
* @return The root node of the opcode tree.
|
||||
*/
|
||||
__inline VXOpcodeTreeNode VXGetOpcodeTreeRoot()
|
||||
{
|
||||
return 0x1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a child node of @c parent specified by @c index.
|
||||
* @param parent The parent node.
|
||||
* @param index The index of the child node to retrieve.
|
||||
* @return The specified child node.
|
||||
*/
|
||||
__inline VXOpcodeTreeNode VXGetOpcodeTreeChild(VXOpcodeTreeNode parent, uint16_t index)
|
||||
{
|
||||
VXOpcodeTreeNodeType nodeType = VXGetOpcodeNodeType(parent);
|
||||
uint16_t tableIndex = VXGetOpcodeNodeValue(parent);
|
||||
switch (nodeType)
|
||||
{
|
||||
case OTNT_TABLE:
|
||||
assert(index < 256);
|
||||
return vxOptreeTable[tableIndex][index];
|
||||
case OTNT_MODRM_MOD:
|
||||
assert(index < 2);
|
||||
return vxOptreeModrmMod[tableIndex][index];
|
||||
case OTNT_MODRM_REG:
|
||||
assert(index < 8);
|
||||
return vxOptreeModrmReg[tableIndex][index];
|
||||
case OTNT_MODRM_RM:
|
||||
assert(index < 8);
|
||||
return vxOptreeModrmRm[tableIndex][index];
|
||||
case OTNT_MANDATORY:
|
||||
assert(index < 4);
|
||||
return vxOptreeMandatory[tableIndex][index];
|
||||
case OTNT_X87:
|
||||
assert(index < 64);
|
||||
return vxOptreeX87[tableIndex][index];
|
||||
case OTNT_ADDRESS_SIZE:
|
||||
assert(index < 3);
|
||||
return vxOptreeAddressSize[tableIndex][index];
|
||||
case OTNT_OPERAND_SIZE:
|
||||
assert(index < 3);
|
||||
return vxOptreeOperandSize[tableIndex][index];
|
||||
case OTNT_MODE:
|
||||
assert(index < 2);
|
||||
return vxOptreeMode[tableIndex][index];
|
||||
case OTNT_VENDOR:
|
||||
assert(index < 3);
|
||||
return vxOptreeVendor[tableIndex][index];
|
||||
case OTNT_AMD3DNOW:
|
||||
assert(index < 256);
|
||||
return vxOptree3dnow[tableIndex][index];
|
||||
case OTNT_VEX:
|
||||
assert(index < 16);
|
||||
return vxOptreeVex[tableIndex][index];
|
||||
case OTNT_VEXW:
|
||||
assert(index < 2);
|
||||
return vxOptreeVexW[tableIndex][index];
|
||||
case OTNT_VEXL:
|
||||
assert(index < 2);
|
||||
return vxOptreeVexL[tableIndex][index];
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the instruction definition that is linked to the given @c node.
|
||||
* @param node The instruction definition node.
|
||||
* @return Pointer to the instruction definition.
|
||||
*/
|
||||
__inline const VXInstructionDefinition* VXGetInstructionDefinition(VXOpcodeTreeNode node)
|
||||
{
|
||||
assert(VXGetOpcodeNodeType(node) == OTNT_INSTRUCTION_DEFINITION);
|
||||
return &vxInstrDefinitions[node & 0x0FFF];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the specified instruction mnemonic string.
|
||||
* @param mnemonic The mnemonic.
|
||||
* @return The instruction mnemonic string.
|
||||
*/
|
||||
__inline const char* VXGetInstructionMnemonicString(VXInstructionMnemonic mnemonic)
|
||||
{
|
||||
return vxInstrMnemonicStrings[(uint16_t)mnemonic];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the numeric value for a simple operand size definition.
|
||||
* @param operandSize The defined operand size.
|
||||
* @return The the numeric value for the simple operand size definition.
|
||||
*/
|
||||
__inline uint16_t VXGetSimpleOperandSize(VXDefinedOperandSize operandSize)
|
||||
{
|
||||
static const uint16_t operandSizes[8] =
|
||||
{
|
||||
8, 16, 32, 64, 80, 12, 128, 256
|
||||
};
|
||||
|
||||
uint16_t index = operandSize - DOS_B;
|
||||
assert(index < 8);
|
||||
return operandSizes[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the memory-size part of a complex operand size definition.
|
||||
* @param operandSize The defined operand size.
|
||||
* @return The memory-size part of the operand size definition.
|
||||
*/
|
||||
__inline VXDefinedOperandSize VXGetComplexOperandMemSize(VXDefinedOperandSize operandSize)
|
||||
{
|
||||
return (VXDefinedOperandSize)(operandSize & 0x0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the register-size part of a complex operand size definition.
|
||||
* @param operandSize The defined operand size.
|
||||
* @return The register-size part of the operand size definition.
|
||||
*/
|
||||
__inline VXDefinedOperandSize VXGetComplexOperandRegSize(VXDefinedOperandSize operandSize)
|
||||
{
|
||||
return (VXDefinedOperandSize)((operandSize >> 4) & 0x0F);
|
||||
}
|
||||
|
||||
#endif // _VDE_VXOPCODETABLEINTERNAL_H_
|
|
@ -44,12 +44,14 @@ if (BUILD_C_BINDINGS)
|
|||
"Bindings/C/VXDisassemblerUtilsC.h"
|
||||
"Bindings/C/VXInstructionDecoderC.h"
|
||||
"Bindings/C/VXInstructionFormatterC.h"
|
||||
"Bindings/C/VXOpcodeTableC.h")
|
||||
"Bindings/C/VXOpcodeTableC.h"
|
||||
"Bindings/C/VXOpcodeTableInternalC.h"
|
||||
"Bindings/C/VXInternalHelpersC.h")
|
||||
set(vdec_sources
|
||||
"Bindings/C/VXDisassemblerUtilsC.cpp"
|
||||
"Bindings/C/VXInstructionFormatterC.cpp"
|
||||
"Bindings/C/VXOpcodeTableC.cpp"
|
||||
"Bindings/C/VXInstructionDecoderC.cpp")
|
||||
"Bindings/C/VXDisassemblerUtilsC.c"
|
||||
"Bindings/C/VXInstructionFormatterC.c"
|
||||
"Bindings/C/VXOpcodeTableC.c"
|
||||
"Bindings/C/VXInstructionDecoderC.c")
|
||||
add_library("VerteronDisassemblerEngineC" ${vdec_headers} ${vdec_sources})
|
||||
target_link_libraries("VerteronDisassemblerEngineC" "VerteronDisassemblerEngine")
|
||||
endif ()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue