From 4a79d5762ea7f15a5961733cc6d3a7704d3d5206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20H=C3=B6ner?= Date: Fri, 18 Aug 2017 13:34:00 +0200 Subject: [PATCH 1/2] Updated README.md - Fixed example - Added credits section - A little bit of rephrasing in the `Feature` section --- README.md | 79 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index e5d223b..2622719 100644 --- a/README.md +++ b/README.md @@ -3,22 +3,23 @@ Fast and lightweight x86/x86-64 disassembler library. -## Features ## +## Features -- Supports all x86 and x86-64 (AMD64) general-purpose and system instructions. -- Supports pretty much all ISA extensions: +- 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 - - Perfect for kernel-mode drivers and embedded devices +- No dynamic memory allocation ("malloc") - Very small file-size overhead compared to other common disassembler libraries -- Complete doxygen documentation +- [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 ## +## Roadmap - Language bindings [v2.0 final] - Tests [v2.0 final] @@ -26,7 +27,7 @@ Fast and lightweight x86/x86-64 disassembler library. - Implement CMake feature gates. Currently, everything is always included. [v2.0 final] - Encoding support [v2.1] -## Quick Example ## +## Quick Example The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console. @@ -43,47 +44,59 @@ int main() 0x88, 0xFC, 0xDA, 0x02, 0x00 }; + // Initialize decoder context. ZydisDecoder decoder; - ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); + 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; - 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); + 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; - char buffer[256]; - while (ZYDIS_SUCCESS( - ZydisDecoderDecodeBuffer(decoder, data, length, instructionPointer, &instruction))) + while (ZYDIS_SUCCESS(ZydisDecoderDecodeBuffer( + &decoder, readPointer, length, instructionPointer, &instruction))) { - data += instruction.length; + // 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; - printf("%016" PRIX64 " ", instruction.instrAddress); - ZydisFormatterFormatInstruction(&formatter, &instruction, &buffer[0], sizeof(buffer)); - printf(" %s\n", &buffer[0]); } } ``` -## Sample Output ## +## Sample Output The above example program generates the following output: ``` 007FFFFFFF400000 push rcx -007FFFFFFF400001 lea eax, dword ptr ss:[rbp-0x01] +007FFFFFFF400001 lea eax, [rbp-0x01] 007FFFFFFF400004 push rax -007FFFFFFF400005 push qword ptr ss:[rbp+0x0C] -007FFFFFFF400008 push qword ptr ss:[rbp+0x08] -007FFFFFFF40000B call qword ptr ds:[0x008000007588A5B1] +007FFFFFFF400005 push qword ptr [rbp+0x0C] +007FFFFFFF400008 push qword ptr [rbp+0x08] +007FFFFFFF40000B call [0x008000007588A5B1] 007FFFFFFF400011 test eax, eax 007FFFFFFF400013 js 0x007FFFFFFF42DB15 ``` -## Compilation ## +## Compilation Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C99 compiler. @@ -96,9 +109,15 @@ cmake .. make ``` -## `ZydisInfo` tool ## +## `ZydisInfo` tool ![ZydisInfo](https://raw.githubusercontent.com/zyantific/zydis/master/assets/screenshots/ZydisInfo.png) -## License ## +## 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) -Zydis is licensed under the MIT license. \ No newline at end of file +## License + +Zydis is licensed under the MIT license. From 95338c59bc1fc75b2711934db05116a2262ba21a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joel=20Ho=CC=88ner?= Date: Tue, 24 Oct 2017 17:21:09 +0200 Subject: [PATCH 2/2] Added previously forgotten const qualifiers - Also, fixed integer comparision warning in `ZydisPerfTest` --- examples/ZydisPerfTest.c | 2 +- include/Zydis/Formatter.h | 4 ++-- src/Formatter.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/ZydisPerfTest.c b/examples/ZydisPerfTest.c index 5344fd6..5783e89 100644 --- a/examples/ZydisPerfTest.c +++ b/examples/ZydisPerfTest.c @@ -393,7 +393,7 @@ int main(int argc, char** argv) } rewind(file); - if (fread(buffer, 1, length, file) != length) + if (fread(buffer, 1, length, file) != (size_t)length) { fprintf(stderr, "Could not read %" PRIu64 " bytes from file \"%s\"", (uint64_t)length, &buf[0]); diff --git a/include/Zydis/Formatter.h b/include/Zydis/Formatter.h index 9593b4a..92fea83 100644 --- a/include/Zydis/Formatter.h +++ b/include/Zydis/Formatter.h @@ -536,7 +536,7 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, * @return A zydis status code. */ ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, - ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen); + const ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen); /** * @brief Formats the given instruction and writes it into the output buffer. @@ -551,7 +551,7 @@ ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* f * @return A zydis status code. */ ZYDIS_EXPORT ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter, - ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen, void* userData); + const ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen, void* userData); /* ============================================================================================== */ diff --git a/src/Formatter.c b/src/Formatter.c index 3368b05..ed4607d 100644 --- a/src/Formatter.c +++ b/src/Formatter.c @@ -1074,13 +1074,13 @@ ZydisStatus ZydisFormatterSetHook(ZydisFormatter* formatter, ZydisFormatterHookT } ZydisStatus ZydisFormatterFormatInstruction(const ZydisFormatter* formatter, - ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen) + const ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen) { return ZydisFormatterFormatInstructionEx(formatter, instruction, buffer, bufferLen, NULL); } ZydisStatus ZydisFormatterFormatInstructionEx(const ZydisFormatter* formatter, - ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen, void* userData) + const ZydisDecodedInstruction* instruction, char* buffer, size_t bufferLen, void* userData) { if (!formatter || !instruction || !buffer || (bufferLen == 0)) {