| @@ -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) | ||
| [](https://opensource.org/licenses/MIT) [](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 | ||
|  | ||
|
|
||
| ## 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) |
| @@ -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; | ||
| } | ||
|
|
||
| /* ============================================================================================== */ | ||
|
|
| @@ -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 */ |
| @@ -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 */ |
| @@ -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 |
| @@ -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 */ |
| @@ -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 */ |