Large diffs are not rendered by default.

@@ -0,0 +1,23 @@
The MIT License (MIT)

Copyright (c) 2017 Florian Bernd
Copyright (c) 2017 Joel Höner

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@@ -0,0 +1,123 @@
# Zyan Disassembler Engine (Zydis)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Gitter](https://badges.gitter.im/zyantific/zyan-disassembler-engine.svg)](https://gitter.im/zyantific/zyan-disassembler-engine?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=body_badge)

Fast and lightweight x86/x86-64 disassembler library.

## Features

- Supports all x86 and x86-64 (AMD64) instructions.
- Supports pretty much all ISA extensions (list incomplete):
- FPU (x87), MMX
- SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, SSE4A, AESNI
- AVX, AVX2, AVX512BW, AVX512CD, AVX512DQ, AVX512ER, AVX512F, AVX512PF, AVX512VL
- ADX, BMI1, BMI2, FMA, FMA4
- Optimized for high performance
- No dynamic memory allocation ("malloc")
- Very small file-size overhead compared to other common disassembler libraries
- [Complete doxygen documentation](https://www.zyantific.com/doc/zydis/index.html)
- No dependencies on platform specific APIs
- Should compile on any platform with a complete libc and CMake
- Tested on Windows, macOS and Linux

## Roadmap

- Language bindings [v2.0 final]
- Tests [v2.0 final]
- Graphical editor for the instruction-database [v2.0 final]
- Implement CMake feature gates. Currently, everything is always included. [v2.0 final]
- Encoding support [v2.1]

## Quick Example

The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console.

```C
#include <stdio.h>
#include <Zydis/Zydis.h>
int main()
{
uint8_t data[] =
{
0x51, 0x8D, 0x45, 0xFF, 0x50, 0xFF, 0x75, 0x0C, 0xFF, 0x75,
0x08, 0xFF, 0x15, 0xA0, 0xA5, 0x48, 0x76, 0x85, 0xC0, 0x0F,
0x88, 0xFC, 0xDA, 0x02, 0x00
};
// Initialize decoder context.
ZydisDecoder decoder;
ZydisDecoderInit(
&decoder,
ZYDIS_MACHINE_MODE_LONG_64,
ZYDIS_ADDRESS_WIDTH_64);
// Initialize formatter. Only required when you actually plan to
// do instruction formatting ("disassembling"), like we do here.
ZydisFormatter formatter;
ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
// Loop over the instructions in our buffer.
uint64_t instructionPointer = 0x007FFFFFFF400000;
uint8_t* readPointer = data;
size_t length = sizeof(data);
ZydisDecodedInstruction instruction;
while (ZYDIS_SUCCESS(ZydisDecoderDecodeBuffer(
&decoder, readPointer, length, instructionPointer, &instruction)))
{
// Print current instruction pointer.
printf("%016" PRIX64 " ", instructionPointer);
// Format & print the binary instruction
// structure to human readable format.
char buffer[256];
ZydisFormatterFormatInstruction(
&formatter, &instruction, buffer, sizeof(buffer));
puts(buffer);
readPointer += instruction.length;
length -= instruction.length;
instructionPointer += instruction.length;
}
}
```

## Sample Output

The above example program generates the following output:

```
007FFFFFFF400000 push rcx
007FFFFFFF400001 lea eax, [rbp-0x01]
007FFFFFFF400004 push rax
007FFFFFFF400005 push qword ptr [rbp+0x0C]
007FFFFFFF400008 push qword ptr [rbp+0x08]
007FFFFFFF40000B call [0x008000007588A5B1]
007FFFFFFF400011 test eax, eax
007FFFFFFF400013 js 0x007FFFFFFF42DB15
```

## Compilation

Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C99 compiler.

```bash
# Linux and OS X
git clone 'https://github.com/zyantific/zydis.git'
cd zydis
mkdir build && cd build
cmake ..
make
```

## `ZydisInfo` tool
![ZydisInfo](https://raw.githubusercontent.com/zyantific/zydis/master/assets/screenshots/ZydisInfo.png)

## Credits
- Intel (for open-sourcing XED, allowing for automatic comparision of our tables against theirs, improving both)
- LLVM (for providing pretty solid instruction data as well)
- Christian Ludloff (http://sandpile.org, insanely helpful)
- Our [contributors on GitHub](https://github.com/zyantific/zydis/graphs/contributors)

## License

Zydis is licensed under the MIT license.
@@ -0,0 +1,41 @@

#ifndef ZYDIS_EXPORT_H
#define ZYDIS_EXPORT_H

#ifdef ZYDIS_STATIC_DEFINE
# define ZYDIS_EXPORT
# define ZYDIS_NO_EXPORT
#else
# ifndef ZYDIS_EXPORT
# ifdef Zydis_EXPORTS
/* We are building this library */
# define ZYDIS_EXPORT
# else
/* We are using this library */
# define ZYDIS_EXPORT
# endif
# endif

# ifndef ZYDIS_NO_EXPORT
# define ZYDIS_NO_EXPORT
# endif
#endif

#ifndef ZYDIS_DEPRECATED
# define ZYDIS_DEPRECATED __attribute__ ((__deprecated__))
#endif

#ifndef ZYDIS_DEPRECATED_EXPORT
# define ZYDIS_DEPRECATED_EXPORT ZYDIS_EXPORT ZYDIS_DEPRECATED
#endif

#ifndef ZYDIS_DEPRECATED_NO_EXPORT
# define ZYDIS_DEPRECATED_NO_EXPORT ZYDIS_NO_EXPORT ZYDIS_DEPRECATED
#endif

#define DEFINE_NO_DEPRECATED 0
#if DEFINE_NO_DEPRECATED
# define ZYDIS_NO_DEPRECATED
#endif

#endif
@@ -0,0 +1,286 @@
/**
*
*
* 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 "pin.H"
#include "xed-interface.h"

#include <iostream>
#include <iomanip>
#include <fstream>
#include <set>
#include <Zydis/Zydis.h>

/* ========================================================================== */
/* TLS struct */
/* ========================================================================== */

struct ThreadData
{
CONTEXT ctx;
ZydisInstructionDecoder decoder;

ThreadData()
{
ZydisDecoderInitInstructionDecoderEx(
&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT, NULL, 0
);
}
};

/* ========================================================================== */
/* Global variables */
/* ========================================================================== */

TLS_KEY tls_key;
std::ostream* out = &cerr;

PIN_LOCK unique_iforms_lock;
std::set<xed_iform_enum_t> unique_iforms;

/* ========================================================================== */
/* Tables */
/* ========================================================================== */

struct RegMapping
{
REG pin;
ZydisRegister zy;
};

RegMapping reg_mapping[] = {
// 64-bit GP register
{REG_RAX, ZYDIS_REGISTER_RAX},
{REG_RBX, ZYDIS_REGISTER_RBX},
{REG_RCX, ZYDIS_REGISTER_RCX},
{REG_RDX, ZYDIS_REGISTER_RDX},
{REG_RSP, ZYDIS_REGISTER_RSP},
{REG_RBP, ZYDIS_REGISTER_RBP},
{REG_RSI, ZYDIS_REGISTER_RSI},
{REG_RDI, ZYDIS_REGISTER_RDI},
{REG_R8, ZYDIS_REGISTER_R8 },
{REG_R9, ZYDIS_REGISTER_R9 },
{REG_R10, ZYDIS_REGISTER_R10},
{REG_R11, ZYDIS_REGISTER_R11},
{REG_R12, ZYDIS_REGISTER_R12},
{REG_R13, ZYDIS_REGISTER_R13},
{REG_R14, ZYDIS_REGISTER_R14},
{REG_R15, ZYDIS_REGISTER_R15},

// Segment registers
{REG_SEG_ES, ZYDIS_REGISTER_ES},
{REG_SEG_SS, ZYDIS_REGISTER_SS},
{REG_SEG_SS, ZYDIS_REGISTER_SS},
{REG_SEG_CS, ZYDIS_REGISTER_CS},
{REG_SEG_DS, ZYDIS_REGISTER_DS},
{REG_SEG_FS, ZYDIS_REGISTER_FS},
{REG_SEG_GS, ZYDIS_REGISTER_GS},

// Mask registers
{REG_K0, ZYDIS_REGISTER_K0},
{REG_K1, ZYDIS_REGISTER_K1},
{REG_K2, ZYDIS_REGISTER_K2},
{REG_K3, ZYDIS_REGISTER_K3},
{REG_K4, ZYDIS_REGISTER_K4},
{REG_K5, ZYDIS_REGISTER_K5},
{REG_K6, ZYDIS_REGISTER_K6},
{REG_K7, ZYDIS_REGISTER_K7},

// TODO: XMM, YMM, ZMM, ST, TR

// Special registers
{REG_MXCSR, ZYDIS_REGISTER_MXCSR},
};

/* ========================================================================== */
/* Command line switches */
/* ========================================================================== */

KNOB<string> knob_out_file(
KNOB_MODE_WRITEONCE, "pintool", "o", "", "Output file name"
);

KNOB<bool> know_unique_iform(
KNOB_MODE_WRITEONCE, "pintool", "unique_iform", "0",
"Only instrument one instruction per iform"
);

KNOB<bool> omit_op_checks(
KNOB_MODE_WRITEONCE, "pintool", "omit_op_checks", "0",
"Skip verification of operand write assumptions"
);

KNOB<bool> omit_flag_checks(
KNOB_MODE_WRITEONCE, "pintool", "omit_flag_checks", "1",
"Skip verification of flag write assumptions"
);

/* ========================================================================== */
/* Instrumentation callbacks */
/* ========================================================================== */

VOID PIN_FAST_ANALYSIS_CALL pre_ins_cb(THREADID tid, const CONTEXT* ctx)
{
ThreadData *tls = static_cast<ThreadData*>(PIN_GetThreadData(tls_key, tid));
PIN_SaveContext(ctx, &tls->ctx);
}

VOID PIN_FAST_ANALYSIS_CALL post_ins_cb(THREADID tid, const CONTEXT* post_ctx)
{
ThreadData *tls = static_cast<ThreadData*>(PIN_GetThreadData(tls_key, tid));

// Get IPs.
ADDRINT pre_ip = PIN_GetContextReg(&tls->ctx, REG_INST_PTR);
ADDRINT post_ip = PIN_GetContextReg(post_ctx, REG_INST_PTR);

// If the IP didn't change, we're probably dealing with a rep.
// Skip instruction until last execution where fallthrough kicks in.
ADDRINT ip_diff = post_ip - pre_ip;
if (!ip_diff) return;

// Disassemble previously executed instruction.
ZydisMemoryInput input;
ZydisInputInitMemoryInput(&input, (void*)pre_ip, 15);
ZydisDecoderSetInput(&tls->decoder, (ZydisCustomInput*)&input);

ZydisInstructionInfo insn_info;
ZydisStatus decode_status = ZydisDecoderDecodeNextInstruction(
&tls->decoder, &insn_info
);

// Can we decode it?
if (!ZYDIS_SUCCESS(decode_status)) {
*out << "Decoding failure" << endl;
goto error;
}

// Does the length look like what we expected?
if (insn_info.length != ip_diff) {
*out << "Instruction length mismatch (expected "
<< dec << ip_diff << ", got " << (int)insn_info.length
<< ')' << endl;
goto error;
}

// Analyze operand effects.
if (!omit_op_checks) {
for (const RegMapping* map = reg_mapping
; map < reg_mapping + sizeof reg_mapping / sizeof reg_mapping[0]
; ++map) {

ADDRINT pre_reg_val = PIN_GetContextReg(&tls->ctx, map->pin);
ADDRINT post_reg_val = PIN_GetContextReg(post_ctx, map->pin);

// Did the instruction touch this register?
if (pre_reg_val != post_reg_val) {
*out << "Reg value changed ("
<< ZydisRegisterGetString(map->zy)
<< ")!" << endl;
}
}
}

// Analyze flag effects.
if (!omit_flag_checks) {
ADDRINT prev_flags = PIN_GetContextReg(&tls->ctx, REG_GFLAGS);
ADDRINT new_flags = PIN_GetContextReg(post_ctx, REG_GFLAGS);
ADDRINT changed_flags = prev_flags ^ new_flags;
if (changed_flags) {
// TODO: implement once flag infos are available.
}
}

return;

error:
// Always print raw bytes on error.
*out << "Raw bytes: ";
for (size_t i = 0; i < 15; ++i) {
*out << setfill('0') << setw(2) << hex
<< (int)((uint8_t*)pre_ip)[i] << ' ';
}
*out << endl;
}

VOID instruction(INS ins, VOID *v)
{
if (!INS_HasFallThrough(ins)) return;

xed_decoded_inst_t* xed = INS_XedDec(ins);
xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(xed);

if (know_unique_iform.Value()) {
PIN_GetLock(&unique_iforms_lock, 0);
if (unique_iforms.find(iform) != unique_iforms.end()) {
PIN_ReleaseLock(&unique_iforms_lock);
return;
}
unique_iforms.insert(iform);
*out << iform << endl;
PIN_ReleaseLock(&unique_iforms_lock);
}

INS_InsertCall(
ins, IPOINT_BEFORE, (AFUNPTR)&pre_ins_cb,
IARG_FAST_ANALYSIS_CALL, IARG_THREAD_ID, IARG_CONST_CONTEXT,
IARG_END
);
INS_InsertCall(
ins, IPOINT_AFTER, (AFUNPTR)&post_ins_cb,
IARG_FAST_ANALYSIS_CALL, IARG_THREAD_ID, IARG_CONST_CONTEXT,
IARG_END
);
}

VOID thread_start(THREADID tid, CONTEXT *ctx, INT32 flags, VOID* v)
{
ThreadData* tls = new ThreadData;
PIN_SetThreadData(tls_key, tls, tid);
}

int main(int argc, char *argv[])
{
if (PIN_Init(argc, argv)) {
cerr << KNOB_BASE::StringKnobSummary() << endl;
return 1;
}

// Open output file.
string file_name = knob_out_file.Value();
if (!file_name.empty()) {
out = new std::ofstream(file_name.c_str());
}

// Init TLS.
tls_key = PIN_CreateThreadDataKey(0);
PIN_InitLock(&unique_iforms_lock);

// Register hooks.
PIN_AddThreadStartFunction(&thread_start, NULL);
INS_AddInstrumentFunction(&instruction, NULL);

// Start the program, never returns.
PIN_StartProgram();

return 0;
}

/* ========================================================================== */
@@ -0,0 +1,21 @@
##############################################################
#
# DO NOT EDIT THIS FILE!
#
##############################################################

# If the tool is built out of the kit, PIN_ROOT must be specified in the make invocation and point to the kit root.
ifdef PIN_ROOT
CONFIG_ROOT := $(PIN_ROOT)/source/tools/Config
else
CONFIG_ROOT := ../Config
endif
include $(CONFIG_ROOT)/makefile.config
include makefile.rules
include $(TOOLS_ROOT)/Config/makefile.default.rules

##############################################################
#
# DO NOT EDIT THIS FILE!
#
##############################################################
@@ -0,0 +1,89 @@
##############################################################
#
# This file includes all the test targets as well as all the
# non-default build rules and test recipes.
#
##############################################################


##############################################################
#
# Test targets
#
##############################################################

###### Place all generic definitions here ######

# This defines tests which run tools of the same name. This is simply for convenience to avoid
# defining the test name twice (once in TOOL_ROOTS and again in TEST_ROOTS).
# Tests defined here should not be defined in TOOL_ROOTS and TEST_ROOTS.
TEST_TOOL_ROOTS := ZydisTestTool

OBJECT_ROOTS += \
zydis/src/Decoder \
zydis/src/Formatter \
zydis/src/Input \
zydis/src/InstructionDetails \
zydis/src/InstructionTable \
zydis/src/Mnemonic \
zydis/src/Register \
zydis/src/Utils \
zydis/src/Zydis

# This defines the tests to be run that were not already defined in TEST_TOOL_ROOTS.
TEST_ROOTS :=

# This defines the tools which will be run during the the tests, and were not already defined in
# TEST_TOOL_ROOTS.
TOOL_ROOTS :=

# This defines the static analysis tools which will be run during the the tests. They should not
# be defined in TEST_TOOL_ROOTS. If a test with the same name exists, it should be defined in
# TEST_ROOTS.
# Note: Static analysis tools are in fact executables linked with the Pin Static Analysis Library.
# This library provides a subset of the Pin APIs which allows the tool to perform static analysis
# of an application or dll. Pin itself is not used when this tool runs.
SA_TOOL_ROOTS :=

# This defines all the applications that will be run during the tests.
APP_ROOTS :=

# This defines any additional object files that need to be compiled.
OBJECT_ROOTS :=

# This defines any additional dlls (shared objects), other than the pintools, that need to be compiled.
DLL_ROOTS :=

# This defines any static libraries (archives), that need to be built.
LIB_ROOTS :=

###### Define the sanity subset ######

# This defines the list of tests that should run in sanity. It should include all the tests listed in
# TEST_TOOL_ROOTS and TEST_ROOTS excluding only unstable tests.
SANITY_SUBSET := $(TEST_TOOL_ROOTS) $(TEST_ROOTS)


##############################################################
#
# Test recipes
#
##############################################################

# This section contains recipes for tests other than the default.
# See makefile.default.rules for the default test rules.
# All tests in this section should adhere to the naming convention: <testname>.test


##############################################################
#
# Build rules
#
##############################################################

ADDITIONAL_INCLUDES := -Izydis/include -I.
TOOL_CFLAGS += $(ADDITIONAL_INCLUDES)
TOOL_CXXFLAGS += $(ADDITIONAL_INCLUDES)

$(OBJDIR)ZydisTestTool$(PINTOOL_SUFFIX): $(OBJDIR)ZydisTestTool$(OBJ_SUFFIX) $(OBJDIR)zydis/src/Decoder$(OBJ_SUFFIX) $(OBJDIR)zydis/src/Formatter$(OBJ_SUFFIX) $(OBJDIR)zydis/src/Input$(OBJ_SUFFIX) $(OBJDIR)zydis/src/InstructionDetails$(OBJ_SUFFIX) $(OBJDIR)zydis/src/InstructionTable$(OBJ_SUFFIX) $(OBJDIR)zydis/src/Mnemonic$(OBJ_SUFFIX) $(OBJDIR)zydis/src/Register$(OBJ_SUFFIX) $(OBJDIR)zydis/src/Utils$(OBJ_SUFFIX) $(OBJDIR)zydis/src/Zydis$(OBJ_SUFFIX)
$(LINKER) $(TOOL_LDFLAGS) $(LINK_EXE)$@ $^ $(TOOL_LPATHS) $(TOOL_LIBS)
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -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,257 @@
/***************************************************************************************************
Zyan Disassembler Library (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 ZydisFormatter class.
*
* This example demonstrates the hooking functionality of the @c ZydisFormatter 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 <inttypes.h>
#include <Zydis/Zydis.h>
#include "FormatHelper.h"
#include <stdlib.h>

/* ============================================================================================== */
/* Static data */
/* ============================================================================================== */

/**
* @brief Static array with the condition-code strings.
*/
static const char* conditionCodeStrings[0x20] =
{
/*00*/ "eq",
/*01*/ "lt",
/*02*/ "le",
/*03*/ "unord",
/*04*/ "neq",
/*05*/ "nlt",
/*06*/ "nle",
/*07*/ "ord",
/*08*/ "eq_uq",
/*09*/ "nge",
/*0A*/ "ngt",
/*0B*/ "false",
/*0C*/ "oq",
/*0D*/ "ge",
/*0E*/ "gt",
/*0F*/ "true",
/*10*/ "eq_os",
/*11*/ "lt_oq",
/*12*/ "le_oq",
/*13*/ "unord_s",
/*14*/ "neq_us",
/*15*/ "nlt_uq",
/*16*/ "nle_uq",
/*17*/ "ord_s",
/*18*/ "eq_us",
/*19*/ "nge_uq",
/*1A*/ "ngt_uq",
/*1B*/ "false_os",
/*1C*/ "neq_os",
/*1D*/ "ge_oq",
/*1E*/ "gt_oq",
/*1F*/ "true_us"
};

/* ============================================================================================== */
/* Enums and Types */
/* ============================================================================================== */

/**
* @brief Custom user data struct.
*/
typedef struct ZydisCustomUserData_
{
ZydisBool ommitImmediate;
} ZydisCustomUserData;

/* ============================================================================================== */
/* Hook callbacks */
/* ============================================================================================== */

ZydisFormatterFormatFunc defaultPrintMnemonic;

static ZydisStatus ZydisFormatterPrintMnemonic(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
ZydisCustomUserData* userData)
{
// We use the user-data to pass data to the @c ZydisFormatterFormatOperandImm function.
userData->ommitImmediate = ZYDIS_TRUE;

// Rewrite the instruction-mnemonic for the given instructions
if (instruction->operands[instruction->operandCount - 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)
{
uint8_t conditionCode =
(uint8_t)instruction->operands[instruction->operandCount - 1].imm.value.u;
switch (instruction->mnemonic)
{
case ZYDIS_MNEMONIC_CMPPS:
if (conditionCode < 0x08)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%sps",
conditionCodeStrings[conditionCode]);
}
break;
case ZYDIS_MNEMONIC_CMPPD:
if (conditionCode < 0x08)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "cmp%spd",
conditionCodeStrings[conditionCode]);
}
break;
case ZYDIS_MNEMONIC_VCMPPS:
if (conditionCode < 0x20)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%sps",
conditionCodeStrings[conditionCode]);
}
break;
case ZYDIS_MNEMONIC_VCMPPD:
if (conditionCode < 0x20)
{
return ZydisStringBufferAppendFormat(buffer, bufferLen,
ZYDIS_STRBUF_APPEND_MODE_DEFAULT, "vcmp%spd",
conditionCodeStrings[conditionCode]);
}
break;
default:
break;
}
}

