mirror of https://github.com/x64dbg/zydis
Complete rewrite of the instruction-formatter
- Added hooking functionality to support custom instruction-formatting - Added FormatterHooks demo that demonstrates the hooking functionality InstructionEditor: - Fixed issues with still non-deterministic output on code-generation
This commit is contained in:
parent
03b4d69b08
commit
816bb570c7
|
@ -56,7 +56,6 @@ set(headers
|
||||||
"include/Zydis/Mnemonic.h"
|
"include/Zydis/Mnemonic.h"
|
||||||
"include/Zydis/Register.h"
|
"include/Zydis/Register.h"
|
||||||
"include/Zydis/Status.h"
|
"include/Zydis/Status.h"
|
||||||
"include/Zydis/SymbolResolver.h"
|
|
||||||
"include/Zydis/Utils.h"
|
"include/Zydis/Utils.h"
|
||||||
"include/Zydis/Zydis.h"
|
"include/Zydis/Zydis.h"
|
||||||
"include/Zydis/Internal/InstructionTable.h")
|
"include/Zydis/Internal/InstructionTable.h")
|
||||||
|
@ -97,11 +96,11 @@ endif ()
|
||||||
if (BUILD_EXAMPLES)
|
if (BUILD_EXAMPLES)
|
||||||
include_directories("include")
|
include_directories("include")
|
||||||
|
|
||||||
if (WIN32)
|
add_executable("FormatterHooks"
|
||||||
add_executable("ZydisPE" "examples/ZydisPE.c")
|
"examples/FormatterHooks.c"
|
||||||
target_link_libraries("ZydisPE" "Zydis")
|
"examples/FormatHelper.h")
|
||||||
set_target_properties ("ZydisPE" PROPERTIES FOLDER "Examples")
|
target_link_libraries("FormatterHooks" "Zydis")
|
||||||
endif ()
|
set_target_properties ("FormatterHooks" PROPERTIES FOLDER "Examples/Formatter")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
|
|
Binary file not shown.
|
@ -257,7 +257,6 @@ var
|
||||||
List: TList<TInstructionDefinition>;
|
List: TList<TInstructionDefinition>;
|
||||||
I, J: Integer;
|
I, J: Integer;
|
||||||
B: Boolean;
|
B: Boolean;
|
||||||
Comparison: TComparison<TInstructionDefinition>;
|
|
||||||
begin
|
begin
|
||||||
List := TList<TInstructionDefinition>.Create;
|
List := TList<TInstructionDefinition>.Create;
|
||||||
try
|
try
|
||||||
|
@ -279,12 +278,16 @@ begin
|
||||||
end;
|
end;
|
||||||
Work(I + 1);
|
Work(I + 1);
|
||||||
end;
|
end;
|
||||||
Comparison :=
|
// Sort definitions with a stable algorithm to ensure deterministic output
|
||||||
|
TListHelper<TInstructionDefinition>.BubbleSort(
|
||||||
|
List, TComparer<TInstructionDefinition>.Construct(
|
||||||
function(const Left, Right: TInstructionDefinition): Integer
|
function(const Left, Right: TInstructionDefinition): Integer
|
||||||
begin
|
begin
|
||||||
Result := CompareStr(Left.Mnemonic, Right.Mnemonic);
|
Result := CompareStr(Left.Mnemonic, Right.Mnemonic);
|
||||||
end;
|
if (Result = 0) then Result := Ord(Left.Encoding) - Ord(Right.Encoding);
|
||||||
List.Sort(TComparer<TInstructionDefinition>.Construct(Comparison));
|
if (Result = 0) then Result := Ord(Left.OpcodeMap) - Ord(Right.OpcodeMap);
|
||||||
|
if (Result = 0) then Result := Ord(Left.Opcode) - Ord(Right.Opcode);
|
||||||
|
end));
|
||||||
SetLength(DefinitionList, List.Count);
|
SetLength(DefinitionList, List.Count);
|
||||||
for I := 0 to List.Count - 1 do
|
for I := 0 to List.Count - 1 do
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Disassembler Engine (Zydis)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ZYDIS_FORMATHELPER_H
|
||||||
|
#define ZYDIS_FORMATHELPER_H
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <Zydis/Defines.h>
|
||||||
|
#include <Zydis/Status.h>
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Format helper functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
/* Enums and types */
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisStringBufferAppendMode datatype.
|
||||||
|
*/
|
||||||
|
typedef uint8_t ZydisStringBufferAppendMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Values that represent zydis string-buffer append-modes.
|
||||||
|
*/
|
||||||
|
enum ZydisStringBufferAppendModes
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Appends the string as it is.
|
||||||
|
*/
|
||||||
|
ZYDIS_STRBUF_APPEND_MODE_DEFAULT,
|
||||||
|
/**
|
||||||
|
* @brief Converts the string to lowercase characters.
|
||||||
|
*/
|
||||||
|
ZYDIS_STRBUF_APPEND_MODE_LOWERCASE,
|
||||||
|
/**
|
||||||
|
* @brief Converts the string to uppercase characters.
|
||||||
|
*/
|
||||||
|
ZYDIS_STRBUF_APPEND_MODE_UPPERCASE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Appends the @c text to the given @c buffer and increases the string-buffer pointer by
|
||||||
|
* the number of chars written.
|
||||||
|
*
|
||||||
|
* @param buffer A pointer to the string-buffer.
|
||||||
|
* @param bufferLen The length of the string-buffer.
|
||||||
|
* @param mode The append-mode.
|
||||||
|
* @param text The text to append.
|
||||||
|
*
|
||||||
|
* @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or
|
||||||
|
* @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not
|
||||||
|
* sufficient to append the given @c text.
|
||||||
|
*/
|
||||||
|
ZYDIS_INLINE ZydisStatus ZydisStringBufferAppend(char** buffer, size_t bufferLen,
|
||||||
|
ZydisStringBufferAppendMode mode, const char* text)
|
||||||
|
{
|
||||||
|
ZYDIS_ASSERT(buffer);
|
||||||
|
ZYDIS_ASSERT(bufferLen != 0);
|
||||||
|
ZYDIS_ASSERT(text);
|
||||||
|
|
||||||
|
size_t strLen = strlen(text);
|
||||||
|
if (strLen >= bufferLen)
|
||||||
|
{
|
||||||
|
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
strncpy(*buffer, text, strLen + 1);
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ZYDIS_STRBUF_APPEND_MODE_LOWERCASE:
|
||||||
|
for (size_t i = 0; i < strLen; ++i)
|
||||||
|
{
|
||||||
|
(*buffer[i]) = (char)tolower((*buffer)[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ZYDIS_STRBUF_APPEND_MODE_UPPERCASE:
|
||||||
|
for (size_t i = 0; i < strLen; ++i)
|
||||||
|
{
|
||||||
|
(*buffer)[i] = (char)toupper((*buffer)[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*buffer += strLen;
|
||||||
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Appends formatted text to the given @c buffer and increases the string-buffer pointer
|
||||||
|
* by the number of chars written.
|
||||||
|
*
|
||||||
|
* @param buffer A pointer to the string-buffer.
|
||||||
|
* @param bufferLen The length of the string-buffer.
|
||||||
|
* @param mode The append-mode.
|
||||||
|
* @param format The format string.
|
||||||
|
*
|
||||||
|
* @return @c ZYDIS_STATUS_SUCCESS, if the function succeeded, or
|
||||||
|
* @c ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE, if the size of the buffer was not
|
||||||
|
* sufficient to append the given text.
|
||||||
|
*/
|
||||||
|
ZYDIS_INLINE ZydisStatus ZydisStringBufferAppendFormat(char** buffer, size_t bufferLen,
|
||||||
|
ZydisStringBufferAppendMode mode, const char* format, ...)
|
||||||
|
{
|
||||||
|
ZYDIS_ASSERT(buffer);
|
||||||
|
ZYDIS_ASSERT(bufferLen != 0);
|
||||||
|
ZYDIS_ASSERT(format);
|
||||||
|
|
||||||
|
va_list arglist;
|
||||||
|
va_start(arglist, format);
|
||||||
|
int w = vsnprintf(*buffer, bufferLen, format, arglist);
|
||||||
|
if ((w < 0) || ((size_t)w >= bufferLen))
|
||||||
|
{
|
||||||
|
va_end(arglist);
|
||||||
|
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case ZYDIS_STRBUF_APPEND_MODE_LOWERCASE:
|
||||||
|
for (size_t i = 0; i < (size_t)w; ++i)
|
||||||
|
{
|
||||||
|
(*buffer)[i] = (char)tolower((*buffer)[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ZYDIS_STRBUF_APPEND_MODE_UPPERCASE:
|
||||||
|
for (size_t i = 0; i < (size_t)w; ++i)
|
||||||
|
{
|
||||||
|
(*buffer)[i] = (char)toupper((*buffer)[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*buffer += (size_t)w;
|
||||||
|
va_end(arglist);
|
||||||
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif /* ZYDIS_FORMATHELPER_H */
|
|
@ -0,0 +1,242 @@
|
||||||
|
/***************************************************************************************************
|
||||||
|
|
||||||
|
Zyan Disassembler Engine (Zydis)
|
||||||
|
|
||||||
|
Original Author : Florian Bernd
|
||||||
|
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Demonstrates the hooking functionality of the @c ZydisInstructionFormatter class.
|
||||||
|
*
|
||||||
|
* This example demonstrates the hooking functionality of the @c ZydisInstructionFormatter class by
|
||||||
|
* rewriting the mnemonics of (V)CMPPS and (V)CMPPD to their corresponding alias-forms (based on
|
||||||
|
* the condition encoded in the immediate operand).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <Zydis/Zydis.h>
|
||||||
|
#include "FormatHelper.h"
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Static data */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Static array with the condition-code strings.
|
||||||
|
*/
|
||||||
|
static const char* conditionCodeStrings[0x20] =
|
||||||
|
{
|
||||||
|
"eq",
|
||||||
|
"lt",
|
||||||
|
"le",
|
||||||
|
"unord",
|
||||||
|
"neq",
|
||||||
|
"nlt",
|
||||||
|
"nle",
|
||||||
|
"ord",
|
||||||
|
"eq_uq",
|
||||||
|
"nge",
|
||||||
|
"ngt",
|
||||||
|
"false",
|
||||||
|
"oq",
|
||||||
|
"ge",
|
||||||
|
"gt",
|
||||||
|
"true",
|
||||||
|
"eq_os",
|
||||||
|
"lt_oq",
|
||||||
|
"le_oq",
|
||||||
|
"unord_s",
|
||||||
|
"neq_us",
|
||||||
|
"nlt_uq",
|
||||||
|
"nle_uq",
|
||||||
|
"ord_s",
|
||||||
|
"eq_us",
|
||||||
|
"nge_uq",
|
||||||
|
"ngt_uq",
|
||||||
|
"false_os",
|
||||||
|
"neq_os",
|
||||||
|
"ge_oq",
|
||||||
|
"gt_oq",
|
||||||
|
"true_us"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Hook callbacks */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
ZydisFormatterFormatFunc defaultPrintMnemonic;
|
||||||
|
|
||||||
|
static ZydisStatus ZydisFormatterPrintMnemonic(ZydisInstructionFormatter* formatter,
|
||||||
|
char** buffer, size_t bufferLen, ZydisInstructionInfo* info)
|
||||||
|
{
|
||||||
|
// We use the user-data field of the instruction-info to pass data to the
|
||||||
|
// @c ZydisFormatterFormatOperandImm function.
|
||||||
|
// In this case we are using a simple ordinal value, but you could pass a pointer to a
|
||||||
|
// complex datatype as well.
|
||||||
|
info->userData = (void*)1;
|
||||||
|
|
||||||
|
// Rewrite the instruction-mnemonic for the given instructions
|
||||||
|
if ((info->operandCount == 3) && (info->operand[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
|
||||||
|
{
|
||||||
|
uint8_t conditionCode = info->operand[2].imm.value.ubyte;
|
||||||
|
if (conditionCode < 0x08)
|
||||||
|
{
|
||||||
|
switch (info->mnemonic)
|
||||||
|
{
|
||||||
|
case ZYDIS_MNEMONIC_CMPPS:
|
||||||
|
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||||
|
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%sps",
|
||||||
|
conditionCodeStrings[conditionCode]);
|
||||||
|
case ZYDIS_MNEMONIC_CMPPD:
|
||||||
|
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||||
|
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%spd",
|
||||||
|
conditionCodeStrings[conditionCode]);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((info->operandCount == 4) && (info->operand[3].type == ZYDIS_OPERAND_TYPE_IMMEDIATE))
|
||||||
|
{
|
||||||
|
uint8_t conditionCode = info->operand[3].imm.value.ubyte;
|
||||||
|
if (conditionCode < 0x20)
|
||||||
|
{
|
||||||
|
switch (info->mnemonic)
|
||||||
|
{
|
||||||
|
case ZYDIS_MNEMONIC_VCMPPS:
|
||||||
|
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||||
|
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%sps",
|
||||||
|
conditionCodeStrings[conditionCode]);
|
||||||
|
case ZYDIS_MNEMONIC_VCMPPD:
|
||||||
|
return ZydisStringBufferAppendFormat(buffer, bufferLen,
|
||||||
|
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%spd",
|
||||||
|
conditionCodeStrings[conditionCode]);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We did not rewrite the instruction-mnemonic. Signal the @c ZydisFormatterFormatOperandImm
|
||||||
|
// function not to omit the operand
|
||||||
|
info->userData = (void*)0;
|
||||||
|
|
||||||
|
// Default mnemonic printing
|
||||||
|
return defaultPrintMnemonic(formatter, buffer, bufferLen, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ZydisFormatterFormatOperandFunc defaultFormatOperandImm;
|
||||||
|
|
||||||
|
static ZydisStatus ZydisFormatterFormatOperandImm(ZydisInstructionFormatter* formatter,
|
||||||
|
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand)
|
||||||
|
{
|
||||||
|
// The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code)
|
||||||
|
// operand, because it got replaced by the alias-mnemonic
|
||||||
|
if ((int)info->userData == 1)
|
||||||
|
{
|
||||||
|
// The formatter will automatically omit the operand, if the buffer remains unchanged
|
||||||
|
// after the callback returns
|
||||||
|
return ZYDIS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default immediate formatting
|
||||||
|
return defaultFormatOperandImm(formatter, buffer, bufferLen, info, operand);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Helper functions */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
void disassembleBuffer(uint8_t* data, size_t length, bool installHooks)
|
||||||
|
{
|
||||||
|
ZydisMemoryInput input;
|
||||||
|
ZydisInputInitMemoryInput(&input, data, length);
|
||||||
|
|
||||||
|
ZydisInstructionDecoder decoder;
|
||||||
|
ZydisDecoderInitInstructionDecoderEx(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT,
|
||||||
|
(ZydisCustomInput*)&input, ZYDIS_DECODER_FLAG_SKIP_DATA);
|
||||||
|
ZydisDecoderSetInstructionPointer(&decoder, 0x007FFFFFFF400000);
|
||||||
|
|
||||||
|
ZydisInstructionFormatter formatter;
|
||||||
|
ZydisFormatterInitInstructionFormatterEx(&formatter, ZYDIS_FORMATTER_STYLE_INTEL,
|
||||||
|
ZYDIS_FMTFLAG_FORCE_SEGMENTS | ZYDIS_FMTFLAG_FORCE_OPERANDSIZE,
|
||||||
|
ZYDIS_FORMATTER_ADDR_ABSOLUTE, ZYDIS_FORMATTER_DISP_DEFAULT, ZYDIS_FORMATTER_IMM_DEFAULT);
|
||||||
|
|
||||||
|
if (installHooks)
|
||||||
|
{
|
||||||
|
defaultPrintMnemonic = &ZydisFormatterPrintMnemonic;
|
||||||
|
ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC,
|
||||||
|
(const void**)&defaultPrintMnemonic);
|
||||||
|
defaultFormatOperandImm = &ZydisFormatterFormatOperandImm;
|
||||||
|
ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
|
||||||
|
(const void**)&defaultFormatOperandImm);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZydisInstructionInfo info;
|
||||||
|
char buffer[256];
|
||||||
|
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
|
||||||
|
{
|
||||||
|
printf("%016llX ", info.instrAddress);
|
||||||
|
if (info.instrFlags & ZYDIS_INSTRFLAG_ERROR_MASK)
|
||||||
|
{
|
||||||
|
printf(" db %02x\n", info.data[0]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ZydisFormatterFormatInstruction(&formatter, &info, &buffer[0], sizeof(buffer));
|
||||||
|
printf(" %s\n", &buffer[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
||||||
|
/* Entry point */
|
||||||
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t data[] =
|
||||||
|
{
|
||||||
|
// cmpps xmm1, xmm4, 0x03
|
||||||
|
0x0F, 0xC2, 0xCC, 0x03,
|
||||||
|
|
||||||
|
// vcmpord_spd xmm1, xmm2, xmm3
|
||||||
|
0xC5, 0xE9, 0xC2, 0xCB, 0x17,
|
||||||
|
|
||||||
|
// vcmpps k2 {k7}, zmm2, dword ptr ds:[rax + rbx*4 + 0x100] {1to16}, 0x0F
|
||||||
|
0x62, 0xF1, 0x6C, 0x5F, 0xC2, 0x54, 0x98, 0x40, 0x0F
|
||||||
|
};
|
||||||
|
|
||||||
|
disassembleBuffer(&data[0], sizeof(data), false);
|
||||||
|
puts("");
|
||||||
|
disassembleBuffer(&data[0], sizeof(data), true);
|
||||||
|
|
||||||
|
getchar();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ============================================================================================== */
|
|
@ -207,6 +207,8 @@ ZYDIS_EXPORT ZydisStatus ZydisDecoderGetDecoderInput(const ZydisInstructionDecod
|
||||||
* @param input A pointer to the new input data-source.
|
* @param input A pointer to the new input data-source.
|
||||||
*
|
*
|
||||||
* @return A zydis status code.
|
* @return A zydis status code.
|
||||||
|
*
|
||||||
|
* This function flushes the internal input-buffer.
|
||||||
*/
|
*/
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisDecoderSetDecoderInput(ZydisInstructionDecoder* decoder,
|
ZYDIS_EXPORT ZydisStatus ZydisDecoderSetDecoderInput(ZydisInstructionDecoder* decoder,
|
||||||
ZydisCustomInput* input);
|
ZydisCustomInput* input);
|
||||||
|
@ -264,7 +266,7 @@ ZYDIS_EXPORT ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecod
|
||||||
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details
|
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details
|
||||||
* about the decoded instruction.
|
* about the decoded instruction.
|
||||||
*
|
*
|
||||||
* @return A zydis status code.
|
* @return A zydis status code.
|
||||||
*/
|
*/
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
|
ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
|
||||||
ZydisInstructionInfo* info);
|
ZydisInstructionInfo* info);
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include <Zydis/Defines.h>
|
#include <Zydis/Defines.h>
|
||||||
#include <Zydis/Status.h>
|
#include <Zydis/Status.h>
|
||||||
#include <Zydis/InstructionInfo.h>
|
#include <Zydis/InstructionInfo.h>
|
||||||
#include <Zydis/SymbolResolver.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -57,16 +56,28 @@ enum ZydisFormatterStyles
|
||||||
ZYDIS_FORMATTER_STYLE_INTEL
|
ZYDIS_FORMATTER_STYLE_INTEL
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
* @brief Defines the @c ZydisFormatterFlags datatype.
|
|
||||||
*/
|
|
||||||
typedef uint8_t ZydisFormatterFlags;
|
|
||||||
|
|
||||||
#define ZYDIS_FORMATTER_FLAG_UPPERCASE 0x01
|
/**
|
||||||
#define ZYDIS_FORMATTER_FLAG_TAB_AFTER_MNEMONIC 0x02
|
* @brief Defines the @c ZydisFormatFlags datatype.
|
||||||
#define ZYDIS_FORMATTER_FLAG_NO_SPACE_BETWEEN_OPERANDS 0x04
|
*/
|
||||||
#define ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SIZE 0x08
|
typedef uint32_t ZydisFormatFlags;
|
||||||
#define ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT 0x10
|
|
||||||
|
/**
|
||||||
|
* @brief Formats the instruction in uppercase instead of lowercase.
|
||||||
|
*/
|
||||||
|
#define ZYDIS_FMTFLAG_UPPERCASE 0x00000001
|
||||||
|
/**
|
||||||
|
* @brief Forces the formatter to always print the segment register of memory-operands, instead
|
||||||
|
* of ommiting implicit DS/SS segments.
|
||||||
|
*/
|
||||||
|
#define ZYDIS_FMTFLAG_FORCE_SEGMENTS 0x00000002
|
||||||
|
/**
|
||||||
|
* @brief Forces the formatter to always print the size of memory-operands.
|
||||||
|
*/
|
||||||
|
#define ZYDIS_FMTFLAG_FORCE_OPERANDSIZE 0x00000004
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisFormatterAddressFormat datatype.
|
* @brief Defines the @c ZydisFormatterAddressFormat datatype.
|
||||||
|
@ -78,6 +89,9 @@ typedef uint8_t ZydisFormatterAddressFormat;
|
||||||
*/
|
*/
|
||||||
enum ZydisFormatterAddressFormat
|
enum ZydisFormatterAddressFormat
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @brief Currently defaults to @c ZYDIS_FORMATTER_ADDR_ABSOLUTE.
|
||||||
|
*/
|
||||||
ZYDIS_FORMATTER_ADDR_DEFAULT,
|
ZYDIS_FORMATTER_ADDR_DEFAULT,
|
||||||
/**
|
/**
|
||||||
* @brief Displays absolute addresses instead of relative ones.
|
* @brief Displays absolute addresses instead of relative ones.
|
||||||
|
@ -101,6 +115,8 @@ enum ZydisFormatterAddressFormat
|
||||||
ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED,
|
ZYDIS_FORMATTER_ADDR_RELATIVE_UNSIGNED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisFormatterDisplacementFormat datatype.
|
* @brief Defines the @c ZydisFormatterDisplacementFormat datatype.
|
||||||
*/
|
*/
|
||||||
|
@ -111,6 +127,9 @@ typedef uint8_t ZydisFormatterDisplacementFormat;
|
||||||
*/
|
*/
|
||||||
enum ZydisFormatterDisplacementFormats
|
enum ZydisFormatterDisplacementFormats
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @brief Currently defaults to @c ZYDIS_FORMATTER_DISP_HEX_SIGNED.
|
||||||
|
*/
|
||||||
ZYDIS_FORMATTER_DISP_DEFAULT,
|
ZYDIS_FORMATTER_DISP_DEFAULT,
|
||||||
/**
|
/**
|
||||||
* @brief Formats displacements as signed hexadecimal values.
|
* @brief Formats displacements as signed hexadecimal values.
|
||||||
|
@ -130,6 +149,8 @@ enum ZydisFormatterDisplacementFormats
|
||||||
ZYDIS_FORMATTER_DISP_HEX_UNSIGNED
|
ZYDIS_FORMATTER_DISP_HEX_UNSIGNED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisFormatterImmediateFormat datatype.
|
* @brief Defines the @c ZydisFormatterImmediateFormat datatype.
|
||||||
*/
|
*/
|
||||||
|
@ -140,7 +161,15 @@ typedef uint8_t ZydisFormatterImmediateFormat;
|
||||||
*/
|
*/
|
||||||
enum ZydisFormatterImmediateFormats
|
enum ZydisFormatterImmediateFormats
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @brief Currently defaults to @c ZYDIS_FORMATTER_IMM_HEX_UNSIGNED.
|
||||||
|
*/
|
||||||
ZYDIS_FORMATTER_IMM_DEFAULT,
|
ZYDIS_FORMATTER_IMM_DEFAULT,
|
||||||
|
/**
|
||||||
|
* @brief Automatically chooses the most suitable formatting-mode based on the operands
|
||||||
|
* @c ZydisOperandInfo.imm.isSigned attribute.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_IMM_HEX_AUTO,
|
||||||
/**
|
/**
|
||||||
* @brief Formats immediates as signed hexadecimal values.
|
* @brief Formats immediates as signed hexadecimal values.
|
||||||
*
|
*
|
||||||
|
@ -159,6 +188,8 @@ enum ZydisFormatterImmediateFormats
|
||||||
ZYDIS_FORMATTER_IMM_HEX_UNSIGNED
|
ZYDIS_FORMATTER_IMM_HEX_UNSIGNED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisFormatterHookType datatype.
|
* @brief Defines the @c ZydisFormatterHookType datatype.
|
||||||
*/
|
*/
|
||||||
|
@ -170,53 +201,199 @@ typedef uint8_t ZydisFormatterHookType;
|
||||||
enum ZydisFormatterHookTypes
|
enum ZydisFormatterHookTypes
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief This hook is called right
|
* @brief This function is called before the formatter starts formatting an instruction.
|
||||||
*/
|
*/
|
||||||
ZYDIS_FORMATTER_HOOK_PRE,
|
ZYDIS_FORMATTER_HOOK_PRE,
|
||||||
|
/**
|
||||||
|
* @brief This function is called before the formatter finished formatting an instruction.
|
||||||
|
*/
|
||||||
ZYDIS_FORMATTER_HOOK_POST,
|
ZYDIS_FORMATTER_HOOK_POST,
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_MNEMONIC,
|
/**
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND,
|
* @brief This function refers to the main formatting function, that internally calls all
|
||||||
|
* other function except the ones that are hooked by @c ZYDIS_FORMATTER_HOOK_PRE and
|
||||||
|
* @c ZYDIS_FORMATTER_HOOK_POST.
|
||||||
|
*
|
||||||
|
* Replacing this function allows for complete custom formatting, but indirectly disables all
|
||||||
|
* other hooks except for @c ZYDIS_FORMATTER_HOOK_PRE and @c ZYDIS_FORMATTER_HOOK_POST.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION,
|
||||||
|
/**
|
||||||
|
* @brief This function is called to print the instruction prefixes.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES,
|
||||||
|
/**
|
||||||
|
* @brief This function is called to print the instruction mnemonic.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC,
|
||||||
|
/**
|
||||||
|
* @brief This function is called to format an register operand.
|
||||||
|
*/
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG,
|
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG,
|
||||||
|
/**
|
||||||
|
* @brief This function is called to format an memory operand.
|
||||||
|
*
|
||||||
|
* Replacing this function might indirectly disable some specific calls to the
|
||||||
|
* @c ZYDIS_FORMATTER_PRINT_ADDRESS function.
|
||||||
|
*/
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM,
|
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM,
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
|
/**
|
||||||
|
* @brief This function is called to format an pointer operand.
|
||||||
|
*/
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR,
|
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR,
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_ADDRESS_ABS,
|
/**
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_ADDRESS_REL,
|
* @brief This function is called to format an immediate operand.
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_DISPLACEMENT,
|
*
|
||||||
ZYDIS_FORMATTER_HOOK_FORMAT_IMMEDIATE
|
* Replacing this function might indirectly disable some specific calls to the
|
||||||
|
* @c ZYDIS_FORMATTER_PRINT_ADDRESS function.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
|
||||||
|
/**
|
||||||
|
* @brief This function is called right before formatting an memory operand to print the
|
||||||
|
* optional size-specifier.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE,
|
||||||
|
/**
|
||||||
|
* @brief This function is called right after formatting an operand to print the optional
|
||||||
|
* avx-512 operand decorator.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR,
|
||||||
|
/**
|
||||||
|
* @brief This function is called to print an absolute address.
|
||||||
|
*/
|
||||||
|
ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef const char* (*ZydisFormatterHookFormatMnemonicFunc)(void* context,
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint64_t address,
|
|
||||||
int64_t* offset);
|
typedef struct ZydisInstructionFormatter_ ZydisInstructionFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisFormatterNotifyFunc function pointer.
|
||||||
|
*
|
||||||
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
|
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||||
|
*
|
||||||
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
|
* formatting process to fail.
|
||||||
|
*
|
||||||
|
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRE and
|
||||||
|
* @c ZYDIS_FORMATTER_HOOK_POST hook-types.
|
||||||
|
*/
|
||||||
|
typedef ZydisStatus (*ZydisFormatterNotifyFunc)(ZydisInstructionFormatter* fornatter,
|
||||||
|
ZydisInstructionInfo* info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisFormatterFormatFunc function pointer.
|
||||||
|
*
|
||||||
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
|
* @param buffer A pointer to the string-buffer.
|
||||||
|
* @param bufferLen The length of the string-buffer.
|
||||||
|
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||||
|
*
|
||||||
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
|
* formatting process to fail.
|
||||||
|
*
|
||||||
|
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
|
||||||
|
* number of chars written. Not increasing the buffer-pointer will cause unexpected behavior.
|
||||||
|
*
|
||||||
|
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_INSTRUCTION,
|
||||||
|
* @c ZYDIS_FORMATTER_HOOK_PRINT_PREFIXES and @c ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC hook-types.
|
||||||
|
*/
|
||||||
|
typedef ZydisStatus (*ZydisFormatterFormatFunc)(ZydisInstructionFormatter* fornatter,
|
||||||
|
char** buffer, size_t bufferLen, ZydisInstructionInfo* info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisFormatterFormatOperandFunc function pointer.
|
||||||
|
*
|
||||||
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
|
* @param buffer A pointer to the string-buffer.
|
||||||
|
* @param bufferLen The length of the string-buffer.
|
||||||
|
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||||
|
* @param operand A pointer to the @c ZydisOperandInfo struct.
|
||||||
|
*
|
||||||
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
|
* formatting process to fail.
|
||||||
|
*
|
||||||
|
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
|
||||||
|
* number of chars written.
|
||||||
|
*
|
||||||
|
* Returning @c ZYDIS_STATUS_SUCCESS in one of the @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_X hooks
|
||||||
|
* without increasing the buffer-pointer is valid and will cause the formatter to omit the current
|
||||||
|
* operand.
|
||||||
|
*
|
||||||
|
* Returning @c ZYDIS_STATUS_SUCCESS in @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE or
|
||||||
|
* @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR without increasing the buffer-pointer is valid and
|
||||||
|
* signals that no operand-size or decorator should be printed for the current operand.
|
||||||
|
*
|
||||||
|
* Not increasing the buffer-pointer for any other hook-type will cause unexpected behavior.
|
||||||
|
*
|
||||||
|
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_REG,
|
||||||
|
* @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_MEM, @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_PTR,
|
||||||
|
* @c ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM, @c ZYDIS_FORMATTER_HOOK_PRINT_OPERANDSIZE and
|
||||||
|
* @c ZYDIS_FORMATTER_HOOK_PRINT_DECORATOR hook-types.
|
||||||
|
*/
|
||||||
|
typedef ZydisStatus (*ZydisFormatterFormatOperandFunc)(ZydisInstructionFormatter* fornatter,
|
||||||
|
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Defines the @c ZydisFormatterFormatAddressFunc function pointer.
|
||||||
|
*
|
||||||
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
|
* @param buffer A pointer to the string-buffer.
|
||||||
|
* @param bufferLen The length of the string-buffer.
|
||||||
|
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||||
|
* @param operand A pointer to the @c ZydisOperandInfo struct.
|
||||||
|
*
|
||||||
|
* @return Returning a status code other than @c ZYDIS_STATUS_SUCCESS will immediately cause the
|
||||||
|
* formatting process to fail.
|
||||||
|
*
|
||||||
|
* After appending text to the @c buffer you MUST increase the buffer-pointer by the size of the
|
||||||
|
* number of chars written.
|
||||||
|
* Not increasing the buffer-pointer will cause unexpected behavior.
|
||||||
|
*
|
||||||
|
* This function type is used for the @c ZYDIS_FORMATTER_HOOK_PRINT_ADDRESS hook-type.
|
||||||
|
*/
|
||||||
|
typedef ZydisStatus (*ZydisFormatterFormatAddressFunc)(ZydisInstructionFormatter* fornatter,
|
||||||
|
char** buffer, size_t bufferLen, ZydisInstructionInfo* info, ZydisOperandInfo* operand,
|
||||||
|
uint64_t address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisInstructionFormatter struct.
|
* @brief Defines the @c ZydisInstructionFormatter struct.
|
||||||
*/
|
*/
|
||||||
typedef struct ZydisInstructionFormatter_
|
typedef struct ZydisInstructionFormatter_
|
||||||
{
|
{
|
||||||
ZydisFormatterStyle style;
|
ZydisFormatFlags flags;
|
||||||
ZydisFormatterFlags flags;
|
|
||||||
ZydisFormatterAddressFormat addressFormat;
|
ZydisFormatterAddressFormat addressFormat;
|
||||||
ZydisFormatterDisplacementFormat displacementFormat;
|
ZydisFormatterDisplacementFormat displacementFormat;
|
||||||
ZydisFormatterImmediateFormat immediateFormat;
|
ZydisFormatterImmediateFormat immediateFormat;
|
||||||
ZydisCustomSymbolResolver* symbolResolver;
|
ZydisFormatterNotifyFunc funcPre;
|
||||||
|
ZydisFormatterNotifyFunc funcPost;
|
||||||
|
ZydisFormatterFormatFunc funcFormatInstruction;
|
||||||
|
ZydisFormatterFormatFunc funcPrintPrefixes;
|
||||||
|
ZydisFormatterFormatFunc funcPrintMnemonic;
|
||||||
|
ZydisFormatterFormatOperandFunc funcFormatOperandReg;
|
||||||
|
ZydisFormatterFormatOperandFunc funcFormatOperandMem;
|
||||||
|
ZydisFormatterFormatOperandFunc funcFormatOperandPtr;
|
||||||
|
ZydisFormatterFormatOperandFunc funcFormatOperandImm;
|
||||||
|
ZydisFormatterFormatOperandFunc funcPrintOperandSize;
|
||||||
|
ZydisFormatterFormatOperandFunc funcPrintDecorator;
|
||||||
|
ZydisFormatterFormatAddressFunc funcPrintAddress;
|
||||||
|
const char* prefixHEX;
|
||||||
|
const char* prefixOCT;
|
||||||
|
const char* delimMnemonic;
|
||||||
|
const char* delimOperands;
|
||||||
|
const char* fmtDecorator; // TODO:
|
||||||
} ZydisInstructionFormatter;
|
} ZydisInstructionFormatter;
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Exported functions */
|
/* Exported functions */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
/* Basic functions */
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the given @c ZydisInstructionFormatter instance.
|
* @brief Initializes the given @c ZydisInstructionFormatter instance.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the instruction-formatter instance.
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
* @param style The formatter style to use.
|
* @param style The formatter style.
|
||||||
*
|
*
|
||||||
* @return A zydis status code.
|
* @return A zydis status code.
|
||||||
*/
|
*/
|
||||||
|
@ -226,69 +403,45 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterInitInstructionFormatter(
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the given @c ZydisInstructionFormatter instance.
|
* @brief Initializes the given @c ZydisInstructionFormatter instance.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the instruction-formatter instance.
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
* @param style The formatter style to use.
|
* @param style The formatter style.
|
||||||
* @param flags Additional formatter-flags.
|
* @param addressFormat The address format.
|
||||||
|
* @param displacementFormat The displacement format.
|
||||||
|
* @param immmediateFormat The immediate format.
|
||||||
*
|
*
|
||||||
* @return A zydis status code.
|
* @return A zydis status code.
|
||||||
*/
|
*/
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterInitInstructionFormatterEx(
|
ZYDIS_EXPORT ZydisStatus ZydisFormatterInitInstructionFormatterEx(
|
||||||
ZydisInstructionFormatter* formatter, ZydisFormatterStyle style, ZydisFormatterFlags flags);
|
ZydisInstructionFormatter* formatter, ZydisFormatterStyle style, ZydisFormatFlags flags,
|
||||||
|
ZydisFormatterAddressFormat addressFormat, ZydisFormatterDisplacementFormat displacementFormat,
|
||||||
|
ZydisFormatterImmediateFormat immmediateFormat);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the symbol-resolver assigned to the given instruction-formatter instance.
|
* @brief TODO:
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the instruction-formatter instance.
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
* @param symbolResolver A pointer to the memory that receives the current symbol-resolver
|
* @param hook The formatter hook-type.
|
||||||
* pointer.
|
* @param callback TODO: In Out
|
||||||
*
|
*
|
||||||
* @return A zydis status code.
|
* @return A zydis status code.
|
||||||
*/
|
*/
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterGetSymbolResolver(
|
|
||||||
const ZydisInstructionFormatter* formatter, ZydisCustomSymbolResolver** symbolResolver);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Changes the symbol-resolver of the given instruction-formatter instance.
|
|
||||||
*
|
|
||||||
* @param formatter A pointer to the instruction-formatter instance.
|
|
||||||
* @param symbolResolver A pointer to the new symbol-resolver instance.
|
|
||||||
*
|
|
||||||
* @return The ZydisStatus.
|
|
||||||
*/
|
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetSymbolResolver(
|
|
||||||
ZydisInstructionFormatter* formatter, ZydisCustomSymbolResolver* symbolResolver);
|
|
||||||
|
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter,
|
ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisInstructionFormatter* formatter,
|
||||||
ZydisFormatterHookType hook, const void* callback);
|
ZydisFormatterHookType hook, const void** callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Formats the given instruction and writes it into the output buffer.
|
* @brief Formats the given instruction and writes it into the output buffer.
|
||||||
*
|
*
|
||||||
* @param formatter A pointer to the instruction-formatter instance.
|
* @param formatter A pointer to the @c ZydisInstructionFormatter instance.
|
||||||
* @param info A pointer to the instruction-info struct.
|
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||||
* @param buffer A pointer to the output buffer.
|
* @param buffer A pointer to the string-buffer buffer.
|
||||||
* @param bufferLen The length of the output buffer.
|
* @param bufferLen The length of the string-buffer.
|
||||||
*
|
*
|
||||||
* @return A zydis status code.
|
* @return A zydis status code.
|
||||||
*/
|
*/
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(
|
ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(
|
||||||
ZydisInstructionFormatter* formatter, const ZydisInstructionInfo* info, char* buffer,
|
ZydisInstructionFormatter* formatter, ZydisInstructionInfo* info, char* buffer,
|
||||||
size_t bufferLen);
|
size_t bufferLen);
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
/* Formatting functions for custom implementations */
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatOperandIntel(
|
|
||||||
const ZydisInstructionFormatter* formatter, char* buffer, size_t bufferLen, size_t* offset,
|
|
||||||
const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint16_t typecast);
|
|
||||||
|
|
||||||
ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatOperandMemIntel(
|
|
||||||
const ZydisInstructionFormatter* formatter, char* buffer, size_t bufferLen, size_t* offset,
|
|
||||||
const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint16_t typecast);
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -45,16 +45,22 @@ extern "C" {
|
||||||
/* Enums and types */
|
/* Enums and types */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
typedef struct ZydisCustomInput_ ZydisCustomInput;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the @c ZydisInputNextFunc function pointer used in the @c ZydisCustomInput
|
* @brief Defines the @c ZydisInputNextFunc function pointer used in the @c ZydisCustomInput
|
||||||
* struct.
|
* struct.
|
||||||
*
|
*
|
||||||
|
* @param input The @c ZydisCustomInput instance.
|
||||||
|
* @param data A pointer to the memory that receives the input byte.
|
||||||
|
*
|
||||||
|
* @return Return @c TRUE, fi the function succeeded or @c FALSE, if the input data-source has no
|
||||||
|
* more data available
|
||||||
|
*
|
||||||
* This function should return the byte at the current input-position and increase the position
|
* This function should return the byte at the current input-position and increase the position
|
||||||
* by one. If the input data-source has no more data available, return @c FALSE.
|
* by one.
|
||||||
*/
|
*/
|
||||||
typedef bool (*ZydisInputNextFunc)(void* context, uint8_t* data);
|
typedef bool (*ZydisInputNextFunc)(ZydisCustomInput* input, uint8_t* data);
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines the zydis custom input struct.
|
* @brief Defines the zydis custom input struct.
|
||||||
|
@ -64,7 +70,7 @@ typedef struct ZydisCustomInput_
|
||||||
/**
|
/**
|
||||||
* @brief The @c ZydisInputNextFunc callback.
|
* @brief The @c ZydisInputNextFunc callback.
|
||||||
*/
|
*/
|
||||||
ZydisInputNextFunc inputNext;
|
ZydisInputNextFunc inputNext;
|
||||||
} ZydisCustomInput;
|
} ZydisCustomInput;
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
@ -90,11 +96,11 @@ typedef struct ZydisMemoryInput_
|
||||||
*/
|
*/
|
||||||
ZydisCustomInput input;
|
ZydisCustomInput input;
|
||||||
/**
|
/**
|
||||||
* @brief A pointer to the mem buffer.
|
* @brief A pointer to the memory buffer.
|
||||||
*/
|
*/
|
||||||
const uint8_t* inputBuffer;
|
const uint8_t* inputBuffer;
|
||||||
/**
|
/**
|
||||||
* @brief The length of the mem buffer.
|
* @brief The length of the memory buffer.
|
||||||
*/
|
*/
|
||||||
uint64_t inputBufferLen;
|
uint64_t inputBufferLen;
|
||||||
/**
|
/**
|
||||||
|
@ -111,8 +117,8 @@ typedef struct ZydisMemoryInput_
|
||||||
* @brief Initializes the given @c ZydisMemoryInput instance.
|
* @brief Initializes the given @c ZydisMemoryInput instance.
|
||||||
*
|
*
|
||||||
* @param input A pointer to the input data-source instance.
|
* @param input A pointer to the input data-source instance.
|
||||||
* @param buffer The mem buffer to use.
|
* @param buffer The memory buffer to use.
|
||||||
* @param length The length of the mem buffer.
|
* @param length The length of the memory buffer.
|
||||||
*
|
*
|
||||||
* @return A zydis status code.
|
* @return A zydis status code.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -592,6 +592,10 @@ enum ZydisAVXRoundingModes // TODO: Mirror "real" values from doc
|
||||||
*/
|
*/
|
||||||
typedef struct ZydisOperandInfo_
|
typedef struct ZydisOperandInfo_
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @brief The operand-id.
|
||||||
|
*/
|
||||||
|
uint8_t id;
|
||||||
/**
|
/**
|
||||||
* @brief The type of the operand.
|
* @brief The type of the operand.
|
||||||
*/
|
*/
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -538,8 +538,8 @@
|
||||||
#define /*0219*/ ZYDIS_MNEMONIC_PMULLW 0x0219
|
#define /*0219*/ ZYDIS_MNEMONIC_PMULLW 0x0219
|
||||||
#define /*021A*/ ZYDIS_MNEMONIC_PMULUDQ 0x021A
|
#define /*021A*/ ZYDIS_MNEMONIC_PMULUDQ 0x021A
|
||||||
#define /*021B*/ ZYDIS_MNEMONIC_POP 0x021B
|
#define /*021B*/ ZYDIS_MNEMONIC_POP 0x021B
|
||||||
#define /*021C*/ ZYDIS_MNEMONIC_POPAL 0x021C
|
#define /*021C*/ ZYDIS_MNEMONIC_POPA 0x021C
|
||||||
#define /*021D*/ ZYDIS_MNEMONIC_POPAW 0x021D
|
#define /*021D*/ ZYDIS_MNEMONIC_POPAD 0x021D
|
||||||
#define /*021E*/ ZYDIS_MNEMONIC_POPCNT 0x021E
|
#define /*021E*/ ZYDIS_MNEMONIC_POPCNT 0x021E
|
||||||
#define /*021F*/ ZYDIS_MNEMONIC_POPF 0x021F
|
#define /*021F*/ ZYDIS_MNEMONIC_POPF 0x021F
|
||||||
#define /*0220*/ ZYDIS_MNEMONIC_POPFD 0x0220
|
#define /*0220*/ ZYDIS_MNEMONIC_POPFD 0x0220
|
||||||
|
@ -589,8 +589,8 @@
|
||||||
#define /*024C*/ ZYDIS_MNEMONIC_PUNPCKLQDQ 0x024C
|
#define /*024C*/ ZYDIS_MNEMONIC_PUNPCKLQDQ 0x024C
|
||||||
#define /*024D*/ ZYDIS_MNEMONIC_PUNPCKLWD 0x024D
|
#define /*024D*/ ZYDIS_MNEMONIC_PUNPCKLWD 0x024D
|
||||||
#define /*024E*/ ZYDIS_MNEMONIC_PUSH 0x024E
|
#define /*024E*/ ZYDIS_MNEMONIC_PUSH 0x024E
|
||||||
#define /*024F*/ ZYDIS_MNEMONIC_PUSHAL 0x024F
|
#define /*024F*/ ZYDIS_MNEMONIC_PUSHA 0x024F
|
||||||
#define /*0250*/ ZYDIS_MNEMONIC_PUSHAW 0x0250
|
#define /*0250*/ ZYDIS_MNEMONIC_PUSHAD 0x0250
|
||||||
#define /*0251*/ ZYDIS_MNEMONIC_PUSHF 0x0251
|
#define /*0251*/ ZYDIS_MNEMONIC_PUSHF 0x0251
|
||||||
#define /*0252*/ ZYDIS_MNEMONIC_PUSHFD 0x0252
|
#define /*0252*/ ZYDIS_MNEMONIC_PUSHFD 0x0252
|
||||||
#define /*0253*/ ZYDIS_MNEMONIC_PUSHFQ 0x0253
|
#define /*0253*/ ZYDIS_MNEMONIC_PUSHFQ 0x0253
|
||||||
|
|
|
@ -538,8 +538,8 @@
|
||||||
/*0219*/ "pmullw",
|
/*0219*/ "pmullw",
|
||||||
/*021A*/ "pmuludq",
|
/*021A*/ "pmuludq",
|
||||||
/*021B*/ "pop",
|
/*021B*/ "pop",
|
||||||
/*021C*/ "popal",
|
/*021C*/ "popa",
|
||||||
/*021D*/ "popaw",
|
/*021D*/ "popad",
|
||||||
/*021E*/ "popcnt",
|
/*021E*/ "popcnt",
|
||||||
/*021F*/ "popf",
|
/*021F*/ "popf",
|
||||||
/*0220*/ "popfd",
|
/*0220*/ "popfd",
|
||||||
|
@ -589,8 +589,8 @@
|
||||||
/*024C*/ "punpcklqdq",
|
/*024C*/ "punpcklqdq",
|
||||||
/*024D*/ "punpcklwd",
|
/*024D*/ "punpcklwd",
|
||||||
/*024E*/ "push",
|
/*024E*/ "push",
|
||||||
/*024F*/ "pushal",
|
/*024F*/ "pusha",
|
||||||
/*0250*/ "pushaw",
|
/*0250*/ "pushad",
|
||||||
/*0251*/ "pushf",
|
/*0251*/ "pushf",
|
||||||
/*0252*/ "pushfd",
|
/*0252*/ "pushfd",
|
||||||
/*0253*/ "pushfq",
|
/*0253*/ "pushfq",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -35,7 +35,6 @@
|
||||||
#include <Zydis/Input.h>
|
#include <Zydis/Input.h>
|
||||||
#include <Zydis/Decoder.h>
|
#include <Zydis/Decoder.h>
|
||||||
#include <Zydis/Formatter.h>
|
#include <Zydis/Formatter.h>
|
||||||
#include <Zydis/SymbolResolver.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -1551,8 +1551,9 @@ static ZydisDecoderStatus ZydisDecodeOperands(ZydisInstructionDecoder* decoder,
|
||||||
ZYDIS_ASSERT((operandCount > 0) && (operandCount < 6));
|
ZYDIS_ASSERT((operandCount > 0) && (operandCount < 6));
|
||||||
|
|
||||||
info->operandCount = operandCount;
|
info->operandCount = operandCount;
|
||||||
for (int i = 0; i < operandCount; ++i)
|
for (uint8_t i = 0; i < operandCount; ++i)
|
||||||
{
|
{
|
||||||
|
info->operand[i].id = i;
|
||||||
ZydisSemanticOperandType type = operands[i].type;
|
ZydisSemanticOperandType type = operands[i].type;
|
||||||
if (type == ZYDIS_SEM_OPERAND_TYPE_UNUSED)
|
if (type == ZYDIS_SEM_OPERAND_TYPE_UNUSED)
|
||||||
{
|
{
|
||||||
|
|
1180
src/Formatter.c
1180
src/Formatter.c
File diff suppressed because it is too large
Load Diff
10
src/Input.c
10
src/Input.c
|
@ -36,13 +36,13 @@
|
||||||
/* Internal functions */
|
/* Internal functions */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static bool ZydisMemoryInputNext(ZydisMemoryInput* context, uint8_t* data)
|
static bool ZydisMemoryInputNext(ZydisMemoryInput* input, uint8_t* data)
|
||||||
{
|
{
|
||||||
if (context->inputBufferPos >= context->inputBufferLen)
|
if (input->inputBufferPos >= input->inputBufferLen)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*data = context->inputBuffer[context->inputBufferPos++];
|
*data = input->inputBuffer[input->inputBufferPos++];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ ZydisStatus ZydisInputInitMemoryInput(ZydisMemoryInput* input, const void* buffe
|
||||||
/* Internal functions */
|
/* Internal functions */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static bool ZydisFileInputNext(ZydisFileInput* context, uint8_t* data)
|
static bool ZydisFileInputNext(ZydisFileInput* input, uint8_t* data)
|
||||||
{
|
{
|
||||||
int c = fgetc(context->file);
|
int c = fgetc(input->file);
|
||||||
*data = (uint8_t)c;
|
*data = (uint8_t)c;
|
||||||
return (c != EOF);
|
return (c != EOF);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue