Initial commit

This commit is contained in:
flobernd 2014-10-24 23:11:16 +02:00
parent 6632e73200
commit 9255a9c6a1
23 changed files with 27599 additions and 2 deletions

View File

@ -0,0 +1,109 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 24. October 2014
* 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 <tchar.h>
#include <stdint.h>
#include <iostream>
#include <iomanip>
#include "VXDisassembler.h"
using namespace Verteron;
using namespace Disassembler;
int _tmain(int argc, _TCHAR* argv[])
{
uint8_t data32[] =
{
0x8B, 0xFF, 0x55, 0x8B, 0xEC, 0x6A, 0xFE, 0x68, 0xD8, 0x18, 0x09, 0x77, 0x68, 0x85, 0xD2,
0x09, 0x77, 0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0xEC, 0x14, 0x53, 0x56, 0x57,
0xA1, 0x68, 0xEE, 0x13, 0x77, 0x31, 0x45, 0xF8, 0x33, 0xC5, 0x50, 0x8D, 0x45, 0xF0, 0x64,
0xA3, 0x00, 0x00, 0x00, 0x00, 0x89, 0x65, 0xE8, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x8B, 0x5D, 0x08, 0xF6, 0xC3, 0x04, 0x0F, 0x85, 0x57, 0x74, 0x00, 0x00, 0x53, 0x6A, 0x00,
0xFF, 0x35, 0xA0, 0xE3, 0x13, 0x77, 0xFF, 0x15, 0x00, 0x10, 0x14, 0x77, 0x85, 0xC0, 0x0F,
0x84, 0xC6, 0x48, 0x04, 0x00, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xFC,
0xFE, 0xFF, 0xFF, 0xFF, 0x33, 0xC0, 0x8B, 0x4D, 0xF0, 0x64, 0x89, 0x0D, 0x00, 0x00, 0x00,
0x00, 0x59, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00
};
uint8_t data64[] =
{
0x48, 0x89, 0x5C, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 0x89, 0x4C, 0x24, 0x08, 0x57,
0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x48, 0x83, 0xEC, 0x40, 0x4C, 0x8B, 0xF2,
0x8B, 0xD9, 0x48, 0xC7, 0x44, 0x24, 0x20, 0x00, 0x00, 0x00, 0x00, 0x33, 0xF6, 0x48, 0x89,
0x74, 0x24, 0x30, 0x45, 0x33, 0xFF, 0xF7, 0xC1, 0x8D, 0xF0, 0xFF, 0xFF, 0x0F, 0x85, 0xAA,
0x53, 0x08, 0x00, 0xF6, 0xC1, 0x40, 0x8B, 0xFE, 0x41, 0xBD, 0x08, 0x00, 0x00, 0x00, 0x41,
0x0F, 0x45, 0xFD, 0xF6, 0xC1, 0x02, 0x48, 0x8B, 0x0D, 0x10, 0xD4, 0x0E, 0x00, 0x0F, 0x85,
0x40, 0xE1, 0x01, 0x00, 0x8B, 0x15, 0x4C, 0xD5, 0x0E, 0x00, 0x81, 0xC2, 0x00, 0x00, 0x14,
0x00, 0x0B, 0xD7, 0x4D, 0x8B, 0xC6, 0xFF, 0x15, 0x3B, 0x2F, 0x10, 0x00, 0x48, 0x8B, 0xD8,
0x48, 0x85, 0xC0, 0x0F, 0x84, 0x93, 0x78, 0x0A, 0x00, 0x48, 0x8B, 0xC3, 0x48, 0x8B, 0x5C,
0x24, 0x78, 0x48, 0x8B, 0xB4, 0x24, 0x80, 0x00, 0x00, 0x00, 0x48, 0x83, 0xC4, 0x40, 0x41,
0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x5F, 0xC3
};
VXInstructionInfo info;
VXIntelInstructionFormatter formatter;
VXInstructionDecoder decoder32(&data32[0], sizeof(data32), VXDisassemblerMode::M32BIT);
VXInstructionDecoder decoder64(&data64[0], sizeof(data64), VXDisassemblerMode::M64BIT);
decoder32.setInstructionPointer(0x77091852);
std::cout << "32 bit test ..." << std::endl << std::endl;
while (decoder32.decodeNextInstruction(info))
{
std::cout << std::hex << std::setw(8) << std::setfill('0') << std::uppercase
<< info.instructionPointer << " ";
if (info.flags & IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << info.instructionBytes[0];
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;
}
}
std::cout << std::endl;
decoder64.setInstructionPointer(0x00007FFA39A81930ull);
std::cout << "64 bit test ..." << std::endl << std::endl;
while (decoder64.decodeNextInstruction(info))
{
std::cout << std::hex << std::setw(16) << std::setfill('0') << std::uppercase
<< info.instructionPointer << " ";
if (info.flags & IF_ERROR_MASK)
{
std::cout << "db " << std::setw(2) << info.instructionBytes[0];
} else
{
std::cout << formatter.formatInstruction(info) << std::endl;
}
}
std::cin.get();
return 0;
}

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>DisassemblerTest</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>..\Verteron Disassembler Engine\;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>..\Verteron Disassembler Engine\;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>..\Verteron Disassembler Engine\;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>..\Verteron Disassembler Engine\;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Disassembler Test.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Verteron Disassembler Engine\Verteron Disassembler Engine.vcxproj">
<Project>{e9860351-f9ea-4d1b-8ae4-188e3212574a}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="Disassembler Test.cpp" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,25 @@
verteron-disassembler-engine
============================
Verteron Disassembler Engine (VDE)
==================================
Fast and lightweight x86/x86-64 disassembler library.
## 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
- Only 44.00 KiB (64 bit: 47.00 KiB) for the decoder and 62.00 KiB (64 bit: 69.50 KiB) with the optional formatting functionality
- Abstract formatter and symbol-resolver classes for custom syntax implementations.
- Intel syntax is implemented by default
## Compilation ##
- While VDE supports other compilers in theory, compilation has not been tested with any other compiler than MSVC12 (Visual Studio 2013)
- Multi-compiler support might be added in the future
## License ##
Verteron Disassembler Engine is licensed under the MIT License. Dependencies are under their respective licenses.

View File

@ -0,0 +1,72 @@
/**
* pugixml parser - version 1.4
* --------------------------------------------------------
* Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Report bugs and download new versions at http://pugixml.org/
*
* This library is distributed under the MIT License. See notice at the end
* of this file.
*
* This work is based on the pugxml parser, which is:
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
*/
#ifndef HEADER_PUGICONFIG_HPP
#define HEADER_PUGICONFIG_HPP
// Uncomment this to enable wchar_t mode
// #define PUGIXML_WCHAR_MODE
// Uncomment this to disable XPath
// #define PUGIXML_NO_XPATH
// Uncomment this to disable STL
// #define PUGIXML_NO_STL
// Uncomment this to disable exceptions
// #define PUGIXML_NO_EXCEPTIONS
// Set this to control attributes for public classes/functions, i.e.:
// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
// Tune these constants to adjust memory-related behavior
// #define PUGIXML_MEMORY_PAGE_SIZE 32768
// #define PUGIXML_MEMORY_OUTPUT_STACK 10240
// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096
// Uncomment this to switch to header-only version
// #define PUGIXML_HEADER_ONLY
// #include "pugixml.cpp"
// Uncomment this to enable long long support
// #define PUGIXML_HAS_LONG_LONG
#endif
/**
* Copyright (c) 2006-2014 Arseny Kapoulkine
*
* 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 diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
#include <tchar.h>
#include <pugixml.hpp>
int _tmain(int argc, _TCHAR* argv[])
{
// TODO:
return 0;
}

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{BAC14FF0-2567-489A-BC83-840B3603C84A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>TableGenerator</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>./PugiXML;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>./PugiXML;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>./PugiXML;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>./PugiXML;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Table Generator.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="Table Generator.cpp" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,48 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Verteron Disassembler Engine", "Verteron Disassembler Engine\Verteron Disassembler Engine.vcxproj", "{E9860351-F9EA-4D1B-8AE4-188E3212574A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Disassembler Test", "Disassembler Test\Disassembler Test.vcxproj", "{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Table Generator", "Table Generator\Table Generator.vcxproj", "{BAC14FF0-2567-489A-BC83-840B3603C84A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Debug|Win32.ActiveCfg = Debug|Win32
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Debug|Win32.Build.0 = Debug|Win32
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Debug|x64.ActiveCfg = Debug|x64
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Debug|x64.Build.0 = Debug|x64
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Release|Win32.ActiveCfg = Release|Win32
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Release|Win32.Build.0 = Release|Win32
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Release|x64.ActiveCfg = Release|x64
{E9860351-F9EA-4D1B-8AE4-188E3212574A}.Release|x64.Build.0 = Release|x64
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Debug|Win32.ActiveCfg = Debug|Win32
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Debug|Win32.Build.0 = Debug|Win32
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Debug|x64.ActiveCfg = Debug|x64
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Debug|x64.Build.0 = Debug|x64
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Release|Win32.ActiveCfg = Release|Win32
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Release|Win32.Build.0 = Release|Win32
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Release|x64.ActiveCfg = Release|x64
{26FB9B13-9A66-44D1-8E78-1E8AA2FCBEF3}.Release|x64.Build.0 = Release|x64
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Debug|Win32.ActiveCfg = Debug|Win32
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Debug|Win32.Build.0 = Debug|Win32
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Debug|x64.ActiveCfg = Debug|x64
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Debug|x64.Build.0 = Debug|x64
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Release|Win32.ActiveCfg = Release|Win32
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Release|Win32.Build.0 = Release|Win32
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Release|x64.ActiveCfg = Release|x64
{BAC14FF0-2567-489A-BC83-840B3603C84A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,35 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 22. October 2014
* 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.
**************************************************************************************************/
#pragma once
#include "VXInstructionDecoder.h"
#include "VXInstructionFormatter.h"

View File

@ -0,0 +1,450 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 22. October 2014
* 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.
**************************************************************************************************/
#pragma once
#include <stdint.h>
#include "VXOpcodeTable.h"
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Values that represent additional flags of a decoded instruction.
*/
enum InstructionFlags : uint32_t
{
IF_NONE = 0x00000000,
/**
* @brief The instruction got decoded in 16 bit disassembler mode.
*/
IF_DISASSEMBLER_MODE_16 = 0x00000001,
/**
* @brief The instruction got decoded in 32 bit disassembler mode.
*/
IF_DISASSEMBLER_MODE_32 = 0x00000002,
/**
* @brief The instruction got decoded in 64 bit disassembler mode.
*/
IF_DISASSEMBLER_MODE_64 = 0x00000004,
/**
* @brief The instruction has a segment override prefix (0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65).
*/
IF_PREFIX_SEGMENT = 0x00000008,
/**
* @brief The instruction has a lock prefix (0xF0).
*/
IF_PREFIX_LOCK = 0x00000010,
/**
* @brief The instruction has a repnz prefix (0xF2).
*/
IF_PREFIX_REPNZ = 0x00000020,
/**
* @brief The instruction has a repz prefix (0xF3).
*/
IF_PREFIX_REPZ = 0x00000040,
/**
* @brief The instruction has an operand size override prefix (0x66).
*/
IF_PREFIX_OPERAND_SIZE_OVERRIDE = 0x00000080,
/**
* @brief The instruction has an address size override prefix (0x67).
*/
IF_PREFIX_ADDRESS_SIZE_OVERRIDE = 0x00000100,
/**
* @brief The instruction has a rex prefix (0x40 - 0x4F).
*/
IF_PREFIX_REX = 0x00000200,
/**
* @brief The instruction has a vex prefix (0xC4 or 0xC5).
*/
IF_PREFIX_VEX = 0x00000400,
/**
* @brief The instruction has a modrm byte.
*/
IF_MODRM = 0x00000800,
/**
* @brief The instruction has a sib byte.
*/
IF_SIB = 0x00001000,
/**
* @brief The instruction has an operand with a relative address.
*/
IF_RELATIVE = 0x00002000,
/**
* @brief An error occured while decoding the instruction.
*/
IF_ERROR_MASK = 0xFFF00000,
/**
* @brief End of input reached while decoding the instruction.
*/
IF_ERROR_END_OF_INPUT = 0x00100000,
/**
* @brief The instruction length has exceeded the maximum of 15 bytes.
*/
IF_ERROR_LENGTH = 0x00200000,
/**
* @brief The instruction is invalid.
*/
IF_ERROR_INVALID = 0x00400000,
/**
* @brief The instruction is invalid in 64 bit mode.
*/
IF_ERROR_INVALID_64 = 0x00800000,
/**
* @brief An error occured while decoding the instruction operands.
*/
IF_ERROR_OPERAND = 0x01000000
};
/**
* @brief Values that represent the type of a decoded operand.
*/
enum class VXOperandType
{
/**
* @brief The operand is not used.
*/
NONE,
/**
* @brief The operand is a register operand.
*/
REGISTER,
/**
* @brief The operand is a memory operand.
*/
MEMORY,
/**
* @brief The operand is a pointer operand.
*/
POINTER,
/**
* @brief The operand is an immediate operand.
*/
IMMEDIATE,
/**
* @brief The operand is a relative immediate operand.
*/
REL_IMMEDIATE,
/**
* @brief The operand is a constant value.
*/
CONSTANT
};
/**
* @brief Values that represent a cpu register.
*/
enum class VXRegister : uint16_t
{
NONE,
/* 8 bit general purpose registers */
AL, CL, DL, BL,
AH, CH, DH, BH,
SPL, BPL, SIL, DIL,
R8B, R9B, R10B, R11B,
R12B, R13B, R14B, R15B,
/* 16 bit general purpose registers */
AX, CX, DX, BX,
SP, BP, SI, DI,
R8W, R9W, R10W, R11W,
R12W, R13W, R14W, R15W,
/* 32 bit general purpose registers */
EAX, ECX, EDX, EBX,
ESP, EBP, ESI, EDI,
R8D, R9D, R10D, R11D,
R12D, R13D, R14D, R15D,
/* 64 bit general purpose registers */
RAX, RCX, RDX, RBX,
RSP, RBP, RSI, RDI,
R8, R9, R10, R11,
R12, R13, R14, R15,
/* segment registers */
ES, CS, SS,
DS, FS, GS,
/* control registers */
CR0, CR1, CR2, CR3,
CR4, CR5, CR6, CR7,
CR8, CR9, CR10, CR11,
CR12, CR13, CR14, CR15,
/* debug registers */
DR0, DR1, DR2, DR3,
DR4, DR5, DR6, DR7,
DR8, DR9, DR10, DR11,
DR12, DR13, DR14, DR15,
/* mmx registers */
MM0, MM1, MM2, MM3,
MM4, MM5, MM6, MM7,
/* x87 registers */
ST0, ST1, ST2, ST3,
ST4, ST5, ST6, ST7,
/* extended multimedia registers */
XMM0, XMM1, XMM2, XMM3,
XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11,
XMM12, XMM13, XMM14, XMM15,
/* 256 bit multimedia registers */
YMM0, YMM1, YMM2, YMM3,
YMM4, YMM5, YMM6, YMM7,
YMM8, YMM9, YMM10, YMM11,
YMM12, YMM13, YMM14, YMM15,
/* instruction pointer register */
RIP
};
/**
* @brief This struct holds information about a decoded operand.
*/
struct VXOperandInfo
{
/**
* @brief The type of the operand.
*/
VXOperandType type;
/**
* @brief The size of the operand.
*/
uint16_t size;
/**
* @brief The base register.
*/
VXRegister base;
/**
* @brief The index register.
*/
VXRegister index;
/**
* @brief The scale factor.
*/
uint8_t scale;
/**
* @brief The offset. TODO: improve documentation
*/
uint8_t offset;
/**
* @brief The lvalue. TODO: improve documentation
*/
union {
int8_t sbyte;
uint8_t ubyte;
int16_t sword;
uint16_t uword;
int32_t sdword;
uint32_t udword;
int64_t sqword;
uint64_t uqword;
struct {
uint16_t seg;
uint32_t off;
} ptr;
} lval;
};
/**
* @brief This struct holds information about a decoded instruction.
*/
struct VXInstructionInfo
{
/**
* @brief The instruction flags.
*/
uint32_t flags;
/**
* @brief The instruction mnemonic.
*/
VXInstructionMnemonic mnemonic;
/**
* @brief The total length of the instruction.
*/
uint8_t length;
/**
* @brief The instruction bytes.
*/
uint8_t instructionBytes[15];
/**
* @brief The length of the instruction opcodes.
*/
uint8_t opcodeLength;
/**
* @brief The instruction opcodes.
*/
uint8_t opcode[3];
/**
* @brief The operand mode.
*/
uint8_t operandMode;
/**
* @brief The address mode.
*/
uint8_t addressMode;
/**
* @brief The decoded operands.
*/
VXOperandInfo operand[4];
/**
* @brief The segment register. This value will default to @c NONE, if no segment register
* override prefix is present.
*/
VXRegister segmentRegister;
/**
* @brief The rex prefix byte.
*/
uint8_t rex;
/**
* @brief When 1, a 64-bit operand size is used. Otherwise, when 0, the default operand size
* is used.
*/
uint8_t rex_w;
/**
* @brief This 1-bit value is an extension to the MODRM.reg field.
*/
uint8_t rex_r;
/**
* @brief This 1-bit value is an extension to the SIB.index field.
*/
uint8_t rex_x;
/**
* @brief This 1-bit value is an extension to the MODRM.rm field or the SIB.base field.
*/
uint8_t rex_b;
/**
* @brief The modrm byte.
*/
uint8_t modrm;
/**
* @brief The modrm modus bits. When this field is b11, then register-direct addressing mode
* is used; otherwise register-indirect addressing mode is used.
*/
uint8_t modrm_mod;
/**
* @brief The modrm register bits. The REX.R, VEX.~R or XOP.~R field can extend this field
* with 1 most-significant bit to 4 bits total.
*/
uint8_t modrm_reg;
/**
* @brief The modrm register/memory bits. Specifies a direct or indirect register operand,
* optionally with a displacement. The REX.B, VEX.~B or XOP.~B field can extend this
* field with 1 most-significant bit to 4 bits total.
*/
uint8_t modrm_rm;
/**
* @brief The sib byte.
*/
uint8_t sib;
/**
* @brief This field indicates the scaling factor of SIB.index.
*/
uint8_t sib_scale;
/**
* @brief The index register to use. The REX.X, VEX.~X or XOP.~X field can extend this field
* with 1 most-significant bit to 4 bits total.
*/
uint8_t sib_index;
/**
* @brief The base register to use. The REX.B, VEX.~B or XOP.~B field can extend this field
* with 1 most-significant bit to 4 bits total.
*/
uint8_t sib_base;
/**
* @brief The primary vex prefix byte.
*/
uint8_t vex_op;
/**
* @brief The second vex prefix byte.
*/
uint8_t vex_b1;
/**
* @brief The third vex prefix byte.
*/
uint8_t vex_b2;
/**
* @brief This 1-bit value is an 'inverted' extension to the MODRM.reg field. The inverse of
* REX.R.
*/
uint8_t vex_r;
/**
* @brief This 1-bit value is an 'inverted' extension to the SIB.index field. The inverse of
* REX.X.
*/
uint8_t vex_x;
/**
* @brief This 1-bit value is an 'inverted' extension to the MODRM.rm field or the SIB.base
* field. The inverse of REX.B.
*/
uint8_t vex_b;
/**
* @brief Specifies the opcode map to use.
* 00 = 0x0F
* 01 = 0x0F 0x38
* 02 = 0x0F 0x3A
*/
uint8_t vex_m_mmmm;
/**
* @brief For integer instructions: when 1, a 64-bit operand size is used; otherwise,
* when 0, the default operand size is used (equivalent with REX.W). For non-integer
* instructions, this bit is a general opcode extension bit.
*/
uint8_t vex_w;
/**
* @brief An additional operand for the instruction. The value of the XMM or YMM register
* is 'inverted'.
*/
uint8_t vex_vvvv;
/**
* @brief When 0, a 128-bit vector lengh is used. Otherwise, when 1, a 256-bit vector length
* is used.
*/
uint8_t vex_l;
/**
* @brief Specifies an implied mandatory prefix for the opcode.
* 00 = none
* 01 = 0x66
* 10 = 0xF3
* 11 = 0xF2
*/
uint8_t vex_pp;
/**
* @brief The instruction definition.
*/
const VXInstructionDefinition *instrDefinition;
/**
* @brief The instruction pointer. This field is used to properly format relative
* instructions.
*/
uint64_t instructionPointer;
};
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,398 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 23. October 2014
* 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.
**************************************************************************************************/
#pragma once
#include <type_traits>
#include "VXDisassemblerTypes.h"
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Values that represent a disassembler mode.
*/
enum class VXDisassemblerMode
{
M16BIT = 16,
M32BIT = 32,
M64BIT = 64
};
/**
* @brief Values that represent an instruction vendor.
*/
enum class VXInstructionSetVendor
{
ANY,
INTEL,
AMD
};
/**
* @brief The @c VXInstructionDecoder class decodes x86/x86-64 assembly instructions from a
* given data source.
*/
class VXInstructionDecoder
{
private:
enum class RegisterClass
{
GENERAL_PURPOSE = 0,
MMX = 1,
CONTROL = 2,
DEBUG = 3,
SEGMENT = 4,
XMM = 5
};
private:
VXDisassemblerMode m_disassemblerMode;
VXInstructionSetVendor m_preferredVendor;
uint64_t m_instructionPointer;
const void *m_inputBuffer;
size_t m_inputBufferLen;
size_t m_inputBufferOffset;
uint8_t m_currentInput;
private:
uint8_t m_effectiveRexW;
uint8_t m_effectiveRexR;
uint8_t m_effectiveRexX;
uint8_t m_effectiveRexB;
uint8_t m_effectiveModrmReg;
uint8_t m_effectiveModrmRm;
bool m_effectiveVexL;
private:
/**
* @brief Reads the next byte from the input data source. This method does NOT increase the
* current input offset and the @c length or @c instructionBytes field of the @c info
* parameter.
* @param info The instruction info.
* @return Returns the current input byte. If the result is zero, you should always check
* the @flags field of the @c info parameter for the @c IF_ERROR_MASK.
*/
uint8_t inputPeek(VXInstructionInfo &info);
/**
* @brief Reads the next byte from the input data source. This method increases the current
* input offset and the @c length field of the @info parameter.
* @param info The instruction info.
* @return Returns the current input byte. If the result is zero, you should always check
* the @flags field of the @c info parameter for the @c IF_ERROR_MASK.
*/
uint8_t inputNext(VXInstructionInfo &info);
/**
* @brief Reads the next byte(s) from the data source. This method increases the current
* input offset and the @c length field of the @info parameter.
* @tparam T Generic integral type parameter.
* @param info The instruction info.
* @return Returns the current input byte(s). If the result is zero, you should always check
* the @flags field of the @c info parameter for the @c IF_ERROR_MASK.
*/
template <typename T>
T inputNext(VXInstructionInfo &info);
/**
* @brief Returns the current input byte. The current input byte is set everytime the
* @c inputPeek or @c inputNext method is called.
* @return The current input byte.
*/
uint8_t inputCurrent() const;
private:
/**
* @brief Decodes a register operand.
* @param info The instruction info.
* @param operand The @c VXOperandInfo struct that receives the decoded data.
* @param registerClass The register class to use.
* @param registerId The register id.
* @param operandSize The defined size of the operand.
* @return True if it succeeds, false if it fails.
*/
bool decodeRegisterOperand(VXInstructionInfo &info, VXOperandInfo &operand,
RegisterClass registerClass, uint8_t registerId, VXDefinedOperandSize operandSize) const;
/**
* @brief Decodes a register/memory operand.
* @param info The instruction info.
* @param operand The @c VXOperandInfo struct that receives the decoded data.
* @param registerClass The register class to use.
* @param operandSize The defined size of the operand.
* @return True if it succeeds, false if it fails.
*/
bool decodeRegisterMemoryOperand(VXInstructionInfo &info, VXOperandInfo &operand,
RegisterClass registerClass, VXDefinedOperandSize operandSize);
/**
* @brief Decodes an immediate operand.
* @param info The instruction info.
* @param operand The @c VXOperandInfo struct that receives the decoded data.
* @param operandSize The defined size of the operand.
* @return True if it succeeds, false if it fails.
*/
bool decodeImmediate(VXInstructionInfo &info, VXOperandInfo &operand,
VXDefinedOperandSize operandSize);
/**
* @brief Decodes a displacement operand.
* @param info The instruction info.
* @param operand The @c VXOperandInfo struct that receives the decoded data.
* @param size The size of the displacement data.
* @return True if it succeeds, false if it fails.
*/
bool decodeDisplacement(VXInstructionInfo &info, VXOperandInfo &operand, uint8_t size);
private:
/**
* @brief Decodes the modrm field of the instruction. This method reads an additional
* input byte.
* @param The @c VXInstructionInfo struct that receives the decoded data.
* @return True if it succeeds, false if it fails.
*/
bool decodeModrm(VXInstructionInfo &info);
/**
* @brief Decodes the sib field of the instruction. This method reads an additional
* input byte.
* @param info The @c VXInstructionInfo struct that receives the decoded data.
* @return True if it succeeds, false if it fails.
*/
bool decodeSIB(VXInstructionInfo &info);
/**
* @brief Decodes vex prefix of the instruction. This method takes the current input byte
* to determine the vex prefix type and reads one or two additional input bytes
* on demand.
* @param info The @c VXInstructionInfo struct that receives the decoded data.
* @return True if it succeeds, false if it fails.
*/
bool decodeVex(VXInstructionInfo &info);
private:
/**
* @brief Resolves the effective operand and address mode of the instruction.
* This method requires a non-null value in the @c instrDefinition field of the
* @c info struct.
* @param info The @c VXInstructionInfo struct that receives the effective operand and
* address mode.
*/
void resolveOperandAndAddressMode(VXInstructionInfo &info) const;
private:
/**
* @brief Returns the effective operand size.
* @param info The instruction info.
* @param operandSize The defined operand size.
* @return The effective operand size.
*/
uint16_t getEffectiveOperandSize(const VXInstructionInfo &info,
VXDefinedOperandSize operandSize) const;
/**
* @brief Decodes all instruction operands.
* @param info The @c VXInstructionInfo struct that receives the decoded data.
* @return True if it succeeds, false if it fails.
*/
bool decodeOperands(VXInstructionInfo &info);
/**
* @brief Decodes the specified instruction operand.
* @param info The instruction info.
* @param operand The @c VXOperandInfo struct that receives the decoded data.
* @param operandType The defined type of the operand.
* @param operandSize The defined size of the operand.
* @return True if it succeeds, false if it fails.
*/
bool decodeOperand(VXInstructionInfo &info, VXOperandInfo &operand,
VXDefinedOperandType operandType, VXDefinedOperandSize operandSize);
private:
/**
* @brief Collects and decodes optional instruction prefixes.
* @param info The @c VXInstructionInfo struct that receives the decoded data.
* @return True if it succeeds, false if it fails.
*/
bool decodePrefixes(VXInstructionInfo &info);
/**
* @brief Collects and decodes the instruction opcodes using the opcode tree.
* @param info The @c VXInstructionInfo struct that receives the decoded data.
* @return True if it succeeds, false if it fails.
*/
bool decodeOpcode(VXInstructionInfo &info);
/**
* @brief Decodes an instruction node.
* @param info The @c VXInstructionInfo struct that receives the decoded data.
* @param node The instruction node.
* @return True if it succeeds, false if it fails.
*/
bool decodeInstructionNode(VXInstructionInfo &info, VXOpcodeTreeNode node);
public:
/**
* @brief Constructor.
* @param buffer The input buffer.
* @param bufferLen The length of the input buffer.
* @param disassemblerMode The disassembler mode.
* @param preferredVendor The preferred instruction-set vendor.
*/
VXInstructionDecoder(const void *buffer, size_t bufferLen,
VXDisassemblerMode disassemblerMode = VXDisassemblerMode::M32BIT,
VXInstructionSetVendor preferredVendor = VXInstructionSetVendor::ANY);
public:
/**
* @brief Decodes the next instruction from the input data source.
* @param info The @c VXInstructionInfo struct that receives the information about the
* decoded instruction.
* @return This method returns false, if the current position has exceeded the maximum input
* length.
* In all other cases (valid and invalid instructions) the return value is true.
*/
bool decodeNextInstruction(VXInstructionInfo &info);
/**
* @brief Decodes a single instruction.
* @param info The @c VXInstructionInfo struct that receives the information
* about the decoded instruction.
* @param buffer The input buffer.
* @param bufferLen The length of the input buffer.
* @param disassemblerMode The disassembler mode.
* @param preferredVendor The preferred instruction-set vendor.
* @return This method returns false, if the current position has exceeded the maximum input
* length.
* In all other cases (valid and invalid instructions) the return value is true.
*/
static bool decodeInstruction(VXInstructionInfo &info, const void *buffer, size_t bufferLen,
VXDisassemblerMode disassemblerMode = VXDisassemblerMode::M32BIT,
VXInstructionSetVendor preferredVendor = VXInstructionSetVendor::ANY);
public:
/**
* @brief Returns the current input position.
* @return The current input position.
*/
uintptr_t getPosition() const;
/**
* @brief Changes the input position.
* @param position The new input position.
* @return True if it succeeds, false if the new position exceeds the maximum input length.
*/
bool setPosition(uintptr_t position);
/**
* @brief Returns the current instruction pointer. The instruction pointer is used to
* properly format relative instructions.
* @return The current instruction pointer.
*/
uint64_t getInstructionPointer() const;
/**
* @brief Sets the current instruction pointer. The instruction pointer is used to
* properly format relative instructions.
* @param instructionPointer The new instruction pointer.
*/
void setInstructionPointer(uint64_t instructionPointer);
};
inline uint8_t VXInstructionDecoder::inputPeek(VXInstructionInfo &info)
{
if (info.length == 15)
{
info.flags |= IF_ERROR_LENGTH;
return 0;
}
if (m_inputBufferOffset == m_inputBufferLen)
{
info.flags |= IF_ERROR_END_OF_INPUT;
return 0;
}
m_currentInput = *(static_cast<const uint8_t*>(m_inputBuffer) + m_inputBufferOffset);
return m_currentInput;
}
inline uint8_t VXInstructionDecoder::inputNext(VXInstructionInfo &info)
{
if (info.length == 15)
{
info.flags |= IF_ERROR_LENGTH;
return 0;
}
if (m_inputBufferOffset == m_inputBufferLen)
{
info.flags |= IF_ERROR_END_OF_INPUT;
return 0;
}
m_currentInput = *(static_cast<const uint8_t*>(m_inputBuffer) + m_inputBufferOffset);
m_inputBufferOffset++;
info.instructionBytes[info.length] = m_currentInput;
info.length++;
return m_currentInput;
}
template <typename T>
inline T VXInstructionDecoder::inputNext(VXInstructionInfo &info)
{
static_assert(std::is_integral<T>::value, "integral type required");
T result = 0;
for (unsigned i = 0; i < (sizeof(T) / sizeof(uint8_t)); i++)
{
T b = inputNext(info);
if (!b && (info.flags & IF_ERROR_MASK))
{
return 0;
}
result |= (b << (i * 8));
}
return result;
}
inline uint8_t VXInstructionDecoder::inputCurrent() const
{
return m_currentInput;
}
inline uintptr_t VXInstructionDecoder::getPosition() const
{
return m_inputBufferOffset;
}
inline bool VXInstructionDecoder::setPosition(uintptr_t position)
{
if (position < m_inputBufferLen)
{
m_inputBufferOffset = position;
return true;
}
return false;
}
inline uint64_t VXInstructionDecoder::getInstructionPointer() const
{
return m_instructionPointer;
}
inline void VXInstructionDecoder::setInstructionPointer(uint64_t instructionPointer)
{
m_instructionPointer = instructionPointer;
}
inline bool VXInstructionDecoder::decodeInstruction(VXInstructionInfo &info, const void *buffer,
size_t bufferLen, VXDisassemblerMode disassemblerMode, VXInstructionSetVendor preferredVendor)
{
return VXInstructionDecoder(
buffer, bufferLen, disassemblerMode, preferredVendor).decodeNextInstruction(info);
}
}
}

View File

@ -0,0 +1,452 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 22. October 2014
* 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 "VXInstructionFormatter.h"
#include <cstdarg>
namespace Verteron
{
namespace Disassembler
{
const char* VXBaseInstructionFormatter::m_registerStrings[] =
{
/* 8 bit general purpose registers */
"al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh",
"spl", "bpl", "sil", "dil",
"r8b", "r9b", "r10b", "r11b",
"r12b", "r13b", "r14b", "r15b",
/* 16 bit general purpose registers */
"ax", "cx", "dx", "bx",
"sp", "bp", "si", "di",
"r8w", "r9w", "r10w", "r11w",
"r12w", "r13w", "r14w", "r15w",
/* 32 bit general purpose registers */
"eax", "ecx", "edx", "ebx",
"esp", "ebp", "esi", "edi",
"r8d", "r9d", "r10d", "r11d",
"r12d", "r13d", "r14d", "r15d",
/* 64 bit general purpose registers */
"rax", "rcx", "rdx", "rbx",
"rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11",
"r12", "r13", "r14", "r15",
/* segment registers */
"es", "cs", "ss",
"ds", "fs", "gs",
/* control registers */
"cr0", "cr1", "cr2", "cr3",
"cr4", "cr5", "cr6", "cr7",
"cr8", "cr9", "cr10", "cr11",
"cr12", "cr13", "cr14", "cr15",
/* debug registers */
"dr0", "dr1", "dr2", "dr3",
"dr4", "dr5", "dr6", "dr7",
"dr8", "dr9", "dr10", "dr11",
"dr12", "dr13", "dr14", "dr15",
/* mmx registers */
"mm0", "mm1", "mm2", "mm3",
"mm4", "mm5", "mm6", "mm7",
/* x87 registers */
"st0", "st1", "st2", "st3",
"st4", "st5", "st6", "st7",
/* extended multimedia registers */
"xmm0", "xmm1", "xmm2", "xmm3",
"xmm4", "xmm5", "xmm6", "xmm7",
"xmm8", "xmm9", "xmm10", "xmm11",
"xmm12", "xmm13", "xmm14", "xmm15",
/* 256 bit multimedia registers */
"ymm0", "ymm1", "ymm2", "ymm3",
"ymm4", "ymm5", "ymm6", "ymm7",
"ymm8", "ymm9", "ymm10", "ymm11",
"ymm12", "ymm13", "ymm14", "ymm15",
/* instruction pointer register */
"rip"
};
void VXBaseInstructionFormatter::internalFormatInstruction(VXInstructionInfo const& info)
{
// Nothing to do here
}
VXBaseInstructionFormatter::VXBaseInstructionFormatter()
: m_symbolResolver(nullptr)
{
}
VXBaseInstructionFormatter::VXBaseInstructionFormatter(VXBaseSymbolResolver *symbolResolver)
: m_symbolResolver(symbolResolver)
{
}
const char* VXBaseInstructionFormatter::formatInstruction(const VXInstructionInfo &info)
{
// Clears the internal string buffer
outputClear();
// Calls the virtual format method that actually formats the instruction
internalFormatInstruction(info);
if (m_outputBuffer.size() == 0)
{
// The basic instruction formatter only returns the instruction menmonic.
return Internal::GetInstructionMnemonicString(info.mnemonic);
}
// Return the formatted instruction string
return outputString();
}
VXBaseInstructionFormatter::~VXBaseInstructionFormatter()
{
}
void VXBaseInstructionFormatter::outputClear()
{
m_outputBuffer.clear();
}
char const* VXBaseInstructionFormatter::outputString()
{
return &m_outputBuffer[0];
}
void VXBaseInstructionFormatter::outputAppend(char const *text)
{
// Get the string length including the null-terminator char
size_t strLen = strlen(text) + 1;
// Get the buffer capacity and size
size_t bufCap = m_outputBuffer.capacity();
size_t bufLen = m_outputBuffer.size();
// Decrease the offset by one, to exclude already existing null-terminator chars in the
// output buffer
size_t offset = (bufLen) ? bufLen - 1 : 0;
// Resize capacity of the output buffer on demand and add some extra space to improve the
// performance
if (bufCap <= (bufLen + strLen))
{
m_outputBuffer.reserve(bufCap + strLen + 256);
}
// Append the text
m_outputBuffer.resize(offset + strLen);
memcpy(&m_outputBuffer[offset], text, strLen);
}
void VXBaseInstructionFormatter::outputAppendFormatted(char const *format, ...)
{
va_list arguments;
va_start(arguments, format);
// Get the string length including the null-terminator char
size_t strLen = _vscprintf(format, arguments) + 1;
// Get the buffer capacity and size
size_t bufCap = m_outputBuffer.capacity();
size_t bufLen = m_outputBuffer.size();
// Decrease the offset by one, to exclude already existing null-terminator chars in the
// output buffer
size_t offset = (bufLen) ? bufLen - 1 : 0;
if (strLen > 1)
{
// Resize capacity of the output buffer on demand and add some extra space to improve the
// performance
if (bufCap < (bufLen + strLen))
{
m_outputBuffer.reserve(bufCap + strLen + 256);
}
// Append the formatted text
m_outputBuffer.resize(offset + strLen);
vsnprintf_s(&m_outputBuffer[offset], strLen, strLen, format, arguments);
}
va_end(arguments);
}
uint64_t VXBaseInstructionFormatter::calcAbsoluteTarget(const VXInstructionInfo &info,
const VXOperandInfo &operand) const
{
switch (operand.size)
{
case 8:
return (info.instructionPointer + info.length + operand.lval.sbyte);
case 16:
return (info.instructionPointer + info.length + operand.lval.sword);
case 32:
case 64:
return (info.instructionPointer + info.length + operand.lval.sdword);
default:
assert(0);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void VXIntelInstructionFormatter::outputAppendAddress(const VXInstructionInfo &info,
uint64_t address)
{
uint64_t offset = 0;
const char* name = resolveSymbol(info, address, offset);
if (name)
{
if (offset)
{
outputAppendFormatted("%s+%.2llX", name, offset);
} else
{
outputAppend(name);
}
} else
{
if (info.flags & IF_DISASSEMBLER_MODE_16)
{
outputAppendFormatted("%.4X", address);
} else if (info.flags & IF_DISASSEMBLER_MODE_32)
{
outputAppendFormatted("%.8lX", address);
} else if (info.flags & IF_DISASSEMBLER_MODE_64)
{
outputAppendFormatted("%.16llX", address);
} else
{
assert(0);
}
}
}
void VXIntelInstructionFormatter::formatOperand(const VXInstructionInfo &info,
const VXOperandInfo &operand)
{
switch (operand.type)
{
case VXOperandType::REGISTER:
outputAppend(registerToString(operand.base));
break;
case VXOperandType::MEMORY:
// TODO: resolve symbols for displacement only and RIP based memory operands
if (info.flags & IF_PREFIX_SEGMENT)
{
outputAppendFormatted("%s:", registerToString(info.segmentRegister));
}
outputAppend("[");
if (operand.base == VXRegister::RIP)
{
// TODO: Add option
outputAppendAddress(info, calcAbsoluteTarget(info, operand));
} else
{
if (operand.base != VXRegister::NONE)
{
outputAppend(registerToString(operand.base));
}
if (operand.index != VXRegister::NONE)
{
outputAppendFormatted("%s%s", operand.base != VXRegister::NONE ? "+" : "",
registerToString(operand.index));
if (operand.scale)
{
outputAppendFormatted("*%d", operand.scale);
}
}
if (operand.lval.uqword ||
(operand.base == VXRegister::NONE && operand.index == VXRegister::NONE))
{
if (operand.base == VXRegister::NONE && operand.index == VXRegister::NONE)
{
// Assume the displacement value is unsigned
assert(operand.scale == 0);
assert(operand.offset != 8);
uint64_t value = 0;
switch (operand.offset)
{
case 16:
value = operand.lval.uword;
break;
case 32:
value = operand.lval.udword;
break;
case 64:
value = operand.lval.uqword;
break;
default:
assert(0);
}
outputAppendFormatted("%.2llX", value);
} else
{
// The displacement value might be negative
assert(operand.offset != 64);
int64_t value = 0;
switch (operand.offset)
{
case 8:
value = operand.lval.sbyte;
break;
case 16:
value = operand.lval.sword;
break;
case 32:
value = operand.lval.sdword;
break;
default:
assert(0);
}
if (value < 0)
{
outputAppendFormatted("-%.2lX", -value);
} else
{
outputAppendFormatted("%s%.2lX", (operand.base != VXRegister::NONE ||
operand.index != VXRegister::NONE) ? "+" : "", value);
}
}
}
}
outputAppend("]");
break;
case VXOperandType::POINTER:
// TODO: resolve symbols
switch (operand.size)
{
case 32:
outputAppendFormatted("word %.4X:%.4X", operand.lval.ptr.seg,
operand.lval.ptr.off & 0xFFFF);
break;
case 48:
outputAppendFormatted("dword %.4X:%.8lX", operand.lval.ptr.seg, operand.lval.ptr.off);
break;
default:
assert(0);
}
break;
case VXOperandType::IMMEDIATE:
{
// TODO: resolve symbols
uint64_t value = 0;
switch (operand.size)
{
case 8 :
value = operand.lval.ubyte;
break;
case 16:
value = operand.lval.uword;
break;
case 32:
value = operand.lval.udword;
break;
case 64:
value = operand.lval.uqword;
break;
default:
assert(0);
}
outputAppendFormatted("%.2llX", value);
}
break;
case VXOperandType::REL_IMMEDIATE:
{
if (operand.size == 8)
{
outputAppend("short ");
}
outputAppendAddress(info, calcAbsoluteTarget(info, operand));
}
break;
case VXOperandType::CONSTANT:
outputAppendFormatted("%d", operand.lval.udword);
break;
default:
assert(0);
break;
}
}
void VXIntelInstructionFormatter::internalFormatInstruction(const VXInstructionInfo &info)
{
// Append string prefixes
if (info.flags & IF_PREFIX_LOCK)
{
outputAppend("lock ");
}
if (info.flags & IF_PREFIX_REPZ)
{
outputAppend("rep ");
} else if (info.flags & IF_PREFIX_REPNZ)
{
outputAppend("repne ");
}
// Append the instruction mnemonic
outputAppend(Internal::GetInstructionMnemonicString(info.mnemonic));
// Append the first operand
if (info.operand[0].type != VXOperandType::NONE)
{
outputAppend(" ");
formatOperand(info, info.operand[0]);
}
// Append the second operand
if (info.operand[1].type != VXOperandType::NONE)
{
outputAppend(", ");
formatOperand(info, info.operand[1]);
}
// Append the third operand
if (info.operand[2].type != VXOperandType::NONE)
{
outputAppend(", ");
formatOperand(info, info.operand[2]);
}
// Append the fourth operand
if (info.operand[3].type != VXOperandType::NONE)
{
outputAppend(", ");
formatOperand(info, info.operand[3]);
}
}
VXIntelInstructionFormatter::VXIntelInstructionFormatter()
: VXBaseInstructionFormatter()
{
}
VXIntelInstructionFormatter::VXIntelInstructionFormatter(VXBaseSymbolResolver* symbolResolver)
: VXBaseInstructionFormatter(symbolResolver)
{
}
VXIntelInstructionFormatter::~VXIntelInstructionFormatter()
{
}
}
}

View File

@ -0,0 +1,212 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 22. October 2014
* 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.
**************************************************************************************************/
#pragma once
#include <vector>
#include "VXDisassemblerTypes.h"
#include "VXSymbolResolver.h"
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Base class for all instruction formatter implementations.
*/
class VXBaseInstructionFormatter
{
private:
static const char *m_registerStrings[];
VXBaseSymbolResolver *m_symbolResolver;
std::vector<char> m_outputBuffer;
protected:
/**
* @brief Clears the output string buffer.
*/
void outputClear();
/**
* @brief Returns the content of the output string buffer.
* @return Pointer to the content of the ouput string buffer.
*/
const char* outputString();
/**
* @brief Appends text to the ouput string buffer.
* @param text The text.
*/
void outputAppend(const char *text);
/**
* @brief Appends formatted text to the output string buffer.
* @param format The format string.
*/
void outputAppendFormatted(const char *format, ...);
protected:
/**
* @brief Calculates the absolute target address for a relative immediate operand.
* @param info The instruction info.
* @param operand The operand.
* @return The absolute target address.
*/
uint64_t calcAbsoluteTarget(const VXInstructionInfo &info, const VXOperandInfo &operand) const;
/**
* @brief Returns the string representation of a given register.
* @param reg The register.
* @return The string representation of the given register.
*/
const char* registerToString(VXRegister reg) const;
/**
* @brief Resolves a symbol.
* @param info The instruction info.
* @param address The address.
* @param offset Reference to an unsigned 64 bit integer that receives an offset
* relative to the base address of the symbol.
* @return The name of the symbol, if the symbol was found, @c NULL if not.
*/
const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset) const;
protected:
/**
* @brief Override this method to implement a custom disassembly syntax. Use the
* @c outputAppend and @c outputAppendFormatted methods to fill the internal
* string buffer.
* @param info The instruction info.
*/
virtual void internalFormatInstruction(const VXInstructionInfo &info);
public:
/**
* @brief Default constructor.
*/
VXBaseInstructionFormatter();
/**
* @brief Constructor.
* @param symbolResolver Pointer to a symbol resolver instance or @c NULL, if no smybol
* resolver should be used.
*/
explicit VXBaseInstructionFormatter(VXBaseSymbolResolver *symbolResolver);
/**
* @brief Destructor.
*/
virtual ~VXBaseInstructionFormatter();
public:
/**
* @brief Formats a decoded instruction.
* @param info The instruction info.
* @return Pointer to the formatted instruction string.
*/
const char* formatInstruction(const VXInstructionInfo &info);
public:
/**
* @brief Returns a pointer to the current symbol resolver.
* @return Pointer to the current symbol resolver or @c NULL, if no symbol resolver is used.
*/
VXBaseSymbolResolver* getSymbolResolver() const;
/**
* @brief Sets a new symbol resolver.
* @param symbolResolver Pointer to a symbol resolver instance or @c NULL, if no smybol
* resolver should be used.
*/
void setSymbolResolver(VXBaseSymbolResolver *symbolResolver);
};
inline char const* VXBaseInstructionFormatter::registerToString(VXRegister reg) const
{
if (reg == VXRegister::NONE)
{
return "error";
}
return m_registerStrings[static_cast<uint16_t>(reg) - 1];
}
inline char const* VXBaseInstructionFormatter::resolveSymbol(const VXInstructionInfo &info,
uint64_t address, uint64_t &offset) const
{
if (m_symbolResolver)
{
return m_symbolResolver->resolveSymbol(info, address, offset);
}
return nullptr;
}
inline VXBaseSymbolResolver* VXBaseInstructionFormatter::getSymbolResolver() const
{
return m_symbolResolver;
}
inline void VXBaseInstructionFormatter::setSymbolResolver(VXBaseSymbolResolver *symbolResolver)
{
m_symbolResolver = symbolResolver;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Intel syntax instruction formatter.
*/
class VXIntelInstructionFormatter : public VXBaseInstructionFormatter
{
private:
void outputAppendAddress(const VXInstructionInfo &info, uint64_t address);
private:
/**
* @brief Formats the specified operand and appends the resulting string to the output
* buffer.
* @param info The instruction info.
* @param operand The operand.
*/
void formatOperand(const VXInstructionInfo &info, const VXOperandInfo &operand);
protected:
/**
* @brief Fills the internal string buffer with an intel style formatted instruction string.
* @param info The instruction info.
*/
void internalFormatInstruction(const VXInstructionInfo &info) override;
public:
/**
* @brief Default constructor.
*/
VXIntelInstructionFormatter();
/**
* @brief Constructor.
* @param symbolResolver Pointer to a symbol resolver instance or @c NULL, if no smybol
* resolver should be used.
*/
explicit VXIntelInstructionFormatter(VXBaseSymbolResolver *symbolResolver);
/**
* @brief Destructor.
*/
~VXIntelInstructionFormatter() override;
};
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 23. October 2014
* 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 "VXSymbolResolver.h"
namespace Verteron
{
namespace Disassembler
{
VXBaseSymbolResolver::~VXBaseSymbolResolver()
{
}
const char* VXBaseSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset)
{
return nullptr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
VXExactSymbolResolver::~VXExactSymbolResolver()
{
}
const char* VXExactSymbolResolver::resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset)
{
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
return (iterator == m_symbolMap.end()) ? nullptr : iterator->second.c_str();
}
void VXExactSymbolResolver::setSymbol(uint64_t address, const char* name)
{
m_symbolMap[address].assign(name);
}
void VXExactSymbolResolver::removeSymbol(uint64_t address)
{
m_symbolMap.erase(address);
}
void VXExactSymbolResolver::clear()
{
m_symbolMap.clear();
}
bool VXExactSymbolResolver::containsSymbol(uint64_t address)
{
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
return (iterator == m_symbolMap.end()) ? false : true;
}
}
}

View File

@ -0,0 +1,119 @@
/**************************************************************************************************
Verteron Disassembler Engine
Version 1.0
Remarks : Freeware, Copyright must be included
Original Author : Florian Bernd
Modifications :
Last change : 23. October 2014
* 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.
**************************************************************************************************/
#pragma once
#include <string>
#include <unordered_map>
#include "VXDisassemblerTypes.h"
namespace Verteron
{
namespace Disassembler
{
/**
* @brief Base class for all symbol resolver implementations.
*/
class VXBaseSymbolResolver
{
public:
/**
* @brief Destructor.
*/
virtual ~VXBaseSymbolResolver();
public:
/**
* @brief Resolves a symbol.
* @param info The instruction info.
* @param address The address.
* @param offset Reference to an unsigned 64 bit integer that receives an offset
* relative to the base address of the symbol.
* @return The name of the symbol, if the symbol was found, @c NULL if not.
*/
virtual const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset);
};
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
* @brief Simple symbol resolver that only matches exact addresses.
*/
class VXExactSymbolResolver : public VXBaseSymbolResolver
{
private:
std::unordered_map<uint64_t, std::string> m_symbolMap;
public:
/**
* @brief Destructor.
*/
~VXExactSymbolResolver() override;
public:
/**
* @brief Resolves a symbol.
* @param info The instruction info.
* @param address The address.
* @param offset Reference to an unsigned 64 bit integer that receives an offset
* relative to the base address of the symbol.
* @return The name of the symbol, if the symbol was found, @c NULL if not.
*/
const char* resolveSymbol(const VXInstructionInfo &info, uint64_t address,
uint64_t &offset) override;
public:
/**
* @brief Adds or changes a symbol.
* @param address The address.
* @param name The symbol name.
*/
void setSymbol(uint64_t address, const char* name);
/**
* @brief Removes the symbol described by address. This will invalidate all char pointers
* to the specific symbol name.
* @param address The address.
*/
void removeSymbol(uint64_t address);
/**
* @brief Clears the symbol tree.
*/
void clear();
/**
* @brief Query if the given address is a known symbol.
* @param address The address.
* @return True if the address is known, false if not.
*/
bool containsSymbol(uint64_t address);
};
}
}

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="VXDisassembler.h" />
<ClInclude Include="VXDisassemblerTypes.h" />
<ClInclude Include="VXInstructionDecoder.h" />
<ClInclude Include="VXInstructionFormatter.h" />
<ClInclude Include="VXOpcodeTable.h" />
<ClInclude Include="VXSymbolResolver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="VXInstructionDecoder.cpp" />
<ClCompile Include="VXInstructionFormatter.cpp" />
<ClCompile Include="VXOpcodeTable.cpp" />
<ClCompile Include="VXSymbolResolver.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E9860351-F9EA-4D1B-8AE4-188E3212574A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>VerteronDisassemblerEngine</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<StringPooling>true</StringPooling>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<StringPooling>true</StringPooling>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<StringPooling>true</StringPooling>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<StringPooling>true</StringPooling>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="VXOpcodeTable.h" />
<ClInclude Include="VXDisassembler.h" />
<ClInclude Include="VXDisassemblerTypes.h" />
<ClInclude Include="VXInstructionDecoder.h" />
<ClInclude Include="VXInstructionFormatter.h" />
<ClInclude Include="VXSymbolResolver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="VXOpcodeTable.cpp" />
<ClCompile Include="VXInstructionDecoder.cpp" />
<ClCompile Include="VXInstructionFormatter.cpp" />
<ClCompile Include="VXSymbolResolver.cpp" />
</ItemGroup>
</Project>