// We did not rewrite the instruction-mnemonic. Signal the @c ZydisFormatterFormatOperandImm
// function not to omit the operand
userData->ommitImmediate = ZYDIS_FALSE;

// Default mnemonic printing
return defaultPrintMnemonic(formatter, buffer, bufferLen, instruction, userData);
}

/* ---------------------------------------------------------------------------------------------- */

ZydisFormatterFormatOperandFunc defaultFormatOperandImm;

static ZydisStatus ZydisFormatterFormatOperandImm(const ZydisFormatter* formatter,
char** buffer, size_t bufferLen, const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, ZydisCustomUserData* userData)
{
// The @c ZydisFormatterFormatMnemonic sinals us to omit the immediate (condition-code)
// operand, because it got replaced by the alias-mnemonic
if (userData->ommitImmediate)
{
// 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, instruction, operand, userData);
}

/* ---------------------------------------------------------------------------------------------- */

/* ============================================================================================== */
/* Helper functions */
/* ============================================================================================== */

void disassembleBuffer(ZydisDecoder* decoder, uint8_t* data, size_t length, ZydisBool installHooks)
{
ZydisFormatter formatter;
ZydisFormatterInitEx(&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 = (ZydisFormatterFormatFunc)&ZydisFormatterPrintMnemonic;
ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_PRINT_MNEMONIC,
(const void**)&defaultPrintMnemonic);
defaultFormatOperandImm = (ZydisFormatterFormatOperandFunc)&ZydisFormatterFormatOperandImm;
ZydisFormatterSetHook(&formatter, ZYDIS_FORMATTER_HOOK_FORMAT_OPERAND_IMM,
(const void**)&defaultFormatOperandImm);
}

uint64_t instructionPointer = 0x007FFFFFFF400000;

ZydisDecodedInstruction instruction;
ZydisCustomUserData userData;
char buffer[256];
while (ZYDIS_SUCCESS(
ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction)))
{
data += instruction.length;
length -= instruction.length;
instructionPointer += instruction.length;
printf("%016" PRIX64 " ", instruction.instrAddress);
ZydisFormatterFormatInstructionEx(
&formatter, &instruction, &buffer[0], sizeof(buffer), &userData);
printf(" %s\n", &buffer[0]);
}
}

