Merge branch 'develop'

This commit is contained in:
athre0z 2015-05-22 17:45:06 +02:00
commit 5bab2410fc
17 changed files with 460 additions and 184 deletions

View File

@ -16,7 +16,7 @@ if (NOT CONFIGURED_ONCE)
set(compiler_specific "-Werror") set(compiler_specific "-Werror")
set(compiler_specific_cxx "-std=c++14") set(compiler_specific_cxx "-std=c++14")
elseif (MSVC) elseif (MSVC)
set(compiler_specific "/WX /W4 /D_CRT_SECURE_NO_WARNINGS") set(compiler_specific "/WX /W4 /D_CRT_SECURE_NO_WARNINGS /GR-")
endif () endif ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${compiler_specific} ${compiler_specific_cxx}" set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${compiler_specific} ${compiler_specific_cxx}"
@ -27,7 +27,7 @@ endif ()
# CMake always orders MSVC to build with a shared CRT. Hack CMake variables in order # CMake always orders MSVC to build with a shared CRT. Hack CMake variables in order
# to generate with a statically linked CRT when we build as a static library. # to generate with a statically linked CRT when we build as a static library.
if (MSVC AND NOT BUILD_SHARED_LIBS AND NOT FORCE_SHARED_CRT) if (MSVC AND NOT FORCE_SHARED_CRT)
set(manipulated_vars set(manipulated_vars
CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL
@ -58,6 +58,11 @@ set(sources
"Zydis/ZydisSymbolResolver.cpp" "Zydis/ZydisSymbolResolver.cpp"
"Zydis/ZydisUtils.cpp") "Zydis/ZydisUtils.cpp")
if (BUILD_SHARED_LIBS AND WIN32)
set(sources ${sources}
"Zydis/VersionInfo.rc")
endif ()
if (BUILD_C_BINDINGS) if (BUILD_C_BINDINGS)
set(headers ${headers} set(headers ${headers}
"Zydis/ZydisAPI.h") "Zydis/ZydisAPI.h")
@ -66,6 +71,7 @@ if (BUILD_C_BINDINGS)
endif () endif ()
add_library("Zydis" ${headers} ${sources}) add_library("Zydis" ${headers} ${sources})
set_target_properties("Zydis" PROPERTIES COMPILE_DEFINITIONS "Zydis_EXPORTS")
generate_export_header( generate_export_header(
"Zydis" "Zydis"
BASE_NAME "ZYDIS" BASE_NAME "ZYDIS"
@ -78,6 +84,8 @@ if (BUILD_EXAMPLES)
add_executable("SimpleDemo_CPP" "Examples/CPP/SimpleDemo/SimpleDemo.cpp") add_executable("SimpleDemo_CPP" "Examples/CPP/SimpleDemo/SimpleDemo.cpp")
target_link_libraries("SimpleDemo_CPP" "Zydis") target_link_libraries("SimpleDemo_CPP" "Zydis")
add_executable("CustomDataSource_CPP" "Examples/CPP/CustomDataSource/CustomDataSource.cpp")
target_link_libraries("CustomDataSource_CPP" "Zydis")
if (BUILD_C_BINDINGS) if (BUILD_C_BINDINGS)
add_executable("SimpleDemo_C" "Examples/C/SimpleDemo/SimpleDemo.c") add_executable("SimpleDemo_C" "Examples/C/SimpleDemo/SimpleDemo.c")

View File

@ -154,7 +154,7 @@ int main()
puts("64 bit test ...\n\n"); puts("64 bit test ...\n\n");
while (ZydisDecodeInstruction(decoder, &info)) while (ZydisDecodeInstruction(decoder, &info))
{ {
printf("%016"PRIu64"X ", info.instrAddress); printf("%016"PRIX64" ", info.instrAddress);
if (info.flags & ZYDIS_IF_ERROR_MASK) if (info.flags & ZYDIS_IF_ERROR_MASK)
{ {
printf("db %02X", info.data[0]); printf("db %02X", info.data[0]);

View File

@ -0,0 +1,169 @@
/***************************************************************************************************
Zyan Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications : 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.
***************************************************************************************************/
#include <stdint.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <sstream>
#include <Zydis.hpp>
class ZydisStdinInput : public Zydis::BaseInput
{
private:
std::vector<uint8_t> m_buffer;
uint32_t m_position = 0;
uint64_t m_globalPosition = 0;
private:
void gatherInput();
protected:
uint8_t internalInputPeek() override;
uint8_t internalInputNext() override;
public:
bool isEndOfInput() const override;
uint64_t getPosition() const override;
bool setPosition(uint64_t position) override;
};
void ZydisStdinInput::gatherInput()
{
if (m_position != m_buffer.size())
{
return;
}
std::vector<uint8_t> buffer;
bool valid;
do
{
valid = true;
buffer.clear();
std::string input;
std::getline(std::cin, input);
if (input.empty())
{
valid = false;
continue;
}
std::istringstream ss(input);
uint32_t x;
do
{
ss >> std::hex >> x;
if (ss.fail())
{
std::cout << std::endl << "# Error: Invalid hex input." << std::endl << std::endl;
ss.ignore();
valid = false;
break;
}
if (buffer.size() == buffer.capacity())
{
buffer.reserve(buffer.capacity() + 512);
}
if (x > 255)
{
std::cout << std::endl << "# Warning: 0x"
<< std::hex << std::setw(8) << std::setfill('0') << std::uppercase << x
<< " converted to uint8_t. Possible data loss." << std::endl << std::endl;
}
buffer.resize(buffer.size() + 1);
buffer[buffer.size() - 1] = static_cast<uint8_t>(x);
} while (!ss.eof());
} while (!valid);
m_buffer = buffer;
m_position = 0;
}
uint8_t ZydisStdinInput::internalInputPeek()
{
gatherInput();
return m_buffer[m_position];
}
uint8_t ZydisStdinInput::internalInputNext()
{
gatherInput();
m_globalPosition++;
return m_buffer[m_position++];
}
bool ZydisStdinInput::isEndOfInput() const
{
return false;
}
uint64_t ZydisStdinInput::getPosition() const
{
return m_globalPosition;
}
bool ZydisStdinInput::setPosition(uint64_t position)
{
if (position > m_globalPosition)
{
return false;
}
int64_t delta = m_globalPosition - position;
if (delta > m_position)
{
return false;
}
m_position = m_position - static_cast<int32_t>(delta);
m_globalPosition = position;
return true;
}
int main()
{
Zydis::InstructionInfo info;
Zydis::InstructionDecoder decoder;
Zydis::IntelInstructionFormatter formatter;
ZydisStdinInput input;
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
decoder.setDataSource(&input);
decoder.setInstructionPointer(0x00000000);
while (decoder.decodeInstruction(info))
{
std::cout << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
<< info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << static_cast<int>(info.data[0]) << std::endl;
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;
}
}
return 0;
}

View File

@ -78,7 +78,7 @@ int main()
<< info.instrAddress << " "; << info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK) if (info.flags & Zydis::IF_ERROR_MASK)
{ {
std::cout << "db " << std::setw(2) << info.data[0]; std::cout << "db " << std::setw(2) << static_cast<int>(info.data[0]) << std::endl;
} else } else
{ {
std::cout << formatter.formatInstruction(info) << std::endl; std::cout << formatter.formatInstruction(info) << std::endl;
@ -97,7 +97,7 @@ int main()
<< info.instrAddress << " "; << info.instrAddress << " ";
if (info.flags & Zydis::IF_ERROR_MASK) if (info.flags & Zydis::IF_ERROR_MASK)
{ {
std::cout << "db " << std::setw(2) << info.data[0]; std::cout << "db " << std::setw(2) << static_cast<int>(info.data[0]) << std::endl;
} else } else
{ {
std::cout << formatter.formatInstruction(info) << std::endl; std::cout << formatter.formatInstruction(info) << std::endl;

View File

@ -1,5 +1,5 @@
Zyan Disassembler Engine (Zydis) Zyan Disassembler Engine (Zydis) [![Build Status](https://travis-ci.org/zyantific/zyan-disassembler-engine.svg?branch=master)](https://travis-ci.org/zyantific/zyan-disassembler-engine)
================================== ================================
Fast and lightweight x86/x86-64 disassembler library. Fast and lightweight x86/x86-64 disassembler library.
@ -20,7 +20,7 @@ Fast and lightweight x86/x86-64 disassembler library.
The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console. The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console.
```C++ ```c++
#include <tchar.h> #include <tchar.h>
#include <iostream> #include <iostream>
#include <stdint.h> #include <stdint.h>
@ -35,7 +35,7 @@ int _tmain(int argc, _TCHAR* argv[])
Zydis::MemoryInput input(&data[0], sizeof(data)); Zydis::MemoryInput input(&data[0], sizeof(data));
Zydis::InstructionInfo info; Zydis::InstructionInfo info;
Zydis::InstructionDecoder decoder; Zydis::InstructionDecoder decoder;
decoder.setDisassemblerMode(Zydis::ZydisMode::M32BIT); decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
decoder.setDataSource(&input); decoder.setDataSource(&input);
decoder.setInstructionPointer(0); decoder.setInstructionPointer(0);
Zydis::IntelInstructionFormatter formatter; Zydis::IntelInstructionFormatter formatter;
@ -50,5 +50,10 @@ int _tmain(int argc, _TCHAR* argv[])
Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C++14 compiler. Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C++14 compiler.
## Documentation ##
[The HTML Doxygen documentation](https://www.zyantific.com/doc/zydis/index.html) is automatically built from master every 12 hours.
## License ## ## License ##
Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses. Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses.

BIN
Zydis/VersionInfo.rc Normal file

Binary file not shown.

View File

@ -28,12 +28,73 @@
***************************************************************************************************/ ***************************************************************************************************/
#ifndef _ZYDIS_DISASSEMBLER_HPP_ /**
#define _ZYDIS_DISASSEMBLER_HPP_ * @file
* @brief C++ API include file.
*/
/**
* @mainpage Zyan Disassembler Engine (Zydis)
*
* Zydis is a fast and lightweight x86/x86-64 disassembler library.
*
* @section Features
* - Supports all x86 and x86-64 (AMD64) General purpose and System instructions.
* - Supported ISA extensions:
* - MMX, FPU (x87), AMD 3DNow
* - SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES,
* - AMD-V, INTEL-VMX, SMX
* - Optimized for high performance
* - Very small overhead compared to other common disassembler libraries (about 60KiB)
* - Abstract formatter and symbol-resolver classes for custom syntax implementations.
* - Intel syntax is implemented by default
* - Complete doxygen documentation
*
* @section Quick Example
* The following example program uses Zydis to disassemble a given memory buffer and prints the
* output to the console.
*
* @code
* #include <tchar.h>
* #include <iostream>
* #include <stdint.h>
* #include "Zydis.hpp"
*
* int _tmain(int argc, _TCHAR* argv[])
* {
* uint8_t data[] =
* {
* 0x90, 0xE9, 0x00, 0x00, 0x00, 0x00, 0xC3
* };
* Zydis::MemoryInput input(&data[0], sizeof(data));
* Zydis::InstructionInfo info;
* Zydis::InstructionDecoder decoder;
* decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
* decoder.setDataSource(&input);
* decoder.setInstructionPointer(0);
* Zydis::IntelInstructionFormatter formatter;
* while (decoder.decodeInstruction(info))
* {
* std::cout << formatter.formatInstruction(info) << std::endl;
* }
* }
* @endcode
*
* @section Compilation
* Zydis builds cleanly on most platforms without any external dependencies. You can use CMake
* to generate project files for your favorite C++14 compiler.
*
* @section License
* Zyan Disassembler Engine is licensed under the MIT License. Dependencies are under their
* respective licenses.
*/
#ifndef _ZYDIS_HPP_
#define _ZYDIS_HPP_
#include "ZydisInstructionDecoder.hpp" #include "ZydisInstructionDecoder.hpp"
#include "ZydisInstructionFormatter.hpp" #include "ZydisInstructionFormatter.hpp"
#include "ZydisSymbolResolver.hpp" #include "ZydisSymbolResolver.hpp"
#include "ZydisUtils.hpp" #include "ZydisUtils.hpp"
#endif /*_ZYDIS_DISASSEMBLER_HPP_ */ #endif /*_ZYDIS_HPP_ */

View File

@ -85,6 +85,7 @@ private:
using FullClassT = ZydisClassEx<ZydisClassT>; using FullClassT = ZydisClassEx<ZydisClassT>;
public: public:
uint32_t type; uint32_t type;
uint32_t align;
std::conditional_t<std::is_abstract<ZydisClassT>::value, char, ZydisClassT> instance; std::conditional_t<std::is_abstract<ZydisClassT>::value, char, ZydisClassT> instance;
public: public:
/** /**
@ -99,6 +100,7 @@ public:
typename... InstanceCtorArgsT> typename... InstanceCtorArgsT>
ZydisClassEx(uint32_t classType, InstanceCtorArgsT... args) ZydisClassEx(uint32_t classType, InstanceCtorArgsT... args)
: type(classType) : type(classType)
, align(0)
, instance(args...) { }; , instance(args...) { };
public: public:
/** /**
@ -126,7 +128,9 @@ public:
static FullClassT* fromInstance(ZydisClassT* instance) static FullClassT* fromInstance(ZydisClassT* instance)
{ {
return reinterpret_cast<FullClassT*>( return reinterpret_cast<FullClassT*>(
reinterpret_cast<uintptr_t>(instance) - sizeof(std::declval<FullClassT>().type)); reinterpret_cast<uintptr_t>(instance)
- sizeof(std::declval<FullClassT>().type)
- sizeof(std::declval<FullClassT>().align));
} }
}; };
#pragma pack(pop) #pragma pack(pop)

View File

@ -28,11 +28,14 @@
***************************************************************************************************/ ***************************************************************************************************/
/**
* @file
* @brief C API for Zydis.
*/
#ifndef _ZYDIS_API_H_ #ifndef _ZYDIS_API_H_
#define _ZYDIS_API_H_ #define _ZYDIS_API_H_
#define Zydis_EXPORTS
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>

View File

@ -28,6 +28,11 @@
***************************************************************************************************/ ***************************************************************************************************/
/**
* @file
* @brief Instruction decoder classes.
*/
#ifndef _ZYDIS_INSTRUCTIONDECODER_HPP_ #ifndef _ZYDIS_INSTRUCTIONDECODER_HPP_
#define _ZYDIS_INSTRUCTIONDECODER_HPP_ #define _ZYDIS_INSTRUCTIONDECODER_HPP_
@ -45,34 +50,10 @@ namespace Zydis
*/ */
class BaseInput class BaseInput
{ {
friend class InstructionDecoder;
private: private:
uint8_t m_currentInput; uint8_t m_currentInput;
protected: private:
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method increases the current
* input position by one.
* @return The current input byte.
*/
virtual uint8_t internalInputPeek() = 0;
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method does NOT increase the
* current input position.
* @return The current input byte.
*/
virtual uint8_t internalInputNext() = 0;
protected:
/**
* @brief Default constructor.
*/
BaseInput() { };
public:
/**
* @brief Destructor.
*/
virtual ~BaseInput() { };
public:
/** /**
* @brief Reads the next byte from the data source. This method does NOT increase the * @brief Reads the next byte from the data source. This method does NOT increase the
* current input position or the @c length field of the @c info parameter. * current input position or the @c length field of the @c info parameter.
@ -111,6 +92,31 @@ public:
* @return The current input byte. * @return The current input byte.
*/ */
uint8_t inputCurrent() const; uint8_t inputCurrent() const;
protected:
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method increases the current
* input position by one.
* @return The current input byte.
*/
virtual uint8_t internalInputPeek() = 0;
/**
* @brief Override this method in your custom data source implementations.
* Reads the next byte from the data source. This method does NOT increase the
* current input position.
* @return The current input byte.
*/
virtual uint8_t internalInputNext() = 0;
protected:
/**
* @brief Default constructor.
*/
BaseInput() { };
public:
/**
* @brief Destructor.
*/
virtual ~BaseInput() { };
public: public:
/** /**
* @brief Override this method in your custom data source implementations. * @brief Override this method in your custom data source implementations.

View File

@ -28,6 +28,11 @@
***************************************************************************************************/ ***************************************************************************************************/
/**
* @file
* @brief Instruction formatting classes.
*/
#ifndef _ZYDIS_INSTRUCTIONFORMATTER_HPP_ #ifndef _ZYDIS_INSTRUCTIONFORMATTER_HPP_
#define _ZYDIS_INSTRUCTIONFORMATTER_HPP_ #define _ZYDIS_INSTRUCTIONFORMATTER_HPP_

View File

@ -28,6 +28,11 @@
***************************************************************************************************/ ***************************************************************************************************/
/**
* @file
* @brief The opcode table definition, mostly internal stuff.
*/
#ifndef _ZYDIS_OPCODETABLE_HPP_ #ifndef _ZYDIS_OPCODETABLE_HPP_
#define _ZYDIS_OPCODETABLE_HPP_ #define _ZYDIS_OPCODETABLE_HPP_

View File

@ -28,6 +28,11 @@
***************************************************************************************************/ ***************************************************************************************************/
/**
* @file
* @brief Classes for symbol resolving in the disassembly.
*/
#ifndef _ZYDIS_SYMBOLRESOLVER_HPP_ #ifndef _ZYDIS_SYMBOLRESOLVER_HPP_
#define _ZYDIS_SYMBOLRESOLVER_HPP_ #define _ZYDIS_SYMBOLRESOLVER_HPP_

View File

@ -28,6 +28,11 @@
***************************************************************************************************/ ***************************************************************************************************/
/**
* @file
* @brief Utility functions.
*/
#ifndef _ZYDIS_UTILS_HPP_ #ifndef _ZYDIS_UTILS_HPP_
#define _ZYDIS_UTILS_HPP_ #define _ZYDIS_UTILS_HPP_