/* ============================================================================================== */
/* Entry point */
/* ============================================================================================== */

int main()
{
if (ZydisGetVersion() != ZYDIS_VERSION)
{
fputs("Invalid zydis version\n", stderr);
return EXIT_FAILURE;
}

uint8_t data[] =
{
// cmpps xmm1, xmm4, 0x03
0x0F, 0xC2, 0xCC, 0x03,

// vcmppd xmm1, xmm2, xmm3, 0x17
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
};

ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);

disassembleBuffer(&decoder, &data[0], sizeof(data), ZYDIS_FALSE);
puts("");
disassembleBuffer(&decoder, &data[0], sizeof(data), ZYDIS_TRUE);

return 0;
}

/* ============================================================================================== */
@@ -0,0 +1,123 @@
/***************************************************************************************************
Zyan Disassembler Engine (Zydis)
Original Author : Joel Höner
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/

/**
* @file
*
* This file implements a tool that is supposed to be fed as input for fuzzers like AFL,
* reading a control block from stdin, allowing the fuzzer to reach every possible
* code-path, testing any possible combination of disassembler configurations.
*/

#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <Zydis/Zydis.h>

typedef struct ZydisFuzzControlBlock_ {
ZydisMachineMode machineMode;
ZydisAddressWidth addressWidth;
ZydisDecodeGranularity granularity;
ZydisFormatterStyle formatterStyle;
ZydisFormatterFlags formatterFlags;
ZydisFormatterAddressFormat formatterAddrFormat;
ZydisFormatterDisplacementFormat formatterDispFormat;
ZydisFormatterImmediateFormat formatterImmFormat;
} ZydisFuzzControlBlock;

/* ============================================================================================== */
/* Entry point */
/* ============================================================================================== */

int main()
{
if (ZydisGetVersion() != ZYDIS_VERSION)
{
fputs("Invalid zydis version\n", stderr);
return EXIT_FAILURE;
}

ZydisFuzzControlBlock controlBlock;
if (fread(&controlBlock, 1, sizeof(controlBlock), stdin) != sizeof(controlBlock))
{
fputs("not enough bytes to fuzz\n", stderr);
return EXIT_FAILURE;
}

ZydisDecoder decoder;
if (!ZYDIS_SUCCESS(ZydisDecoderInitEx(&decoder, controlBlock.machineMode,
controlBlock.addressWidth, controlBlock.granularity)))
{
fputs("Failed to initialize decoder\n", stderr);
return EXIT_FAILURE;
}

ZydisFormatter formatter;
if (!ZYDIS_SUCCESS(ZydisFormatterInitEx(&formatter, controlBlock.formatterStyle,
controlBlock.formatterFlags, controlBlock.formatterAddrFormat,
controlBlock.formatterDispFormat, controlBlock.formatterImmFormat)))
{
fputs("failed to initialize instruction-formatter\n", stderr);
return EXIT_FAILURE;
}

uint8_t readBuf[ZYDIS_MAX_INSTRUCTION_LENGTH * 1024];
size_t numBytesRead;
do
{
numBytesRead = fread(readBuf, 1, sizeof(readBuf), stdin);

ZydisDecodedInstruction instruction;
ZydisStatus status;
size_t readOffs = 0;
while ((status = ZydisDecoderDecodeBuffer(&decoder, readBuf + readOffs,
numBytesRead - readOffs, readOffs, &instruction)) != ZYDIS_STATUS_NO_MORE_DATA)
{
if (!ZYDIS_SUCCESS(status))
{
++readOffs;
continue;
}

char printBuffer[256];
ZydisFormatterFormatInstruction(
&formatter, &instruction, printBuffer, sizeof(printBuffer));
readOffs += instruction.length;
}

if (readOffs < sizeof(readBuf))
{
memmove(readBuf, readBuf + readOffs, sizeof(readBuf) - readOffs);
}
} while (numBytesRead == sizeof(readBuf));

return 0;
}

/* ============================================================================================== */

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,100 @@
/***************************************************************************************************
Zyan Disassembler Library (Zydis)
Original Author : Florian Bernd, Joel Höner
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/

/**
* @file
* @brief Includes and defines some default datatypes.
*/

#ifndef ZYDIS_COMMONTYPES_H
#define ZYDIS_COMMONTYPES_H

#include <Zydis/Defines.h>

/* ============================================================================================== */
/* Integral types */
/* ============================================================================================== */

// Fixed width integer types.
#if defined(ZYDIS_WINKERNEL)
# if !defined(ZYDIS_MSVC)
# error "Windows kernel drivers are only supported with MSVC"
# endif
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
# define UINT8_MAX (255)
# define UINT16_MAX (65535U)
# define UINT32_MAX (4294967295UL)
# define UINT64_MAX (18446744073709551615ULL)
# define INT8_MAX (127)
# define INT8_MIN (-128)
# define INT16_MAX (32767)
# define INT16_MIN (-32767-1)
# define INT32_MIN (-2147483647L-1)
# define INT32_MAX (2147483647L)
# define INT64_MIN (-9223372036854775807LL-1)
# define INT64_MAX (9223372036854775807LL)
# define PRIX8 "hhX"
# define PRIX16 "hX"
# define PRIX32 "X"
# define PRIX64 "llX"
#else
# include <stdint.h>
# include <inttypes.h>
#endif

// size_t, ptrdiff_t
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Boolean */
/* ============================================================================================== */

#define ZYDIS_FALSE 0
#define ZYDIS_TRUE 1

/**
* @briefs Defines the @c ZydisBool datatype.
*/
typedef uint8_t ZydisBool;

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_COMMONTYPES_H */
@@ -0,0 +1,146 @@
/***************************************************************************************************
Zyan Disassembler Library (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 Functions for decoding instructions.
*/

#ifndef ZYDIS_DECODER_H
#define ZYDIS_DECODER_H

#include <Zydis/CommonTypes.h>
#include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h>
#include <Zydis/Status.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */

/**
* @brief Defines the @c ZydisDecodeGranularity datatype.
*/
typedef uint8_t ZydisDecodeGranularity;

/**
* @brief Decoder modes defining how granular the instruction should be decoded.
*/
enum ZydisDecodeGranularities
{
/**
* @brief Defaults to `ZYDIS_DECODE_GRANULARITY_FULL`.
*/
ZYDIS_DECODE_GRANULARITY_DEFAULT,
/**
* @brief Minimal instruction decoding without semantic analysis.
*
* This mode provides access to the mnemonic, the instruction-length, the effective
* operand-size, the effective address-width, some attributes (e.g. `ZYDIS_ATTRIB_IS_RELATIVE`)
* and all of the information in the `raw` field of the `ZydisDecodedInstruction` struct.
*
* Operands, most attributes and other specific information (like AVX info) are not
* accessible in this mode.
*/
ZYDIS_DECODE_GRANULARITY_MINIMAL,
/**
* @brief Full physical and semantic instruction-decoding.
*/
ZYDIS_DECODE_GRANULARITY_FULL,
/**
* @brief Maximum value of this enum.
*/
ZYDIS_DECODE_GRANULARITY_MAX_VALUE = ZYDIS_DECODE_GRANULARITY_FULL,
};

/**
* @brief Defines the @c ZydisDecoder struct.
*/
typedef struct ZydisDecoder_
{
ZydisMachineMode machineMode;
ZydisAddressWidth addressWidth;
ZydisDecodeGranularity granularity;
} ZydisDecoder;

/* ---------------------------------------------------------------------------------------------- */

/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */

/**
* @brief Initializes the given @c ZydisDecoder instance.
*
* @param decoder A pointer to the @c ZydisDecoder instance.
* @param machineMode The machine mode.
* @param addressWidth The address width.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisDecoderInit(ZydisDecoder* decoder, ZydisMachineMode machineMode,
ZydisAddressWidth addressWidth);

/**
* @brief Initializes the given @c ZydisDecoder instance.
*
* @param decoder A pointer to the @c ZydisDecoder instance.
* @param machineMode The machine mode.
* @param addressWidth The address width.
* @param granularity The decode granularity.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisDecoderInitEx(ZydisDecoder* decoder, ZydisMachineMode machineMode,
ZydisAddressWidth addressWidth, ZydisDecodeGranularity granularity);

/**
* @brief Decodes the instruction in the given input @c buffer.
*
* @param decoder A pointer to the @c ZydisDecoder instance.
* @param buffer A pointer to the input buffer.
* @param bufferLen The length of the input buffer.
* @param instructionPointer The instruction-pointer.
* @param instruction A pointer to the @c ZydisDecodedInstruction struct, that receives
* the details about the decoded instruction.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisDecoderDecodeBuffer(const ZydisDecoder* decoder,
const void* buffer, size_t bufferLen, uint64_t instructionPointer,
ZydisDecodedInstruction* instruction);

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_DECODER_H */

Large diffs are not rendered by default.

@@ -0,0 +1,175 @@
/***************************************************************************************************
Zyan Disassembler Library (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 General helper and platform detection macros.
*/

#ifndef ZYDIS_DEFINES_H
#define ZYDIS_DEFINES_H

#include <ZydisExportConfig.h>

/* ============================================================================================== */
/* Compiler detection */
/* ============================================================================================== */

#if defined(__clang__)
# define ZYDIS_CLANG
# define ZYDIS_GNUC
#elif defined(__ICC) || defined(__INTEL_COMPILER)
# define ZYDIS_ICC
#elif defined(__GNUC__) || defined(__GNUG__)
# define ZYDIS_GCC
# define ZYDIS_GNUC
#elif defined(_MSC_VER)
# define ZYDIS_MSVC
#elif defined(__BORLANDC__)
# define ZYDIS_BORLAND
#else
# define ZYDIS_UNKNOWN_COMPILER
#endif

/* ============================================================================================== */
/* Platform detection */
/* ============================================================================================== */

#if defined(_WIN32)
# define ZYDIS_WINDOWS
#elif defined(__APPLE__)
# define ZYDIS_APPLE
# define ZYDIS_POSIX
#elif defined(__linux)
# define ZYDIS_LINUX
# define ZYDIS_POSIX
#elif defined(__unix)
# define ZYDIS_UNIX
# define ZYDIS_POSIX
#elif defined(__posix)
# define ZYDIS_POSIX
#else
# error "Unsupported platform detected"
#endif

/* ============================================================================================== */
/* Architecture detection */
/* ============================================================================================== */

#if defined (_M_AMD64) || defined (__x86_64__)
# define ZYDIS_X64
#elif defined (_M_IX86) || defined (__i386__)
# define ZYDIS_X86
#else
# error "Unsupported architecture detected"
#endif

/* ============================================================================================== */
/* Debug/Release detection */
/* ============================================================================================== */

#if defined(ZYDIS_MSVC) || defined(ZYDIS_BORLAND)
# ifdef _DEBUG
# define ZYDIS_DEBUG
# else
# define ZYDIS_RELEASE
# endif
#elif defined(ZYDIS_GNUC) || defined(ZYDIS_ICC)
# ifdef NDEBUG
# define ZYDIS_RELEASE
# else
# define ZYDIS_DEBUG
# endif
#else
# error "Unsupported compiler detected"
#endif

/* ============================================================================================== */
/* Misc compatibility macros */
/* ============================================================================================== */

#if defined(ZYDIS_MSVC) || defined(ZYDIS_BORLAND)
# define ZYDIS_INLINE __inline
#else
# define ZYDIS_INLINE static inline
#endif

/* ============================================================================================== */
/* Debugging and optimization macros */
/* ============================================================================================== */

#if defined(ZYDIS_WINKERNEL)
# define ZYDIS_ASSERT(condition)
#else
# include <assert.h>
# define ZYDIS_ASSERT(condition) assert(condition)
#endif

#if defined(ZYDIS_RELEASE)
# if defined(ZYDIS_CLANG) // GCC eagerly evals && RHS, we have to use nested ifs.
# if __has_builtin(__builtin_unreachable)
# define ZYDIS_UNREACHABLE __builtin_unreachable()
# else
# define ZYDIS_UNREACHABLE
# endif
# elif defined(ZYDIS_GCC) && ((__GNUC__ == 4 && __GNUC_MINOR__ > 4) || __GNUC__ > 4)
# define ZYDIS_UNREACHABLE __builtin_unreachable()
# elif defined(ZYDIS_ICC)
# ifdef ZYDIS_WINDOWS
# include <stdlib.h> // "missing return statement" workaround
# define ZYDIS_UNREACHABLE __assume(0); (void)abort()
# else
# define ZYDIS_UNREACHABLE __builtin_unreachable()
# endif
# elif defined(ZYDIS_MSVC)
# define ZYDIS_UNREACHABLE __assume(0)
# else
# define ZYDIS_UNREACHABLE
# endif
#elif defined(ZYDIS_WINKERNEL)
# define ZYDIS_UNREACHABLE
#else
# include <stdlib.h>
# define ZYDIS_UNREACHABLE { assert(0); abort(); }
#endif

/* ============================================================================================== */
/* Utils */
/* ============================================================================================== */

/**
* @brief Declares a bitfield.
*/
#define ZYDIS_BITFIELD(x) : x

/**
* @brief Calculates the size of an array.
*/
#define ZYDIS_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))

/* ============================================================================================== */

#endif /* ZYDIS_DEFINES_H */

Large diffs are not rendered by default.

@@ -0,0 +1,133 @@
/**
* @brief Defines the `ZydisISAExt` datatype.
*/
typedef uint8_t ZydisISAExt;

/**
* @brief Values that represent `ZydisISAExt` elements.
*/
enum ZydisISAExts
{
ZYDIS_ISA_EXT_INVALID,
ZYDIS_ISA_EXT_AES,
ZYDIS_ISA_EXT_AMD,
ZYDIS_ISA_EXT_AMD3DNOW,
ZYDIS_ISA_EXT_AVX,
ZYDIS_ISA_EXT_AVX2,
ZYDIS_ISA_EXT_AVX2GATHER,
ZYDIS_ISA_EXT_AVX512BW_128,
ZYDIS_ISA_EXT_AVX512BW_128N,
ZYDIS_ISA_EXT_AVX512BW_256,
ZYDIS_ISA_EXT_AVX512BW_512,
ZYDIS_ISA_EXT_AVX512BW_KOP,
ZYDIS_ISA_EXT_AVX512CD_128,
ZYDIS_ISA_EXT_AVX512CD_256,
ZYDIS_ISA_EXT_AVX512CD_512,
ZYDIS_ISA_EXT_AVX512DQ_128,
ZYDIS_ISA_EXT_AVX512DQ_128N,
ZYDIS_ISA_EXT_AVX512DQ_256,
ZYDIS_ISA_EXT_AVX512DQ_512,
ZYDIS_ISA_EXT_AVX512DQ_KOP,
ZYDIS_ISA_EXT_AVX512DQ_SCALAR,
ZYDIS_ISA_EXT_AVX512ER_512,
ZYDIS_ISA_EXT_AVX512ER_SCALAR,
ZYDIS_ISA_EXT_AVX512F_128,
ZYDIS_ISA_EXT_AVX512F_128N,
ZYDIS_ISA_EXT_AVX512F_256,
ZYDIS_ISA_EXT_AVX512F_512,
ZYDIS_ISA_EXT_AVX512F_KOP,
ZYDIS_ISA_EXT_AVX512F_SCALAR,
ZYDIS_ISA_EXT_AVX512PF_512,
ZYDIS_ISA_EXT_AVX512_4FMAPS_512,
ZYDIS_ISA_EXT_AVX512_4FMAPS_SCALAR,
ZYDIS_ISA_EXT_AVX512_4VNNIW_512,
ZYDIS_ISA_EXT_AVX512_IFMA_128,
ZYDIS_ISA_EXT_AVX512_IFMA_256,
ZYDIS_ISA_EXT_AVX512_IFMA_512,
ZYDIS_ISA_EXT_AVX512_VBMI_128,
ZYDIS_ISA_EXT_AVX512_VBMI_256,
ZYDIS_ISA_EXT_AVX512_VBMI_512,
ZYDIS_ISA_EXT_AVX512_VPOPCNTDQ_512,
ZYDIS_ISA_EXT_AVXAES,
ZYDIS_ISA_EXT_BDW,
ZYDIS_ISA_EXT_BMI1,
ZYDIS_ISA_EXT_BMI2,
ZYDIS_ISA_EXT_CET,
ZYDIS_ISA_EXT_CLFLUSHOPT,
ZYDIS_ISA_EXT_CLFSH,
ZYDIS_ISA_EXT_CLWB,
ZYDIS_ISA_EXT_CLZERO,
ZYDIS_ISA_EXT_CMOV,
ZYDIS_ISA_EXT_CMPXCHG16B,
ZYDIS_ISA_EXT_F16C,
ZYDIS_ISA_EXT_FAT_NOP,
ZYDIS_ISA_EXT_FCMOV,
ZYDIS_ISA_EXT_FMA,
ZYDIS_ISA_EXT_FMA4,
ZYDIS_ISA_EXT_FXSAVE,
ZYDIS_ISA_EXT_FXSAVE64,
ZYDIS_ISA_EXT_I186,
ZYDIS_ISA_EXT_I286PROTECTED,
ZYDIS_ISA_EXT_I286REAL,
ZYDIS_ISA_EXT_I386,
ZYDIS_ISA_EXT_I486,
ZYDIS_ISA_EXT_I486REAL,
ZYDIS_ISA_EXT_I86,
ZYDIS_ISA_EXT_INVPCID,
ZYDIS_ISA_EXT_KNCE,
ZYDIS_ISA_EXT_KNCJKBR,
ZYDIS_ISA_EXT_KNCSTREAM,
ZYDIS_ISA_EXT_KNCV,
ZYDIS_ISA_EXT_KNC_MISC,
ZYDIS_ISA_EXT_KNC_PF_HINT,
ZYDIS_ISA_EXT_LAHF,
ZYDIS_ISA_EXT_LONGMODE,
ZYDIS_ISA_EXT_LZCNT,
ZYDIS_ISA_EXT_MONITOR,
ZYDIS_ISA_EXT_MOVBE,
ZYDIS_ISA_EXT_MPX,
ZYDIS_ISA_EXT_PAUSE,
ZYDIS_ISA_EXT_PCLMULQDQ,
ZYDIS_ISA_EXT_PENTIUMMMX,
ZYDIS_ISA_EXT_PENTIUMREAL,
ZYDIS_ISA_EXT_PKU,
ZYDIS_ISA_EXT_POPCNT,
ZYDIS_ISA_EXT_PPRO,
ZYDIS_ISA_EXT_PREFETCHWT1,
ZYDIS_ISA_EXT_PREFETCH_NOP,
ZYDIS_ISA_EXT_PT,
ZYDIS_ISA_EXT_RDPMC,
ZYDIS_ISA_EXT_RDRAND,
ZYDIS_ISA_EXT_RDSEED,
ZYDIS_ISA_EXT_RDTSCP,
ZYDIS_ISA_EXT_RDWRFSGS,
ZYDIS_ISA_EXT_RTM,
ZYDIS_ISA_EXT_SGX,
ZYDIS_ISA_EXT_SHA,
ZYDIS_ISA_EXT_SMAP,
ZYDIS_ISA_EXT_SMX,
ZYDIS_ISA_EXT_SSE,
ZYDIS_ISA_EXT_SSE2,
ZYDIS_ISA_EXT_SSE2MMX,
ZYDIS_ISA_EXT_SSE3,
ZYDIS_ISA_EXT_SSE3X87,
ZYDIS_ISA_EXT_SSE4,
ZYDIS_ISA_EXT_SSE42,
ZYDIS_ISA_EXT_SSEMXCSR,
ZYDIS_ISA_EXT_SSE_PREFETCH,
ZYDIS_ISA_EXT_SSSE3,
ZYDIS_ISA_EXT_SSSE3MMX,
ZYDIS_ISA_EXT_SVM,
ZYDIS_ISA_EXT_TBM,
ZYDIS_ISA_EXT_VMFUNC,
ZYDIS_ISA_EXT_VTX,
ZYDIS_ISA_EXT_X87,
ZYDIS_ISA_EXT_XOP,
ZYDIS_ISA_EXT_XSAVE,
ZYDIS_ISA_EXT_XSAVEC,
ZYDIS_ISA_EXT_XSAVEOPT,
ZYDIS_ISA_EXT_XSAVES
};

#define ZYDIS_ISA_EXT_MAX_VALUE ZYDIS_ISA_EXT_XSAVES
#define ZYDIS_ISA_EXT_MAX_BITS 0x0007
@@ -0,0 +1,74 @@
/**
* @brief Defines the `ZydisISASet` datatype.
*/
typedef uint8_t ZydisISASet;

/**
* @brief Values that represent `ZydisISASet` elements.
*/
enum ZydisISASets
{
ZYDIS_ISA_SET_INVALID,
ZYDIS_ISA_SET_AES,
ZYDIS_ISA_SET_AMD3DNOW,
ZYDIS_ISA_SET_AVX,
ZYDIS_ISA_SET_AVX2,
ZYDIS_ISA_SET_AVX2GATHER,
ZYDIS_ISA_SET_AVX512EVEX,
ZYDIS_ISA_SET_AVX512VEX,
ZYDIS_ISA_SET_AVXAES,
ZYDIS_ISA_SET_BASE,
ZYDIS_ISA_SET_BDW,
ZYDIS_ISA_SET_BMI1,
ZYDIS_ISA_SET_BMI2,
ZYDIS_ISA_SET_CET,
ZYDIS_ISA_SET_CLFLUSHOPT,
ZYDIS_ISA_SET_CLFSH,
ZYDIS_ISA_SET_CLWB,
ZYDIS_ISA_SET_CLZERO,
ZYDIS_ISA_SET_F16C,
ZYDIS_ISA_SET_FMA,
ZYDIS_ISA_SET_FMA4,
ZYDIS_ISA_SET_INVPCID,
ZYDIS_ISA_SET_KNC,
ZYDIS_ISA_SET_KNCE,
ZYDIS_ISA_SET_KNCV,
ZYDIS_ISA_SET_LONGMODE,
ZYDIS_ISA_SET_LZCNT,
ZYDIS_ISA_SET_MMX,
ZYDIS_ISA_SET_MONITOR,
ZYDIS_ISA_SET_MOVBE,
ZYDIS_ISA_SET_MPX,
ZYDIS_ISA_SET_PAUSE,
ZYDIS_ISA_SET_PCLMULQDQ,
ZYDIS_ISA_SET_PKU,
ZYDIS_ISA_SET_PREFETCHWT1,
ZYDIS_ISA_SET_PT,
ZYDIS_ISA_SET_RDRAND,
ZYDIS_ISA_SET_RDSEED,
ZYDIS_ISA_SET_RDTSCP,
ZYDIS_ISA_SET_RDWRFSGS,
ZYDIS_ISA_SET_RTM,
ZYDIS_ISA_SET_SGX,
ZYDIS_ISA_SET_SHA,
ZYDIS_ISA_SET_SMAP,
ZYDIS_ISA_SET_SMX,
ZYDIS_ISA_SET_SSE,
ZYDIS_ISA_SET_SSE2,
ZYDIS_ISA_SET_SSE3,
ZYDIS_ISA_SET_SSE4,
ZYDIS_ISA_SET_SSSE3,
ZYDIS_ISA_SET_SVM,
ZYDIS_ISA_SET_TBM,
ZYDIS_ISA_SET_VMFUNC,
ZYDIS_ISA_SET_VTX,
ZYDIS_ISA_SET_X87,
ZYDIS_ISA_SET_XOP,
ZYDIS_ISA_SET_XSAVE,
ZYDIS_ISA_SET_XSAVEC,
ZYDIS_ISA_SET_XSAVEOPT,
ZYDIS_ISA_SET_XSAVES
};

#define ZYDIS_ISA_SET_MAX_VALUE ZYDIS_ISA_SET_XSAVES
#define ZYDIS_ISA_SET_MAX_BITS 0x0006
@@ -0,0 +1,99 @@
/**
* @brief Defines the `ZydisInstructionCategory` datatype.
*/
typedef uint8_t ZydisInstructionCategory;

/**
* @brief Values that represent `ZydisInstructionCategory` elements.
*/
enum ZydisInstructionCategories
{
ZYDIS_CATEGORY_INVALID,
ZYDIS_CATEGORY_AES,
ZYDIS_CATEGORY_AMD3DNOW,
ZYDIS_CATEGORY_AVX,
ZYDIS_CATEGORY_AVX2,
ZYDIS_CATEGORY_AVX2GATHER,
ZYDIS_CATEGORY_AVX512,
ZYDIS_CATEGORY_AVX512_4FMAPS,
ZYDIS_CATEGORY_AVX512_4VNNIW,
ZYDIS_CATEGORY_AVX512_VBMI,
ZYDIS_CATEGORY_BDW,
ZYDIS_CATEGORY_BINARY,
ZYDIS_CATEGORY_BITBYTE,
ZYDIS_CATEGORY_BLEND,
ZYDIS_CATEGORY_BMI1,
ZYDIS_CATEGORY_BMI2,
ZYDIS_CATEGORY_BROADCAST,
ZYDIS_CATEGORY_CALL,
ZYDIS_CATEGORY_CET,
ZYDIS_CATEGORY_CLFLUSHOPT,
ZYDIS_CATEGORY_CLWB,
ZYDIS_CATEGORY_CLZERO,
ZYDIS_CATEGORY_CMOV,
ZYDIS_CATEGORY_COMPRESS,
ZYDIS_CATEGORY_COND_BR,
ZYDIS_CATEGORY_CONFLICT,
ZYDIS_CATEGORY_CONVERT,
ZYDIS_CATEGORY_DATAXFER,
ZYDIS_CATEGORY_DECIMAL,
ZYDIS_CATEGORY_EXPAND,
ZYDIS_CATEGORY_FCMOV,
ZYDIS_CATEGORY_FLAGOP,
ZYDIS_CATEGORY_FMA4,
ZYDIS_CATEGORY_GATHER,
ZYDIS_CATEGORY_IFMA,
ZYDIS_CATEGORY_INTERRUPT,
ZYDIS_CATEGORY_IO,
ZYDIS_CATEGORY_IOSTRINGOP,
ZYDIS_CATEGORY_KMASK,
ZYDIS_CATEGORY_KNC,
ZYDIS_CATEGORY_KNCMASK,
ZYDIS_CATEGORY_KNCSCALAR,
ZYDIS_CATEGORY_LOGICAL,
ZYDIS_CATEGORY_LOGICAL_FP,
ZYDIS_CATEGORY_LZCNT,
ZYDIS_CATEGORY_MISC,
ZYDIS_CATEGORY_MMX,
ZYDIS_CATEGORY_MPX,
ZYDIS_CATEGORY_NOP,
ZYDIS_CATEGORY_PCLMULQDQ,
ZYDIS_CATEGORY_PKU,
ZYDIS_CATEGORY_POP,
ZYDIS_CATEGORY_PREFETCH,
ZYDIS_CATEGORY_PREFETCHWT1,
ZYDIS_CATEGORY_PT,
ZYDIS_CATEGORY_PUSH,
ZYDIS_CATEGORY_RDRAND,
ZYDIS_CATEGORY_RDSEED,
ZYDIS_CATEGORY_RDWRFSGS,
ZYDIS_CATEGORY_RET,
ZYDIS_CATEGORY_ROTATE,
ZYDIS_CATEGORY_SCATTER,
ZYDIS_CATEGORY_SEGOP,
ZYDIS_CATEGORY_SEMAPHORE,
ZYDIS_CATEGORY_SETCC,
ZYDIS_CATEGORY_SGX,
ZYDIS_CATEGORY_SHA,
ZYDIS_CATEGORY_SHIFT,
ZYDIS_CATEGORY_SMAP,
ZYDIS_CATEGORY_SSE,
ZYDIS_CATEGORY_STRINGOP,
ZYDIS_CATEGORY_STTNI,
ZYDIS_CATEGORY_SYSCALL,
ZYDIS_CATEGORY_SYSRET,
ZYDIS_CATEGORY_SYSTEM,
ZYDIS_CATEGORY_TBM,
ZYDIS_CATEGORY_UFMA,
ZYDIS_CATEGORY_UNCOND_BR,
ZYDIS_CATEGORY_VFMA,
ZYDIS_CATEGORY_VTX,
ZYDIS_CATEGORY_WIDENOP,
ZYDIS_CATEGORY_X87_ALU,
ZYDIS_CATEGORY_XOP,
ZYDIS_CATEGORY_XSAVE,
ZYDIS_CATEGORY_XSAVEOPT
};

#define ZYDIS_CATEGORY_MAX_VALUE ZYDIS_CATEGORY_XSAVEOPT
#define ZYDIS_CATEGORY_MAX_BITS 0x0007

Large diffs are not rendered by default.

@@ -0,0 +1,87 @@
/***************************************************************************************************
Zyan Disassembler Library (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
*/

#ifndef ZYDIS_METAINFO_H
#define ZYDIS_METAINFO_H

#include <Zydis/Defines.h>
#include <Zydis/CommonTypes.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */

#include <Zydis/Generated/EnumInstructionCategory.h>
#include <Zydis/Generated/EnumISASet.h>
#include <Zydis/Generated/EnumISAExt.h>

/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */

/**
* @brief Returns the specified instruction category string.
*
* @param category The instruction category.
*
* @return The instruction category string or @c NULL, if an invalid category was passed.
*/
ZYDIS_EXPORT const char* ZydisCategoryGetString(ZydisInstructionCategory category);

/**
* @brief Returns the specified isa-set string.
*
* @param isaSet The isa-set.
*
* @return The isa-set string or @c NULL, if an invalid isa-set was passed.
*/
ZYDIS_EXPORT const char* ZydisISASetGetString(ZydisISASet isaSet);

/**
* @brief Returns the specified isa-extension string.
*
* @param isaExt The isa-extension.
*
* @return The isa-extension string or @c NULL, if an invalid isa-extension was passed.
*/
ZYDIS_EXPORT const char* ZydisISAExtGetString(ZydisISAExt isaExt);

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_METAINFO_H */
@@ -0,0 +1,67 @@
/***************************************************************************************************
Zyan Disassembler Library (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 Mnemonic constant definitions and helper functions.
*/

#ifndef ZYDIS_MNEMONIC_H
#define ZYDIS_MNEMONIC_H

#include <Zydis/Defines.h>
#include <Zydis/CommonTypes.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */

#include <Zydis/Generated/EnumMnemonic.h>

/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */

/**
* @brief Returns the specified instruction mnemonic string.
*
* @param mnemonic The mnemonic.
*
* @return The instruction mnemonic string or @c NULL, if an invalid mnemonic was passed.
*/
ZYDIS_EXPORT const char* ZydisMnemonicGetString(ZydisMnemonic mnemonic);

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_MNEMONIC_H */
@@ -0,0 +1,323 @@
/***************************************************************************************************
Zyan Disassembler Library (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 Utility functions and constants for registers.
*/

#ifndef ZYDIS_REGISTER_H
#define ZYDIS_REGISTER_H

#include <Zydis/Defines.h>
#include <Zydis/CommonTypes.h>
#include <Zydis/Status.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */

/* ---------------------------------------------------------------------------------------------- */
/* Registers */
/* ---------------------------------------------------------------------------------------------- */

/**
* @brief Defines the @c ZydisRegister datatype.
*/
typedef uint8_t ZydisRegister;

/**
* @brief Values that represent zydis registers.
*/
enum ZydisRegisters
{
ZYDIS_REGISTER_NONE,
// General purpose registers 8-bit
ZYDIS_REGISTER_AL, ZYDIS_REGISTER_CL, ZYDIS_REGISTER_DL, ZYDIS_REGISTER_BL,
ZYDIS_REGISTER_AH, ZYDIS_REGISTER_CH, ZYDIS_REGISTER_DH, ZYDIS_REGISTER_BH,
ZYDIS_REGISTER_SPL, ZYDIS_REGISTER_BPL, ZYDIS_REGISTER_SIL, ZYDIS_REGISTER_DIL,
ZYDIS_REGISTER_R8B, ZYDIS_REGISTER_R9B, ZYDIS_REGISTER_R10B, ZYDIS_REGISTER_R11B,
ZYDIS_REGISTER_R12B, ZYDIS_REGISTER_R13B, ZYDIS_REGISTER_R14B, ZYDIS_REGISTER_R15B,
// General purpose registers 16-bit
ZYDIS_REGISTER_AX, ZYDIS_REGISTER_CX, ZYDIS_REGISTER_DX, ZYDIS_REGISTER_BX,
ZYDIS_REGISTER_SP, ZYDIS_REGISTER_BP, ZYDIS_REGISTER_SI, ZYDIS_REGISTER_DI,
ZYDIS_REGISTER_R8W, ZYDIS_REGISTER_R9W, ZYDIS_REGISTER_R10W, ZYDIS_REGISTER_R11W,
ZYDIS_REGISTER_R12W, ZYDIS_REGISTER_R13W, ZYDIS_REGISTER_R14W, ZYDIS_REGISTER_R15W,
// General purpose registers 32-bit
ZYDIS_REGISTER_EAX, ZYDIS_REGISTER_ECX, ZYDIS_REGISTER_EDX, ZYDIS_REGISTER_EBX,
ZYDIS_REGISTER_ESP, ZYDIS_REGISTER_EBP, ZYDIS_REGISTER_ESI, ZYDIS_REGISTER_EDI,
ZYDIS_REGISTER_R8D, ZYDIS_REGISTER_R9D, ZYDIS_REGISTER_R10D, ZYDIS_REGISTER_R11D,
ZYDIS_REGISTER_R12D, ZYDIS_REGISTER_R13D, ZYDIS_REGISTER_R14D, ZYDIS_REGISTER_R15D,
// General purpose registers 64-bit
ZYDIS_REGISTER_RAX, ZYDIS_REGISTER_RCX, ZYDIS_REGISTER_RDX, ZYDIS_REGISTER_RBX,
ZYDIS_REGISTER_RSP, ZYDIS_REGISTER_RBP, ZYDIS_REGISTER_RSI, ZYDIS_REGISTER_RDI,
ZYDIS_REGISTER_R8, ZYDIS_REGISTER_R9, ZYDIS_REGISTER_R10, ZYDIS_REGISTER_R11,
ZYDIS_REGISTER_R12, ZYDIS_REGISTER_R13, ZYDIS_REGISTER_R14, ZYDIS_REGISTER_R15,
// Floating point legacy registers
ZYDIS_REGISTER_ST0, ZYDIS_REGISTER_ST1, ZYDIS_REGISTER_ST2, ZYDIS_REGISTER_ST3,
ZYDIS_REGISTER_ST4, ZYDIS_REGISTER_ST5, ZYDIS_REGISTER_ST6, ZYDIS_REGISTER_ST7,
// Floating point multimedia registers
ZYDIS_REGISTER_MM0, ZYDIS_REGISTER_MM1, ZYDIS_REGISTER_MM2, ZYDIS_REGISTER_MM3,
ZYDIS_REGISTER_MM4, ZYDIS_REGISTER_MM5, ZYDIS_REGISTER_MM6, ZYDIS_REGISTER_MM7,
// Floating point vector registers 512-bit
ZYDIS_REGISTER_ZMM0, ZYDIS_REGISTER_ZMM1, ZYDIS_REGISTER_ZMM2, ZYDIS_REGISTER_ZMM3,
ZYDIS_REGISTER_ZMM4, ZYDIS_REGISTER_ZMM5, ZYDIS_REGISTER_ZMM6, ZYDIS_REGISTER_ZMM7,
ZYDIS_REGISTER_ZMM8, ZYDIS_REGISTER_ZMM9, ZYDIS_REGISTER_ZMM10, ZYDIS_REGISTER_ZMM11,
ZYDIS_REGISTER_ZMM12, ZYDIS_REGISTER_ZMM13, ZYDIS_REGISTER_ZMM14, ZYDIS_REGISTER_ZMM15,
ZYDIS_REGISTER_ZMM16, ZYDIS_REGISTER_ZMM17, ZYDIS_REGISTER_ZMM18, ZYDIS_REGISTER_ZMM19,
ZYDIS_REGISTER_ZMM20, ZYDIS_REGISTER_ZMM21, ZYDIS_REGISTER_ZMM22, ZYDIS_REGISTER_ZMM23,
ZYDIS_REGISTER_ZMM24, ZYDIS_REGISTER_ZMM25, ZYDIS_REGISTER_ZMM26, ZYDIS_REGISTER_ZMM27,
ZYDIS_REGISTER_ZMM28, ZYDIS_REGISTER_ZMM29, ZYDIS_REGISTER_ZMM30, ZYDIS_REGISTER_ZMM31,
// Floating point vector registers 256-bit
ZYDIS_REGISTER_YMM0, ZYDIS_REGISTER_YMM1, ZYDIS_REGISTER_YMM2, ZYDIS_REGISTER_YMM3,
ZYDIS_REGISTER_YMM4, ZYDIS_REGISTER_YMM5, ZYDIS_REGISTER_YMM6, ZYDIS_REGISTER_YMM7,
ZYDIS_REGISTER_YMM8, ZYDIS_REGISTER_YMM9, ZYDIS_REGISTER_YMM10, ZYDIS_REGISTER_YMM11,
ZYDIS_REGISTER_YMM12, ZYDIS_REGISTER_YMM13, ZYDIS_REGISTER_YMM14, ZYDIS_REGISTER_YMM15,
ZYDIS_REGISTER_YMM16, ZYDIS_REGISTER_YMM17, ZYDIS_REGISTER_YMM18, ZYDIS_REGISTER_YMM19,
ZYDIS_REGISTER_YMM20, ZYDIS_REGISTER_YMM21, ZYDIS_REGISTER_YMM22, ZYDIS_REGISTER_YMM23,
ZYDIS_REGISTER_YMM24, ZYDIS_REGISTER_YMM25, ZYDIS_REGISTER_YMM26, ZYDIS_REGISTER_YMM27,
ZYDIS_REGISTER_YMM28, ZYDIS_REGISTER_YMM29, ZYDIS_REGISTER_YMM30, ZYDIS_REGISTER_YMM31,
// Floating point vector registers 128-bit
ZYDIS_REGISTER_XMM0, ZYDIS_REGISTER_XMM1, ZYDIS_REGISTER_XMM2, ZYDIS_REGISTER_XMM3,
ZYDIS_REGISTER_XMM4, ZYDIS_REGISTER_XMM5, ZYDIS_REGISTER_XMM6, ZYDIS_REGISTER_XMM7,
ZYDIS_REGISTER_XMM8, ZYDIS_REGISTER_XMM9, ZYDIS_REGISTER_XMM10, ZYDIS_REGISTER_XMM11,
ZYDIS_REGISTER_XMM12, ZYDIS_REGISTER_XMM13, ZYDIS_REGISTER_XMM14, ZYDIS_REGISTER_XMM15,
ZYDIS_REGISTER_XMM16, ZYDIS_REGISTER_XMM17, ZYDIS_REGISTER_XMM18, ZYDIS_REGISTER_XMM19,
ZYDIS_REGISTER_XMM20, ZYDIS_REGISTER_XMM21, ZYDIS_REGISTER_XMM22, ZYDIS_REGISTER_XMM23,
ZYDIS_REGISTER_XMM24, ZYDIS_REGISTER_XMM25, ZYDIS_REGISTER_XMM26, ZYDIS_REGISTER_XMM27,
ZYDIS_REGISTER_XMM28, ZYDIS_REGISTER_XMM29, ZYDIS_REGISTER_XMM30, ZYDIS_REGISTER_XMM31,
// Flags registers
ZYDIS_REGISTER_RFLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_FLAGS,
// Instruction-pointer registers
ZYDIS_REGISTER_RIP, ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP,
// Special registers
ZYDIS_REGISTER_MXCSR, ZYDIS_REGISTER_PKRU, ZYDIS_REGISTER_XCR0,
// Segment registers
ZYDIS_REGISTER_ES, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_DS,
ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS,
// Table registers
ZYDIS_REGISTER_GDTR, ZYDIS_REGISTER_LDTR, ZYDIS_REGISTER_IDTR, ZYDIS_REGISTER_TR,
// Test registers
ZYDIS_REGISTER_TR0, ZYDIS_REGISTER_TR1, ZYDIS_REGISTER_TR2, ZYDIS_REGISTER_TR3,
ZYDIS_REGISTER_TR4, ZYDIS_REGISTER_TR5, ZYDIS_REGISTER_TR6, ZYDIS_REGISTER_TR7,
// Control registers
ZYDIS_REGISTER_CR0, ZYDIS_REGISTER_CR1, ZYDIS_REGISTER_CR2, ZYDIS_REGISTER_CR3,
ZYDIS_REGISTER_CR4, ZYDIS_REGISTER_CR5, ZYDIS_REGISTER_CR6, ZYDIS_REGISTER_CR7,
ZYDIS_REGISTER_CR8, ZYDIS_REGISTER_CR9, ZYDIS_REGISTER_CR10, ZYDIS_REGISTER_CR11,
ZYDIS_REGISTER_CR12, ZYDIS_REGISTER_CR13, ZYDIS_REGISTER_CR14, ZYDIS_REGISTER_CR15,
// Debug registers
ZYDIS_REGISTER_DR0, ZYDIS_REGISTER_DR1, ZYDIS_REGISTER_DR2, ZYDIS_REGISTER_DR3,
ZYDIS_REGISTER_DR4, ZYDIS_REGISTER_DR5, ZYDIS_REGISTER_DR6, ZYDIS_REGISTER_DR7,
ZYDIS_REGISTER_DR8, ZYDIS_REGISTER_DR9, ZYDIS_REGISTER_DR10, ZYDIS_REGISTER_DR11,
ZYDIS_REGISTER_DR12, ZYDIS_REGISTER_DR13, ZYDIS_REGISTER_DR14, ZYDIS_REGISTER_DR15,
// Mask registers
ZYDIS_REGISTER_K0, ZYDIS_REGISTER_K1, ZYDIS_REGISTER_K2, ZYDIS_REGISTER_K3,
ZYDIS_REGISTER_K4, ZYDIS_REGISTER_K5, ZYDIS_REGISTER_K6, ZYDIS_REGISTER_K7,
// Bound registers
ZYDIS_REGISTER_BND0, ZYDIS_REGISTER_BND1, ZYDIS_REGISTER_BND2, ZYDIS_REGISTER_BND3,
ZYDIS_REGISTER_BNDCFG, ZYDIS_REGISTER_BNDSTATUS,

/**
* @brief Maximum value of this enum.
*/
ZYDIS_REGISTER_MAX_VALUE = ZYDIS_REGISTER_BNDSTATUS,
/**
* @brief Maximum amount of bits occupied by an integer from this enum.
*/
ZYDIS_REGISTER_MAX_BITS = 8
};

/* ---------------------------------------------------------------------------------------------- */
/* Register classes */
/* ---------------------------------------------------------------------------------------------- */

/**
* @brief Defines the @c ZydisRegisterClass datatype.
*/
typedef uint8_t ZydisRegisterClass;

/**
* @brief Values that represent zydis register-classes.
*/
enum ZydisRegisterClasses
{
ZYDIS_REGCLASS_INVALID,
/**
* @brief 8-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR8,
/**
* @brief 16-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR16,
/**
* @brief 32-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR32,
/**
* @brief 64-bit general-purpose registers.
*/
ZYDIS_REGCLASS_GPR64,
/**
* @brief Floating point legacy registers.
*/
ZYDIS_REGCLASS_X87,
/**
* @brief Floating point multimedia registers.
*/
ZYDIS_REGCLASS_MMX,
/**
* @brief 128-bit vector registers.
*/
ZYDIS_REGCLASS_XMM,
/**
* @brief 256-bit vector registers.
*/
ZYDIS_REGCLASS_YMM,
/**
* @brief 512-bit vector registers.
*/
ZYDIS_REGCLASS_ZMM,
/**
* @brief Flags registers.
*/
ZYDIS_REGCLASS_FLAGS,
/**
* @brief Instruction-pointer registers.
*/
ZYDIS_REGCLASS_IP,
/**
* @brief Segment registers.
*/
ZYDIS_REGCLASS_SEGMENT,
/**
* @brief Test registers.
*/
ZYDIS_REGCLASS_TEST,
/**
* @brief Control registers.
*/
ZYDIS_REGCLASS_CONTROL,
/**
* @brief Debug registers.
*/
ZYDIS_REGCLASS_DEBUG,
/**
* @brief Mask registers.
*/
ZYDIS_REGCLASS_MASK,
/**
* @brief Bound registers.
*/
ZYDIS_REGCLASS_BOUND,
/**
* @brief Maximum value of this enum.
*/
ZYDIS_REGCLASS_MAX_VALUE = ZYDIS_REGCLASS_BOUND
};

/* ---------------------------------------------------------------------------------------------- */
/* Register width */
/* ---------------------------------------------------------------------------------------------- */

/**
* @brief Defines the @c ZydisRegisterWidth datatype.
*/
typedef uint16_t ZydisRegisterWidth;

/* ---------------------------------------------------------------------------------------------- */

/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */

/**
* @brief Returns the register specified by the @c registerClass and the @c id.
*
* @param registerClass The register class.
* @param id The register id.
*
* @return The register specified by the @c registerClass and the @c id or @c ZYDIS_REGISTER_NONE,
* if an invalid parameter was passed.
*/
ZYDIS_EXPORT ZydisRegister ZydisRegisterEncode(ZydisRegisterClass registerClass, uint8_t id);

/**
* @brief Returns the id of the specified register.
*
* @param reg The register.
*
* @return The id of the specified register, or -1 if an invalid parameter was passed.
*/
ZYDIS_EXPORT int16_t ZydisRegisterGetId(ZydisRegister reg);

/**
* @brief Returns the register-class of the specified register.
*
* @param reg The register.
*
* @return The register-class of the specified register.
*/
ZYDIS_EXPORT ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg);

/**
* @brief Returns the width of the specified register.
*
* @param reg The register.
*
* @return The width of the specified register.
*/
ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth(ZydisRegister reg);

/**
* @brief Returns the width of the specified register in 64-bit mode.
*
* @param reg The register.
*
* @return The width of the specified register.
*/
ZYDIS_EXPORT ZydisRegisterWidth ZydisRegisterGetWidth64(ZydisRegister reg);

/**
* @brief Returns the specified register string.
*
* @param reg The register.
*
* @return The register string or @c NULL, if an invalid register was passed.
*/
ZYDIS_EXPORT const char* ZydisRegisterGetString(ZydisRegister reg);

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_REGISTER_H */

Large diffs are not rendered by default.

@@ -0,0 +1,180 @@
/***************************************************************************************************
Zyan Disassembler Library (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 Status code definitions and check macros.
*/

#ifndef ZYDIS_STATUS_H
#define ZYDIS_STATUS_H

#include <Zydis/CommonTypes.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */

/**
* @brief Defines the @c ZydisStatus datatype.
*/
typedef uint32_t ZydisStatus;

/**
* @brief Values that represent a zydis status-codes.
*/
enum ZydisStatusCode
{
/* ------------------------------------------------------------------------------------------ */
/* General */
/* ------------------------------------------------------------------------------------------ */

/**
* @brief The operation completed successfully.
*/
ZYDIS_STATUS_SUCCESS = 0x00000000,
/**
* @brief An invalid parameter was passed to a function.
*/
ZYDIS_STATUS_INVALID_PARAMETER,
/**
* @brief An attempt was made to perform an invalid operation.
*/
ZYDIS_STATUS_INVALID_OPERATION,
/**
* @brief A buffer passed to a function was too small to complete the requested operation.
*/
ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE,

/* ------------------------------------------------------------------------------------------ */
/* Decoder */
/* ------------------------------------------------------------------------------------------ */

/**
* @brief An attempt was made to read data from an input data-source that has no more data
* available.
*/
ZYDIS_STATUS_NO_MORE_DATA,
/**
* @brief An general error occured while decoding the current instruction. The instruction
* might be undefined.
*/
ZYDIS_STATUS_DECODING_ERROR,
/**
* @brief The instruction exceeded the maximum length of 15 bytes.
*/
ZYDIS_STATUS_INSTRUCTION_TOO_LONG,
/**
* @brief The instruction encoded an invalid register.
*/
ZYDIS_STATUS_BAD_REGISTER,
/**
* @brief A lock-prefix (F0) was found while decoding an instruction that does not support
* locking.
*/
ZYDIS_STATUS_ILLEGAL_LOCK,
/**
* @brief A legacy-prefix (F2, F3, 66) was found while decoding a XOP/VEX/EVEX/MVEX
* instruction.
*/
ZYDIS_STATUS_ILLEGAL_LEGACY_PFX,
/**
* @brief A rex-prefix was found while decoding a XOP/VEX/EVEX/MVEX instruction.
*/
ZYDIS_STATUS_ILLEGAL_REX,
/**
* @brief An invalid opcode-map value was found while decoding a XOP/VEX/EVEX/MVEX-prefix.
*/
ZYDIS_STATUS_INVALID_MAP,
/**
* @brief An error occured while decoding the EVEX-prefix.
*/
ZYDIS_STATUS_MALFORMED_EVEX,
/**
* @brief An error occured while decoding the MVEX-prefix.
*/
ZYDIS_STATUS_MALFORMED_MVEX, // TODO: Do we need this?
/**
* @brief An invalid write-mask was specified for an EVEX/MVEX instruction.
*/
ZYDIS_STATUS_INVALID_MASK,

/* ------------------------------------------------------------------------------------------ */
/* Encoder */
/* ------------------------------------------------------------------------------------------ */

ZYDIS_STATUS_IMPOSSIBLE_INSTRUCTION,

/* ------------------------------------------------------------------------------------------ */
/* Misc */
/* ------------------------------------------------------------------------------------------ */

/**
* @brief The base value for user-defined status codes.
*/
ZYDIS_STATUS_USER = 0x10000000

// Max value entry intentionally omitted since users might
// define custom error codes for formatter hooks.
};

/* ============================================================================================== */
/* Macros */
/* ============================================================================================== */

/**
* @brief Checks if a zydis operation was successfull.
*
* @param status The zydis status-code to check.
*/
#define ZYDIS_SUCCESS(status) (status == ZYDIS_STATUS_SUCCESS)

/**
* @brief Checks if a zydis operation was successfull and returns the status-code, if not.
*
* @param status The zydis status-code to check.
*/
#define ZYDIS_CHECK(status) \
do \
{ \
ZydisStatus s = status; \
if (!ZYDIS_SUCCESS(s)) \
{ \
return s; \
} \
} while (0)

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_STATUS_H */
@@ -0,0 +1,87 @@
/***************************************************************************************************
Zyan Disassembler Library (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 Other utility functions.
*/

#ifndef ZYDIS_UTILS_H
#define ZYDIS_UTILS_H

#include <Zydis/Defines.h>
#include <Zydis/Status.h>
#include <Zydis/DecoderTypes.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Address calculation */
/* ============================================================================================== */

/**
* @brief Calculates the absolute target-address for the given instruction operand.
*
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param operand A pointer to the @c ZydisDecodedOperand struct.
* @param address A pointer to the memory that receives the absolute target-address.
*
* @return A zydis status code.
*
* You should use this function in the following cases:
* - `IMM` operands with relative address (e.g. `JMP`, `CALL`, ...)
* - `MEM` operands with RIP/EIP-relative address (e.g. `MOV RAX, [RIP+0x12345678]`)
* - `MEM` operands with absolute address (e.g. `MOV RAX, [0x12345678]`)
* - The displacement needs to get truncated and zero extended
*/
ZYDIS_EXPORT ZydisStatus ZydisCalcAbsoluteAddress(const ZydisDecodedInstruction* instruction,
const ZydisDecodedOperand* operand, uint64_t* address);

/* ============================================================================================== */
/* Flags */
/* ============================================================================================== */

/**
* @brief Returns a mask of accessed CPU-flags matching the given `action`.
*
* @param instruction A pointer to the @c ZydisDecodedInstruction struct.
* @param action The CPU-flag action.
* @param flags A pointer to the variable that receives the flag mask.
*
* @return A zydis status code.
*/
ZYDIS_EXPORT ZydisStatus ZydisGetAccessedFlagsByAction(const ZydisDecodedInstruction* instruction,
ZydisCPUFlagAction action, ZydisCPUFlagMask* flags);

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_UTILS_H */
@@ -0,0 +1,147 @@
/***************************************************************************************************
Zyan Disassembler Library (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 Master include file, including everything else.
*/

#ifndef ZYDIS_H
#define ZYDIS_H

#include <Zydis/CommonTypes.h>
#include <Zydis/Decoder.h>
#include <Zydis/DecoderTypes.h>
#include <Zydis/Defines.h>
#include <Zydis/Formatter.h>
#include <Zydis/MetaInfo.h>
#include <Zydis/Mnemonic.h>
#include <Zydis/Register.h>
#include <Zydis/SharedTypes.h>
#include <Zydis/Status.h>
#include <Zydis/Utils.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ============================================================================================== */
/* Macros */
/* ============================================================================================== */

/* ---------------------------------------------------------------------------------------------- */
/* Constants */
/* ---------------------------------------------------------------------------------------------- */

/**
* @brief A macro that defines the zydis version.
*/
#define ZYDIS_VERSION (uint64_t)0x0002000000000000

/* ---------------------------------------------------------------------------------------------- */
/* Helper macros */
/* ---------------------------------------------------------------------------------------------- */

/**
* @brief Extracts the major-part of the zydis version.
*
* @param version The zydis version value
*/
#define ZYDIS_VERSION_MAJOR(version) (uint16_t)((version & 0xFFFF000000000000) >> 48)

/**
* @brief Extracts the minor-part of the zydis version.
*
* @param version The zydis version value
*/
#define ZYDIS_VERSION_MINOR(version) (uint16_t)((version & 0x0000FFFF00000000) >> 32)

/**
* @brief Extracts the patch-part of the zydis version.
*
* @param version The zydis version value
*/
#define ZYDIS_VERSION_PATCH(version) (uint16_t)((version & 0x00000000FFFF0000) >> 16)

/**
* @brief Extracts the build-part of the zydis version.
*
* @param version The zydis version value
*/
#define ZYDIS_VERSION_BUILD(version) (uint16_t)(version & 0x000000000000FFFF)

/* ---------------------------------------------------------------------------------------------- */

/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */

/**
* @brief Defines the @c ZydisFeature datatype.
*/
typedef uint8_t ZydisFeature;

/**
* @brief Values that represent zydis features.
*/
enum ZydisFeatures
{
ZYDIS_FEATURE_EVEX,
ZYDIS_FEATURE_MVEX,
ZYDIS_FEATURE_FLAGS,
ZYDIS_FEATURE_CPUID
};

/* ============================================================================================== */
/* Exported functions */
/* ============================================================================================== */

/**
* @brief Returns the zydis version.
*
* @return The zydis version.
*
* Use the macros provided in this file to extract the major, minor, patch and build part from the
* returned version value.
*/
ZYDIS_EXPORT uint64_t ZydisGetVersion();

/**
* @brief Checks, if the specified feature is enabled in the current zydis library instance.
*
* @param feature The feature.
*
* @return @c True if the feature is enabled, @c false if not.
*/
ZYDIS_EXPORT ZydisBool ZydisIsFeatureEnabled(ZydisFeature feature);

/* ============================================================================================== */

#ifdef __cplusplus
}
#endif

#endif /* ZYDIS_H */