mirror of https://github.com/x64dbg/zydis
Initial version 2.0 release
This commit is contained in:
parent
f377f7b559
commit
7c9a6db6af
|
@ -1,183 +1,78 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
# Created by https://www.gitignore.io/api/c,c++,cmake
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
build/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Roslyn cache directories
|
||||
*.ide/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
#NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
### C ###
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
### C++ ###
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# JustCode is a .NET coding addin-in
|
||||
.JustCode
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# If using the old MSBuild-Integrated Package Restore, uncomment this:
|
||||
#!**/packages/repositories.config
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
### CMake ###
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
CTestTestfile.cmake
|
||||
|
|
29
.travis.yml
29
.travis.yml
|
@ -1,29 +0,0 @@
|
|||
language: cpp
|
||||
compiler: clang
|
||||
|
||||
script: make
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
before_install:
|
||||
# Install clang 3.6
|
||||
- echo "yes" | sudo add-apt-repository 'deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main'
|
||||
- echo "yes" | sudo add-apt-repository 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.6 main'
|
||||
- wget --no-check-certificate -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -;
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install -qq --allow-unauthenticated llvm-3.6 llvm-3.6-dev clang-3.6 libstdc++-4.8-dev lib32stdc++6
|
||||
- export CXX="clang++-3.6" CC="clang-3.6"
|
||||
# Install cmake 3.2
|
||||
- wget --no-check-certificate https://www.cmake.org/files/v3.2/cmake-3.2.2-Linux-i386.sh
|
||||
- chmod a+x cmake-3.2.2-Linux-i386.sh
|
||||
- sudo ./cmake-3.2.2-Linux-i386.sh --skip-license --prefix=/usr
|
||||
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake ..
|
||||
|
||||
script:
|
||||
- make
|
101
CMakeLists.txt
101
CMakeLists.txt
|
@ -2,21 +2,21 @@ cmake_minimum_required(VERSION 2.8.12)
|
|||
include(GenerateExportHeader)
|
||||
|
||||
project(Zydis)
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries rather than static ones" FALSE)
|
||||
option(FORCE_SHARED_CRT
|
||||
"Forces shared linkage against the CRT even when building a static library"
|
||||
FALSE)
|
||||
option(BUILD_EXAMPLES "Build examples" TRUE)
|
||||
option(BUILD_C_BINDINGS "Build C bindings" TRUE)
|
||||
option(BUILD_TOOLS "Build tools")
|
||||
|
||||
if (NOT CONFIGURED_ONCE)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
|
||||
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(compiler_specific "-Werror")
|
||||
set(compiler_specific_cxx "-std=c++14")
|
||||
set(compiler_specific "-std=c99 -pedantic -Wextra -Werror")
|
||||
elseif (MSVC)
|
||||
set(compiler_specific "/WX /W4 /D_CRT_SECURE_NO_WARNINGS /GR-")
|
||||
set(compiler_specific "/WX /W4 /D_CRT_SECURE_NO_WARNINGS /TC")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${compiler_specific} ${compiler_specific_cxx}"
|
||||
|
@ -28,46 +28,41 @@ endif ()
|
|||
# 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.
|
||||
if (MSVC AND NOT FORCE_SHARED_CRT)
|
||||
set(manipulated_vars
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
foreach (cur_var ${manipulated_vars})
|
||||
string(REPLACE "/MD" "/MT" ${cur_var} "${${cur_var}}")
|
||||
endforeach ()
|
||||
foreach(flag_var
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if(${flag_var} MATCHES "/MD")
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endif(${flag_var} MATCHES "/MD")
|
||||
endforeach(flag_var)
|
||||
endif ()
|
||||
|
||||
# Library
|
||||
set(headers
|
||||
"Zydis/Zydis.hpp"
|
||||
"Zydis/ZydisInstructionDecoder.hpp"
|
||||
"Zydis/ZydisInstructionFormatter.hpp"
|
||||
"Zydis/ZydisOpcodeTable.hpp"
|
||||
"Zydis/ZydisSymbolResolver.hpp"
|
||||
"Zydis/ZydisTypes.hpp"
|
||||
"Zydis/ZydisUtils.hpp")
|
||||
"include/Zydis/Decoder.h"
|
||||
"include/Zydis/Defines.h"
|
||||
"include/Zydis/Formatter.h"
|
||||
"include/Zydis/Input.h"
|
||||
"include/Zydis/InstructionInfo.h"
|
||||
"include/Zydis/Mnemonic.h"
|
||||
"include/Zydis/Register.h"
|
||||
"include/Zydis/Status.h"
|
||||
"include/Zydis/SymbolResolver.h"
|
||||
"include/Zydis/Utils.h"
|
||||
"include/Zydis/Zydis.h"
|
||||
"include/Zydis/Internal/InstructionTable.h")
|
||||
set(sources
|
||||
"Zydis/ZydisInstructionDecoder.cpp"
|
||||
"Zydis/ZydisInstructionFormatter.cpp"
|
||||
"Zydis/ZydisOpcodeTable.cpp"
|
||||
"Zydis/ZydisSymbolResolver.cpp"
|
||||
"Zydis/ZydisUtils.cpp")
|
||||
"src/Decoder.c"
|
||||
"src/Formatter.c"
|
||||
"src/Input.c"
|
||||
"src/InstructionTable.c"
|
||||
"src/Mnemonic.c"
|
||||
"src/Register.c"
|
||||
"src/Utils.c"
|
||||
"src/Zydis.c")
|
||||
|
||||
if (BUILD_SHARED_LIBS AND WIN32)
|
||||
set(sources ${sources}
|
||||
"Zydis/VersionInfo.rc")
|
||||
endif ()
|
||||
|
||||
if (BUILD_C_BINDINGS)
|
||||
set(headers ${headers}
|
||||
"Zydis/ZydisAPI.h")
|
||||
set(sources ${sources}
|
||||
"Zydis/ZydisAPI.cpp")
|
||||
set(sources ${sources} "src/VersionInfo.rc")
|
||||
endif ()
|
||||
|
||||
add_library("Zydis" ${headers} ${sources})
|
||||
|
@ -80,17 +75,25 @@ include_directories(${PROJECT_BINARY_DIR})
|
|||
|
||||
# Examples
|
||||
if (BUILD_EXAMPLES)
|
||||
include_directories("Zydis")
|
||||
|
||||
add_executable("SimpleDemo_CPP" "Examples/CPP/SimpleDemo/SimpleDemo.cpp")
|
||||
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)
|
||||
add_executable("SimpleDemo_C" "Examples/C/SimpleDemo/SimpleDemo.c")
|
||||
target_link_libraries("SimpleDemo_C" "Zydis")
|
||||
endif ()
|
||||
include_directories("include")
|
||||
add_executable("ZydisTest" "examples/ZydisTest.c")
|
||||
target_link_libraries("ZydisTest" "Zydis")
|
||||
set_target_properties ("ZydisTest" PROPERTIES
|
||||
FOLDER "Examples"
|
||||
)
|
||||
add_executable("ZydisPE" "examples/ZydisPE.c")
|
||||
target_link_libraries("ZydisPE" "Zydis")
|
||||
set_target_properties ("ZydisPE" PROPERTIES
|
||||
FOLDER "Examples"
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(CONFIGURED_ONCE TRUE CACHE INTERNAL "CMake has configured at least once.")
|
||||
# Tools
|
||||
if (BUILD_TOOLS)
|
||||
include_directories("include")
|
||||
add_executable("ZydisDisasm" "tools/ZydisDisasm.c")
|
||||
target_link_libraries("ZydisDisasm" "Zydis")
|
||||
set_target_properties ("ZydisDisasm" PROPERTIES
|
||||
FOLDER "Tools"
|
||||
)
|
||||
endif ()
|
||||
|
|
2432
Doxygen/Doxyfile
2432
Doxygen/Doxyfile
File diff suppressed because it is too large
Load Diff
|
@ -1,199 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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 <ZydisAPI.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
void PrintZydisError()
|
||||
{
|
||||
puts("Zydis error: ");
|
||||
switch (ZydisGetLastError())
|
||||
{
|
||||
case ZYDIS_ERROR_SUCCESS:
|
||||
puts("success");
|
||||
break;
|
||||
case ZYDIS_ERROR_UNKNOWN:
|
||||
puts("unknown error");
|
||||
break;
|
||||
case ZYDIS_ERROR_NOT_ENOUGH_MEMORY:
|
||||
puts("not enough memory");
|
||||
break;
|
||||
case ZYDIS_ERROR_INVALID_PARAMETER:
|
||||
puts("invalid parameter");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
ZydisInstructionInfo info;
|
||||
ZydisInstructionDecoderContext* decoder = NULL;
|
||||
ZydisInstructionFormatterContext* formatter = NULL;
|
||||
ZydisInputContext* input32 = NULL;
|
||||
ZydisInputContext* input64 = NULL;
|
||||
|
||||
// Create decoder and formatter instances
|
||||
decoder = ZydisCreateInstructionDecoder();
|
||||
if (!decoder)
|
||||
{
|
||||
goto ZydisError;
|
||||
}
|
||||
formatter = ZydisCreateIntelInstructionFormatter();
|
||||
if (!formatter)
|
||||
{
|
||||
goto FreeZydisDecoder;
|
||||
}
|
||||
|
||||
// Create memory data sources
|
||||
input32 = ZydisCreateMemoryInput(&data32[0], sizeof(data32));
|
||||
if (!input32)
|
||||
{
|
||||
goto FreeZydisFormatter;
|
||||
}
|
||||
input64 = ZydisCreateMemoryInput(&data64[0], sizeof(data64));
|
||||
if (!input64)
|
||||
{
|
||||
goto FreeZydisInput32;
|
||||
}
|
||||
|
||||
// Set decoder properties
|
||||
ZydisSetDisassemblerMode(decoder, ZYDIS_DM_M32BIT);
|
||||
ZydisSetDataSource(decoder, input32);
|
||||
ZydisSetInstructionPointer(decoder, 0x77091852);
|
||||
|
||||
// Decode and format all instructions
|
||||
puts("32 bit test ...\n\n");
|
||||
while (ZydisDecodeInstruction(decoder, &info))
|
||||
{
|
||||
printf("%08X ", (uint32_t)(info.instrAddress & 0xFFFFFFFF));
|
||||
if (info.flags & ZYDIS_IF_ERROR_MASK)
|
||||
{
|
||||
printf("db %02X\n", info.data[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* instructionText;
|
||||
if (!ZydisFormatInstruction(formatter, &info, &instructionText))
|
||||
{
|
||||
goto FreeZydisInput64;
|
||||
}
|
||||
printf("%s\n", instructionText);
|
||||
}
|
||||
}
|
||||
// Check if an error occured in ZydisDecodeInstruction or the end of the input was reached.
|
||||
if (ZydisGetLastError() != ZYDIS_ERROR_SUCCESS)
|
||||
{
|
||||
goto FreeZydisInput64;
|
||||
}
|
||||
|
||||
puts("\n");
|
||||
|
||||
// Set decoder properties
|
||||
ZydisSetDisassemblerMode(decoder, ZYDIS_DM_M64BIT);
|
||||
ZydisSetDataSource(decoder, input64);
|
||||
ZydisSetInstructionPointer(decoder, 0x00007FFA39A81930ull);
|
||||
|
||||
// Decode and format all instructions
|
||||
puts("64 bit test ...\n\n");
|
||||
while (ZydisDecodeInstruction(decoder, &info))
|
||||
{
|
||||
printf("%016"PRIX64" ", info.instrAddress);
|
||||
if (info.flags & ZYDIS_IF_ERROR_MASK)
|
||||
{
|
||||
printf("db %02X", info.data[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* instructionText;
|
||||
if (!ZydisFormatInstruction(formatter, &info, &instructionText))
|
||||
{
|
||||
goto FreeZydisInput64;
|
||||
}
|
||||
printf("%s\n", instructionText);
|
||||
}
|
||||
}
|
||||
// Check if an error occured in ZydisDecodeInstruction or the end of the input was reached.
|
||||
if (ZydisGetLastError() != ZYDIS_ERROR_SUCCESS)
|
||||
{
|
||||
goto FreeZydisInput64;
|
||||
}
|
||||
|
||||
// Cleanup code
|
||||
FreeZydisInput64:
|
||||
ZydisFreeInput(input64);
|
||||
FreeZydisInput32:
|
||||
ZydisFreeInput(input32);
|
||||
FreeZydisFormatter:
|
||||
ZydisFreeInstructionFormatter(formatter);
|
||||
FreeZydisDecoder:
|
||||
ZydisFreeInstructionDecoder(decoder);
|
||||
ZydisError:
|
||||
|
||||
if (ZydisGetLastError() != ZYDIS_ERROR_SUCCESS)
|
||||
{
|
||||
PrintZydisError();
|
||||
getchar();
|
||||
return 1;
|
||||
}
|
||||
|
||||
getchar();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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;
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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 <Zydis.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
Zydis::InstructionInfo info;
|
||||
Zydis::InstructionDecoder decoder;
|
||||
Zydis::IntelInstructionFormatter formatter;
|
||||
Zydis::MemoryInput input32(&data32[0], sizeof(data32));
|
||||
Zydis::MemoryInput input64(&data64[0], sizeof(data64));
|
||||
|
||||
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
|
||||
decoder.setDataSource(&input32);
|
||||
decoder.setInstructionPointer(0x77091852);
|
||||
std::cout << "32 bit test ..." << std::endl << std::endl;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M64BIT);
|
||||
decoder.setDataSource(&input64);
|
||||
decoder.setInstructionPointer(0x00007FFA39A81930ull);
|
||||
std::cout << "64 bit test ..." << std::endl << std::endl;
|
||||
while (decoder.decodeInstruction(info))
|
||||
{
|
||||
std::cout << std::hex << std::setw(16) << 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;
|
||||
}
|
||||
}
|
||||
|
||||
std::cin.get();
|
||||
return 0;
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
<?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>{EFA075B8-AFB9-4E06-99AD-BD58F50A9500}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>OptableGenerator</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>..\VerteronDisassemblerEngine\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>..\VerteronDisassemblerEngine\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>..\VerteronDisassemblerEngine\;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>..\VerteronDisassemblerEngine\;$(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>
|
||||
</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>
|
||||
</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>
|
||||
</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>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VerteronDisassemblerEngine\VerteronDisassemblerEngine.vcxproj">
|
||||
<Project>{f5c6f0a7-f75d-42bd-a8ab-a2d1d5f67099}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Main.cpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,72 +0,0 @@
|
|||
/**
|
||||
* 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
83
README.md
83
README.md
|
@ -1,30 +1,28 @@
|
|||
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)
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
================================
|
||||
|
||||
Fast and lightweight x86/x86-64 disassembler library.
|
||||
|
||||
## Features ##
|
||||
|
||||
- Supports all x86 and x86-64 (AMD64) General purpose and System instructions.
|
||||
- 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
|
||||
- FPU (x87), MMX
|
||||
- SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, SSE4A, AESNI
|
||||
- AVX, AVX2, AVX512BW, AVX512CD, AVX512DQ, AVX512ER, AVX512F, AVX512PF, AVX512VL
|
||||
- ADX, BMI1, BMI2, FMA, FMA4
|
||||
- ..
|
||||
- Optimized for high performance
|
||||
- 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
|
||||
- Very small overhead compared to other common disassembler libraries
|
||||
- Complete doxygen documentation
|
||||
|
||||
## Quick Example ##
|
||||
|
||||
The following example program uses Zydis to disassemble a given memory buffer and prints the output to the console.
|
||||
|
||||
```c++
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <stdint.h>
|
||||
#include <Zydis.hpp>
|
||||
```C
|
||||
#include <stdio.h>
|
||||
#include <Zydis/Zydis.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
|
@ -35,29 +33,30 @@ int main()
|
|||
0x88, 0xFC, 0xDA, 0x02, 0x00
|
||||
};
|
||||
|
||||
Zydis::MemoryInput input(&data[0], sizeof(data));
|
||||
Zydis::InstructionInfo info;
|
||||
Zydis::InstructionDecoder decoder;
|
||||
decoder.setDisassemblerMode(Zydis::DisassemblerMode::M32BIT);
|
||||
decoder.setDataSource(&input);
|
||||
decoder.setInstructionPointer(0x00400000);
|
||||
Zydis::IntelInstructionFormatter formatter;
|
||||
ZydisMemoryInput input;
|
||||
ZydisInputInitMemoryInput(&input, &data, sizeof(data));
|
||||
|
||||
while (decoder.decodeInstruction(info))
|
||||
{
|
||||
std::cout << std::hex << std::setw(8) << std::setfill('0')
|
||||
<< std::uppercase << info.instrAddress << " ";
|
||||
ZydisInstructionDecoder decoder;
|
||||
ZydisDecoderInitInstructionDecoderEx(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT,
|
||||
(ZydisCustomInput*)&input, ZYDIS_DECODER_FLAG_SKIP_DATA);
|
||||
ZydisDecoderSetInstructionPointer(&decoder, 0x007FFFFFFF400000);
|
||||
|
||||
if (info.flags & Zydis::IF_ERROR_MASK)
|
||||
ZydisInstructionFormatter formatter;
|
||||
ZydisFormatterInitInstructionFormatterEx(&formatter,
|
||||
ZYDIS_FORMATTER_STYLE_INTEL, ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT);
|
||||
|
||||
ZydisInstructionInfo info;
|
||||
char buffer[256];
|
||||
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
|
||||
{
|
||||
std::cout << "db " << std::setw(2)
|
||||
<< static_cast<int>(info.data[0])
|
||||
<< std::endl;
|
||||
}
|
||||
else
|
||||
printf("%016llX ", info.instrAddress);
|
||||
if (info.flags & ZYDIS_IFLAG_ERROR_MASK)
|
||||
{
|
||||
std::cout << formatter.formatInstruction(info) << std::endl;
|
||||
printf(" db %02x\n", info.data[0]);
|
||||
continue;
|
||||
}
|
||||
ZydisFormatterFormatInstruction(&formatter, &info, &buffer[0], sizeof(buffer));
|
||||
printf(" %s\n", &buffer[0]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -67,23 +66,19 @@ int main()
|
|||
The above example program generates the following output:
|
||||
|
||||
```
|
||||
00400000 push ecx
|
||||
00400001 lea eax, [ebp-01]
|
||||
00400004 push eax
|
||||
00400005 push dword ptr [ebp+0C]
|
||||
00400008 push dword ptr [ebp+08]
|
||||
0040000B call dword ptr [7648A5A0]
|
||||
00400011 test eax, eax
|
||||
00400013 js 0042DB15
|
||||
007FFFFFFF400000 push rcx
|
||||
007FFFFFFF400001 lea eax, dword ptr ss:[rbp-0x01]
|
||||
007FFFFFFF400004 push rax
|
||||
007FFFFFFF400005 push qword ptr ss:[rbp+0x0C]
|
||||
007FFFFFFF400008 push qword ptr ss:[rbp+0x08]
|
||||
007FFFFFFF40000B call qword ptr ds:[0x008000007588A5B1]
|
||||
007FFFFFFF400011 test eax, eax
|
||||
007FFFFFFF400013 js 0x007FFFFFFF42DB15
|
||||
```
|
||||
|
||||
## Compilation ##
|
||||
|
||||
Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C++14 compiler.
|
||||
|
||||
## Documentation ##
|
||||
|
||||
[The HTML Doxygen documentation](https://www.zyantific.com/doc/zydis/index.html) is automatically built from master every 12 hours.
|
||||
Zydis builds cleanly on most platforms without any external dependencies. You can use CMake to generate project files for your favorite C99 compiler.
|
||||
|
||||
## License ##
|
||||
|
||||
|
|
100
Zydis/Zydis.hpp
100
Zydis/Zydis.hpp
|
@ -1,100 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @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 "ZydisInstructionFormatter.hpp"
|
||||
#include "ZydisSymbolResolver.hpp"
|
||||
#include "ZydisUtils.hpp"
|
||||
|
||||
#endif /*_ZYDIS_HPP_ */
|
|
@ -1,653 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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 "ZydisAPI.h"
|
||||
#include "ZydisInstructionDecoder.hpp"
|
||||
#include "ZydisInstructionFormatter.hpp"
|
||||
|
||||
/* Static Checks ================================================================================ */
|
||||
|
||||
static_assert(
|
||||
sizeof(ZydisOperandInfo) == sizeof(Zydis::OperandInfo),
|
||||
"struct size mismatch");
|
||||
|
||||
static_assert(
|
||||
sizeof(ZydisInstructionInfo) == sizeof(Zydis::InstructionInfo),
|
||||
"struct size mismatch");
|
||||
|
||||
/* Error Handling =============================================================================== */
|
||||
|
||||
static uint32_t g_zydisLastError = ZYDIS_ERROR_SUCCESS;
|
||||
|
||||
uint32_t ZydisGetLastError()
|
||||
{
|
||||
return g_zydisLastError;
|
||||
}
|
||||
|
||||
void ZydisSetLastError(uint32_t errorCode)
|
||||
{
|
||||
g_zydisLastError = errorCode;
|
||||
}
|
||||
|
||||
/* Conversion Helper ============================================================================ */
|
||||
|
||||
typedef enum _ZydisClassType
|
||||
{
|
||||
ZYDIS_CONTEXT_INPUT = 0x00000080,
|
||||
ZYDIS_CONTEXT_INPUT_CUSTOM = ZYDIS_CONTEXT_INPUT | 0x00000001,
|
||||
ZYDIS_CONTEXT_INPUT_MEMORY = ZYDIS_CONTEXT_INPUT | 0x00000002,
|
||||
ZYDIS_CONTEXT_INSTRUCTIONDECODER = 0x00000040,
|
||||
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER = 0x00000020,
|
||||
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_CUSTOM = ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | 0x00000001,
|
||||
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL = ZYDIS_CONTEXT_INSTRUCTIONFORMATTER | 0x00000002,
|
||||
ZYDIS_CONTEXT_SYMBOLRESOLVER = 0x00000010,
|
||||
ZYDIS_CONTEXT_SYMBOLRESOLVER_CUSTOM = ZYDIS_CONTEXT_SYMBOLRESOLVER | 0x00000001,
|
||||
ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT = ZYDIS_CONTEXT_SYMBOLRESOLVER | 0x00000002
|
||||
} ZydisClassType;
|
||||
|
||||
/**
|
||||
* @brief This helper class extends a zydis class with a type field. It is used by the C-bindings
|
||||
* to check type correctness for input parameters.
|
||||
* @param ZydisClassT The zydis class type.
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
template <typename ZydisClassT>
|
||||
class ZydisClassEx final
|
||||
{
|
||||
private:
|
||||
using FullClassT = ZydisClassEx<ZydisClassT>;
|
||||
public:
|
||||
uint32_t type;
|
||||
uint32_t align;
|
||||
std::conditional_t<std::is_abstract<ZydisClassT>::value, char, ZydisClassT> instance;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param InstanceCtorArgsT The argument types for the constructor of the zydis class.
|
||||
* @param classType The type of the zydis class.
|
||||
* @param args... The arguments for the constructor of the zydis class.
|
||||
*/
|
||||
template<
|
||||
typename ZydisClassTT=ZydisClassT,
|
||||
std::enable_if_t<!std::is_abstract<ZydisClassTT>::value, int> = 0,
|
||||
typename... InstanceCtorArgsT>
|
||||
ZydisClassEx(uint32_t classType, InstanceCtorArgsT... args)
|
||||
: type(classType)
|
||||
, align(0)
|
||||
, instance(args...) { };
|
||||
public:
|
||||
/**
|
||||
* @brief Returns the class type.
|
||||
* @return The assigned class type.
|
||||
*/
|
||||
uint32_t getClassType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
/**
|
||||
* @brief Returns the zydis class instance.
|
||||
* @return Pointer to the zydis class instance.
|
||||
*/
|
||||
ZydisClassT* getInstance()
|
||||
{
|
||||
return reinterpret_cast<ZydisClassT*>(&instance);
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief Casts the given instance to @c ZydisClassEx.
|
||||
* @param instance The zydis class instance.
|
||||
* @return Pointer to the @c ZydisClassEx instance.
|
||||
*/
|
||||
static FullClassT* fromInstance(ZydisClassT* instance)
|
||||
{
|
||||
return reinterpret_cast<FullClassT*>(
|
||||
reinterpret_cast<uintptr_t>(instance)
|
||||
- sizeof(std::declval<FullClassT>().type)
|
||||
- sizeof(std::declval<FullClassT>().align));
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/**
|
||||
* @brief Creates a context by constructing a new wrapped zydis class instance.
|
||||
* @param ContextClassT The context class.
|
||||
* @param ZydisClassT The zydis class type.
|
||||
* @param ZydisClassCtorArgsT The argument types for the constructor of the zydis class.
|
||||
* @param classType The type of the zydis class.
|
||||
* @param args... The arguments for the constructor of the zydis class.
|
||||
*/
|
||||
template <typename ContextClassT, typename ZydisClassT, typename... ZydisClassCtorArgsT>
|
||||
ContextClassT* ZydisCreateContext(uint32_t classType, ZydisClassCtorArgsT... args)
|
||||
{
|
||||
auto instanceEx = new (std::nothrow) ZydisClassEx<ZydisClassT>(classType, args...);
|
||||
if (!instanceEx)
|
||||
{
|
||||
ZydisSetLastError(ZYDIS_ERROR_NOT_ENOUGH_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
// Return the original instance as context.
|
||||
return reinterpret_cast<ContextClassT*>(instanceEx->getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the zydis class instance of the given context.
|
||||
* @param ContextClassT The context class.
|
||||
* @param ZydisClassT The zydis class type.
|
||||
* @param expectedType The expected type of the zydis class.
|
||||
*/
|
||||
template <typename ContextClassT, typename ZydisClassT>
|
||||
ZydisClassT* ZydisRetrieveInstance(uint32_t expectedType, const ContextClassT* context)
|
||||
{
|
||||
auto instanceEx = ZydisClassEx<ZydisClassT>::fromInstance(
|
||||
reinterpret_cast<ZydisClassT*>(const_cast<ContextClassT*>(context)));
|
||||
if ((instanceEx->getClassType() & expectedType) != expectedType)
|
||||
{
|
||||
ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER);
|
||||
return nullptr;
|
||||
}
|
||||
// The context points to the same address as the instance. We just need to cast it.
|
||||
return reinterpret_cast<ZydisClassT*>(const_cast<ContextClassT*>(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a context by constructing a new wrapped zydis instance.
|
||||
* @param ContextClassT The context class.
|
||||
* @param ZydisClassT The zydis class type.
|
||||
* @param expectedType The expected type of the zydis class.
|
||||
*/
|
||||
template <typename ContextClassT, typename ZydisClassT>
|
||||
bool ZydisFreeContext(uint32_t expectedType, const ContextClassT* context)
|
||||
{
|
||||
auto instanceEx = ZydisClassEx<ZydisClassT>::fromInstance(
|
||||
reinterpret_cast<ZydisClassT*>(const_cast<ContextClassT*>(context)));
|
||||
if ((instanceEx->getClassType() & expectedType) != expectedType)
|
||||
{
|
||||
ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER);
|
||||
return false;
|
||||
}
|
||||
delete instanceEx;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Input ======================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Helper class for custom input implementations.
|
||||
*/
|
||||
class ZydisCustomInput : public Zydis::BaseInput
|
||||
{
|
||||
private:
|
||||
void* m_userData;
|
||||
ZydisCustomDestructorT m_cbDestructor;
|
||||
ZydisCustomInputPeekT m_cbPeek;
|
||||
ZydisCustomInputNextT m_cbNext;
|
||||
ZydisCustomInputIsEndOfInputT m_cbIsEndOfInput;
|
||||
ZydisCustomInputGetPositionT m_cbGetPosition;
|
||||
ZydisCustomInputSetPositionT m_cbSetPosition;
|
||||
protected:
|
||||
uint8_t internalInputPeek() override
|
||||
{
|
||||
return m_cbPeek(m_userData);
|
||||
}
|
||||
|
||||
uint8_t internalInputNext() override
|
||||
{
|
||||
return m_cbNext(m_userData);
|
||||
}
|
||||
public:
|
||||
ZydisCustomInput(void* userData,
|
||||
ZydisCustomInputPeekT cbPeek, ZydisCustomInputNextT cbNext,
|
||||
ZydisCustomInputIsEndOfInputT cbIsEndOfInput, ZydisCustomInputGetPositionT cbGetPosition,
|
||||
ZydisCustomInputSetPositionT cbSetPosition, ZydisCustomDestructorT cbDestructor)
|
||||
: m_userData(userData)
|
||||
, m_cbDestructor(cbDestructor)
|
||||
, m_cbPeek(cbPeek)
|
||||
, m_cbNext(cbNext)
|
||||
, m_cbIsEndOfInput(cbIsEndOfInput)
|
||||
, m_cbGetPosition(cbGetPosition)
|
||||
, m_cbSetPosition(cbSetPosition)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~ZydisCustomInput() override
|
||||
{
|
||||
if (m_cbDestructor)
|
||||
{
|
||||
m_cbDestructor(m_userData);
|
||||
}
|
||||
}
|
||||
public:
|
||||
bool isEndOfInput() const override
|
||||
{
|
||||
return m_cbIsEndOfInput(m_userData);
|
||||
}
|
||||
|
||||
uint64_t getPosition() const override
|
||||
{
|
||||
return m_cbGetPosition(m_userData);
|
||||
}
|
||||
|
||||
bool setPosition(uint64_t position) override
|
||||
{
|
||||
return m_cbSetPosition(m_userData, position);
|
||||
}
|
||||
};
|
||||
|
||||
ZydisInputContext* ZydisCreateCustomInput(void* userData,
|
||||
ZydisCustomInputPeekT cbPeek, ZydisCustomInputNextT cbNext,
|
||||
ZydisCustomInputIsEndOfInputT cbIsEndOfInput, ZydisCustomInputGetPositionT cbGetPosition,
|
||||
ZydisCustomInputSetPositionT cbSetPosition, ZydisCustomDestructorT cbDestructor)
|
||||
{
|
||||
if (!cbPeek || !cbNext || !cbIsEndOfInput || !cbGetPosition || !cbSetPosition)
|
||||
{
|
||||
ZydisSetLastError(ZYDIS_ERROR_INVALID_PARAMETER);
|
||||
return nullptr;
|
||||
}
|
||||
return ZydisCreateContext<ZydisInputContext, ZydisCustomInput>(ZYDIS_CONTEXT_INPUT_CUSTOM,
|
||||
userData, cbPeek, cbNext, cbIsEndOfInput, cbGetPosition, cbSetPosition, cbDestructor);
|
||||
}
|
||||
|
||||
ZydisInputContext* ZydisCreateMemoryInput(const void* buffer, size_t bufferLen)
|
||||
{
|
||||
return ZydisCreateContext<ZydisInputContext, Zydis::MemoryInput>(
|
||||
ZYDIS_CONTEXT_INPUT_MEMORY, buffer, bufferLen);
|
||||
}
|
||||
|
||||
bool ZydisIsEndOfInput(const ZydisInputContext* input, bool* isEndOfInput)
|
||||
{
|
||||
Zydis::BaseInput* instance =
|
||||
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*isEndOfInput = instance->isEndOfInput();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisGetInputPosition(const ZydisInputContext* input, uint64_t* position)
|
||||
{
|
||||
Zydis::BaseInput* instance =
|
||||
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*position = instance->getPosition();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisSetInputPosition(const ZydisInputContext* input, uint64_t position)
|
||||
{
|
||||
Zydis::BaseInput* instance =
|
||||
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ZydisSetLastError(ZYDIS_ERROR_SUCCESS);
|
||||
return instance->setPosition(position);
|
||||
}
|
||||
|
||||
bool ZydisFreeInput(const ZydisInputContext* input)
|
||||
{
|
||||
return ZydisFreeContext<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
|
||||
}
|
||||
|
||||
/* InstructionDecoder =========================================================================== */
|
||||
|
||||
ZydisInstructionDecoderContext* ZydisCreateInstructionDecoder()
|
||||
{
|
||||
return ZydisCreateContext<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
|
||||
ZYDIS_CONTEXT_INSTRUCTIONDECODER);
|
||||
}
|
||||
|
||||
ZydisInstructionDecoderContext* ZydisCreateInstructionDecoderEx(
|
||||
const ZydisInputContext* input, ZydisDisassemblerMode disassemblerMode,
|
||||
ZydisInstructionSetVendor preferredVendor, uint64_t instructionPointer)
|
||||
{
|
||||
Zydis::BaseInput* object =
|
||||
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
|
||||
if (!object)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return ZydisCreateContext<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
|
||||
ZYDIS_CONTEXT_INSTRUCTIONDECODER, object,
|
||||
static_cast<Zydis::DisassemblerMode>(disassemblerMode),
|
||||
static_cast<Zydis::InstructionSetVendor>(preferredVendor), instructionPointer);
|
||||
}
|
||||
|
||||
bool ZydisDecodeInstruction(const ZydisInstructionDecoderContext* decoder,
|
||||
ZydisInstructionInfo* info)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ZydisSetLastError(ZYDIS_ERROR_SUCCESS);
|
||||
return instance->decodeInstruction(*reinterpret_cast<Zydis::InstructionInfo*>(info));
|
||||
}
|
||||
|
||||
bool ZydisGetDataSource(const ZydisInstructionDecoderContext* decoder,
|
||||
ZydisInputContext** input)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*input = reinterpret_cast<ZydisInputContext*>(instance->getDataSource());
|
||||
if (!input)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisSetDataSource(const ZydisInstructionDecoderContext* decoder,
|
||||
ZydisInputContext* input)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Zydis::BaseInput* object =
|
||||
ZydisRetrieveInstance<ZydisInputContext, Zydis::BaseInput>(ZYDIS_CONTEXT_INPUT, input);
|
||||
if (!object)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->setDataSource(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisGetDisassemblerMode(const ZydisInstructionDecoderContext* decoder,
|
||||
ZydisDisassemblerMode* disassemblerMode)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*disassemblerMode = static_cast<ZydisDisassemblerMode>(instance->getDisassemblerMode());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisSetDisassemblerMode(const ZydisInstructionDecoderContext* decoder,
|
||||
ZydisDisassemblerMode disassemblerMode)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->setDisassemblerMode(static_cast<Zydis::DisassemblerMode>(disassemblerMode));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisGetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
|
||||
ZydisInstructionSetVendor* preferredVendor)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*preferredVendor = static_cast<ZydisInstructionSetVendor>(instance->getPreferredVendor());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisSetPreferredVendor(const ZydisInstructionDecoderContext* decoder,
|
||||
ZydisInstructionSetVendor preferredVendor)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->setPreferredVendor(static_cast<Zydis::InstructionSetVendor>(preferredVendor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisGetInstructionPointer(const ZydisInstructionDecoderContext* decoder,
|
||||
uint64_t* instructionPointer)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*instructionPointer = instance->getInstructionPointer();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisSetInstructionPointer(const ZydisInstructionDecoderContext* decoder,
|
||||
uint64_t instructionPointer)
|
||||
{
|
||||
Zydis::InstructionDecoder* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionDecoderContext,
|
||||
Zydis::InstructionDecoder>(ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->setInstructionPointer(instructionPointer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisFreeInstructionDecoder(const ZydisInstructionDecoderContext* decoder)
|
||||
{
|
||||
return ZydisFreeContext<ZydisInstructionDecoderContext, Zydis::InstructionDecoder>(
|
||||
ZYDIS_CONTEXT_INSTRUCTIONDECODER, decoder);
|
||||
}
|
||||
|
||||
/* InstructionFormatter ========================================================================= */
|
||||
|
||||
ZydisInstructionFormatterContext* ZydisCreateCustomInstructionFormatter(/* TODO */)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ZydisInstructionFormatterContext* ZydisCreateIntelInstructionFormatter()
|
||||
{
|
||||
return ZydisCreateContext<ZydisInstructionFormatterContext,
|
||||
Zydis::IntelInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER_INTEL);
|
||||
}
|
||||
|
||||
bool ZydisFormatInstruction(const ZydisInstructionFormatterContext* formatter,
|
||||
const ZydisInstructionInfo* info, const char** instructionText)
|
||||
{
|
||||
Zydis::BaseInstructionFormatter* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionFormatterContext,
|
||||
Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*instructionText =
|
||||
instance->formatInstruction(*reinterpret_cast<const Zydis::InstructionInfo*>(info));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisGetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
|
||||
ZydisSymbolResolverContext** resolver)
|
||||
{
|
||||
Zydis::BaseInstructionFormatter* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionFormatterContext,
|
||||
Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*resolver = reinterpret_cast<ZydisSymbolResolverContext*>(instance->getSymbolResolver());
|
||||
if (!resolver)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisSetSymbolResolver(const ZydisInstructionFormatterContext* formatter,
|
||||
ZydisSymbolResolverContext* resolver)
|
||||
{
|
||||
Zydis::BaseInstructionFormatter* instance =
|
||||
ZydisRetrieveInstance<ZydisInstructionFormatterContext,
|
||||
Zydis::BaseInstructionFormatter>(ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Zydis::BaseSymbolResolver* object =
|
||||
ZydisRetrieveInstance<ZydisSymbolResolverContext,
|
||||
Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
|
||||
if (!object)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->setSymbolResolver(object);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisFreeInstructionFormatter(const ZydisInstructionFormatterContext* formatter)
|
||||
{
|
||||
return ZydisFreeContext<ZydisInstructionFormatterContext, Zydis::BaseInstructionFormatter>(
|
||||
ZYDIS_CONTEXT_INSTRUCTIONFORMATTER, formatter);
|
||||
}
|
||||
|
||||
/* SymbolResolver =============================================================================== */
|
||||
|
||||
ZydisSymbolResolverContext* ZydisCreateCustomSymbolResolver(/*TODO*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ZydisSymbolResolverContext* ZydisCreateExactSymbolResolver()
|
||||
{
|
||||
return ZydisCreateContext<ZydisSymbolResolverContext, Zydis::ExactSymbolResolver>(
|
||||
ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT);
|
||||
}
|
||||
|
||||
bool ZydisResolveSymbol(const ZydisSymbolResolverContext* resolver,
|
||||
const ZydisInstructionInfo* info, uint64_t address, const char** symbol, uint64_t* offset)
|
||||
{
|
||||
Zydis::BaseSymbolResolver* instance =
|
||||
ZydisRetrieveInstance<ZydisSymbolResolverContext,
|
||||
Zydis::BaseSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*symbol = instance->resolveSymbol(*reinterpret_cast<const Zydis::InstructionInfo*>(info),
|
||||
address, *offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisExactSymbolResolverContainsSymbol(
|
||||
const ZydisSymbolResolverContext* resolver, uint64_t address, bool* containsSymbol)
|
||||
{
|
||||
Zydis::ExactSymbolResolver* instance =
|
||||
ZydisRetrieveInstance<ZydisSymbolResolverContext,
|
||||
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*containsSymbol = instance->containsSymbol(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisExactSymbolResolverSetSymbol(const ZydisSymbolResolverContext* resolver,
|
||||
uint64_t address, const char* name)
|
||||
{
|
||||
Zydis::ExactSymbolResolver* instance =
|
||||
ZydisRetrieveInstance<ZydisSymbolResolverContext,
|
||||
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->setSymbol(address, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisExactSymbolResolverRemoveSymbol(const ZydisSymbolResolverContext* resolver,
|
||||
uint64_t address)
|
||||
{
|
||||
Zydis::ExactSymbolResolver* instance =
|
||||
ZydisRetrieveInstance<ZydisSymbolResolverContext,
|
||||
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->removeSymbol(address);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisExactSymbolResolverClear(const ZydisSymbolResolverContext* resolver)
|
||||
{
|
||||
Zydis::ExactSymbolResolver* instance =
|
||||
ZydisRetrieveInstance<ZydisSymbolResolverContext,
|
||||
Zydis::ExactSymbolResolver>(ZYDIS_CONTEXT_SYMBOLRESOLVER_EXACT, resolver);
|
||||
if (!instance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
instance->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisFreeSymbolResolver(const ZydisSymbolResolverContext* resolver)
|
||||
{
|
||||
return ZydisFreeContext<ZydisSymbolResolverContext, Zydis::BaseSymbolResolver>(
|
||||
ZYDIS_CONTEXT_SYMBOLRESOLVER, resolver);
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
1631
Zydis/ZydisAPI.h
1631
Zydis/ZydisAPI.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,728 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Instruction decoder classes.
|
||||
*/
|
||||
|
||||
#ifndef _ZYDIS_INSTRUCTIONDECODER_HPP_
|
||||
#define _ZYDIS_INSTRUCTIONDECODER_HPP_
|
||||
|
||||
#include <type_traits>
|
||||
#include <istream>
|
||||
#include "ZydisTypes.hpp"
|
||||
|
||||
namespace Zydis
|
||||
{
|
||||
|
||||
/* BaseInput ==================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief The base class for all data-source implementations.
|
||||
*/
|
||||
class BaseInput
|
||||
{
|
||||
friend class InstructionDecoder;
|
||||
private:
|
||||
uint8_t m_currentInput;
|
||||
private:
|
||||
/**
|
||||
* @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.
|
||||
* @param info The instruction info.
|
||||
* @return The current input byte. If the result is zero, you should always check the
|
||||
* @c flags field of the @c info parameter for error flags.
|
||||
* Possible error values are @c IF_ERROR_END_OF_INPUT or @c IF_ERROR_LENGTH.
|
||||
*/
|
||||
uint8_t inputPeek(InstructionInfo& info);
|
||||
/**
|
||||
* @brief Reads the next byte from the data source. This method increases the current
|
||||
* input position and the @c length field of the @c info parameter.
|
||||
* This method also appends the new byte to to @c data field of the @c info
|
||||
* parameter.
|
||||
* @param info The instruction info.
|
||||
* @return The current input byte. If the result is zero, you should always check the
|
||||
* @c flags field of the @c info parameter for error flags.
|
||||
* Possible error values are @c IF_ERROR_END_OF_INPUT or @c IF_ERROR_LENGTH.
|
||||
*/
|
||||
uint8_t inputNext(InstructionInfo& info);
|
||||
/**
|
||||
* @brief Reads the next byte(s) from the data source. This method increases the current
|
||||
* input position and the @c length field of the @c info parameter.
|
||||
* This method also appends the new byte(s) to to @c data field of the @c info
|
||||
* parameter.
|
||||
* @param info The instruction info.
|
||||
* @return The current input data. If the result is zero, you should always check the
|
||||
* @c flags field of the @c info parameter for error flags.
|
||||
* Possible error values are @c IF_ERROR_END_OF_INPUT or @c IF_ERROR_LENGTH.
|
||||
*/
|
||||
template <typename T>
|
||||
T inputNext(InstructionInfo& 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;
|
||||
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:
|
||||
/**
|
||||
* @brief Override this method in your custom data source implementations.
|
||||
* Signals, if the end of the data source is reached.
|
||||
* @return True if end of input, false if not.
|
||||
*/
|
||||
virtual bool isEndOfInput() const = 0;
|
||||
/**
|
||||
* @brief Override this method in your custom data source implementations.
|
||||
* Returns the current input position.
|
||||
* @return The current input position.
|
||||
*/
|
||||
virtual uint64_t getPosition() const = 0;
|
||||
/**
|
||||
* @brief Override this method in your custom data source implementations.
|
||||
* Sets a new input position.
|
||||
* @param position The new input position.
|
||||
* @return Returns false, if the new position exceeds the maximum input length.
|
||||
*/
|
||||
virtual bool setPosition(uint64_t position) = 0;
|
||||
};
|
||||
|
||||
inline uint8_t BaseInput::inputPeek(InstructionInfo& info)
|
||||
{
|
||||
if (info.length == 15)
|
||||
{
|
||||
info.flags |= IF_ERROR_LENGTH;
|
||||
return 0;
|
||||
}
|
||||
if (isEndOfInput())
|
||||
{
|
||||
info.flags |= IF_ERROR_END_OF_INPUT;
|
||||
return 0;
|
||||
}
|
||||
m_currentInput = internalInputPeek();
|
||||
return m_currentInput;
|
||||
}
|
||||
|
||||
inline uint8_t BaseInput::inputNext(InstructionInfo& info)
|
||||
{
|
||||
if (info.length == 15)
|
||||
{
|
||||
info.flags |= IF_ERROR_LENGTH;
|
||||
return 0;
|
||||
}
|
||||
if (isEndOfInput())
|
||||
{
|
||||
info.flags |= IF_ERROR_END_OF_INPUT;
|
||||
return 0;
|
||||
}
|
||||
m_currentInput = internalInputNext();
|
||||
info.data[info.length] = m_currentInput;
|
||||
info.length++;
|
||||
return m_currentInput;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T BaseInput::inputNext(InstructionInfo& 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 BaseInput::inputCurrent() const
|
||||
{
|
||||
return m_currentInput;
|
||||
}
|
||||
|
||||
/* MemoryInput ================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief A memory-buffer based data source for the @c InstructionDecoder class.
|
||||
*/
|
||||
class MemoryInput : public BaseInput
|
||||
{
|
||||
private:
|
||||
const void* m_inputBuffer;
|
||||
uint64_t m_inputBufferLen;
|
||||
uint64_t m_inputBufferPos;
|
||||
protected:
|
||||
/**
|
||||
* @brief Reads the next byte from the data source. This method increases the current
|
||||
* input position by one.
|
||||
* @return The current input byte.
|
||||
*/
|
||||
uint8_t internalInputPeek() override;
|
||||
/**
|
||||
* @brief Reads the next byte from the data source. This method does NOT increase the
|
||||
* current input position.
|
||||
* @return The current input byte.
|
||||
*/
|
||||
uint8_t internalInputNext() override;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param buffer The input buffer.
|
||||
* @param bufferLen The length of the input buffer.
|
||||
*/
|
||||
MemoryInput(const void* buffer, size_t bufferLen)
|
||||
: m_inputBuffer(buffer)
|
||||
, m_inputBufferLen(bufferLen)
|
||||
, m_inputBufferPos(0) { };
|
||||
public:
|
||||
/**
|
||||
* @brief Signals, if the end of the data source is reached.
|
||||
* @return True if end of input, false if not.
|
||||
*/
|
||||
bool isEndOfInput() const override;
|
||||
/**
|
||||
* @brief Returns the current input position.
|
||||
* @return The current input position.
|
||||
*/
|
||||
uint64_t getPosition() const override;
|
||||
/**
|
||||
* @brief Sets a new input position.
|
||||
* @param position The new input position.
|
||||
* @return Returns false, if the new position exceeds the maximum input length.
|
||||
*/
|
||||
bool setPosition(uint64_t position) override;
|
||||
};
|
||||
|
||||
inline uint8_t MemoryInput::internalInputPeek()
|
||||
{
|
||||
return *(static_cast<const uint8_t*>(m_inputBuffer) + m_inputBufferPos);
|
||||
}
|
||||
|
||||
inline uint8_t MemoryInput::internalInputNext()
|
||||
{
|
||||
++m_inputBufferPos;
|
||||
return *(static_cast<const uint8_t*>(m_inputBuffer) + m_inputBufferPos - 1);
|
||||
}
|
||||
|
||||
inline bool MemoryInput::isEndOfInput() const
|
||||
{
|
||||
return (m_inputBufferPos >= m_inputBufferLen);
|
||||
}
|
||||
|
||||
inline uint64_t MemoryInput::getPosition() const
|
||||
{
|
||||
return m_inputBufferPos;
|
||||
}
|
||||
|
||||
inline bool MemoryInput::setPosition(uint64_t position)
|
||||
{
|
||||
m_inputBufferPos = position;
|
||||
return isEndOfInput();
|
||||
}
|
||||
|
||||
/* StreamInput ================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief A stream based data source for the @c InstructionDecoder class.
|
||||
*/
|
||||
class StreamInput : public BaseInput
|
||||
{
|
||||
private:
|
||||
std::istream* m_inputStream;
|
||||
protected:
|
||||
/**
|
||||
* @brief Reads the next byte from the data source. This method increases the current
|
||||
* input position by one.
|
||||
* @return The current input byte.
|
||||
*/
|
||||
uint8_t internalInputPeek() override;
|
||||
/**
|
||||
* @brief Reads the next byte from the data source. This method does NOT increase the
|
||||
* current input position.
|
||||
* @return The current input byte.
|
||||
*/
|
||||
uint8_t internalInputNext() override;
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param stream The input stream.
|
||||
*/
|
||||
explicit StreamInput(std::istream* stream)
|
||||
: m_inputStream(stream) { };
|
||||
public:
|
||||
/**
|
||||
* @brief Signals, if the end of the data source is reached.
|
||||
* @return True if end of input, false if not.
|
||||
*/
|
||||
bool isEndOfInput() const override;
|
||||
/**
|
||||
* @brief Returns the current input position.
|
||||
* @return The current input position.
|
||||
*/
|
||||
uint64_t getPosition() const override;
|
||||
/**
|
||||
* @brief Sets a new input position.
|
||||
* @param position The new input position.
|
||||
* @return Returns false, if the new position exceeds the maximum input length.
|
||||
*/
|
||||
bool setPosition(uint64_t position) override;
|
||||
};
|
||||
|
||||
inline uint8_t StreamInput::internalInputPeek()
|
||||
{
|
||||
if (!m_inputStream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return static_cast<uint8_t>(m_inputStream->peek());
|
||||
}
|
||||
|
||||
inline uint8_t StreamInput::internalInputNext()
|
||||
{
|
||||
if (!m_inputStream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return static_cast<uint8_t>(m_inputStream->get());
|
||||
}
|
||||
|
||||
inline bool StreamInput::isEndOfInput() const
|
||||
{
|
||||
if (!m_inputStream)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// We use good() instead of eof() to make sure the decoding will fail, if an stream internal
|
||||
// error occured.
|
||||
return !m_inputStream->good();
|
||||
}
|
||||
|
||||
inline uint64_t StreamInput::getPosition() const
|
||||
{
|
||||
if (!m_inputStream)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return m_inputStream->tellg();
|
||||
}
|
||||
|
||||
inline bool StreamInput::setPosition(uint64_t position)
|
||||
{
|
||||
if (!m_inputStream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_inputStream->seekg(position);
|
||||
return isEndOfInput();
|
||||
}
|
||||
|
||||
/* Enums ======================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Values that represent a disassembler mode.
|
||||
*/
|
||||
enum class DisassemblerMode : uint8_t
|
||||
{
|
||||
M16BIT,
|
||||
M32BIT,
|
||||
M64BIT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Values that represent an instruction-set vendor.
|
||||
*/
|
||||
enum class InstructionSetVendor : uint8_t
|
||||
{
|
||||
ANY,
|
||||
INTEL,
|
||||
AMD
|
||||
};
|
||||
|
||||
/* InstructionDecoder =========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief The @c InstructionDecoder class decodes x86/x86-64 assembly instructions from a
|
||||
* given data source.
|
||||
*/
|
||||
class InstructionDecoder
|
||||
{
|
||||
private:
|
||||
enum class RegisterClass : uint8_t
|
||||
{
|
||||
GENERAL_PURPOSE,
|
||||
MMX,
|
||||
CONTROL,
|
||||
DEBUG,
|
||||
SEGMENT,
|
||||
XMM
|
||||
};
|
||||
private:
|
||||
BaseInput* m_input;
|
||||
DisassemblerMode m_disassemblerMode;
|
||||
InstructionSetVendor m_preferredVendor;
|
||||
uint64_t m_instructionPointer;
|
||||
private:
|
||||
/**
|
||||
* @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.
|
||||
* @param info The instruction info.
|
||||
* @return The current input byte. If the result is zero, you should always check the
|
||||
* @c flags field of the @c info parameter for error flags.
|
||||
* Possible error values are @c IF_ERROR_END_OF_INPUT or @c IF_ERROR_LENGTH.
|
||||
*/
|
||||
uint8_t inputPeek(InstructionInfo& info);
|
||||
/**
|
||||
* @brief Reads the next byte from the data source. This method increases the current
|
||||
* input position and the @c length field of the @info parameter.
|
||||
* This method also appends the new byte to to @c data field of the @c info
|
||||
* parameter.
|
||||
* @param info The instruction info.
|
||||
* @return The current input byte. If the result is zero, you should always check the
|
||||
* @c flags field of the @c info parameter for error flags.
|
||||
* Possible error values are @c IF_ERROR_END_OF_INPUT or @c IF_ERROR_LENGTH.
|
||||
*/
|
||||
uint8_t inputNext(InstructionInfo& info);
|
||||
/**
|
||||
* @brief Reads the next byte(s) from the data source. This method increases the current
|
||||
* input position and the @c length field of the @info parameter.
|
||||
* This method also appends the new byte(s) to to @c data field of the @c info
|
||||
* parameter.
|
||||
* @param info The instruction info.
|
||||
* @return The current input data. If the result is zero, you should always check the
|
||||
* @c flags field of the @c info parameter for error flags.
|
||||
* Possible error values are @c IF_ERROR_END_OF_INPUT or @c IF_ERROR_LENGTH.
|
||||
*/
|
||||
template <typename T>
|
||||
T inputNext(InstructionInfo& 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 OperandInfo 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(InstructionInfo& info, OperandInfo& operand,
|
||||
RegisterClass registerClass, uint8_t registerId, DefinedOperandSize operandSize) const;
|
||||
/**
|
||||
* @brief Decodes a register/memory operand.
|
||||
* @param info The instruction info.
|
||||
* @param operand The @c OperandInfo 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(InstructionInfo& info, OperandInfo& operand,
|
||||
RegisterClass registerClass, DefinedOperandSize operandSize);
|
||||
/**
|
||||
* @brief Decodes an immediate operand.
|
||||
* @param info The instruction info.
|
||||
* @param operand The @c OperandInfo 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(InstructionInfo& info, OperandInfo& operand,
|
||||
DefinedOperandSize operandSize);
|
||||
/**
|
||||
* @brief Decodes a displacement operand.
|
||||
* @param info The instruction info.
|
||||
* @param operand The @c OperandInfo 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(InstructionInfo& info, OperandInfo& operand, uint8_t size);
|
||||
private:
|
||||
/**
|
||||
* @brief Decodes the modrm field of the instruction. This method reads an additional
|
||||
* input byte.
|
||||
* @param The @c InstructionInfo struct that receives the decoded data.
|
||||
* @return True if it succeeds, false if it fails.
|
||||
*/
|
||||
bool decodeModrm(InstructionInfo& info);
|
||||
/**
|
||||
* @brief Decodes the sib field of the instruction. This method reads an additional
|
||||
* input byte.
|
||||
* @param info The @c InstructionInfo struct that receives the decoded data.
|
||||
* @return True if it succeeds, false if it fails.
|
||||
*/
|
||||
bool decodeSIB(InstructionInfo& 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 InstructionInfo struct that receives the decoded data.
|
||||
* @return True if it succeeds, false if it fails.
|
||||
*/
|
||||
bool decodeVex(InstructionInfo& info);
|
||||
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 InstructionInfo& info,
|
||||
DefinedOperandSize operandSize) const;
|
||||
/**
|
||||
* @brief Decodes all instruction operands.
|
||||
* @param info The @c InstructionInfo struct that receives the decoded data.
|
||||
* @return True if it succeeds, false if it fails.
|
||||
*/
|
||||
bool decodeOperands(InstructionInfo& info);
|
||||
/**
|
||||
* @brief Decodes the specified instruction operand.
|
||||
* @param info The instruction info.
|
||||
* @param operand The @c OperandInfo 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(InstructionInfo& info, OperandInfo& operand,
|
||||
DefinedOperandType operandType, DefinedOperandSize operandSize);
|
||||
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 InstructionInfo struct that receives the effective operand and
|
||||
* address mode.
|
||||
*/
|
||||
void resolveOperandAndAddressMode(InstructionInfo& info) const;
|
||||
/**
|
||||
* @brief Calculates the effective REX/VEX.w, r, x, b, l values.
|
||||
* This method requires a non-null value in the @c instrDefinition field of the
|
||||
* @c info struct.
|
||||
* @param info The @c InstructionInfo struct that receives the effective operand and
|
||||
* address mode.
|
||||
*/
|
||||
void calculateEffectiveRexVexValues(InstructionInfo& info) const;
|
||||
private:
|
||||
/**
|
||||
* @brief Collects and decodes optional instruction prefixes.
|
||||
* @param info The @c InstructionInfo struct that receives the decoded data.
|
||||
* @return True if it succeeds, false if it fails.
|
||||
*/
|
||||
bool decodePrefixes(InstructionInfo& info);
|
||||
/**
|
||||
* @brief Collects and decodes the instruction opcodes using the opcode tree.
|
||||
* @param info The @c InstructionInfo struct that receives the decoded data.
|
||||
* @return True if it succeeds, false if it fails.
|
||||
*/
|
||||
bool decodeOpcode(InstructionInfo& info);
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor.
|
||||
*/
|
||||
InstructionDecoder();
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param input A reference to the input data source.
|
||||
* @param disassemblerMode The disasasembler mode.
|
||||
* @param preferredVendor The preferred instruction-set vendor.
|
||||
* @param instructionPointer The initial instruction pointer.
|
||||
*/
|
||||
explicit InstructionDecoder(BaseInput* input,
|
||||
DisassemblerMode disassemblerMode = DisassemblerMode::M32BIT,
|
||||
InstructionSetVendor preferredVendor = InstructionSetVendor::ANY,
|
||||
uint64_t instructionPointer = 0);
|
||||
public:
|
||||
/**
|
||||
* @brief Decodes the next instruction from the input data source.
|
||||
* @param info The @c InstructionInfo 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 decodeInstruction(InstructionInfo& info);
|
||||
public:
|
||||
/**
|
||||
* @brief Returns a pointer to the current data source.
|
||||
* @return A pointer to the current data source.
|
||||
*/
|
||||
BaseInput* getDataSource() const;
|
||||
/**
|
||||
* @brief Sets a new data source.
|
||||
* @param input A reference to the new input data source.
|
||||
*/
|
||||
void setDataSource(BaseInput* input);
|
||||
/**
|
||||
* @brief Returns the current disassembler mode.
|
||||
* @return The current disassembler mode.
|
||||
*/
|
||||
DisassemblerMode getDisassemblerMode() const;
|
||||
/**
|
||||
* @brief Sets the current disassembler mode.
|
||||
* @param disassemblerMode The new disassembler mode.
|
||||
*/
|
||||
void setDisassemblerMode(DisassemblerMode disassemblerMode);
|
||||
/**
|
||||
* @brief Returns the preferred instruction-set vendor.
|
||||
* @return The preferred instruction-set vendor.
|
||||
*/
|
||||
InstructionSetVendor getPreferredVendor() const;
|
||||
/**
|
||||
* @brief Sets the preferred instruction-set vendor.
|
||||
* @param preferredVendor The new preferred instruction-set vendor.
|
||||
*/
|
||||
void setPreferredVendor(InstructionSetVendor preferredVendor);
|
||||
/**
|
||||
* @brief Returns the current instruction pointer.
|
||||
* @return The current instruction pointer.
|
||||
*/
|
||||
uint64_t getInstructionPointer() const;
|
||||
/**
|
||||
* @brief Sets a new instruction pointer.
|
||||
* @param instructionPointer The new instruction pointer.
|
||||
*/
|
||||
void setInstructionPointer(uint64_t instructionPointer);
|
||||
};
|
||||
|
||||
inline uint8_t InstructionDecoder::inputPeek(InstructionInfo& info)
|
||||
{
|
||||
if (!m_input)
|
||||
{
|
||||
info.flags |= IF_ERROR_END_OF_INPUT;
|
||||
return 0;
|
||||
}
|
||||
return m_input->inputPeek(info);
|
||||
}
|
||||
|
||||
inline uint8_t InstructionDecoder::inputNext(InstructionInfo& info)
|
||||
{
|
||||
if (!m_input)
|
||||
{
|
||||
info.flags |= IF_ERROR_END_OF_INPUT;
|
||||
return 0;
|
||||
}
|
||||
return m_input->inputNext(info);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T InstructionDecoder::inputNext(InstructionInfo& info)
|
||||
{
|
||||
if (!m_input)
|
||||
{
|
||||
info.flags |= IF_ERROR_END_OF_INPUT;
|
||||
return 0;
|
||||
}
|
||||
return m_input->inputNext<T>(info);
|
||||
}
|
||||
|
||||
inline uint8_t InstructionDecoder::inputCurrent() const
|
||||
{
|
||||
if (!m_input)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return m_input->inputCurrent();
|
||||
}
|
||||
|
||||
inline BaseInput *InstructionDecoder::getDataSource() const
|
||||
{
|
||||
return m_input;
|
||||
}
|
||||
|
||||
inline void InstructionDecoder::setDataSource(BaseInput* input)
|
||||
{
|
||||
m_input = input;
|
||||
}
|
||||
|
||||
inline DisassemblerMode InstructionDecoder::getDisassemblerMode() const
|
||||
{
|
||||
return m_disassemblerMode;
|
||||
}
|
||||
|
||||
inline void InstructionDecoder::setDisassemblerMode(DisassemblerMode disassemblerMode)
|
||||
{
|
||||
m_disassemblerMode = disassemblerMode;
|
||||
}
|
||||
|
||||
inline InstructionSetVendor InstructionDecoder::getPreferredVendor() const
|
||||
{
|
||||
return m_preferredVendor;
|
||||
}
|
||||
|
||||
inline void InstructionDecoder::setPreferredVendor(InstructionSetVendor preferredVendor)
|
||||
{
|
||||
m_preferredVendor = preferredVendor;
|
||||
}
|
||||
|
||||
inline uint64_t InstructionDecoder::getInstructionPointer() const
|
||||
{
|
||||
return m_instructionPointer;
|
||||
}
|
||||
|
||||
inline void InstructionDecoder::setInstructionPointer(uint64_t instructionPointer)
|
||||
{
|
||||
m_instructionPointer = instructionPointer;
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
}
|
||||
|
||||
#endif /* _ZYDIS_INSTRUCTIONDECODER_HPP_ */
|
|
@ -1,602 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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 "ZydisInstructionFormatter.hpp"
|
||||
#include "ZydisUtils.hpp"
|
||||
#include <cstdarg>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
namespace Zydis
|
||||
{
|
||||
|
||||
/* BaseInstructionFormatter ================================================================ */
|
||||
|
||||
const char* BaseInstructionFormatter::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 BaseInstructionFormatter::internalFormatInstruction(const InstructionInfo& /*info*/)
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
BaseInstructionFormatter::BaseInstructionFormatter()
|
||||
: m_symbolResolver(nullptr)
|
||||
, m_outputStringLen(0)
|
||||
, m_outputUppercase(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BaseInstructionFormatter::BaseInstructionFormatter(
|
||||
BaseSymbolResolver *symbolResolver)
|
||||
: m_symbolResolver(symbolResolver)
|
||||
, m_outputStringLen(0)
|
||||
, m_outputUppercase(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* BaseInstructionFormatter::formatInstruction(const InstructionInfo& 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();
|
||||
}
|
||||
|
||||
BaseInstructionFormatter::~BaseInstructionFormatter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BaseInstructionFormatter::outputClear()
|
||||
{
|
||||
m_outputStringLen = 0;
|
||||
}
|
||||
|
||||
char const *BaseInstructionFormatter::outputString()
|
||||
{
|
||||
return& m_outputBuffer[0];
|
||||
}
|
||||
|
||||
void BaseInstructionFormatter::outputAppend(char const* text)
|
||||
{
|
||||
// Get the string length including the null-terminator char
|
||||
size_t strLen = strlen(text) + 1;
|
||||
// Get the buffer size
|
||||
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 = (m_outputStringLen) ? m_outputStringLen - 1 : 0;
|
||||
// Resize capacity of the output buffer on demand and add some extra space to improve the
|
||||
// performance
|
||||
if (bufLen <= (m_outputStringLen + strLen))
|
||||
{
|
||||
m_outputBuffer.resize(bufLen + strLen + 512);
|
||||
}
|
||||
// Write the text to the output buffer
|
||||
memcpy(&m_outputBuffer[offset], text, strLen);
|
||||
// Increase the string length
|
||||
m_outputStringLen = offset + strLen;
|
||||
// Convert to uppercase
|
||||
if (m_outputUppercase)
|
||||
{
|
||||
for (size_t i = offset; i < m_outputStringLen - 1; ++i)
|
||||
{
|
||||
m_outputBuffer[i] = static_cast<char>(toupper(m_outputBuffer[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseInstructionFormatter::outputAppendFormatted(char const* format, ...)
|
||||
{
|
||||
va_list arguments;
|
||||
va_start(arguments, format);
|
||||
// Get the buffer size
|
||||
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 = (m_outputStringLen) ? m_outputStringLen - 1 : 0;
|
||||
// Resize the output buffer on demand and add some extra space to improve the performance
|
||||
if ((bufLen - m_outputStringLen) < 256)
|
||||
{
|
||||
bufLen = bufLen + 512;
|
||||
m_outputBuffer.resize(bufLen);
|
||||
}
|
||||
int strLen = 0;
|
||||
do
|
||||
{
|
||||
// If the formatted text did not fit in the output buffer, resize it, and try again
|
||||
if (strLen < 0)
|
||||
{
|
||||
m_outputBuffer.resize(bufLen + 512);
|
||||
return outputAppendFormatted(format, arguments);
|
||||
}
|
||||
// Write the formatted text to the output buffer
|
||||
assert((bufLen - offset) > 0);
|
||||
strLen = std::vsnprintf(&m_outputBuffer[offset], bufLen - offset, format, arguments);
|
||||
} while (strLen < 0);
|
||||
// Increase the string length
|
||||
m_outputStringLen = offset + strLen + 1;
|
||||
// Convert to uppercase
|
||||
if (m_outputUppercase)
|
||||
{
|
||||
for (size_t i = offset; i < m_outputStringLen - 1; ++i)
|
||||
{
|
||||
m_outputBuffer[i] = static_cast<char>(toupper(m_outputBuffer[i]));
|
||||
}
|
||||
}
|
||||
va_end(arguments);
|
||||
}
|
||||
|
||||
void BaseInstructionFormatter::outputAppendAddress(const InstructionInfo& info,
|
||||
uint64_t address, bool resolveSymbols)
|
||||
{
|
||||
uint64_t offset = 0;
|
||||
const char *name = nullptr;
|
||||
if (resolveSymbols)
|
||||
{
|
||||
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 BaseInstructionFormatter::outputAppendImmediate(const InstructionInfo& info,
|
||||
const OperandInfo& operand, bool resolveSymbols)
|
||||
{
|
||||
assert(operand.type == OperandType::IMMEDIATE);
|
||||
uint64_t value = 0;
|
||||
if (operand.signed_lval&& (operand.size != info.operand_mode))
|
||||
{
|
||||
if (operand.size == 8)
|
||||
{
|
||||
value = static_cast<int64_t>(operand.lval.sbyte);
|
||||
} else
|
||||
{
|
||||
assert(operand.size == 32);
|
||||
value = static_cast<int64_t>(operand.lval.sdword);
|
||||
}
|
||||
if (info.operand_mode < 64)
|
||||
{
|
||||
value = value& ((1ull << info.operand_mode) - 1ull);
|
||||
}
|
||||
} else
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
uint64_t offset = 0;
|
||||
const char* name = nullptr;
|
||||
if (resolveSymbols)
|
||||
{
|
||||
name = resolveSymbol(info, value, offset);
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
outputAppendFormatted("%s+%.2llX", name, offset);
|
||||
} else
|
||||
{
|
||||
outputAppend(name);
|
||||
}
|
||||
} else
|
||||
{
|
||||
outputAppendFormatted("%.2llX", value);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseInstructionFormatter::outputAppendDisplacement(const OperandInfo& operand)
|
||||
{
|
||||
assert(operand.offset > 0);
|
||||
if ((operand.base == Register::NONE) && (operand.index == Register::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 != Register::NONE ||
|
||||
operand.index != Register::NONE) ? "+" : "", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* IntelInstructionFormatter =============================================================== */
|
||||
|
||||
void IntelInstructionFormatter::outputAppendOperandCast(const OperandInfo& operand)
|
||||
{
|
||||
switch(operand.size)
|
||||
{
|
||||
case 8:
|
||||
outputAppend("byte ptr " );
|
||||
break;
|
||||
case 16:
|
||||
outputAppend("word ptr " );
|
||||
break;
|
||||
case 32:
|
||||
outputAppend("dword ptr ");
|
||||
break;
|
||||
case 64:
|
||||
outputAppend("qword ptr ");
|
||||
break;
|
||||
case 80:
|
||||
outputAppend("tword ptr ");
|
||||
break;
|
||||
case 128:
|
||||
outputAppend("oword ptr ");
|
||||
break;
|
||||
case 256:
|
||||
outputAppend("yword ptr ");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IntelInstructionFormatter::formatOperand(const InstructionInfo& info,
|
||||
const OperandInfo& operand)
|
||||
{
|
||||
switch (operand.type)
|
||||
{
|
||||
case OperandType::REGISTER:
|
||||
outputAppend(registerToString(operand.base));
|
||||
break;
|
||||
case OperandType::MEMORY:
|
||||
if (info.flags & IF_PREFIX_SEGMENT)
|
||||
{
|
||||
outputAppendFormatted("%s:", registerToString(info.segment));
|
||||
}
|
||||
outputAppend("[");
|
||||
if (operand.base == Register::RIP)
|
||||
{
|
||||
// TODO: Add option
|
||||
outputAppendAddress(info, CalcAbsoluteTarget(info, operand), true);
|
||||
} else
|
||||
{
|
||||
if (operand.base != Register::NONE)
|
||||
{
|
||||
outputAppend(registerToString(operand.base));
|
||||
}
|
||||
if (operand.index != Register::NONE)
|
||||
{
|
||||
outputAppendFormatted("%s%s", operand.base != Register::NONE ? "+" : "",
|
||||
registerToString(operand.index));
|
||||
if (operand.scale)
|
||||
{
|
||||
outputAppendFormatted("*%d", operand.scale);
|
||||
}
|
||||
}
|
||||
if (operand.offset)
|
||||
{
|
||||
outputAppendDisplacement(operand);
|
||||
}
|
||||
}
|
||||
outputAppend("]");
|
||||
break;
|
||||
case OperandType::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 OperandType::IMMEDIATE:
|
||||
{
|
||||
outputAppendImmediate(info, operand, true);
|
||||
}
|
||||
break;
|
||||
case OperandType::REL_IMMEDIATE:
|
||||
{
|
||||
if (operand.size == 8)
|
||||
{
|
||||
outputAppend("short ");
|
||||
}
|
||||
outputAppendAddress(info, CalcAbsoluteTarget(info, operand), true);
|
||||
}
|
||||
break;
|
||||
case OperandType::CONSTANT:
|
||||
outputAppendFormatted("%.2X", operand.lval.udword);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IntelInstructionFormatter::internalFormatInstruction(const InstructionInfo& info)
|
||||
{
|
||||
// Append string prefixes
|
||||
if (info.flags & IF_PREFIX_LOCK)
|
||||
{
|
||||
outputAppend("lock ");
|
||||
}
|
||||
if (info.flags & IF_PREFIX_REP)
|
||||
{
|
||||
outputAppend("rep ");
|
||||
} else if (info.flags & IF_PREFIX_REPNE)
|
||||
{
|
||||
outputAppend("repne ");
|
||||
}
|
||||
// Append the instruction mnemonic
|
||||
outputAppend(Internal::GetInstructionMnemonicString(info.mnemonic));
|
||||
// Append the first operand
|
||||
if (info.operand[0].type != OperandType::NONE)
|
||||
{
|
||||
outputAppend(" ");
|
||||
bool cast = false;
|
||||
if (info.operand[0].type == OperandType::MEMORY)
|
||||
{
|
||||
if (info.operand[1].type == OperandType::IMMEDIATE ||
|
||||
info.operand[1].type == OperandType::CONSTANT ||
|
||||
info.operand[1].type == OperandType::NONE ||
|
||||
(info.operand[0].size != info.operand[1].size))
|
||||
{
|
||||
cast = true;
|
||||
} else if (info.operand[1].type == OperandType::REGISTER &&
|
||||
info.operand[1].base == Register::CL)
|
||||
{
|
||||
switch (info.mnemonic)
|
||||
{
|
||||
case InstructionMnemonic::RCL:
|
||||
case InstructionMnemonic::ROL:
|
||||
case InstructionMnemonic::ROR:
|
||||
case InstructionMnemonic::RCR:
|
||||
case InstructionMnemonic::SHL:
|
||||
case InstructionMnemonic::SHR:
|
||||
case InstructionMnemonic::SAR:
|
||||
cast = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cast)
|
||||
{
|
||||
outputAppendOperandCast(info.operand[0]);
|
||||
}
|
||||
formatOperand(info, info.operand[0]);
|
||||
}
|
||||
// Append the second operand
|
||||
if (info.operand[1].type != OperandType::NONE)
|
||||
{
|
||||
outputAppend(", ");
|
||||
bool cast = false;
|
||||
if (info.operand[1].type == OperandType::MEMORY &&
|
||||
info.operand[0].size != info.operand[1].size &&
|
||||
((info.operand[0].type != OperandType::REGISTER) ||
|
||||
((info.operand[0].base != Register::ES) &&
|
||||
(info.operand[0].base != Register::CS) &&
|
||||
(info.operand[0].base != Register::SS) &&
|
||||
(info.operand[0].base != Register::DS) &&
|
||||
(info.operand[0].base != Register::FS) &&
|
||||
(info.operand[0].base != Register::GS))))
|
||||
{
|
||||
cast = true;
|
||||
}
|
||||
if (cast)
|
||||
{
|
||||
outputAppendOperandCast(info.operand[1]);
|
||||
}
|
||||
formatOperand(info, info.operand[1]);
|
||||
}
|
||||
// Append the third operand
|
||||
if (info.operand[2].type != OperandType::NONE)
|
||||
{
|
||||
outputAppend(", ");
|
||||
bool cast = false;
|
||||
if (info.operand[2].type == OperandType::MEMORY &&
|
||||
(info.operand[2].size != info.operand[1].size))
|
||||
{
|
||||
cast = true;
|
||||
}
|
||||
if (cast)
|
||||
{
|
||||
outputAppendOperandCast(info.operand[2]);
|
||||
}
|
||||
formatOperand(info, info.operand[2]);
|
||||
}
|
||||
// Append the fourth operand
|
||||
if (info.operand[3].type != OperandType::NONE)
|
||||
{
|
||||
outputAppend(", ");
|
||||
formatOperand(info, info.operand[3]);
|
||||
}
|
||||
}
|
||||
|
||||
IntelInstructionFormatter::IntelInstructionFormatter()
|
||||
: BaseInstructionFormatter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IntelInstructionFormatter::IntelInstructionFormatter(
|
||||
BaseSymbolResolver *symbolResolver)
|
||||
: BaseInstructionFormatter(symbolResolver)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IntelInstructionFormatter::~IntelInstructionFormatter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
}
|
|
@ -1,250 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Instruction formatting classes.
|
||||
*/
|
||||
|
||||
#ifndef _ZYDIS_INSTRUCTIONFORMATTER_HPP_
|
||||
#define _ZYDIS_INSTRUCTIONFORMATTER_HPP_
|
||||
|
||||
#include <vector>
|
||||
#include "ZydisTypes.hpp"
|
||||
#include "ZydisSymbolResolver.hpp"
|
||||
|
||||
namespace Zydis
|
||||
{
|
||||
|
||||
/* BaseInstructionFormatter ===================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Base class for all instruction formatter implementations.
|
||||
*/
|
||||
class BaseInstructionFormatter
|
||||
{
|
||||
private:
|
||||
static const char* m_registerStrings[];
|
||||
BaseSymbolResolver* m_symbolResolver;
|
||||
std::vector<char> m_outputBuffer;
|
||||
size_t m_outputStringLen;
|
||||
bool m_outputUppercase;
|
||||
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, ...);
|
||||
/**
|
||||
* @brief Changes automatic conversion of characters to uppercase.
|
||||
* @param uppercase Set true to enable automatic uppercase conversion.
|
||||
*/
|
||||
void outputSetUppercase(bool uppercase);
|
||||
/**
|
||||
* @brief Appends a formatted address to the output string buffer.
|
||||
* @param info The instruction info.
|
||||
* @param address The address.
|
||||
* @param resolveSymbols If this parameter is true, the method will try to display a
|
||||
* smybol name instead of the numeric value.
|
||||
*/
|
||||
void outputAppendAddress(const InstructionInfo& info, uint64_t address,
|
||||
bool resolveSymbols = true);
|
||||
/**
|
||||
* @brief Appends a formatted immediate value to the output string buffer.
|
||||
* @param info The instruction info.
|
||||
* @param operand The immediate operand.
|
||||
* @param resolveSymbols If this parameter is true, the method will try to display a
|
||||
* smybol name instead of the numeric value.
|
||||
*/
|
||||
void outputAppendImmediate(const InstructionInfo& info, const OperandInfo& operand,
|
||||
bool resolveSymbols = false);
|
||||
/**
|
||||
* @brief Appends a formatted memory displacement value to the output string buffer.
|
||||
* @param operand The memory operand.
|
||||
*/
|
||||
void outputAppendDisplacement(const OperandInfo& operand);
|
||||
protected:
|
||||
/**
|
||||
* @brief Returns the string representation of a given register.
|
||||
* @param reg The register.
|
||||
* @return The string representation of the given register.
|
||||
*/
|
||||
const char *registerToString(Register 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 InstructionInfo& 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 InstructionInfo& info);
|
||||
/**
|
||||
* @brief Default constructor.
|
||||
*/
|
||||
BaseInstructionFormatter();
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param symbolResolver Pointer to a symbol resolver instance or @c NULL, if no smybol
|
||||
* resolver should be used.
|
||||
*/
|
||||
explicit BaseInstructionFormatter(BaseSymbolResolver* symbolResolver);
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~BaseInstructionFormatter();
|
||||
public:
|
||||
/**
|
||||
* @brief Formats a decoded instruction.
|
||||
* @param info The instruction info.
|
||||
* @return Pointer to the formatted instruction string.
|
||||
*/
|
||||
const char* formatInstruction(const InstructionInfo& 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.
|
||||
*/
|
||||
BaseSymbolResolver* 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(BaseSymbolResolver* symbolResolver);
|
||||
};
|
||||
|
||||
inline void BaseInstructionFormatter::outputSetUppercase(bool uppercase)
|
||||
{
|
||||
m_outputUppercase = uppercase;
|
||||
}
|
||||
|
||||
inline char const* BaseInstructionFormatter::registerToString(Register reg) const
|
||||
{
|
||||
if (reg == Register::NONE)
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
return m_registerStrings[static_cast<uint16_t>(reg) - 1];
|
||||
}
|
||||
|
||||
inline char const* BaseInstructionFormatter::resolveSymbol(const InstructionInfo& info,
|
||||
uint64_t address, uint64_t& offset) const
|
||||
{
|
||||
if (m_symbolResolver)
|
||||
{
|
||||
return m_symbolResolver->resolveSymbol(info, address, offset);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline BaseSymbolResolver* BaseInstructionFormatter::getSymbolResolver() const
|
||||
{
|
||||
return m_symbolResolver;
|
||||
}
|
||||
|
||||
inline void BaseInstructionFormatter::setSymbolResolver(
|
||||
BaseSymbolResolver* symbolResolver)
|
||||
{
|
||||
m_symbolResolver = symbolResolver;
|
||||
}
|
||||
|
||||
/* IntelInstructionFormatter ==================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Intel syntax instruction formatter.
|
||||
*/
|
||||
class IntelInstructionFormatter : public BaseInstructionFormatter
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* @brief Appends an operand cast to the output string buffer.
|
||||
* @param operand The operand.
|
||||
*/
|
||||
void outputAppendOperandCast(const OperandInfo& operand);
|
||||
/**
|
||||
* @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 InstructionInfo& info, const OperandInfo& operand);
|
||||
protected:
|
||||
/**
|
||||
* @brief Fills the internal string buffer with an intel style formatted instruction string.
|
||||
* @param info The instruction info.
|
||||
*/
|
||||
void internalFormatInstruction(const InstructionInfo& info) override;
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor.
|
||||
*/
|
||||
IntelInstructionFormatter();
|
||||
/**
|
||||
* @brief Constructor.
|
||||
* @param symbolResolver Pointer to a symbol resolver instance or @c NULL, if no smybol
|
||||
* resolver should be used.
|
||||
*/
|
||||
explicit IntelInstructionFormatter(BaseSymbolResolver* symbolResolver);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
~IntelInstructionFormatter() override;
|
||||
};
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
}
|
||||
|
||||
#endif /* _ZYDIS_INSTRUCTIONFORMATTER_HPP_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,91 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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 "ZydisSymbolResolver.hpp"
|
||||
|
||||
namespace Zydis
|
||||
{
|
||||
|
||||
/* BaseSymbolResolver ====================================================================== */
|
||||
|
||||
BaseSymbolResolver::~BaseSymbolResolver()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* BaseSymbolResolver::resolveSymbol(const InstructionInfo& /*info*/,
|
||||
uint64_t /*address*/, uint64_t& /*offset*/)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* ExactSymbolResolver ===================================================================== */
|
||||
|
||||
ExactSymbolResolver::~ExactSymbolResolver()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char* ExactSymbolResolver::resolveSymbol(const InstructionInfo& /*info*/,
|
||||
uint64_t address, uint64_t& offset)
|
||||
{
|
||||
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
|
||||
if (iterator != m_symbolMap.cend())
|
||||
{
|
||||
offset = 0;
|
||||
return iterator->second.c_str();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ExactSymbolResolver::containsSymbol(uint64_t address) const
|
||||
{
|
||||
std::unordered_map<uint64_t, std::string>::const_iterator iterator = m_symbolMap.find(address);
|
||||
return (iterator != m_symbolMap.end());
|
||||
}
|
||||
|
||||
void ExactSymbolResolver::setSymbol(uint64_t address, const char *name)
|
||||
{
|
||||
m_symbolMap[address].assign(name);
|
||||
}
|
||||
|
||||
void ExactSymbolResolver::removeSymbol(uint64_t address)
|
||||
{
|
||||
m_symbolMap.erase(address);
|
||||
}
|
||||
|
||||
void ExactSymbolResolver::clear()
|
||||
{
|
||||
m_symbolMap.clear();
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Classes for symbol resolving in the disassembly.
|
||||
*/
|
||||
|
||||
#ifndef _ZYDIS_SYMBOLRESOLVER_HPP_
|
||||
#define _ZYDIS_SYMBOLRESOLVER_HPP_
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "ZydisTypes.hpp"
|
||||
|
||||
namespace Zydis
|
||||
{
|
||||
|
||||
/* BaseSymbolResolver =========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Base class for all symbol resolver implementations.
|
||||
*/
|
||||
class BaseSymbolResolver
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
virtual ~BaseSymbolResolver();
|
||||
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 InstructionInfo& info, uint64_t address,
|
||||
uint64_t& offset);
|
||||
};
|
||||
|
||||
/* ExactSymbolResolver ========================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Simple symbol resolver that only matches exact addresses.
|
||||
*/
|
||||
class ExactSymbolResolver : public BaseSymbolResolver
|
||||
{
|
||||
private:
|
||||
std::unordered_map<uint64_t, std::string> m_symbolMap;
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
~ExactSymbolResolver() 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 InstructionInfo& info, uint64_t address,
|
||||
uint64_t& offset) override;
|
||||
public:
|
||||
/**
|
||||
* @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) const;
|
||||
/**
|
||||
* @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();
|
||||
};
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
}
|
||||
|
||||
#endif /* _ZYDIS_SYMBOLRESOLVER_HPP_ */
|
|
@ -1,543 +0,0 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef _ZYDIS_TYPES_HPP_
|
||||
#define _ZYDIS_TYPES_HPP_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ZydisOpcodeTable.hpp"
|
||||
|
||||
namespace Zydis
|
||||
{
|
||||
|
||||
/* InstructionFlags ============================================================================= */
|
||||
|
||||
/**
|
||||
* @brief Values that represent additional flags of a decoded instruction.
|
||||
*/
|
||||
enum InstructionFlags : uint32_t
|
||||
{
|
||||
IF_NONE = 0x00000000,
|
||||
/**
|
||||
* @brief The instruction was decoded in 16 bit disassembler mode.
|
||||
*/
|
||||
IF_DISASSEMBLER_MODE_16 = 0x00000001,
|
||||
/**
|
||||
* @brief The instruction was decoded in 32 bit disassembler mode.
|
||||
*/
|
||||
IF_DISASSEMBLER_MODE_32 = 0x00000002,
|
||||
/**
|
||||
* @brief The instruction was decoded in 64 bit disassembler mode.
|
||||
*/
|
||||
IF_DISASSEMBLER_MODE_64 = 0x00000004,
|
||||
/**
|
||||
* @brief The instruction has a segment 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 repne prefix (0xF2).
|
||||
*/
|
||||
IF_PREFIX_REPNE = 0x00000020,
|
||||
/**
|
||||
* @brief The instruction has a rep prefix (0xF3).
|
||||
*/
|
||||
IF_PREFIX_REP = 0x00000040,
|
||||
/**
|
||||
* @brief The instruction has an operand size prefix (0x66).
|
||||
*/
|
||||
IF_PREFIX_OPERAND_SIZE = 0x00000080,
|
||||
/**
|
||||
* @brief The instruction has an address size prefix (0x67).
|
||||
*/
|
||||
IF_PREFIX_ADDRESS_SIZE = 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
|
||||
};
|
||||
|
||||
/* Register ===================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Values that represent a cpu register.
|
||||
*/
|
||||
enum class Register : 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
|
||||
};
|
||||
|
||||
/* OperandType ================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Values that represent the type of a decoded operand.
|
||||
*/
|
||||
enum class OperandType : uint8_t
|
||||
{
|
||||
/**
|
||||
* @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
|
||||
};
|
||||
|
||||
/* ZydisOperandAccessMode ============================================================================ */
|
||||
|
||||
/**
|
||||
* @brief Values that represent the operand access mode.
|
||||
*/
|
||||
enum class OperandAccessMode : uint8_t
|
||||
{
|
||||
NA,
|
||||
/**
|
||||
* @brief The operand is accessed in read-only mode.
|
||||
*/
|
||||
READ,
|
||||
/**
|
||||
* @brief The operand is accessed in write mode.
|
||||
*/
|
||||
WRITE,
|
||||
/**
|
||||
* @brief The operand is accessed in read-write mode.
|
||||
*/
|
||||
READWRITE
|
||||
};
|
||||
|
||||
/* OperandInfo ================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief This struct holds information about a decoded operand.
|
||||
*/
|
||||
struct OperandInfo
|
||||
{
|
||||
/**
|
||||
* @brief The type of the operand.
|
||||
*/
|
||||
OperandType type;
|
||||
/**
|
||||
* @brief The size of the operand.
|
||||
*/
|
||||
uint16_t size;
|
||||
/**
|
||||
* @brief The operand access mode.
|
||||
*/
|
||||
OperandAccessMode access_mode;
|
||||
/**
|
||||
* @brief The base register.
|
||||
*/
|
||||
Register base;
|
||||
/**
|
||||
* @brief The index register.
|
||||
*/
|
||||
Register index;
|
||||
/**
|
||||
* @brief The scale factor.
|
||||
*/
|
||||
uint8_t scale;
|
||||
/**
|
||||
* @brief The lvalue offset. If the @c offset is zero and the operand @c type is not
|
||||
* @c CONSTANT, no lvalue is present.
|
||||
*/
|
||||
uint8_t offset;
|
||||
/**
|
||||
* @brief Signals, if the lval is signed.
|
||||
*/
|
||||
bool signed_lval;
|
||||
/**
|
||||
* @brief The lvalue.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
/* InstructionInfo ============================================================================== */
|
||||
|
||||
/**
|
||||
* @brief This struct holds information about a decoded instruction.
|
||||
*/
|
||||
struct InstructionInfo
|
||||
{
|
||||
/**
|
||||
* @brief The instruction flags.
|
||||
*/
|
||||
uint32_t flags;
|
||||
/**
|
||||
* @brief The instruction mnemonic.
|
||||
*/
|
||||
InstructionMnemonic mnemonic;
|
||||
/**
|
||||
* @brief The total length of the instruction.
|
||||
*/
|
||||
uint8_t length;
|
||||
/**
|
||||
* @brief Contains all bytes of the instruction.
|
||||
*/
|
||||
uint8_t data[15];
|
||||
/**
|
||||
* @brief The length of the instruction opcodes.
|
||||
*/
|
||||
uint8_t opcode_length;
|
||||
/**
|
||||
* @brief The instruction opcodes.
|
||||
*/
|
||||
uint8_t opcode[3];
|
||||
/**
|
||||
* @brief The operand mode.
|
||||
*/
|
||||
uint8_t operand_mode;
|
||||
/**
|
||||
* @brief The address mode.
|
||||
*/
|
||||
uint8_t address_mode;
|
||||
/**
|
||||
* @brief The decoded operands.
|
||||
*/
|
||||
OperandInfo operand[4];
|
||||
/**
|
||||
* @brief The segment register. This value will default to @c NONE, if no segment register
|
||||
* prefix is present.
|
||||
*/
|
||||
Register segment;
|
||||
/**
|
||||
* @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 extended modrm register bits. If the instruction definition does not have the
|
||||
* @c IDF_ACCEPTS_REXR flag set, this value defaults to the normal @c modrm_reg
|
||||
* field.
|
||||
*/
|
||||
uint8_t modrm_reg_ext;
|
||||
/**
|
||||
* @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 extended modrm register/memory bits. If the instruction definition does not
|
||||
* have the @c IDF_ACCEPTS_REXB flag set, this value defaults to the normal
|
||||
* @c modrm_rm field.
|
||||
*/
|
||||
uint8_t modrm_rm_ext;
|
||||
/**
|
||||
* @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 extended index register. If the instruction definition does not have the
|
||||
* @c IDF_ACCEPTS_REXX flag set, this value defaults to the normal @c sib_index
|
||||
* field.
|
||||
*/
|
||||
uint8_t sib_index_ext;
|
||||
/**
|
||||
* @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 extended base register. If the instruction definition does not have the
|
||||
* @c IDF_ACCEPTS_REXB flag set, this value defaults to the normal @c sib_index
|
||||
* field.
|
||||
*/
|
||||
uint8_t sib_base_ext;
|
||||
/**
|
||||
* @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 effectively used REX/VEX.w value. If the instruction definition does not have
|
||||
* the @c IDF_ACCEPTS_REXW flag set, this value defaults to zero.
|
||||
*/
|
||||
uint8_t eff_rexvex_w;
|
||||
/**
|
||||
* @brief The effectively used REX/VEX.r value. If the instruction definition does not have
|
||||
* the @c IDF_ACCEPTS_REXR flag set, this value defaults to zero.
|
||||
*/
|
||||
uint8_t eff_rexvex_r;
|
||||
/**
|
||||
* @brief The effectively used REX/VEX.x value. If the instruction definition does not have
|
||||
* the @c IDF_ACCEPTS_REXX flag set, this value defaults to zero.
|
||||
*/
|
||||
uint8_t eff_rexvex_x;
|
||||
/**
|
||||
* @brief The effectively used REX/VEX.b value. If the instruction definition does not have
|
||||
* the @c IDF_ACCEPTS_REXB flag set, this value defaults to zero.
|
||||
*/
|
||||
uint8_t eff_rexvex_b;
|
||||
/**
|
||||
* @brief The effectively used VEX.l value. If the instruction definition does not have
|
||||
* the @c IDF_ACCEPTS_VEXL flag set, this value defaults to zero.
|
||||
*/
|
||||
uint8_t eff_vex_l;
|
||||
/**
|
||||
* @brief The instruction definition.
|
||||
*/
|
||||
const InstructionDefinition* instrDefinition;
|
||||
/**
|
||||
* @brief The instruction address points to the current instruction (relative to the
|
||||
* initial instruction pointer).
|
||||
*/
|
||||
uint64_t instrAddress;
|
||||
/**
|
||||
* @brief The instruction pointer points to the address of the next instruction (relative
|
||||
* to the initial instruction pointer).
|
||||
* This field is used to properly format relative instructions.
|
||||
*/
|
||||
uint64_t instrPointer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _ZYDIS_TYPES_HPP_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,435 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <Windows.h>
|
||||
#include <Zydis/Zydis.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Custom Symbol Resolving */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Returns the name of the exported function at the given @c address.
|
||||
*
|
||||
* @param moduleHandle The module handle.
|
||||
* @param address The function address.
|
||||
*
|
||||
* @return The name of the exported function at @c address or @c NULL.
|
||||
*/
|
||||
static const char* GetExportName(HMODULE moduleHandle, uintptr_t address)
|
||||
{
|
||||
if (!moduleHandle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleHandle;
|
||||
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((uint8_t*)dosHeader + dosHeader->e_lfanew);
|
||||
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
uintptr_t entryPoint =
|
||||
(uintptr_t)((uint8_t*)moduleHandle + ntHeaders->OptionalHeader.AddressOfEntryPoint);
|
||||
if (address == entryPoint)
|
||||
{
|
||||
return "EntryPoint";
|
||||
}
|
||||
if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
|
||||
{
|
||||
PIMAGE_EXPORT_DIRECTORY exportDirectory =
|
||||
(PIMAGE_EXPORT_DIRECTORY)((uint8_t*)moduleHandle +
|
||||
ntHeaders->OptionalHeader.DataDirectory[
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
PDWORD exportAddresses =
|
||||
(PDWORD)((uint8_t*)moduleHandle +exportDirectory->AddressOfFunctions);
|
||||
PDWORD exportNames =
|
||||
(PDWORD)((uint8_t*)moduleHandle + exportDirectory->AddressOfNames);
|
||||
|
||||
for (uint32_t i = 0; i < exportDirectory->NumberOfFunctions; ++i)
|
||||
{
|
||||
if (address == (uintptr_t)moduleHandle + exportAddresses[i])
|
||||
{
|
||||
return (const char*)moduleHandle + exportNames[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts formatted text into the @c buffer at the given @c offset and increases the
|
||||
* @c offset by the length of the text.
|
||||
*
|
||||
* @param buffer A pointer to the target buffer.
|
||||
* @param bufferLen The length of the buffer.
|
||||
* @param offset A pointer to the buffer-offset.
|
||||
* @param format The format string.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
static ZydisStatus ZydisBufferAppendFormat(char* buffer, size_t bufferLen, size_t* offset,
|
||||
const char* format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
va_start(arglist, format);
|
||||
size_t n = bufferLen - *offset;
|
||||
int w = vsnprintf(&buffer[*offset], n, format, arglist);
|
||||
if ((w < 0) || ((size_t)w >= n))
|
||||
{
|
||||
va_end(arglist);
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
*offset += (size_t)w;
|
||||
va_end(arglist);
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts the name of the exported function at @c address into the @c buffer at the given
|
||||
* @c offset and increases the @c offset by the length of the name.
|
||||
*
|
||||
* @param buffer A pointer to the target buffer.
|
||||
* @param bufferLen The length of the buffer.
|
||||
* @param offset A pointer to the buffer-offset.
|
||||
* @param moduleHandle The module handle.
|
||||
* @param address The function address.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
static ZydisStatus ZydisBufferAppendExport(char* buffer, size_t bufferLen, size_t* offset,
|
||||
HMODULE moduleHandle, uintptr_t address)
|
||||
{
|
||||
const char* exportName = GetExportName(moduleHandle, address);
|
||||
if (!exportName)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
char nameBuffer[MAX_PATH];
|
||||
DWORD l = GetModuleFileNameA(moduleHandle, &nameBuffer[0], MAX_PATH);
|
||||
if (l == 0)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
for (int i = l - 4; i >= 0; --i)
|
||||
{
|
||||
if (nameBuffer[i] == '\\')
|
||||
{
|
||||
memcpy(&nameBuffer[0], &nameBuffer[i + 1], l - i);
|
||||
nameBuffer[l - i - 4] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset, "%s%s", &nameBuffer[0], exportName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts the name of the imported function at @c address into the @c buffer at the given
|
||||
* @c offset and increases the @c offset by the length of the name.
|
||||
*
|
||||
* @param buffer A pointer to the target buffer.
|
||||
* @param bufferLen The length of the buffer.
|
||||
* @param offset A pointer to the buffer-offset.
|
||||
* @param moduleHandle The module handle.
|
||||
* @param address The function address.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
static ZydisStatus ZydisBufferAppendImport(char* buffer, size_t bufferLen, size_t* offset,
|
||||
HMODULE moduleHandle, uintptr_t address)
|
||||
{
|
||||
if (!moduleHandle)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)moduleHandle;
|
||||
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((uint8_t*)dosHeader + dosHeader->e_lfanew);
|
||||
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
|
||||
{
|
||||
PIMAGE_IMPORT_DESCRIPTOR descriptor =
|
||||
(PIMAGE_IMPORT_DESCRIPTOR)((uint8_t*)moduleHandle +
|
||||
ntHeaders->OptionalHeader.DataDirectory[
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
while (descriptor->OriginalFirstThunk)
|
||||
{
|
||||
const char* moduleName = (char*)((uint8_t*)moduleHandle + descriptor->Name);
|
||||
PIMAGE_THUNK_DATA originalThunk =
|
||||
(PIMAGE_THUNK_DATA)((uint8_t*)moduleHandle + descriptor->OriginalFirstThunk);
|
||||
PIMAGE_THUNK_DATA thunk =
|
||||
(PIMAGE_THUNK_DATA)((uint8_t*)moduleHandle + descriptor->FirstThunk);
|
||||
|
||||
while (originalThunk->u1.ForwarderString)
|
||||
{
|
||||
if (!(originalThunk->u1.Ordinal & 0x80000000))
|
||||
{
|
||||
if (address == (uintptr_t)&thunk->u1.Function)
|
||||
{
|
||||
PIMAGE_IMPORT_BY_NAME import = (PIMAGE_IMPORT_BY_NAME)
|
||||
((uint8_t*)moduleHandle + originalThunk->u1.AddressOfData);
|
||||
ZydisStatus status =
|
||||
ZydisBufferAppendFormat(buffer, bufferLen, offset, "%s", moduleName);
|
||||
if (!ZYDIS_SUCCESS(status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
*offset -= 3;
|
||||
buffer[*offset] = 0;
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset, "%s",
|
||||
import->Name);
|
||||
}
|
||||
}
|
||||
++originalThunk;
|
||||
++thunk;
|
||||
}
|
||||
++descriptor;
|
||||
}
|
||||
}
|
||||
return ZYDIS_STATUS_USER + 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisPESymbolResolver struct.
|
||||
*/
|
||||
typedef struct ZydisPESymbolResolver_
|
||||
{
|
||||
ZydisCustomSymbolResolver resolver;
|
||||
HMODULE moduleHandle;
|
||||
char buffer[256];
|
||||
} ZydisPESymbolResolver;
|
||||
|
||||
/**
|
||||
* @brief The custom symbol resolver callback function.
|
||||
*
|
||||
* @param context A pointer to the @c ZydisPESymbolResolver instance.
|
||||
* @param info A pointer to the @c ZydisInstructionInfo struct.
|
||||
* @param operand A pointer to the @c ZydisOperandInfo struct.
|
||||
* @param address The address.
|
||||
* @param offset A pointer to the memory that receives the optional symbol-offset.
|
||||
*
|
||||
* @return The name of the resolved symbol or @c NULL, if no symbol was found at the given
|
||||
* @c address.
|
||||
*/
|
||||
static const char* ResolveSymbol(ZydisPESymbolResolver* context, const ZydisInstructionInfo* info,
|
||||
const ZydisOperandInfo* operand, uint64_t address, int64_t* offset)
|
||||
{
|
||||
(void)context;
|
||||
(void)info;
|
||||
(void)operand;
|
||||
(void)address;
|
||||
|
||||
*offset = 0;
|
||||
size_t bufferOffset = 0;
|
||||
if (ZYDIS_SUCCESS(ZydisBufferAppendExport(&context->buffer[0], sizeof(context->buffer),
|
||||
&bufferOffset, context->moduleHandle, (uintptr_t)address)))
|
||||
{
|
||||
return &context->buffer[0];
|
||||
}
|
||||
if (ZYDIS_SUCCESS(ZydisBufferAppendImport(&context->buffer[0], sizeof(context->buffer),
|
||||
&bufferOffset, context->moduleHandle, (uintptr_t)address)))
|
||||
{
|
||||
return &context->buffer[0];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Entry point */
|
||||
/* ============================================================================================== */
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <input file>\n", (argc > 0 ? argv[0] : "ZydisPE"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Load PE file
|
||||
HMODULE hModule = LoadLibraryExA(argv[1], 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if (!hModule)
|
||||
{
|
||||
fprintf(stderr, "Could not load PE file. Error code: %d\n", GetLastError());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hModule;
|
||||
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
fprintf(stderr, "Invalid file signature\n");
|
||||
goto FatalError;
|
||||
}
|
||||
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((uint8_t*)dosHeader + dosHeader->e_lfanew);
|
||||
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
fprintf(stderr, "Invalid file signature\n");
|
||||
goto FatalError;
|
||||
}
|
||||
|
||||
// Determine disassembler-mode
|
||||
ZydisDisassemblerMode disassemblerMode;
|
||||
switch (ntHeaders->FileHeader.Machine)
|
||||
{
|
||||
case IMAGE_FILE_MACHINE_I386:
|
||||
disassemblerMode = ZYDIS_DISASSEMBLER_MODE_32BIT;
|
||||
break;
|
||||
case IMAGE_FILE_MACHINE_IA64:
|
||||
case IMAGE_FILE_MACHINE_AMD64:
|
||||
disassemblerMode = ZYDIS_DISASSEMBLER_MODE_64BIT;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid assembly format\n");
|
||||
goto FatalError;
|
||||
}
|
||||
|
||||
ZydisMemoryInput input;
|
||||
ZydisInstructionDecoder decoder;
|
||||
if (!ZYDIS_SUCCESS(ZydisDecoderInitInstructionDecoderEx(&decoder, disassemblerMode,
|
||||
(ZydisCustomInput*)&input, ZYDIS_DECODER_FLAG_SKIP_DATA)))
|
||||
{
|
||||
fputs("Failed to initialize instruction-decoder\n", stderr);
|
||||
goto FatalError;
|
||||
}
|
||||
|
||||
ZydisInstructionFormatter formatter;
|
||||
if (!ZYDIS_SUCCESS(ZydisFormatterInitInstructionFormatterEx(&formatter,
|
||||
ZYDIS_FORMATTER_STYLE_INTEL, ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SIZE |
|
||||
ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT)))
|
||||
{
|
||||
fputs("Failed to initialize instruction-formatter\n", stderr);
|
||||
goto FatalError;
|
||||
}
|
||||
|
||||
// Initialize custom symbol resolver
|
||||
ZydisPESymbolResolver resolver;
|
||||
resolver.resolver.resolveSymbol = (ZydisResolverResolveSymbolFunc)&ResolveSymbol;
|
||||
resolver.moduleHandle = hModule;
|
||||
ZydisFormatterSetSymbolResolver(&formatter, (ZydisCustomSymbolResolver*)&resolver);
|
||||
|
||||
LARGE_INTEGER frequency;
|
||||
LARGE_INTEGER t1, t2;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
QueryPerformanceCounter(&t1);
|
||||
|
||||
// Disassemble all executable PE-sections
|
||||
PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)((uint8_t*)ntHeaders +
|
||||
sizeof(IMAGE_NT_HEADERS) - sizeof(IMAGE_OPTIONAL_HEADER) +
|
||||
ntHeaders->FileHeader.SizeOfOptionalHeader);
|
||||
for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; ++i)
|
||||
{
|
||||
if (sectionHeader->SizeOfRawData == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!(sectionHeader->Characteristics & IMAGE_SCN_CNT_CODE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
void* data = (void*)((uint8_t*)dosHeader + sectionHeader->VirtualAddress);
|
||||
if (!ZYDIS_SUCCESS(ZydisDecoderSetInstructionPointer(&decoder, (uint64_t)data)))
|
||||
{
|
||||
fputs("Failed to set instruction-pointer\n", stderr);
|
||||
goto FatalError;
|
||||
}
|
||||
if (!ZYDIS_SUCCESS(ZydisInputInitMemoryInput(&input, data, sectionHeader->SizeOfRawData)))
|
||||
{
|
||||
fputs("Failed to initialize memory-input\n", stderr);
|
||||
goto FatalError;
|
||||
}
|
||||
char buffer[256];
|
||||
ZydisInstructionInfo info;
|
||||
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
|
||||
{
|
||||
const char* symbol = GetExportName(hModule, (uintptr_t)info.instrAddress);
|
||||
if (symbol)
|
||||
{
|
||||
printf("\n%s:\n", symbol);
|
||||
}
|
||||
switch (info.mode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
printf("%04llX ", info.instrAddress);
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
printf("%08llX ", info.instrAddress);
|
||||
break;
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
printf("%016llX ", info.instrAddress);
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < info.length; ++j)
|
||||
{
|
||||
printf("%02X ", info.data[j]);
|
||||
}
|
||||
for (int j = info.length; j < 15; ++j)
|
||||
{
|
||||
printf(" ");
|
||||
}
|
||||
if (info.flags & ZYDIS_IFLAG_ERROR_MASK)
|
||||
{
|
||||
printf(" db %02x\n", info.data[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ZYDIS_SUCCESS(ZydisFormatterFormatInstruction(&formatter, &info, &buffer[0],
|
||||
sizeof(buffer))))
|
||||
{
|
||||
fputs("Failed to format decoded instruction\n", stderr);
|
||||
goto FatalError;
|
||||
}
|
||||
printf(" %s\n", &buffer[0]);
|
||||
}
|
||||
++sectionHeader;
|
||||
}
|
||||
|
||||
QueryPerformanceCounter(&t2);
|
||||
double elapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / frequency.QuadPart;
|
||||
printf("\n%f", elapsedTime);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
FatalError:
|
||||
FreeLibrary(hModule);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
|
@ -0,0 +1,233 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_DECODER_H
|
||||
#define ZYDIS_DECODER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/Input.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisDecoderFlags datatype.
|
||||
*/
|
||||
typedef uint32_t ZydisDecoderFlags;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis decoder-flags.
|
||||
*/
|
||||
enum ZydisDecoderFlag
|
||||
{
|
||||
ZYDIS_DECODER_FLAG_SKIP_DATA = 0x00000001
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisInstructionDecoder struct.
|
||||
*/
|
||||
typedef struct ZydisInstructionDecoder_
|
||||
{
|
||||
/**
|
||||
* @brief The current disassembler-mode.
|
||||
*/
|
||||
ZydisDisassemblerMode disassemblerMode;
|
||||
/**
|
||||
* @brief A pointer to the current input data-source.
|
||||
*/
|
||||
ZydisCustomInput* input;
|
||||
/**
|
||||
* @brief Decoder flags.
|
||||
*/
|
||||
ZydisDecoderFlags flags;
|
||||
/**
|
||||
* @brief The current instruction-pointer value.
|
||||
*/
|
||||
uint64_t instructionPointer;
|
||||
/**
|
||||
* @brief Internal buffer.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint8_t data[30];
|
||||
uint8_t count;
|
||||
uint8_t posRead;
|
||||
uint8_t posWrite;
|
||||
} buffer;
|
||||
} ZydisInstructionDecoder;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Initializes the given @c ZydisInstructionDecoder instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param disassemblerMode The desired disassembler-mode.
|
||||
* @param input A pointer to the input data-source.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderInitInstructionDecoder(ZydisInstructionDecoder* decoder,
|
||||
ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input);
|
||||
|
||||
/**
|
||||
* @brief Initializes the given @c ZydisInstructionDecoder instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param disassemblerMode The desired disassembler-mode.
|
||||
* @param input A pointer to the input data-source.
|
||||
* @param flags Additional flags for the instruction-decoder.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderInitInstructionDecoderEx(ZydisInstructionDecoder* decoder,
|
||||
ZydisDisassemblerMode disassemblerMode, ZydisCustomInput* input, ZydisDecoderFlags flags);
|
||||
|
||||
/**
|
||||
* @brief Returns the current disassembler-mode of the given @c ZydisInstructionDecoder
|
||||
* instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param disassemblerMode A pointer to the memory that receives the current disassembler-mode.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderGetDisassemblerMode(const ZydisInstructionDecoder* decoder,
|
||||
ZydisDisassemblerMode* disassemblerMode);
|
||||
|
||||
/**
|
||||
* @brief Changes the disassembler-mode of the given @c ZydisInstructionDecoder instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param disassemblerMode The new disassembler-mode.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderSetDisassemblerMode(ZydisInstructionDecoder* decoder,
|
||||
ZydisDisassemblerMode disassemblerMode);
|
||||
|
||||
/**
|
||||
* @brief Returns the current input data-source of the given @c ZydisInstructionDecoder
|
||||
* instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param input A pointer to the memory that receives the current input data-source pointer.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderGetDecoderInput(const ZydisInstructionDecoder* decoder,
|
||||
ZydisCustomInput** input);
|
||||
|
||||
/**
|
||||
* @brief Changes the input data-source of the given @c ZydisInstructionDecoder instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param input A pointer to the new input data-source.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderSetDecoderInput(ZydisInstructionDecoder* decoder,
|
||||
ZydisCustomInput* input);
|
||||
|
||||
/**
|
||||
* @brief Returns the current decoder-flags of the given @c ZydisInstructionDecoder instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param flags A pointer to the memory that receives the current decoder-flags.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderGetDecoderFlags(const ZydisInstructionDecoder* decoder,
|
||||
ZydisDecoderFlags* flags);
|
||||
|
||||
/**
|
||||
* @brief Changes the decoder-flags of the given @c ZydisInstructionDecoder instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param flags The new decoder-flags.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderSetDecoderFlags(ZydisInstructionDecoder* decoder,
|
||||
ZydisDecoderFlags flags);
|
||||
|
||||
/**
|
||||
* @brief Returns the current instruction-pointer of the given @c ZydisInstructionDecoder
|
||||
* instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param instructionPointer A pointer to the memory that receives the current
|
||||
* instruction-pointer.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderGetInstructionPointer(
|
||||
const ZydisInstructionDecoder* decoder, uint64_t* instructionPointer);
|
||||
|
||||
/**
|
||||
* @brief Changes the instruction-pointer of the given @c ZydisInstructionDecoder instance.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param instructionPointer The new instruction-pointer value.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderSetInstructionPointer(ZydisInstructionDecoder* decoder,
|
||||
uint64_t instructionPointer);
|
||||
|
||||
/**
|
||||
* @brief Decodes the next instruction from the decoders input data-source.
|
||||
*
|
||||
* @param decoder A pointer to the @c ZydisInstructionDecoder instance.
|
||||
* @param info A pointer to the @c ZydisInstructionInfo struct, that receives the details
|
||||
* about the decoded instruction.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisDecoderDecodeNextInstruction(ZydisInstructionDecoder* decoder,
|
||||
ZydisInstructionInfo* info);
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_DECODER_H */
|
|
@ -0,0 +1,136 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_DEFINES_H
|
||||
#define ZYDIS_DEFINES_H
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Compiler detection */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#if defined(__clang__)
|
||||
# define ZYDIS_CLANG
|
||||
# define ZYDIS_GNUC
|
||||
#elif defined(__ICC) || defined(__INTEL_COMPILER)
|
||||
# define ZYDIS_ICC
|
||||
#elif defined(__GNUC__) || defined(__GNUG__)
|
||||
# define ZYDIS_GCC
|
||||
# define ZYDIS_GNUC
|
||||
#elif defined(_MSC_VER)
|
||||
# define ZYDIS_MSVC
|
||||
#elif defined(__BORLANDC__)
|
||||
# define ZYDIS_BORLAND
|
||||
#else
|
||||
# define ZYDIS_UNKNOWN_COMPILER
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Platform detection */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define ZYDIS_WINDOWS
|
||||
#elif defined(__APPLE__)
|
||||
# define ZYDIS_APPLE
|
||||
# define ZYDIS_POSIX
|
||||
#elif defined(__linux)
|
||||
# define ZYDIS_LINUX
|
||||
# define ZYDIS_POSIX
|
||||
#elif defined(__unix)
|
||||
# define ZYDIS_UNIX
|
||||
# define ZYDIS_POSIX
|
||||
#elif defined(__posix)
|
||||
# define ZYDIS_POSIX
|
||||
#else
|
||||
# error "Unsupported platform detected"
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Architecture detection */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#if defined (_M_AMD64) || defined (__x86_64__)
|
||||
# define ZYDIS_X64
|
||||
#elif defined (_M_IX86) || defined (__i386__)
|
||||
# define ZYDIS_X86
|
||||
#else
|
||||
# error "Unsupported architecture detected"
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Debug/Release detection */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#if defined(ZYDIS_MSVC) || defined(ZYDIS_BORLAND)
|
||||
# ifdef _DEBUG
|
||||
# define ZYDIS_DEBUG
|
||||
# else
|
||||
# define ZYDIS_RELEASE
|
||||
# endif
|
||||
#elif defined(ZYDIS_GNUC) || defined(ZYDIS_ICC)
|
||||
# ifdef NDEBUG
|
||||
# define ZYDIS_RELEASE
|
||||
# else
|
||||
# define ZYDIS_DEBUG
|
||||
# endif
|
||||
#else
|
||||
# error "Unsupported compiler detected"
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Misc compatibility macros */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#if defined(ZYDIS_MSVC) || defined(ZYDIS_BORLAND)
|
||||
# define ZYDIS_INLINE __inline
|
||||
#else
|
||||
# define ZYDIS_INLINE static inline
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Dynamic linkage macros */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#if defined(ZYDIS_MSVC) && defined(ZYDIS_DYNAMIC)
|
||||
# ifdef ZYDIS_EXPORTS
|
||||
# define ZYDIS_DLLEXTERN __declspec(dllexport)
|
||||
# else
|
||||
# define ZYDIS_DLLEXTERN __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define ZYDIS_DLLEXTERN
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Debugging macros */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#define ZYDIS_ASSERT(condition) assert(condition)
|
||||
#define ZYDIS_UNREACHABLE assert(0)
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#endif /* ZYDIS_DEFINES_H */
|
|
@ -0,0 +1,255 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_FORMATTER_H
|
||||
#define ZYDIS_FORMATTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
#include <Zydis/SymbolResolver.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Instruction formatter */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Enums and types */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis formatter-style datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterStyle;
|
||||
|
||||
/**
|
||||
* @brief Values that represent formatter-styles.
|
||||
*/
|
||||
enum ZydisFormatterStyles
|
||||
{
|
||||
/**
|
||||
* @brief Generates intel-style disassembly.
|
||||
*/
|
||||
ZYDIS_FORMATTER_STYLE_INTEL
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis formatter-flags datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterFlags;
|
||||
|
||||
/**
|
||||
* @brief Values that represent formatter-flags.
|
||||
*/
|
||||
enum ZydisFormatterFlag
|
||||
{
|
||||
ZYDIS_FORMATTER_FLAG_UPPERCASE = 0x01,
|
||||
ZYDIS_FORMATTER_FLAG_TAB_AFTER_MNEMONIC = 0x02,
|
||||
ZYDIS_FORMATTER_FLAG_NO_SPACE_BETWEEN_OPERANDS = 0x04,
|
||||
ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SIZE = 0x08,
|
||||
ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT = 0x10
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis address-format datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterAddressFormat;
|
||||
|
||||
/**
|
||||
* @brief Values that represent address-formats.
|
||||
*/
|
||||
enum ZydisFormatterAddressFormat
|
||||
{
|
||||
/**
|
||||
* @brief Displays absolute addresses instead of relative ones.
|
||||
*/
|
||||
ZYDIS_FORMATTER_ADDRESS_ABSOLUTE,
|
||||
/**
|
||||
* @brief Uses signed hexadecimal values to display relative addresses.
|
||||
*
|
||||
* Examples:
|
||||
* "JMP 0x20"
|
||||
* "JMP -0x20"
|
||||
*/
|
||||
ZYDIS_FORMATTER_ADDRESS_RELATIVE_SIGNED,
|
||||
/**
|
||||
* @brief Uses unsigned hexadecimal values to display relative addresses.
|
||||
*
|
||||
* Examples:
|
||||
* "JMP 0x20"
|
||||
* "JMP 0xE0"
|
||||
*/
|
||||
ZYDIS_FORMATTER_ADDRESS_RELATIVE_UNSIGNED,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis displacement-format datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterDisplacementFormat;
|
||||
|
||||
/**
|
||||
* @brief Values that represent displacement-formats.
|
||||
*/
|
||||
enum ZydisFormatterDisplacementFormats
|
||||
{
|
||||
/**
|
||||
* @brief Formats displacements as signed hexadecimal values.
|
||||
*
|
||||
* Examples:
|
||||
* "MOV EAX, DWORD PTR SS:[ESP+0x400]"
|
||||
* "MOV EAX, DWORD PTR SS:[ESP-0x400]"
|
||||
*/
|
||||
ZYDIS_FORMATTER_DISP_HEX_SIGNED,
|
||||
/**
|
||||
* @brief Formats displacements as unsigned hexadecimal values.
|
||||
*
|
||||
* Examples:
|
||||
* "MOV EAX, DWORD PTR SS:[ESP+0x400]"
|
||||
* "MOV EAX, DWORD PTR SS:[ESP+0xFFFFFC00]"
|
||||
*/
|
||||
ZYDIS_FORMATTER_DISP_HEX_UNSIGNED
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis formatter immediate-format datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisFormatterImmediateFormat;
|
||||
|
||||
/**
|
||||
* @brief Values that represent formatter immediate-formats.
|
||||
*/
|
||||
enum ZydisFormatterImmediateFormats
|
||||
{
|
||||
/**
|
||||
* @brief Formats immediates as signed hexadecimal values.
|
||||
*
|
||||
* Examples:
|
||||
* "MOV EAX, 0x400"
|
||||
* "MOV EAX, -0x400"
|
||||
*/
|
||||
ZYDIS_FORMATTER_IMM_HEX_SIGNED,
|
||||
/**
|
||||
* @brief Formats immediates as unsigned hexadecimal values.
|
||||
*
|
||||
* Examples:
|
||||
* "MOV EAX, 0x400"
|
||||
* "MOV EAX, 0xFFFFFC00"
|
||||
*/
|
||||
ZYDIS_FORMATTER_IMM_HEX_UNSIGNED
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis instruction-formatter struct.
|
||||
*/
|
||||
typedef struct ZydisInstructionFormatter_
|
||||
{
|
||||
ZydisFormatterStyle style;
|
||||
ZydisFormatterFlags flags;
|
||||
ZydisFormatterAddressFormat addressFormat;
|
||||
ZydisFormatterDisplacementFormat displacementFormat;
|
||||
ZydisFormatterImmediateFormat immediateFormat;
|
||||
ZydisCustomSymbolResolver* symbolResolver;
|
||||
|
||||
} ZydisInstructionFormatter;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initializes the given @c ZydisInstructionFormatter instance.
|
||||
*
|
||||
* @param formatter A pointer to the instruction-formatter instance.
|
||||
* @param style The formatter style to use.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisFormatterInitInstructionFormatter(
|
||||
ZydisInstructionFormatter* formatter, ZydisFormatterStyle style);
|
||||
|
||||
/**
|
||||
* @brief Initializes the given @c ZydisInstructionFormatter instance.
|
||||
*
|
||||
* @param formatter A pointer to the instruction-formatter instance.
|
||||
* @param style The formatter style to use.
|
||||
* @param flags Additional formatter-flags.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisFormatterInitInstructionFormatterEx(
|
||||
ZydisInstructionFormatter* formatter, ZydisFormatterStyle style, ZydisFormatterFlags flags);
|
||||
|
||||
/**
|
||||
* @brief Returns the symbol-resolver assigned to the given instruction-formatter instance.
|
||||
*
|
||||
* @param formatter A pointer to the instruction-formatter instance.
|
||||
* @param symbolResolver A pointer to the memory that receives the current symbol-resolver
|
||||
* pointer.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisFormatterGetSymbolResolver(
|
||||
const ZydisInstructionFormatter* formatter, ZydisCustomSymbolResolver** symbolResolver);
|
||||
|
||||
/**
|
||||
* @brief Changes the symbol-resolver of the given instruction-formatter instance.
|
||||
*
|
||||
* @param formatter A pointer to the instruction-formatter instance.
|
||||
* @param symbolResolver A pointer to the new symbol-resolver instance.
|
||||
*
|
||||
* @return The ZydisStatus.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisFormatterSetSymbolResolver(
|
||||
ZydisInstructionFormatter* formatter, ZydisCustomSymbolResolver* symbolResolver);
|
||||
|
||||
/**
|
||||
* @brief Formats the given instruction and writes it into the output buffer.
|
||||
*
|
||||
* @param formatter A pointer to the instruction-formatter instance.
|
||||
* @param info A pointer to the instruction-info struct.
|
||||
* @param buffer A pointer to the output buffer.
|
||||
* @param bufferLen The length of the output buffer.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisFormatterFormatInstruction(
|
||||
ZydisInstructionFormatter* formatter, const ZydisInstructionInfo* info, char* buffer,
|
||||
size_t bufferLen);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_FORMATTER_H */
|
|
@ -0,0 +1,172 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_INPUT_H
|
||||
#define ZYDIS_INPUT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Status.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Custom input */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Enums and types */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisInputNextFunc function pointer used in the @c ZydisCustomInput
|
||||
* struct.
|
||||
*
|
||||
* This function should return the byte at the current input-position and increase the position
|
||||
* by one. If the input data-source has no more data available, return @c FALSE.
|
||||
*/
|
||||
typedef bool (*ZydisInputNextFunc)(void* context, uint8_t* data);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis custom input struct.
|
||||
*/
|
||||
typedef struct ZydisCustomInput_
|
||||
{
|
||||
/**
|
||||
* @brief The @c ZydisInputNextFunc callback.
|
||||
*/
|
||||
ZydisInputNextFunc inputNext;
|
||||
} ZydisCustomInput;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Memory input */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Enums and types */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis memory input struct.
|
||||
*/
|
||||
typedef struct ZydisMemoryInput_
|
||||
{
|
||||
/**
|
||||
* @brief The @c ZydisCustomInput base struct.
|
||||
*
|
||||
* This has to be the first element in every custom input data-source struct to ensure we
|
||||
* can safely downcast it.
|
||||
*/
|
||||
ZydisCustomInput input;
|
||||
/**
|
||||
* @brief A pointer to the mem buffer.
|
||||
*/
|
||||
const uint8_t* inputBuffer;
|
||||
/**
|
||||
* @brief The length of the mem buffer.
|
||||
*/
|
||||
uint64_t inputBufferLen;
|
||||
/**
|
||||
* @brief The current input position.
|
||||
*/
|
||||
uint64_t inputBufferPos;
|
||||
} ZydisMemoryInput;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initializes the given @c ZydisMemoryInput instance.
|
||||
*
|
||||
* @param input A pointer to the input data-source instance.
|
||||
* @param buffer The mem buffer to use.
|
||||
* @param length The length of the mem buffer.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisInputInitMemoryInput(ZydisMemoryInput* input, const void* buffer,
|
||||
uint64_t length);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* File input */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Enums and types */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis file input struct.
|
||||
*/
|
||||
typedef struct ZydisFileInput_
|
||||
{
|
||||
/**
|
||||
* @brief The @c ZydisCustomInput base struct.
|
||||
*
|
||||
* This has to be the first element in every custom input data-source struct to ensure we can
|
||||
* safely downcast it.
|
||||
*/
|
||||
ZydisCustomInput input;
|
||||
/**
|
||||
* @brief The input file.
|
||||
*/
|
||||
FILE* file;
|
||||
} ZydisFileInput;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Initializes the given @c ZydisFileInput instance.
|
||||
*
|
||||
* @param input A pointer to the input data-source instance.
|
||||
* @param file The file to use. You may freely `fseek` around after creation of the source.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisInputInitFileInput(ZydisFileInput* input, FILE* file);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_INPUT_H */
|
|
@ -0,0 +1,928 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief TODO
|
||||
*/
|
||||
|
||||
#ifndef ZYDIS_INSTRUCTIONINFO_H
|
||||
#define ZYDIS_INSTRUCTIONINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <Zydis/Mnemonic.h>
|
||||
#include <Zydis/Register.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Disassembler mode */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis disassembler-mode datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisDisassemblerMode;
|
||||
|
||||
/**
|
||||
* @brief Values that represent disassembler-modes.
|
||||
*/
|
||||
enum ZydisDisassemblerModes
|
||||
{
|
||||
ZYDIS_DISASSEMBLER_MODE_16BIT = 16,
|
||||
ZYDIS_DISASSEMBLER_MODE_32BIT = 32,
|
||||
ZYDIS_DISASSEMBLER_MODE_64BIT = 64
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction flags */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing instruction flags.
|
||||
*/
|
||||
typedef uint32_t ZydisInstructionFlags;
|
||||
|
||||
/**
|
||||
* @brief Values that represent instruction flags.
|
||||
*/
|
||||
enum ZydisInstructionFlag
|
||||
{
|
||||
/**
|
||||
* @brief The instruction has one or more operand with position-relative offsets.
|
||||
*/
|
||||
ZYDIS_IFLAG_RELATIVE = 0x00000001,
|
||||
/**
|
||||
* @brief The instruction has the modrm byte.
|
||||
*/
|
||||
ZYDIS_IFLAG_HAS_MODRM = 0x00000002,
|
||||
/**
|
||||
* @brief The instruction has the sib byte.
|
||||
*/
|
||||
ZYDIS_IFLAG_HAS_SIB = 0x00000004,
|
||||
/**
|
||||
* @brief An error occured while decoding the current instruction.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_MASK = 0x7F000000,
|
||||
/**
|
||||
* @brief The instruction is invalid.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_INVALID = 0x01000000,
|
||||
/**
|
||||
* @brief The instruction length has exceeded the maximum of 15 bytes.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_INSTRUCTION_LENGTH = 0x02000000,
|
||||
/**
|
||||
* @brief An error occured while decoding the vex-prefix.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_MALFORMED_VEX = 0x04000000,
|
||||
/**
|
||||
* @brief An error occured while decoding the evex-prefix.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_MALFORMED_EVEX = 0x08000000,
|
||||
/**
|
||||
* @brief An error occured while decoding the xop-prefix.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_MALFORMED_XOP = 0x10000000,
|
||||
/**
|
||||
* @brief A rex-prefix was found while decoding a vex/evex/xop instruction.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_ILLEGAL_REX = 0x20000000,
|
||||
/**
|
||||
* @brief An invalid constellation was found while decoding an instruction that uses the VSIB
|
||||
* addressing mode.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_INVALID_VSIB = 0x40000000,
|
||||
/**
|
||||
* @brief An error occured while decoding the instruction-operands.
|
||||
*/
|
||||
ZYDIS_IFLAG_ERROR_OPERANDS = 0x40000000
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Prefix flags */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis prefix-flags datatype.
|
||||
*/
|
||||
typedef uint32_t ZydisPrefixFlags;
|
||||
|
||||
/**
|
||||
* @brief Values that represent instruction encodings.
|
||||
*/
|
||||
enum ZydisPrefixFlag
|
||||
{
|
||||
/**
|
||||
* @brief The instruction has the rex-prefix (0x40 - 0x4F).
|
||||
*/
|
||||
ZYDIS_PREFIX_REX = 0x00000001,
|
||||
/**
|
||||
* @brief The instruction has the xop-prefix (0x8F).
|
||||
*/
|
||||
ZYDIS_PREFIX_XOP = 0x00000002,
|
||||
/**
|
||||
* @brief The instruction has the vex-prefix (0xC4 or 0xC5).
|
||||
*/
|
||||
ZYDIS_PREFIX_VEX = 0x00000004,
|
||||
/**
|
||||
* @brief The instruction has the evex-prefix (0x62).
|
||||
*/
|
||||
ZYDIS_PREFIX_EVEX = 0x00000008,
|
||||
/**
|
||||
* @brief The instruction has the lock-prefix (0x0F)
|
||||
*/
|
||||
ZYDIS_PREFIX_LOCK = 0x00000010,
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
ZYDIS_PREFIX_REP = 0x00000020,
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
ZYDIS_PREFIX_REPE = 0x00000020,
|
||||
/**
|
||||
* @brief The instruction has the rep/repe/repz-prefix (0xF3)
|
||||
*/
|
||||
ZYDIS_PREFIX_REPZ = 0x00000020,
|
||||
/**
|
||||
* @brief The instruction has the repne/repnz-prefix (0xF2)
|
||||
*/
|
||||
ZYDIS_PREFIX_REPNE = 0x00000040,
|
||||
/**
|
||||
* @brief The instruction has the repne/repnz-prefix (0xF2)
|
||||
*/
|
||||
ZYDIS_PREFIX_REPNZ = 0x00000040,
|
||||
/**
|
||||
* @brief The instruction has a segment-override prefix.
|
||||
*/
|
||||
ZYDIS_PREFIX_SEGMENT_MASK = 0x00001F80,
|
||||
/**
|
||||
* @brief The instruction has the cs segment-override prefix (0x2E).
|
||||
*/
|
||||
ZYDIS_PREFIX_SEGMENT_CS = 0x00000080,
|
||||
/**
|
||||
* @brief The instruction has the ss segment-override prefix (0x36).
|
||||
*/
|
||||
ZYDIS_PREFIX_SEGMENT_SS = 0x00000100,
|
||||
/**
|
||||
* @brief The instruction has the ds segment-override prefix (0x3E).
|
||||
*/
|
||||
ZYDIS_PREFIX_SEGMENT_DS = 0x00000200,
|
||||
/**
|
||||
* @brief The instruction has the es segment-override prefix (0x26).
|
||||
*/
|
||||
ZYDIS_PREFIX_SEGMENT_ES = 0x00000400,
|
||||
/**
|
||||
* @brief The instruction has the fs segment-override prefix (0x64).
|
||||
*/
|
||||
ZYDIS_PREFIX_SEGMENT_FS = 0x00000800,
|
||||
/**
|
||||
* @brief The instruction has the gs segment-override prefix (0x65).
|
||||
*/
|
||||
ZYDIS_PREFIX_SEGMENT_GS = 0x00001000,
|
||||
/**
|
||||
* @brief The instruction has the operand-size-override prefix (0x66).
|
||||
*/
|
||||
ZYDIS_PREFIX_OPERANDSIZE = 0x00002000,
|
||||
/**
|
||||
* @brief The instruction has the address-size-override prefix (0x67).
|
||||
*/
|
||||
ZYDIS_PREFIX_ADDRESSSIZE = 0x00004000,
|
||||
/**
|
||||
* @brief The instruction has the xacquire prefix (0xF2).
|
||||
*/
|
||||
ZYDIS_PREFIX_XACQUIRE = 0x00008000,
|
||||
/**
|
||||
* @brief The instruction has the xrelease prefix (0xF3).
|
||||
*/
|
||||
ZYDIS_PREFIX_XRELEASE = 0x00010000,
|
||||
/**
|
||||
* @brief The instruction has the branch-not-taken hint (0x2E).
|
||||
*/
|
||||
ZYDIS_PREFIX_BRANCH_NOT_TAKEN = 0x00020000,
|
||||
/**
|
||||
* @brief The instruction has the branch-taken hint (0x3E).
|
||||
*/
|
||||
ZYDIS_PREFIX_BRANCH_TAKEN = 0x00040000,
|
||||
/**
|
||||
* @brief The instruction accepts the lock-prefix.
|
||||
*/
|
||||
ZYDIS_PREFIX_ACCEPTS_LOCK = 0x00080000,
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
ZYDIS_PREFIX_ACCEPTS_REP = 0x00100000,
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
ZYDIS_PREFIX_ACCEPTS_REPE = 0x00100000,
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
ZYDIS_PREFIX_ACCEPTS_REPZ = 0x00100000,
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
ZYDIS_PREFIX_ACCEPTS_REPNE = 0x00100000,
|
||||
/**
|
||||
* @brief The instruction accepts the string prefixes (rep/repe/repz/repne/repnz).
|
||||
*/
|
||||
ZYDIS_PREFIX_ACCEPTS_REPNZ = 0x00100000,
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the first prefix-group (0x0F, 0xF3, 0xF2).
|
||||
*/
|
||||
ZYDIS_PREFIX_MULTIPLE_GRP1 = 0x01000000,
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the second prefix-group (0x2E, 0x36,
|
||||
* 0x3E, 0x26, 0x64, 0x65).
|
||||
*/
|
||||
ZYDIS_PREFIX_MULTIPLE_GRP2 = 0x02000000,
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the third prefix-group (0x66).
|
||||
*/
|
||||
ZYDIS_PREFIX_MULTIPLE_GRP3 = 0x04000000,
|
||||
/**
|
||||
* @brief The instruction has multiple prefixes of the fourth prefix-group (0x67).
|
||||
*/
|
||||
ZYDIS_PREFIX_MULTIPLE_GRP4 = 0x08000000,
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction encoding */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis instruction-encoding datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisInstructionEncoding;
|
||||
|
||||
/**
|
||||
* @brief Values that represent instruction encodings.
|
||||
*/
|
||||
enum ZydisInstructionEncodings
|
||||
{
|
||||
ZYDIS_INSTRUCTION_ENCODING_DEFAULT = 0x00,
|
||||
ZYDIS_INSTRUCTION_ENCODING_3DNOW = 0x01,
|
||||
ZYDIS_INSTRUCTION_ENCODING_XOP = 0x02,
|
||||
ZYDIS_INSTRUCTION_ENCODING_VEX = 0x03,
|
||||
ZYDIS_INSTRUCTION_ENCODING_EVEX = 0x04
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Opcode map */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing an opcode map.
|
||||
*/
|
||||
typedef uint8_t ZydisOpcodeMap;
|
||||
|
||||
/**
|
||||
* @brief Values that represent opcode maps.
|
||||
*/
|
||||
enum ZydisOpcodeMaps
|
||||
{
|
||||
ZYDIS_OPCODE_MAP_DEFAULT = 0x00,
|
||||
ZYDIS_OPCODE_MAP_0F = 0x01,
|
||||
ZYDIS_OPCODE_MAP_0F38 = 0x02,
|
||||
ZYDIS_OPCODE_MAP_0F3A = 0x03,
|
||||
ZYDIS_OPCODE_MAP_XOP8 = 0x04,
|
||||
ZYDIS_OPCODE_MAP_XOP9 = 0x05,
|
||||
ZYDIS_OPCODE_MAP_XOPA = 0x06
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Operand type */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing an operand-type.
|
||||
*/
|
||||
typedef uint8_t ZydisOperandType;
|
||||
|
||||
/**
|
||||
* @brief Values that represent operand-types.
|
||||
*/
|
||||
enum ZydisOperandTypes
|
||||
{
|
||||
/**
|
||||
* @brief The operand is not used.
|
||||
*/
|
||||
ZYDIS_OPERAND_TYPE_UNUSED,
|
||||
/**
|
||||
* @brief The operand is a register operand.
|
||||
*/
|
||||
ZYDIS_OPERAND_TYPE_REGISTER,
|
||||
/**
|
||||
* @brief The operand is a mem operand.
|
||||
*/
|
||||
ZYDIS_OPERAND_TYPE_MEMORY,
|
||||
/**
|
||||
* @brief The operand is a pointer operand with a segment:offset lvalue.
|
||||
*/
|
||||
ZYDIS_OPERAND_TYPE_POINTER,
|
||||
/**
|
||||
* @brief The operand is an immediate operand.
|
||||
*/
|
||||
ZYDIS_OPERAND_TYPE_IMMEDIATE
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Operand encoding */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing an operand-encoding.
|
||||
*/
|
||||
typedef uint8_t ZydisOperandEncoding;
|
||||
|
||||
/**
|
||||
* @brief Values that represent operand-encodings.
|
||||
*/
|
||||
enum ZydisOperandEncodings
|
||||
{
|
||||
ZYDIS_OPERAND_ENCODING_NONE,
|
||||
ZYDIS_OPERAND_ENCODING_REG,
|
||||
ZYDIS_OPERAND_ENCODING_RM,
|
||||
ZYDIS_OPERAND_ENCODING_RM_CD2,
|
||||
ZYDIS_OPERAND_ENCODING_RM_CD4,
|
||||
ZYDIS_OPERAND_ENCODING_RM_CD8,
|
||||
ZYDIS_OPERAND_ENCODING_RM_CD16,
|
||||
ZYDIS_OPERAND_ENCODING_RM_CD32,
|
||||
ZYDIS_OPERAND_ENCODING_RM_CD64,
|
||||
ZYDIS_OPERAND_ENCODING_OPCODE,
|
||||
ZYDIS_OPERAND_ENCODING_VVVV,
|
||||
ZYDIS_OPERAND_ENCODING_AAA,
|
||||
ZYDIS_OPERAND_ENCODING_IMM8,
|
||||
ZYDIS_OPERAND_ENCODING_IMM16,
|
||||
ZYDIS_OPERAND_ENCODING_IMM32,
|
||||
ZYDIS_OPERAND_ENCODING_IMM64
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Operand access mode */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines an alias representing an operand-access mode.
|
||||
*/
|
||||
typedef uint8_t ZydisOperandAccess;
|
||||
|
||||
/**
|
||||
* @brief Values that represent operand-access-modes.
|
||||
*/
|
||||
enum ZydisOperandAccessModes
|
||||
{
|
||||
/**
|
||||
* @brief The operand gets read by the instruction.
|
||||
*/
|
||||
ZYDIS_OPERAND_ACCESS_READ,
|
||||
/**
|
||||
* @brief The operand gets written by the instruction.
|
||||
*/
|
||||
ZYDIS_OPERAND_ACCESS_WRITE,
|
||||
/**
|
||||
* @brief The operand gets read and written by the instruction.
|
||||
*/
|
||||
ZYDIS_OPERAND_ACCESS_READWRITE
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* AVX mask mode */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisAVXMaskMode datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisAVXMaskMode;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis avx mask-modes.
|
||||
*/
|
||||
enum ZydisAVXMaskModes
|
||||
{
|
||||
ZYDIS_AVX_MASKMODE_INVALID,
|
||||
/**
|
||||
* @brief Merge mode. This is the default mode for all evex-instructions.
|
||||
*/
|
||||
ZYDIS_AVX_MASKMODE_MERGE,
|
||||
/**
|
||||
* @brief The zeroing mode is enabled for this instruction.
|
||||
*/
|
||||
ZYDIS_AVX_MASKMODE_ZERO
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* AVX broadcast type */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisAVXBroadcastType datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisAVXBroadcastType;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis avx broadcast-types.
|
||||
*/
|
||||
enum ZydisAVXBroadcastTypes
|
||||
{
|
||||
ZYDIS_AVX_BCSTMODE_INVALID,
|
||||
/**
|
||||
* @brief 1to2 broadcast.
|
||||
*/
|
||||
ZYDIS_AVX_BCSTMODE_2,
|
||||
/**
|
||||
* @brief 1to4 broadcast.
|
||||
*/
|
||||
ZYDIS_AVX_BCSTMODE_4,
|
||||
/**
|
||||
* @brief 1to8 broadcast.
|
||||
*/
|
||||
ZYDIS_AVX_BCSTMODE_8,
|
||||
/**
|
||||
* @brief 1to16 broadcast.
|
||||
*/
|
||||
ZYDIS_AVX_BCSTMODE_16
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* AVX rounding mode */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisAVXRoundingMode datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisAVXRoundingMode;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis avx rounding-mode.
|
||||
*/
|
||||
enum ZydisAVXRoundingModes // TODO: Mirror "real" values from documentation
|
||||
{
|
||||
ZYDIS_AVX_RNDMODE_INVALID,
|
||||
/**
|
||||
* @brief Round to nearest.
|
||||
*/
|
||||
ZYDIS_AVX_RNDMODE_RN,
|
||||
/**
|
||||
* @brief Round down.
|
||||
*/
|
||||
ZYDIS_AVX_RNDMODE_RD,
|
||||
/**
|
||||
* @brief Round up.
|
||||
*/
|
||||
ZYDIS_AVX_RNDMODE_RU,
|
||||
/**
|
||||
* @brief Round towards zero.
|
||||
*/
|
||||
ZYDIS_AVX_RNDMODE_RZ
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Operand info */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis operand info struct.
|
||||
*/
|
||||
typedef struct ZydisOperandInfo_
|
||||
{
|
||||
/**
|
||||
* @brief The type of the operand.
|
||||
*/
|
||||
ZydisOperandType type;
|
||||
/**
|
||||
* @brief The logical size of the operand.
|
||||
*/
|
||||
uint16_t size;
|
||||
/**
|
||||
* @brief The operand encoding.
|
||||
*/
|
||||
ZydisOperandEncoding encoding;
|
||||
/**
|
||||
* @brief The operand access mode.
|
||||
*/
|
||||
ZydisOperandAccess access;
|
||||
/**
|
||||
* @brief Specifies the register for register-operands.
|
||||
*/
|
||||
ZydisRegister reg;
|
||||
/**
|
||||
* @brief Extended info for memory-operands.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief The segment register.
|
||||
*/
|
||||
ZydisRegister segment;
|
||||
/**
|
||||
* @brief The base register.
|
||||
*/
|
||||
ZydisRegister base;
|
||||
/**
|
||||
* @brief The index register.
|
||||
*/
|
||||
ZydisRegister index;
|
||||
/**
|
||||
* @brief The scale factor.
|
||||
*/
|
||||
uint8_t scale;
|
||||
/**
|
||||
* @brief Extended info for memory-operand with displacement.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief The physical displacement size.
|
||||
*/
|
||||
uint8_t size;
|
||||
/**
|
||||
* @brief The displacement value
|
||||
*/
|
||||
union
|
||||
{
|
||||
int8_t sbyte;
|
||||
int16_t sword;
|
||||
int32_t sdword;
|
||||
int64_t sqword;
|
||||
} value;
|
||||
/**
|
||||
* @brief The offset of the displacement data, relative to the beginning of the
|
||||
* instruction.
|
||||
*/
|
||||
uint8_t dataOffset;
|
||||
} disp;
|
||||
} mem;
|
||||
/**
|
||||
* @brief Extended info for pointer operands.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint16_t segment;
|
||||
uint32_t offset;
|
||||
} ptr;
|
||||
/**
|
||||
* @brief Extended info for immediate operands.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief Signals, if the immediate value is signed.
|
||||
*/
|
||||
bool isSigned;
|
||||
/**
|
||||
* @brief Signals, if the immediate value contains a relative offset.
|
||||
*/
|
||||
bool isRelative;
|
||||
/**
|
||||
* @brief The physical immediate size.
|
||||
*/
|
||||
uint8_t size;
|
||||
/**
|
||||
* @brief The immediate value.
|
||||
*/
|
||||
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;
|
||||
} value;
|
||||
/**
|
||||
* @brief The offset of the immediate data, relative to the beginning of the instruction.
|
||||
*/
|
||||
uint8_t dataOffset;
|
||||
} imm;
|
||||
} ZydisOperandInfo;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction info */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis instruction info struct.
|
||||
*/
|
||||
typedef struct ZydisInstructionInfo_
|
||||
{
|
||||
/**
|
||||
* @brief The disassembler-mode used to decode this instruction.
|
||||
*/
|
||||
ZydisDisassemblerMode mode;
|
||||
/**
|
||||
* @brief Instruction specific info- and error-flags.
|
||||
*/
|
||||
ZydisInstructionFlags flags;
|
||||
/**
|
||||
* @brief Prefix flags.
|
||||
*/
|
||||
ZydisPrefixFlags prefixFlags;
|
||||
/**
|
||||
* @brief The instruction-mnemonic.
|
||||
*/
|
||||
ZydisInstructionMnemonic mnemonic;
|
||||
/**
|
||||
* @brief The length of the decoded instruction.
|
||||
*/
|
||||
uint8_t length;
|
||||
/**
|
||||
* @brief The raw bytes of the decoded instruction.
|
||||
*/
|
||||
uint8_t data[15];
|
||||
/**
|
||||
* @brief The instruction-encoding (default, 3dnow, vex, evex, xop).
|
||||
*/
|
||||
ZydisInstructionEncoding encoding;
|
||||
/**
|
||||
* @brief The opcode-map.
|
||||
*/
|
||||
ZydisOpcodeMap opcodeMap;
|
||||
/**
|
||||
* @brief The instruction-opcode.
|
||||
*/
|
||||
uint8_t opcode;
|
||||
/**
|
||||
* @brief The number of instruction-operands.
|
||||
*/
|
||||
uint8_t operandCount;
|
||||
/**
|
||||
* @brief Detailed info for all instruction operands.
|
||||
*/
|
||||
ZydisOperandInfo operand[4];
|
||||
/**
|
||||
* @brief The operand mode (16, 32, 64).
|
||||
*/
|
||||
uint8_t operandMode;
|
||||
/**
|
||||
* @brief The address mode (16, 32, 64).
|
||||
*/
|
||||
uint8_t addressMode;
|
||||
/**
|
||||
* @brief Extended info for avx-related instructions.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief The AVX mask-register.
|
||||
*/
|
||||
ZydisRegister maskRegister;
|
||||
/**
|
||||
* @brief The AVX mask-mode.
|
||||
*/
|
||||
ZydisAVXMaskMode maskMode;
|
||||
/**
|
||||
* @brief The AVX broadcast-type.
|
||||
*/
|
||||
ZydisAVXBroadcastType broadcast;
|
||||
/**
|
||||
* @brief The AVX rounding-mode.
|
||||
*/
|
||||
ZydisAVXRoundingMode roundingMode;
|
||||
/**
|
||||
* @brief The AVX suppress-all-exceptions flag.
|
||||
*/
|
||||
bool sae;
|
||||
} avx;
|
||||
/**
|
||||
* @brief The instruction address points at the current instruction (relative to the
|
||||
* initial instruction pointer).
|
||||
*/
|
||||
uint64_t instrAddress;
|
||||
/**
|
||||
* @brief The instruction pointer points at the address of the next instruction (relative
|
||||
* to the initial instruction pointer).
|
||||
*
|
||||
* This field is used to properly format relative instructions.
|
||||
*/
|
||||
uint64_t instrPointer;
|
||||
/**
|
||||
* @brief Extended info about different instruction-parts like modrm, sib or
|
||||
* encoding-prefixes.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
// TODO: uint8_t map[15];
|
||||
/**
|
||||
* @brief Detailed info about the rex-prefix.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief True if the prefix got already decoded.
|
||||
*/
|
||||
bool isDecoded;
|
||||
/**
|
||||
* @brief The raw bytes of the prefix.
|
||||
*/
|
||||
uint8_t data[1];
|
||||
/**
|
||||
* @brief 64 bit operand-size override.
|
||||
*/
|
||||
uint8_t w;
|
||||
/**
|
||||
* @brief Extension of the modrm.reg field.
|
||||
*/
|
||||
uint8_t r;
|
||||
/**
|
||||
* @brief Extension of the sib.index field.
|
||||
*/
|
||||
uint8_t x;
|
||||
/**
|
||||
* @brief Extension of the modrm.rm field, sib.base field, or opcode.reg field.
|
||||
*/
|
||||
uint8_t b;
|
||||
} rex;
|
||||
/**
|
||||
* @brief Detailed info about the vex-prefix.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief True if the prefix got already decoded.
|
||||
*/
|
||||
bool isDecoded;
|
||||
/**
|
||||
* @brief The raw bytes of the prefix.
|
||||
*/
|
||||
uint8_t data[3];
|
||||
uint8_t r;
|
||||
uint8_t x;
|
||||
uint8_t b;
|
||||
uint8_t m_mmmm;
|
||||
uint8_t w;
|
||||
uint8_t vvvv;
|
||||
uint8_t l;
|
||||
uint8_t pp;
|
||||
} vex;
|
||||
/**
|
||||
* @brief Detailed info about the evex-prefix.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief True if the prefix got already decoded.
|
||||
*/
|
||||
bool isDecoded;
|
||||
/**
|
||||
* @brief The raw bytes of the prefix.
|
||||
*/
|
||||
uint8_t data[4];
|
||||
/**
|
||||
* @brief TODO:
|
||||
*/
|
||||
uint8_t r;
|
||||
/**
|
||||
* @brief TODO:
|
||||
*/
|
||||
uint8_t x;
|
||||
/**
|
||||
* @brief TODO:
|
||||
*/
|
||||
uint8_t b;
|
||||
/**
|
||||
* @brief High-16 register specifier modifier.
|
||||
*/
|
||||
uint8_t r2;
|
||||
/**
|
||||
* @brief Compressed legacy escape.
|
||||
*/
|
||||
uint8_t mm;
|
||||
/**
|
||||
* @brief Osize promotion/Opcode extension.
|
||||
*/
|
||||
uint8_t w;
|
||||
/**
|
||||
* @brief NDS register specifier.
|
||||
*/
|
||||
uint8_t vvvv;
|
||||
/**
|
||||
* @brief Compressed legacy prefix.
|
||||
*/
|
||||
uint8_t pp;
|
||||
/**
|
||||
* @brief Zeroing/Merging.
|
||||
*/
|
||||
uint8_t z;
|
||||
/**
|
||||
* @brief Vector length/RC (most significant bit).
|
||||
*/
|
||||
uint8_t l2;
|
||||
/**
|
||||
* @brief Vector length/RC (least significant bit).
|
||||
*/
|
||||
uint8_t l;
|
||||
/**
|
||||
* @brief Broadcast/RC/SAE Context.
|
||||
*/
|
||||
uint8_t b0;
|
||||
/**
|
||||
* @brief High-16 NDS/VIDX register specifier.
|
||||
*/
|
||||
uint8_t v2;
|
||||
/**
|
||||
* @brief Embedded opmask register specifier.
|
||||
*/
|
||||
uint8_t aaa;
|
||||
} evex;
|
||||
/**
|
||||
* @brief Detailed info about the xop-prefix.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief True if the prefix got already decoded.
|
||||
*/
|
||||
bool isDecoded;
|
||||
/**
|
||||
* @brief The raw bytes of the prefix.
|
||||
*/
|
||||
uint8_t data[3];
|
||||
uint8_t r;
|
||||
uint8_t x;
|
||||
uint8_t b;
|
||||
uint8_t m_mmmm;
|
||||
uint8_t w;
|
||||
uint8_t vvvv;
|
||||
uint8_t l;
|
||||
uint8_t pp;
|
||||
} xop;
|
||||
/**
|
||||
* @brief Detailed info about the modrm-byte.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool isDecoded;
|
||||
uint8_t data[1];
|
||||
uint8_t mod;
|
||||
uint8_t reg;
|
||||
uint8_t rm;
|
||||
} modrm;
|
||||
/**
|
||||
* @brief Detailed info about the sib-byte.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
bool isDecoded;
|
||||
uint8_t data[1];
|
||||
uint8_t scale;
|
||||
uint8_t index;
|
||||
uint8_t base;
|
||||
} sib;
|
||||
/**
|
||||
* @brief Internal data.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
uint8_t w;
|
||||
uint8_t r;
|
||||
uint8_t x;
|
||||
uint8_t b;
|
||||
uint8_t l;
|
||||
} internal;
|
||||
} details;
|
||||
} ZydisInstructionInfo;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_INSTRUCTIONINFO_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,634 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_INSTRUCTIONTABLE_H
|
||||
#define ZYDIS_INSTRUCTIONTABLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Mnemonic.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction table */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisInstructionTableNodeType datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisInstructionTableNodeType;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis instruction table node types.
|
||||
*/
|
||||
enum ZydisInstructionTableNodeTypes
|
||||
{
|
||||
ZYDIS_NODETYPE_INVALID = 0x00,
|
||||
/**
|
||||
* @brief Reference to a concrete instruction definition.
|
||||
*/
|
||||
ZYDIS_NODETYPE_DEFINITION = 0x01,
|
||||
/**
|
||||
* @brief Reference to an opcode filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_OPCODE = 0x02,
|
||||
/**
|
||||
* @brief Reference to an vex-map filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_VEX = 0x03,
|
||||
/**
|
||||
* @brief Reference to an xop-map filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_XOP = 0x04,
|
||||
/**
|
||||
* @brief Reference to an instruction-mode filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_MODE = 0x05,
|
||||
/**
|
||||
* @brief Reference to a mandatory-prefix filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_MANDATORYPREFIX = 0x06,
|
||||
/**
|
||||
* @brief Reference to a modrm.mod filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_MODRMMOD = 0x07,
|
||||
/**
|
||||
* @brief Reference to a modrm.reg filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_MODRMREG = 0x08,
|
||||
/**
|
||||
* @brief Reference to a modrm.rm filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_MODRMRM = 0x09,
|
||||
/**
|
||||
* @brief Reference to an operand-size filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_OPERANDSIZE = 0x0A,
|
||||
/**
|
||||
* @brief Reference to an address-size filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_ADDRESSSIZE = 0x0B,
|
||||
/**
|
||||
* @brief Reference to an rex/vex/evex.w filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_REXW = 0x0C,
|
||||
/**
|
||||
* @brief Reference to an vex/evex.l filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_VEXL = 0x0D,
|
||||
/**
|
||||
* @brief Reference to an evex.l' filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_EVEXL2 = 0x0E,
|
||||
/**
|
||||
* @brief Reference to an evex.b filter.
|
||||
*/
|
||||
ZYDIS_NODETYPE_FILTER_EVEXB = 0x0F
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
#pragma pack (push, 1)
|
||||
/**
|
||||
* @brief Defines the @c ZydisInstructionTableNode struct.
|
||||
*/
|
||||
typedef struct ZydisInstructionTableNode_
|
||||
{
|
||||
/**
|
||||
* @brief The instruction table node type.
|
||||
*/
|
||||
ZydisInstructionTableNodeType type;
|
||||
/**
|
||||
* @brief The instruction table node value.
|
||||
*/
|
||||
uint16_t value;
|
||||
} ZydisInstructionTableNode;
|
||||
#pragma pack (pop)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Instruction definition */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisSemanticOperandType datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisSemanticOperandType;
|
||||
|
||||
/**
|
||||
* @brief Values that represent semantic operand types.
|
||||
*/
|
||||
enum ZydisSemanticOperandTypes
|
||||
{
|
||||
ZYDIS_SEM_OPERAND_TYPE_UNUSED,
|
||||
ZYDIS_SEM_OPERAND_TYPE_GPR8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_GPR16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_GPR32,
|
||||
ZYDIS_SEM_OPERAND_TYPE_GPR64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_FPR,
|
||||
ZYDIS_SEM_OPERAND_TYPE_VR64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_VR128,
|
||||
ZYDIS_SEM_OPERAND_TYPE_VR256,
|
||||
ZYDIS_SEM_OPERAND_TYPE_VR512,
|
||||
ZYDIS_SEM_OPERAND_TYPE_CR,
|
||||
ZYDIS_SEM_OPERAND_TYPE_DR,
|
||||
ZYDIS_SEM_OPERAND_TYPE_SREG,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MSKR,
|
||||
ZYDIS_SEM_OPERAND_TYPE_BNDR,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM80,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM128,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM256,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM512,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST2,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST4,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32_BCST16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST2,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST4,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64_BCST16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBX,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBY,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM32_VSIBZ,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBX,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBY,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM64_VSIBZ,
|
||||
ZYDIS_SEM_OPERAND_TYPE_M1616,
|
||||
ZYDIS_SEM_OPERAND_TYPE_M1632,
|
||||
ZYDIS_SEM_OPERAND_TYPE_M1664,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM112,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MEM224,
|
||||
ZYDIS_SEM_OPERAND_TYPE_IMM8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_IMM16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_IMM32,
|
||||
ZYDIS_SEM_OPERAND_TYPE_IMM64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_IMM8U,
|
||||
ZYDIS_SEM_OPERAND_TYPE_REL8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_REL16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_REL32,
|
||||
ZYDIS_SEM_OPERAND_TYPE_REL64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_PTR1616,
|
||||
ZYDIS_SEM_OPERAND_TYPE_PTR1632,
|
||||
ZYDIS_SEM_OPERAND_TYPE_PTR1664,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MOFFS16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MOFFS32,
|
||||
ZYDIS_SEM_OPERAND_TYPE_MOFFS64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_SRCIDX8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_SRCIDX16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_SRCIDX32,
|
||||
ZYDIS_SEM_OPERAND_TYPE_SRCIDX64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_DSTIDX8,
|
||||
ZYDIS_SEM_OPERAND_TYPE_DSTIDX16,
|
||||
ZYDIS_SEM_OPERAND_TYPE_DSTIDX32,
|
||||
ZYDIS_SEM_OPERAND_TYPE_DSTIDX64,
|
||||
ZYDIS_SEM_OPERAND_TYPE_FIXED1,
|
||||
ZYDIS_SEM_OPERAND_TYPE_AL,
|
||||
ZYDIS_SEM_OPERAND_TYPE_CL,
|
||||
ZYDIS_SEM_OPERAND_TYPE_AX,
|
||||
ZYDIS_SEM_OPERAND_TYPE_DX,
|
||||
ZYDIS_SEM_OPERAND_TYPE_EAX,
|
||||
ZYDIS_SEM_OPERAND_TYPE_RAX,
|
||||
ZYDIS_SEM_OPERAND_TYPE_ES,
|
||||
ZYDIS_SEM_OPERAND_TYPE_CS,
|
||||
ZYDIS_SEM_OPERAND_TYPE_SS,
|
||||
ZYDIS_SEM_OPERAND_TYPE_DS,
|
||||
ZYDIS_SEM_OPERAND_TYPE_GS,
|
||||
ZYDIS_SEM_OPERAND_TYPE_FS,
|
||||
ZYDIS_SEM_OPERAND_TYPE_ST0
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisEvexBFunctionality datatype .
|
||||
*/
|
||||
typedef uint8_t ZydisEvexBFunctionality;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis evex.b-functionalities.
|
||||
*/
|
||||
enum ZydisEvexBFunctionalities
|
||||
{
|
||||
ZYDIS_EVEXB_FUNCTIONALITY_NONE,
|
||||
ZYDIS_EVEXB_FUNCTIONALITY_BC,
|
||||
ZYDIS_EVEXB_FUNCTIONALITY_RC,
|
||||
ZYDIS_EVEXB_FUNCTIONALITY_SAE
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis operand definition datatype.
|
||||
*/
|
||||
typedef uint16_t ZydisOperandDefinition;
|
||||
|
||||
#pragma pack (push, 1)
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis operands definition datatype.
|
||||
*/
|
||||
typedef struct ZydisInstructionOperands_
|
||||
{
|
||||
ZydisOperandDefinition operands[4];
|
||||
} ZydisInstructionOperands;
|
||||
|
||||
/**
|
||||
* @brief Defines the zydis instruction definition struct.
|
||||
*/
|
||||
typedef struct ZydisInstructionDefinition_
|
||||
{
|
||||
/**
|
||||
* @brief The instruction mnemonic.
|
||||
*/
|
||||
ZydisInstructionMnemonic mnemonic;
|
||||
/**
|
||||
* @brief The instruction operand.
|
||||
*/
|
||||
uint16_t operands;
|
||||
//ZydisOperandDefinition operands[4];
|
||||
} ZydisInstructionDefinition;
|
||||
#pragma pack (pop)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Data tables */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Contains all opcode filters.
|
||||
*
|
||||
* Indexed by the numeric value of the opcode.
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterOpcode[][256];
|
||||
|
||||
/**
|
||||
* @brief Contains all vex-map filters.
|
||||
*
|
||||
* Index values:
|
||||
* 0 = LES, LDS or BOUND instruction (default encoding)
|
||||
* 1 = 0F
|
||||
* 2 = 0F38
|
||||
* 3 = 0F3A
|
||||
* 4 = 66
|
||||
* 5 = 66_0F
|
||||
* 6 = 66_0F38
|
||||
* 7 = 66_0F3A
|
||||
* 8 = F3
|
||||
* 9 = F3_0F
|
||||
* A = F3_0F38
|
||||
* B = F3_0F3A
|
||||
* C = F2
|
||||
* D = F2_0F
|
||||
* E = F2_0F38
|
||||
* F = F2_0F3A
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterVEX[][16];
|
||||
|
||||
/**
|
||||
* @brief Contains all xop-map filters.
|
||||
*
|
||||
* Index values:
|
||||
* 0 = POP instruction (default encoding)
|
||||
* 1 = xop8
|
||||
* 2 = xop9
|
||||
* 3 = xopA
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterXOP[][4];
|
||||
|
||||
/**
|
||||
* @brief Contains all instruction-mode filters.
|
||||
*
|
||||
* Index values:
|
||||
* 0 = 64 bit mode required
|
||||
* 1 = 64 bit mode excluded
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterMode[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all mandatory-prefix switch tables.
|
||||
*
|
||||
* Index values:
|
||||
* 0 = none
|
||||
* 1 = 66
|
||||
* 2 = F3
|
||||
* 3 = F2
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterMandatoryPrefix[][4];
|
||||
|
||||
/**
|
||||
* @brief Contains all modrm.mod filters.
|
||||
*
|
||||
* Index values:
|
||||
* 0 = [modrm_mod == !11] = memory
|
||||
* 1 = [modrm_mod == 11] = register
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterModrmMod[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all modrm.reg filters.
|
||||
*
|
||||
* Indexed by the numeric value of the modrm_reg field.
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterModrmReg[][8];
|
||||
|
||||
/**
|
||||
* @brief Contains all modrm.rm filters.
|
||||
*
|
||||
* Indexed by the numeric value of the modrm_rm field.
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterModrmRm[][8];
|
||||
|
||||
/**
|
||||
* @brief Contains all operand-size filters.
|
||||
*
|
||||
* Index values:
|
||||
* 0 = 16bit = 0x66 prefix in 32 bit mode
|
||||
* 1 = 32bit = 0x66 prefix in 16 bit mode
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterOperandSize[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all address-size filters.
|
||||
*
|
||||
* Index values:
|
||||
* 0 = 16
|
||||
* 1 = 32
|
||||
* 2 = 64
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterAddressSize[][3];
|
||||
|
||||
/**
|
||||
* @brief Contains all rex/vex/evex.w filters.
|
||||
*
|
||||
* Indexed by the numeric value of the rex/vex/evex.w field.
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterREXW[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all vex.l filters.
|
||||
*
|
||||
* Indexed by the numeric value of the vex/evex.l field.
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterVEXL[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all evex.l' filters.
|
||||
*
|
||||
* Indexed by the numeric value of the evex.l' field.
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterEVEXL2[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all evex.b filters.
|
||||
*
|
||||
* Indexed by the numeric value of the evex.b field.
|
||||
*/
|
||||
extern const ZydisInstructionTableNode filterEVEXB[][2];
|
||||
|
||||
/**
|
||||
* @brief Contains all instruction-definitions.
|
||||
*/
|
||||
extern const ZydisInstructionDefinition instructionDefinitions[];
|
||||
|
||||
/**
|
||||
* @brief Contains all instruction-operand-definitions.
|
||||
*/
|
||||
extern const ZydisInstructionOperands instructionOperands[];
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Returns the type of the specified instruction table node.
|
||||
*
|
||||
* @param node The node.
|
||||
*
|
||||
* @return The type of the specified instruction table node.
|
||||
*/
|
||||
ZYDIS_INLINE ZydisInstructionTableNodeType ZydisInstructionTableGetNodeType(
|
||||
ZydisInstructionTableNode node)
|
||||
{
|
||||
return node.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the value of the specified instruction table node.
|
||||
*
|
||||
* @param node The node.
|
||||
*
|
||||
* @return The value of the specified instruction table node.
|
||||
*/
|
||||
ZYDIS_INLINE uint16_t ZydisInstructionTableGetNodeValue(ZydisInstructionTableNode node)
|
||||
{
|
||||
return node.value;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Returns the root node of the instruction table.
|
||||
*
|
||||
* @return The root node of the instruction table.
|
||||
*/
|
||||
ZYDIS_INLINE ZydisInstructionTableNode ZydisInstructionTableGetRootNode()
|
||||
{
|
||||
ZydisInstructionTableNode root = { ZYDIS_NODETYPE_FILTER_OPCODE, 0x00000000 };
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the child node of @c parent specified by @c index.
|
||||
*
|
||||
* @param parent The parent node.
|
||||
* @param index The index of the child node to retrieve.
|
||||
*
|
||||
* @return The specified child node.
|
||||
*/
|
||||
ZYDIS_INLINE ZydisInstructionTableNode ZydisInstructionTableGetChildNode(
|
||||
ZydisInstructionTableNode parent, uint16_t index)
|
||||
{
|
||||
ZydisInstructionTableNodeType nodeType = ZydisInstructionTableGetNodeType(parent);
|
||||
uint16_t tableIndex = ZydisInstructionTableGetNodeValue(parent);
|
||||
switch (nodeType)
|
||||
{
|
||||
case ZYDIS_NODETYPE_FILTER_OPCODE:
|
||||
ZYDIS_ASSERT(index < 256);
|
||||
return filterOpcode[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_VEX:
|
||||
ZYDIS_ASSERT(index < 16);
|
||||
return filterVEX[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_XOP:
|
||||
ZYDIS_ASSERT(index < 4);
|
||||
return filterXOP[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_MODE:
|
||||
ZYDIS_ASSERT(index < 3);
|
||||
return filterMode[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_MANDATORYPREFIX:
|
||||
ZYDIS_ASSERT(index < 4);
|
||||
return filterMandatoryPrefix[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_MODRMMOD:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return filterModrmMod[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_MODRMREG:
|
||||
ZYDIS_ASSERT(index < 8);
|
||||
return filterModrmReg[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_MODRMRM:
|
||||
ZYDIS_ASSERT(index < 8);
|
||||
return filterModrmRm[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_OPERANDSIZE:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return filterOperandSize[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_ADDRESSSIZE:
|
||||
ZYDIS_ASSERT(index < 3);
|
||||
return filterAddressSize[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_REXW:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return filterREXW[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_VEXL:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return filterVEXL[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_EVEXL2:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return filterEVEXL2[tableIndex][index];
|
||||
case ZYDIS_NODETYPE_FILTER_EVEXB:
|
||||
ZYDIS_ASSERT(index < 2);
|
||||
return filterEVEXB[tableIndex][index];
|
||||
default:
|
||||
ZYDIS_UNREACHABLE;
|
||||
}
|
||||
ZydisInstructionTableNode node = { ZYDIS_NODETYPE_INVALID, 0x00000000 };
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the instruction definition that is linked to the given @c node.
|
||||
*
|
||||
* @param node The instruction definition node.
|
||||
*
|
||||
* @return Pointer to the instruction definition.
|
||||
*/
|
||||
ZYDIS_INLINE const ZydisInstructionDefinition* ZydisInstructionDefinitionByNode(
|
||||
ZydisInstructionTableNode node)
|
||||
{
|
||||
ZYDIS_ASSERT(ZydisInstructionTableGetNodeType(node) == ZYDIS_NODETYPE_DEFINITION);
|
||||
return &instructionDefinitions[ZydisInstructionTableGetNodeValue(node)];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZYDIS_INLINE ZydisInstructionMnemonic ZydisInstructionDefinitionGetMnemonic(
|
||||
const ZydisInstructionDefinition* definition)
|
||||
{
|
||||
return (definition->mnemonic >> 4) & 0xFFF;
|
||||
}
|
||||
|
||||
ZYDIS_INLINE const ZydisInstructionOperands* ZydisInstructionDefinitionGetOperands(
|
||||
const ZydisInstructionDefinition* definition)
|
||||
{
|
||||
return &instructionOperands[definition->operands];
|
||||
}
|
||||
|
||||
ZYDIS_INLINE ZydisEvexBFunctionality ZydisInstructionDefinitionGetEvexBFunctionality(
|
||||
const ZydisInstructionDefinition* definition)
|
||||
{
|
||||
return (definition->mnemonic >> 2) & 0x03;
|
||||
}
|
||||
|
||||
ZYDIS_INLINE bool ZydisInstructionDefinitionHasEvexAAA(const ZydisInstructionDefinition* definition)
|
||||
{
|
||||
return (definition->mnemonic >> 1) & 0x01;
|
||||
}
|
||||
|
||||
ZYDIS_INLINE bool ZydisInstructionDefinitionHasEvexZ(const ZydisInstructionDefinition* definition)
|
||||
{
|
||||
return definition->mnemonic & 0x01;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Returns the defined operand-type of the specified operand-definition.
|
||||
*
|
||||
* @param definition The operand definition.
|
||||
*
|
||||
* @return The defined operand-type of the specified operand-definition.
|
||||
*/
|
||||
ZYDIS_INLINE ZydisSemanticOperandType ZydisOperandDefinitionGetType(
|
||||
ZydisOperandDefinition definition)
|
||||
{
|
||||
return ((definition >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the operand-encoding of the specified operand-definition.
|
||||
*
|
||||
* @param definition The operand definition.
|
||||
*
|
||||
* @return The operand-encoding of the specified operand-definition.
|
||||
*/
|
||||
ZYDIS_INLINE ZydisOperandEncoding ZydisOperandDefinitionGetEncoding(
|
||||
ZydisOperandDefinition definition)
|
||||
{
|
||||
return ((definition >> 2) & 0x3F);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the access-mode of the specified operand-definition.
|
||||
*
|
||||
* @param definition The operand definition.
|
||||
*
|
||||
* @return The access-mode of the specified operand-definition.
|
||||
*/
|
||||
ZYDIS_INLINE ZydisOperandAccess ZydisOperandDefinitionGetAccessMode(
|
||||
ZydisOperandDefinition definition)
|
||||
{
|
||||
return ((definition >> 0) & 0x03);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_INSTRUCTIONTABLE_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,85 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_MNEMONIC_H
|
||||
#define ZYDIS_MNEMONIC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Status.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisInstructionMnemonic datatype.
|
||||
*/
|
||||
typedef uint16_t ZydisInstructionMnemonic;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis instruction-mnemonics.
|
||||
*/
|
||||
enum ZydisInstructionMnemonics
|
||||
{
|
||||
#include <Zydis/Internal/Mnemonics.inc>
|
||||
};
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Returns the specified instruction mnemonic string.
|
||||
*
|
||||
* @param mnemonic The mnemonic.
|
||||
*
|
||||
* @return The instruction mnemonic string or @c NULL, if an invalid mnemonic was passed.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic);
|
||||
|
||||
/**
|
||||
* @brief Replaces the string representation of the given mnemonic with a new value.
|
||||
*
|
||||
* @param mnemonic The mnemonic.
|
||||
* @param mnemonicString The new mnemonic string. Use @c NULL to restore default value.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisMnemonicReplaceString(ZydisInstructionMnemonic mnemonic,
|
||||
const char* mnemonicString);
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_MNEMONIC_H */
|
|
@ -0,0 +1,394 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_REGISTER_H
|
||||
#define ZYDIS_REGISTER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <Zydis/Defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisRegister datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisRegister;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis registers.
|
||||
*/
|
||||
enum ZydisRegisters
|
||||
{
|
||||
ZYDIS_REGISTER_NONE,
|
||||
// General purpose registers 64-bit
|
||||
ZYDIS_REGISTER_RAX, ZYDIS_REGISTER_RCX, ZYDIS_REGISTER_RDX, ZYDIS_REGISTER_RBX,
|
||||
ZYDIS_REGISTER_RSP, ZYDIS_REGISTER_RBP, ZYDIS_REGISTER_RSI, ZYDIS_REGISTER_RDI,
|
||||
ZYDIS_REGISTER_R8, ZYDIS_REGISTER_R9, ZYDIS_REGISTER_R10, ZYDIS_REGISTER_R11,
|
||||
ZYDIS_REGISTER_R12, ZYDIS_REGISTER_R13, ZYDIS_REGISTER_R14, ZYDIS_REGISTER_R15,
|
||||
// General purpose registers 32-bit
|
||||
ZYDIS_REGISTER_EAX, ZYDIS_REGISTER_ECX, ZYDIS_REGISTER_EDX, ZYDIS_REGISTER_EBX,
|
||||
ZYDIS_REGISTER_ESP, ZYDIS_REGISTER_EBP, ZYDIS_REGISTER_ESI, ZYDIS_REGISTER_EDI,
|
||||
ZYDIS_REGISTER_R8D, ZYDIS_REGISTER_r9D, ZYDIS_REGISTER_R10D, ZYDIS_REGISTER_R11D,
|
||||
ZYDIS_REGISTER_R12D, ZYDIS_REGISTER_R13D, ZYDIS_REGISTER_R14D, ZYDIS_REGISTER_R15D,
|
||||
// General purpose registers 16-bit
|
||||
ZYDIS_REGISTER_AX, ZYDIS_REGISTER_CX, ZYDIS_REGISTER_DX, ZYDIS_REGISTER_BX,
|
||||
ZYDIS_REGISTER_SP, ZYDIS_REGISTER_BP, ZYDIS_REGISTER_SI, ZYDIS_REGISTER_DI,
|
||||
ZYDIS_REGISTER_R8W, ZYDIS_REGISTER_R9W, ZYDIS_REGISTER_R10W, ZYDIS_REGISTER_R11W,
|
||||
ZYDIS_REGISTER_R12W, ZYDIS_REGISTER_R13W, ZYDIS_REGISTER_R14W, ZYDIS_REGISTER_R15W,
|
||||
// General purpose registers 8-bit
|
||||
ZYDIS_REGISTER_AL, ZYDIS_REGISTER_CL, ZYDIS_REGISTER_DL, ZYDIS_REGISTER_BL,
|
||||
ZYDIS_REGISTER_AH, ZYDIS_REGISTER_CH, ZYDIS_REGISTER_DH, ZYDIS_REGISTER_BH,
|
||||
ZYDIS_REGISTER_SPL, ZYDIS_REGISTER_BPL, ZYDIS_REGISTER_SIL, ZYDIS_REGISTER_DIL,
|
||||
ZYDIS_REGISTER_R8B, ZYDIS_REGISTER_R9B, ZYDIS_REGISTER_R10B, ZYDIS_REGISTER_R11B,
|
||||
ZYDIS_REGISTER_R12B, ZYDIS_REGISTER_R13B, ZYDIS_REGISTER_R14B, ZYDIS_REGISTER_R15B,
|
||||
// Floating point legacy registers
|
||||
ZYDIS_REGISTER_ST0, ZYDIS_REGISTER_ST1, ZYDIS_REGISTER_ST2, ZYDIS_REGISTER_ST3,
|
||||
ZYDIS_REGISTER_ST4, ZYDIS_REGISTER_ST5, ZYDIS_REGISTER_ST6, ZYDIS_REGISTER_ST7,
|
||||
// Floating point multimedia registers
|
||||
ZYDIS_REGISTER_MM0, ZYDIS_REGISTER_MM1, ZYDIS_REGISTER_MM2, ZYDIS_REGISTER_MM3,
|
||||
ZYDIS_REGISTER_MM4, ZYDIS_REGISTER_MM5, ZYDIS_REGISTER_MM6, ZYDIS_REGISTER_MM7,
|
||||
// Floating point vector registers 512-bit
|
||||
ZYDIS_REGISTER_ZMM0, ZYDIS_REGISTER_ZMM1, ZYDIS_REGISTER_ZMM2, ZYDIS_REGISTER_ZMM3,
|
||||
ZYDIS_REGISTER_ZMM4, ZYDIS_REGISTER_ZMM5, ZYDIS_REGISTER_ZMM6, ZYDIS_REGISTER_ZMM7,
|
||||
ZYDIS_REGISTER_ZMM8, ZYDIS_REGISTER_ZMM9, ZYDIS_REGISTER_ZMM10, ZYDIS_REGISTER_ZMM11,
|
||||
ZYDIS_REGISTER_ZMM12, ZYDIS_REGISTER_ZMM13, ZYDIS_REGISTER_ZMM14, ZYDIS_REGISTER_ZMM15,
|
||||
ZYDIS_REGISTER_ZMM16, ZYDIS_REGISTER_ZMM17, ZYDIS_REGISTER_ZMM18, ZYDIS_REGISTER_ZMM19,
|
||||
ZYDIS_REGISTER_ZMM20, ZYDIS_REGISTER_ZMM21, ZYDIS_REGISTER_ZMM22, ZYDIS_REGISTER_ZMM23,
|
||||
ZYDIS_REGISTER_ZMM24, ZYDIS_REGISTER_ZMM25, ZYDIS_REGISTER_ZMM26, ZYDIS_REGISTER_ZMM27,
|
||||
ZYDIS_REGISTER_ZMM28, ZYDIS_REGISTER_ZMM29, ZYDIS_REGISTER_ZMM30, ZYDIS_REGISTER_ZMM31,
|
||||
// Floating point vector registers 256-bit
|
||||
ZYDIS_REGISTER_YMM0, ZYDIS_REGISTER_YMM1, ZYDIS_REGISTER_YMM2, ZYDIS_REGISTER_YMM3,
|
||||
ZYDIS_REGISTER_YMM4, ZYDIS_REGISTER_YMM5, ZYDIS_REGISTER_YMM6, ZYDIS_REGISTER_YMM7,
|
||||
ZYDIS_REGISTER_YMM8, ZYDIS_REGISTER_YMM9, ZYDIS_REGISTER_YMM10, ZYDIS_REGISTER_YMM11,
|
||||
ZYDIS_REGISTER_YMM12, ZYDIS_REGISTER_YMM13, ZYDIS_REGISTER_YMM14, ZYDIS_REGISTER_YMM15,
|
||||
ZYDIS_REGISTER_YMM16, ZYDIS_REGISTER_YMM17, ZYDIS_REGISTER_YMM18, ZYDIS_REGISTER_YMM19,
|
||||
ZYDIS_REGISTER_YMM20, ZYDIS_REGISTER_YMM21, ZYDIS_REGISTER_YMM22, ZYDIS_REGISTER_YMM23,
|
||||
ZYDIS_REGISTER_YMM24, ZYDIS_REGISTER_YMM25, ZYDIS_REGISTER_YMM26, ZYDIS_REGISTER_YMM27,
|
||||
ZYDIS_REGISTER_YMM28, ZYDIS_REGISTER_YMM29, ZYDIS_REGISTER_YMM30, ZYDIS_REGISTER_YMM31,
|
||||
// Floating point vector registers 128-bit
|
||||
ZYDIS_REGISTER_XMM0, ZYDIS_REGISTER_XMM1, ZYDIS_REGISTER_XMM2, ZYDIS_REGISTER_XMM3,
|
||||
ZYDIS_REGISTER_XMM4, ZYDIS_REGISTER_XMM5, ZYDIS_REGISTER_XMM6, ZYDIS_REGISTER_XMM7,
|
||||
ZYDIS_REGISTER_XMM8, ZYDIS_REGISTER_XMM9, ZYDIS_REGISTER_XMM10, ZYDIS_REGISTER_XMM11,
|
||||
ZYDIS_REGISTER_XMM12, ZYDIS_REGISTER_XMM13, ZYDIS_REGISTER_XMM14, ZYDIS_REGISTER_XMM15,
|
||||
ZYDIS_REGISTER_XMM16, ZYDIS_REGISTER_XMM17, ZYDIS_REGISTER_XMM18, ZYDIS_REGISTER_XMM19,
|
||||
ZYDIS_REGISTER_XMM20, ZYDIS_REGISTER_XMM21, ZYDIS_REGISTER_XMM22, ZYDIS_REGISTER_XMM23,
|
||||
ZYDIS_REGISTER_XMM24, ZYDIS_REGISTER_XMM25, ZYDIS_REGISTER_XMM26, ZYDIS_REGISTER_XMM27,
|
||||
ZYDIS_REGISTER_XMM28, ZYDIS_REGISTER_XMM29, ZYDIS_REGISTER_XMM30, ZYDIS_REGISTER_XMM31,
|
||||
// Special registers
|
||||
ZYDIS_REGISTER_RFLAGS, ZYDIS_REGISTER_EFLAGS, ZYDIS_REGISTER_FLAGS, ZYDIS_REGISTER_RIP,
|
||||
ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_IP,
|
||||
// Segment registers
|
||||
ZYDIS_REGISTER_ES, ZYDIS_REGISTER_SS, ZYDIS_REGISTER_CS, ZYDIS_REGISTER_DS,
|
||||
ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS,
|
||||
// Control registers
|
||||
ZYDIS_REGISTER_CR0, ZYDIS_REGISTER_CR1, ZYDIS_REGISTER_CR2, ZYDIS_REGISTER_CR3,
|
||||
ZYDIS_REGISTER_CR4, ZYDIS_REGISTER_CR5, ZYDIS_REGISTER_CR6, ZYDIS_REGISTER_CR7,
|
||||
ZYDIS_REGISTER_CR8, ZYDIS_REGISTER_CR9, ZYDIS_REGISTER_CR10, ZYDIS_REGISTER_CR11,
|
||||
ZYDIS_REGISTER_CR12, ZYDIS_REGISTER_CR13, ZYDIS_REGISTER_CR14, ZYDIS_REGISTER_CR15,
|
||||
// Debug registers
|
||||
ZYDIS_REGISTER_DR0, ZYDIS_REGISTER_DR1, ZYDIS_REGISTER_DR2, ZYDIS_REGISTER_DR3,
|
||||
ZYDIS_REGISTER_DR4, ZYDIS_REGISTER_DR5, ZYDIS_REGISTER_DR6, ZYDIS_REGISTER_DR7,
|
||||
ZYDIS_REGISTER_DR8, ZYDIS_REGISTER_DR9, ZYDIS_REGISTER_DR10, ZYDIS_REGISTER_DR11,
|
||||
ZYDIS_REGISTER_DR12, ZYDIS_REGISTER_DR13, ZYDIS_REGISTER_DR14, ZYDIS_REGISTER_DR15,
|
||||
// Mask registers
|
||||
ZYDIS_REGISTER_K0, ZYDIS_REGISTER_K1, ZYDIS_REGISTER_K2, ZYDIS_REGISTER_K3,
|
||||
ZYDIS_REGISTER_K4, ZYDIS_REGISTER_K5, ZYDIS_REGISTER_K6, ZYDIS_REGISTER_K7,
|
||||
// Bounds registers
|
||||
ZYDIS_REGISTER_BND0, ZYDIS_REGISTER_BND1, ZYDIS_REGISTER_BND2, ZYDIS_REGISTER_BND3
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisRegisterClass datatype.
|
||||
*/
|
||||
typedef uint8_t ZydisRegisterClass;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis register-classes.
|
||||
*/
|
||||
enum ZydisRegisterClasses
|
||||
{
|
||||
ZYDIS_REGISTERCLASS_INVALID,
|
||||
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8,
|
||||
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16,
|
||||
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32,
|
||||
ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64,
|
||||
ZYDIS_REGISTERCLASS_FLOATING_POINT,
|
||||
ZYDIS_REGISTERCLASS_MULTIMEDIA,
|
||||
ZYDIS_REGISTERCLASS_VECTOR128,
|
||||
ZYDIS_REGISTERCLASS_VECTOR256,
|
||||
ZYDIS_REGISTERCLASS_VECTOR512,
|
||||
ZYDIS_REGISTERCLASS_FLAGS,
|
||||
ZYDIS_REGISTERCLASS_IP,
|
||||
ZYDIS_REGISTERCLASS_SEGMENT,
|
||||
ZYDIS_REGISTERCLASS_CONTROL,
|
||||
ZYDIS_REGISTERCLASS_DEBUG,
|
||||
ZYDIS_REGISTERCLASS_MASK,
|
||||
ZYDIS_REGISTERCLASS_BOUNDS
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisRegisterSize datatype.
|
||||
*/
|
||||
typedef uint32_t ZydisRegisterSize;
|
||||
|
||||
/**
|
||||
* @brief Values that represent zydis register-sizes.
|
||||
*/
|
||||
enum ZydisRegisterSizes
|
||||
{
|
||||
ZYDIS_REGISTERSIZE_INVALID = 0,
|
||||
ZYDIS_REGISTERSIZE_DYNAMIC = 1,
|
||||
ZYDIS_REGISTERSIZE_8 = 8,
|
||||
ZYDIS_REGISTERSIZE_16 = 16,
|
||||
ZYDIS_REGISTERSIZE_32 = 32,
|
||||
ZYDIS_REGISTERSIZE_64 = 64,
|
||||
ZYDIS_REGISTERSIZE_80 = 80,
|
||||
ZYDIS_REGISTERSIZE_128 = 128,
|
||||
ZYDIS_REGISTERSIZE_256 = 256,
|
||||
ZYDIS_REGISTERSIZE_512 = 512
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Returns the register specified by the @c registerClass and the @c id.
|
||||
*
|
||||
* @param registerClass The register class.
|
||||
* @param id The register id.
|
||||
*
|
||||
* @return The register specified by the @c registerClass and the @c id.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id);
|
||||
|
||||
/**
|
||||
* @brief Returns the specified register string.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return The register string or @c NULL, if an invalid register was passed.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN const char* ZydisRegisterGetString(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Returns the register-class of the specified register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return The register-class of the specified register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Returns the size of the specified register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return The size of the specified register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a general purpose register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsGPR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 8-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 8-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsGPR8(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 16-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 16-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsGPR16(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 32-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 32-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsGPR32(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 64-bit general purpose register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 64-bit general purpose register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsGPR64(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a legacy floating-point register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a legacy floating-point register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsFPRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a multi-media register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a multi-media register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsMMRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a vector register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsVR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 128-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 128-bit vector register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsVR128(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 256-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 256-bit vector register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsVR256(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a 512-bit vector register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a 512-bit vector register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsVR512(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a flags register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a flags register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsFlagsRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is an instruction-pointer register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a instruction-pointer register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsIPRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a segment register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a segment register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsSegmentRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a control register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a control register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsCR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a debug register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a debug register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsDR(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a mask register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a mask register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsMaskRegister(ZydisRegister reg);
|
||||
|
||||
/**
|
||||
* @brief Checks if the specified register is a bound register.
|
||||
*
|
||||
* @param reg The register.
|
||||
*
|
||||
* @return True, if the specified register is a bound register.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN bool ZydisRegisterIsBoundsRegister(ZydisRegister reg);
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_REGISTER_H */
|
|
@ -0,0 +1,99 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_STATUS_H
|
||||
#define ZYDIS_STATUS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Enums and types */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisStatus datatype.
|
||||
*/
|
||||
typedef uint32_t ZydisStatus;
|
||||
|
||||
/**
|
||||
* @brief Values that represent a zydis status-codes.
|
||||
*/
|
||||
enum ZydisStatusCode
|
||||
{
|
||||
/**
|
||||
* @brief The operation completed successfully.
|
||||
*/
|
||||
ZYDIS_STATUS_SUCCESS = 0x00000000,
|
||||
/**
|
||||
* @brief An invalid parameter was passed to a function.
|
||||
*/
|
||||
ZYDIS_STATUS_INVALID_PARAMETER = 0x00000001,
|
||||
/**
|
||||
* @brief An attempt was made to perform an invalid operation.
|
||||
*/
|
||||
ZYDIS_STATUS_INVALID_OPERATION = 0x00000002,
|
||||
/**
|
||||
* @brief An attempt was made to read data from an input data-source that has no more data
|
||||
* available.
|
||||
*/
|
||||
ZYDIS_STATUS_NO_MORE_DATA = 0x00000003,
|
||||
/**
|
||||
* @brief An error occured while decoding the current instruction. Check the @c flags field
|
||||
* of the @c ZydisInstructionInfo struct for further details.
|
||||
*/
|
||||
ZYDIS_STATUS_INVALID_INSTRUCTION = 0x00000004, // TODO: Rename
|
||||
/**
|
||||
* @brief A buffer passed to a function was too small to complete the requested operation.
|
||||
*/
|
||||
ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE = 0x00000008,
|
||||
/**
|
||||
* @brief The start range of user defined status-codes.
|
||||
*/
|
||||
ZYDIS_STATUS_USER = 0x10000000 // TODO: Remove
|
||||
};
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Macros */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Checks a zydis status code for success.
|
||||
*
|
||||
* @param status The status code.
|
||||
*/
|
||||
#define ZYDIS_SUCCESS(status) (status == ZYDIS_STATUS_SUCCESS)
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_STATUS_H */
|
|
@ -0,0 +1,71 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_SYMBOLRESOLVER_H
|
||||
#define ZYDIS_SYMBOLRESOLVER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Custom resolver */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Enums and types */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Defines the @c ZydisResolverResolveSymbolFunc function pointer used in the
|
||||
* @c ZydisCustomSymbolResolver struct.
|
||||
*
|
||||
* This function should return the name of the symbol found at the given @c address and an
|
||||
* optional @c offset.
|
||||
*/
|
||||
typedef const char* (*ZydisResolverResolveSymbolFunc)(void* context,
|
||||
const ZydisInstructionInfo* info, const ZydisOperandInfo* operand, uint64_t address,
|
||||
int64_t* offset);
|
||||
|
||||
typedef struct ZydisCustomSymbolResolver_
|
||||
{
|
||||
ZydisResolverResolveSymbolFunc resolveSymbol;
|
||||
} ZydisCustomSymbolResolver;
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_SYMBOLRESOLVER_H */
|
|
@ -0,0 +1,67 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_UTILS_H
|
||||
#define ZYDIS_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Operand utils */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Calculates the absolute target-address of an relative instruction operand.
|
||||
*
|
||||
* @param info A pointer to the instruction-info struct.
|
||||
* @param operand A pointer to the operand-info struct.
|
||||
* @param address A pointer to the memory address that receives the absolute target-address.
|
||||
*
|
||||
* @return A zydis status code
|
||||
*/
|
||||
ZYDIS_DLLEXTERN ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info,
|
||||
const ZydisOperandInfo* operand, uint64_t* address);
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_UTILS_H */
|
|
@ -0,0 +1,110 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#ifndef ZYDIS_H
|
||||
#define ZYDIS_H
|
||||
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/Mnemonic.h>
|
||||
#include <Zydis/Register.h>
|
||||
#include <Zydis/InstructionInfo.h>
|
||||
#include <Zydis/Input.h>
|
||||
#include <Zydis/Decoder.h>
|
||||
#include <Zydis/Formatter.h>
|
||||
#include <Zydis/SymbolResolver.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Macros */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Constants */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief A macro that defines zydis version.
|
||||
*/
|
||||
#define ZYDIS_VERSION 0x0002000000000000
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Helper macros */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Extracts the major-part of the zydis version.
|
||||
*
|
||||
* @param version The zydis version value
|
||||
*/
|
||||
#define ZYDIS_VERSION_MAJOR(version) (uint16_t)((version & 0xFFFF000000000000) >> 48)
|
||||
|
||||
/**
|
||||
* @brief Extracts the minor-part of the zydis version.
|
||||
*
|
||||
* @param version The zydis version value
|
||||
*/
|
||||
#define ZYDIS_VERSION_MINOR(version) (uint16_t)((version & 0x0000FFFF00000000) >> 32)
|
||||
|
||||
/**
|
||||
* @brief Extracts the patch-part of the zydis version.
|
||||
*
|
||||
* @param version The zydis version value
|
||||
*/
|
||||
#define ZYDIS_VERSION_PATCH(version) (uint16_t)((version & 0x00000000FFFF0000) >> 16)
|
||||
|
||||
/**
|
||||
* @brief Extracts the build-part of the zydis version.
|
||||
*
|
||||
* @param version The zydis version value
|
||||
*/
|
||||
#define ZYDIS_VERSION_BUILD(version) (uint16_t)(version & 0x000000000000FFFF)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/**
|
||||
* @brief Returns the zydis version.
|
||||
*
|
||||
* @return The zydis version.
|
||||
*
|
||||
* Use the macros provided in this file to extract the major, minor, patch and build part from the
|
||||
* returned version value.
|
||||
*/
|
||||
ZYDIS_DLLEXTERN uint64_t ZydisGetVersion();
|
||||
|
||||
/* ============================================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZYDIS_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,685 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/Formatter.h>
|
||||
#include <Zydis/SymbolResolver.h>
|
||||
#include <Zydis/Utils.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Internal macros */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Helper macros */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
#define ZYDIS_CHECK(status) \
|
||||
if (status != ZYDIS_STATUS_SUCCESS) \
|
||||
{ \
|
||||
return status; \
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Instruction formatter */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Internal functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @brief Inserts the @c text into the @c buffer at the given @c offset and increases the
|
||||
* @c offset by the length of the text.
|
||||
*
|
||||
* @param buffer A pointer to the target buffer.
|
||||
* @param bufferLen The length of the buffer.
|
||||
* @param offset A pointer to the buffer-offset.
|
||||
* @param text The text to insert.
|
||||
* @param uppercase Set true, to convert to uppercase characters.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
static ZydisStatus ZydisBufferAppend(char* buffer, size_t bufferLen, size_t* offset,
|
||||
bool uppercase, const char* text)
|
||||
{
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen != 0);
|
||||
ZYDIS_ASSERT(offset);
|
||||
ZYDIS_ASSERT(text);
|
||||
|
||||
size_t strLen = strlen(text);
|
||||
if ((*offset + strLen) >= bufferLen)
|
||||
{
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
strncpy(&buffer[*offset], text, strLen + 1);
|
||||
if (uppercase)
|
||||
{
|
||||
for (size_t i = *offset; i < *offset + strLen; ++i)
|
||||
{
|
||||
buffer[i] = (char)toupper(buffer[i]);
|
||||
}
|
||||
}
|
||||
*offset += strLen;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inserts formatted text into the @c buffer at the given @c offset and increases the
|
||||
* @c offset by the length of the text.
|
||||
*
|
||||
* @param buffer A pointer to the target buffer.
|
||||
* @param bufferLen The length of the buffer.
|
||||
* @param offset A pointer to the buffer-offset.
|
||||
* @param format The format string.
|
||||
*
|
||||
* @return A zydis status code.
|
||||
*/
|
||||
static ZydisStatus ZydisBufferAppendFormat(char* buffer, size_t bufferLen, size_t* offset,
|
||||
bool uppercase, const char* format, ...)
|
||||
{
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen != 0);
|
||||
ZYDIS_ASSERT(offset);
|
||||
ZYDIS_ASSERT(format);
|
||||
|
||||
va_list arglist;
|
||||
va_start(arglist, format);
|
||||
size_t n = bufferLen - *offset;
|
||||
int w = vsnprintf(&buffer[*offset], n, format, arglist);
|
||||
if ((w < 0) || ((size_t)w >= n))
|
||||
{
|
||||
va_end(arglist);
|
||||
return ZYDIS_STATUS_INSUFFICIENT_BUFFER_SIZE;
|
||||
}
|
||||
if (uppercase)
|
||||
{
|
||||
for (size_t i = *offset; i < *offset + (size_t)w; ++i)
|
||||
{
|
||||
buffer[i] = (char)toupper(buffer[i]);
|
||||
}
|
||||
}
|
||||
*offset += (size_t)w;
|
||||
va_end(arglist);
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
static ZydisStatus ZydisBufferAppendAbsoluteAddress(const ZydisInstructionFormatter* formatter,
|
||||
char* buffer, size_t bufferLen, size_t* offset, const ZydisInstructionInfo* info,
|
||||
const ZydisOperandInfo* operand)
|
||||
{
|
||||
ZYDIS_ASSERT(formatter);
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen != 0);
|
||||
ZYDIS_ASSERT(offset);
|
||||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(operand);
|
||||
ZYDIS_ASSERT((operand->type == ZYDIS_OPERAND_TYPE_MEMORY) ||
|
||||
(operand->type == ZYDIS_OPERAND_TYPE_IMMEDIATE));
|
||||
|
||||
uint64_t address = 0;
|
||||
switch (operand->type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
ZYDIS_ASSERT(operand->mem.disp.size != 0);
|
||||
if ((operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(info, operand, &address));
|
||||
} else
|
||||
{
|
||||
ZYDIS_ASSERT(operand->mem.base == ZYDIS_REGISTER_NONE);
|
||||
ZYDIS_ASSERT(operand->mem.index == ZYDIS_REGISTER_NONE);
|
||||
ZYDIS_ASSERT(operand->mem.scale == 0);
|
||||
address = (uint64_t)operand->mem.disp.value.sqword;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
ZYDIS_CHECK(ZydisUtilsCalcAbsoluteTargetAddress(info, operand, &address));
|
||||
break;
|
||||
}
|
||||
|
||||
const char* symbol = NULL;
|
||||
int64_t symbolOffset = 0;
|
||||
if (formatter->symbolResolver)
|
||||
{
|
||||
symbol = formatter->symbolResolver->resolveSymbol(formatter->symbolResolver, info, operand,
|
||||
address, &symbolOffset);
|
||||
}
|
||||
if (symbol)
|
||||
{
|
||||
if (symbolOffset == 0)
|
||||
{
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset, false, "%s", symbol);
|
||||
}
|
||||
if (symbolOffset > 0)
|
||||
{
|
||||
return ZydisBufferAppendFormat(
|
||||
buffer, bufferLen, offset, false, "%s+0x%02llX", symbol, symbolOffset);
|
||||
}
|
||||
if (symbolOffset < 0)
|
||||
{
|
||||
return ZydisBufferAppendFormat(
|
||||
buffer, bufferLen, offset, false, "%s-0x%02llX", symbol, -symbolOffset);
|
||||
}
|
||||
}
|
||||
if (info->operandMode == 16)
|
||||
{
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address);
|
||||
}
|
||||
switch (info->mode)
|
||||
{
|
||||
case ZYDIS_DISASSEMBLER_MODE_16BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%04X", address);
|
||||
case ZYDIS_DISASSEMBLER_MODE_32BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%08lX", address);
|
||||
case ZYDIS_DISASSEMBLER_MODE_64BIT:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%016llX", address);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisBufferAppendImmediate(const ZydisInstructionFormatter* formatter,
|
||||
char* buffer, size_t bufferLen, size_t* offset, const ZydisInstructionInfo* info,
|
||||
const ZydisOperandInfo* operand)
|
||||
{
|
||||
ZYDIS_ASSERT(formatter);
|
||||
ZYDIS_ASSERT(buffer);
|
||||
ZYDIS_ASSERT(bufferLen != 0);
|
||||
ZYDIS_ASSERT(offset);
|
||||
ZYDIS_ASSERT(info);
|
||||
ZYDIS_ASSERT(operand);
|
||||
|
||||
if ((formatter->addressFormat == ZYDIS_FORMATTER_ADDRESS_ABSOLUTE) &&
|
||||
(operand->imm.isRelative))
|
||||
{
|
||||
return ZydisBufferAppendAbsoluteAddress(formatter, buffer, bufferLen, offset, info,
|
||||
operand);
|
||||
}
|
||||
|
||||
bool useSignedHex = ((operand->imm.isSigned &&
|
||||
(formatter->addressFormat == ZYDIS_FORMATTER_ADDRESS_RELATIVE_SIGNED)) ||
|
||||
(!operand->imm.isSigned && (formatter->immediateFormat == ZYDIS_FORMATTER_IMM_HEX_SIGNED)));
|
||||
|
||||
if (useSignedHex && (operand->imm.value.sqword < 0))
|
||||
{
|
||||
switch (operand->size)
|
||||
{
|
||||
case 8:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "-0x%02X",
|
||||
-operand->imm.value.sbyte);
|
||||
case 16:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "-0x%02X",
|
||||
-operand->imm.value.sword);
|
||||
case 32:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "-0x%02lX",
|
||||
-operand->imm.value.sdword);
|
||||
case 64:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "-0x%02llX",
|
||||
-operand->imm.value.sqword);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
switch (operand->size)
|
||||
{
|
||||
case 8:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%02X",
|
||||
operand->imm.value.ubyte);
|
||||
case 16:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%02X",
|
||||
operand->imm.value.uword);
|
||||
case 32:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%02lX",
|
||||
operand->imm.value.udword);
|
||||
case 64:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%02llX",
|
||||
operand->imm.value.uqword);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
static ZydisStatus ZydisBufferAppendOperandIntelMemory(const ZydisInstructionFormatter* formatter,
|
||||
char* buffer, size_t bufferLen, size_t* offset, const ZydisInstructionInfo* info,
|
||||
const ZydisOperandInfo* operand, uint16_t typecast)
|
||||
{
|
||||
if (typecast)
|
||||
{
|
||||
char* str = "";
|
||||
switch (typecast)
|
||||
{
|
||||
case 8:
|
||||
str = "byte ptr ";
|
||||
break;
|
||||
case 16:
|
||||
str = "word ptr ";
|
||||
break;
|
||||
case 32:
|
||||
str = "dword ptr ";
|
||||
break;
|
||||
case 48:
|
||||
str = "fword ptr ";
|
||||
break;
|
||||
case 64:
|
||||
str = "qword ptr ";
|
||||
break;
|
||||
case 80:
|
||||
str = "tbyte ptr ";
|
||||
break;
|
||||
case 128:
|
||||
str = "xmmword ptr ";
|
||||
break;
|
||||
case 256:
|
||||
str = "ymmword ptr ";
|
||||
break;
|
||||
case 512:
|
||||
str = "zmmword ptr ";
|
||||
break;
|
||||
}
|
||||
ZYDIS_CHECK(ZydisBufferAppend(
|
||||
buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), str));
|
||||
}
|
||||
if (operand->mem.segment != ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
if ((formatter->flags & ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT) ||
|
||||
(((operand->mem.segment != ZYDIS_REGISTER_DS) ||
|
||||
(info->prefixFlags & ZYDIS_PREFIX_SEGMENT_DS)) &&
|
||||
((operand->mem.segment != ZYDIS_REGISTER_SS) ||
|
||||
(info->prefixFlags & ZYDIS_PREFIX_SEGMENT_SS))))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "%s:",
|
||||
ZydisRegisterGetString(operand->mem.segment)));
|
||||
}
|
||||
}
|
||||
ZYDIS_CHECK(ZydisBufferAppend(
|
||||
buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "["));
|
||||
if ((operand->mem.disp.size != 0) && ((operand->mem.base == ZYDIS_REGISTER_NONE) ||
|
||||
(operand->mem.base == ZYDIS_REGISTER_EIP) || (operand->mem.base == ZYDIS_REGISTER_RIP)) &&
|
||||
(operand->mem.index == ZYDIS_REGISTER_NONE) && (operand->mem.scale == 0))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppendAbsoluteAddress(formatter, buffer, bufferLen, offset, info,
|
||||
operand));
|
||||
} else
|
||||
{
|
||||
if (operand->mem.base != ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE),
|
||||
ZydisRegisterGetString(operand->mem.base)));
|
||||
}
|
||||
if (operand->mem.index != ZYDIS_REGISTER_NONE)
|
||||
{
|
||||
const char* c = (operand->mem.base != ZYDIS_REGISTER_NONE) ? "+" : "";
|
||||
ZYDIS_CHECK(ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "%s%s", c,
|
||||
ZydisRegisterGetString(operand->mem.index)));
|
||||
if (operand->mem.scale)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "*%d",
|
||||
operand->mem.scale));
|
||||
}
|
||||
}
|
||||
if ((operand->mem.disp.size) && ((operand->mem.disp.value.sqword) ||
|
||||
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
|
||||
(operand->mem.index == ZYDIS_REGISTER_NONE))))
|
||||
{
|
||||
if ((operand->mem.disp.value.sqword < 0) && (
|
||||
(operand->mem.base != ZYDIS_REGISTER_NONE) ||
|
||||
(operand->mem.index != ZYDIS_REGISTER_NONE)))
|
||||
{
|
||||
ZYDIS_CHECK(
|
||||
ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "-0x%02llX",
|
||||
-operand->mem.disp.value.sqword));
|
||||
} else
|
||||
{
|
||||
const char* sign =
|
||||
((operand->mem.base == ZYDIS_REGISTER_NONE) &&
|
||||
(operand->mem.index == ZYDIS_REGISTER_NONE)) ? "" : "+";
|
||||
ZYDIS_CHECK(
|
||||
ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "%s0x%02llX",
|
||||
sign, operand->mem.disp.value.sqword));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ZydisBufferAppend(
|
||||
buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "]");
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Intel style */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
static ZydisStatus ZydisBufferAppendOperandIntel(const ZydisInstructionFormatter* formatter,
|
||||
char* buffer, size_t bufferLen, size_t* offset, const ZydisInstructionInfo* info,
|
||||
const ZydisOperandInfo* operand, uint16_t typecast)
|
||||
{
|
||||
switch (operand->type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER:
|
||||
{
|
||||
const char* reg = ZydisRegisterGetString(operand->reg);
|
||||
if (!reg)
|
||||
{
|
||||
reg = "invalid";
|
||||
}
|
||||
return ZydisBufferAppend(
|
||||
buffer, bufferLen, offset, (formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), reg);
|
||||
}
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
return ZydisBufferAppendOperandIntelMemory(formatter, buffer, bufferLen, offset, info,
|
||||
operand, typecast);
|
||||
case ZYDIS_OPERAND_TYPE_POINTER:
|
||||
return ZydisBufferAppendFormat(buffer, bufferLen, offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "0x%02X:0x%02lX",
|
||||
operand->ptr.segment, operand->ptr.offset);
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
return ZydisBufferAppendImmediate(formatter, buffer, bufferLen, offset, info, operand);
|
||||
}
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
static ZydisStatus ZydisFormatterFormatInstructionIntel(ZydisInstructionFormatter* formatter,
|
||||
const ZydisInstructionInfo* info, char* buffer, size_t bufferLen)
|
||||
{
|
||||
size_t offset = 0;
|
||||
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_REPNE) &&
|
||||
(info->prefixFlags & ZYDIS_PREFIX_REPNE))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "repne "));
|
||||
}
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_REP) && (info->prefixFlags & ZYDIS_PREFIX_REP))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "rep "));
|
||||
}
|
||||
if ((info->prefixFlags & ZYDIS_PREFIX_ACCEPTS_LOCK) && (info->prefixFlags & ZYDIS_PREFIX_LOCK))
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "lock "));
|
||||
}
|
||||
if (info->prefixFlags & ZYDIS_PREFIX_XACQUIRE)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xacquire "));
|
||||
} else if (info->prefixFlags & ZYDIS_PREFIX_XRELEASE)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "xrelease "));
|
||||
}
|
||||
|
||||
const char* mnemonic = ZydisMnemonicGetString(info->mnemonic);
|
||||
if (!mnemonic)
|
||||
{
|
||||
mnemonic = "invalid";
|
||||
}
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), mnemonic));
|
||||
|
||||
uint16_t typecast = 0;
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (info->operand[i].type == ZYDIS_OPERAND_TYPE_UNUSED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
if (formatter->flags & ZYDIS_FORMATTER_FLAG_TAB_AFTER_MNEMONIC)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), "\t"));
|
||||
} else
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " "));
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (formatter->flags & ZYDIS_FORMATTER_FLAG_NO_SPACE_BETWEEN_OPERANDS)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), ","));
|
||||
} else
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), ", "));
|
||||
}
|
||||
}
|
||||
if (formatter->flags & ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SIZE)
|
||||
{
|
||||
if (info->operand[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
typecast = info->operand[i].size;
|
||||
}
|
||||
} else if (info->operand[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
typecast = ((info->operand[1].type == ZYDIS_OPERAND_TYPE_UNUSED) ||
|
||||
(info->operand[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE) ||
|
||||
(info->operand[0].size != info->operand[1].size)) ? info->operand[0].size : 0;
|
||||
if (!typecast && (info->operand[1].type == ZYDIS_OPERAND_TYPE_REGISTER) &&
|
||||
(info->operand[1].reg == ZYDIS_REGISTER_CL))
|
||||
{
|
||||
switch (info->mnemonic)
|
||||
{
|
||||
case ZYDIS_MNEMONIC_RCL:
|
||||
case ZYDIS_MNEMONIC_ROL:
|
||||
case ZYDIS_MNEMONIC_ROR:
|
||||
case ZYDIS_MNEMONIC_RCR:
|
||||
case ZYDIS_MNEMONIC_SHL:
|
||||
case ZYDIS_MNEMONIC_SHR:
|
||||
case ZYDIS_MNEMONIC_SAR:
|
||||
typecast = info->operand[0].size;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
typecast = (info->operand[i - 1].size != info->operand[i].size) ?
|
||||
info->operand[i - 1].size : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZYDIS_CHECK(ZydisBufferAppendOperandIntel(formatter, buffer, bufferLen, &offset, info,
|
||||
&info->operand[i], typecast));
|
||||
if (info->encoding == ZYDIS_INSTRUCTION_ENCODING_EVEX)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if (info->avx.maskRegister)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppendFormat(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {%s}",
|
||||
ZydisRegisterGetString(info->avx.maskRegister)));
|
||||
}
|
||||
if (info->avx.maskMode == ZYDIS_AVX_MASKMODE_ZERO)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {z}"));
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (info->operand[i].type == ZYDIS_OPERAND_TYPE_MEMORY)
|
||||
{
|
||||
switch (info->avx.broadcast)
|
||||
{
|
||||
case ZYDIS_AVX_BCSTMODE_2:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {1to2}"));
|
||||
break;
|
||||
case ZYDIS_AVX_BCSTMODE_4:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {1to4}"));
|
||||
break;
|
||||
case ZYDIS_AVX_BCSTMODE_8:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {1to8}"));
|
||||
break;
|
||||
case ZYDIS_AVX_BCSTMODE_16:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {1to16}"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((i == (info->operandCount - 1)) || ((i != (info->operandCount - 1)) &&
|
||||
(info->operand[i + 1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE)))
|
||||
{
|
||||
switch (info->avx.roundingMode)
|
||||
{
|
||||
case ZYDIS_AVX_RNDMODE_INVALID:
|
||||
if (info->avx.sae)
|
||||
{
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {sae}"));
|
||||
}
|
||||
break;
|
||||
case ZYDIS_AVX_RNDMODE_RN:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {rn-sae}"));
|
||||
break;
|
||||
case ZYDIS_AVX_RNDMODE_RD:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {rd-sae}"));
|
||||
break;
|
||||
case ZYDIS_AVX_RNDMODE_RU:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {ru-sae}"));
|
||||
break;
|
||||
case ZYDIS_AVX_RNDMODE_RZ:
|
||||
ZYDIS_CHECK(ZydisBufferAppend(buffer, bufferLen, &offset,
|
||||
(formatter->flags & ZYDIS_FORMATTER_FLAG_UPPERCASE), " {rz-sae}"));
|
||||
break;
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZydisStatus ZydisFormatterInitInstructionFormatter(ZydisInstructionFormatter* formatter,
|
||||
ZydisFormatterStyle style)
|
||||
{
|
||||
return ZydisFormatterInitInstructionFormatterEx(formatter, style, 0);
|
||||
}
|
||||
|
||||
ZydisStatus ZydisFormatterInitInstructionFormatterEx(
|
||||
ZydisInstructionFormatter* formatter, ZydisFormatterStyle style, ZydisFormatterFlags flags)
|
||||
{
|
||||
if (!formatter || (style != ZYDIS_FORMATTER_STYLE_INTEL))
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
formatter->style = style;
|
||||
formatter->flags = flags;
|
||||
formatter->addressFormat = ZYDIS_FORMATTER_ADDRESS_ABSOLUTE;
|
||||
formatter->displacementFormat = ZYDIS_FORMATTER_DISP_HEX_SIGNED;
|
||||
formatter->immediateFormat = ZYDIS_FORMATTER_IMM_HEX_UNSIGNED;
|
||||
formatter->symbolResolver = NULL;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ZydisStatus ZydisFormatterGetSymbolResolver(const ZydisInstructionFormatter* formatter,
|
||||
ZydisCustomSymbolResolver** symbolResolver)
|
||||
{
|
||||
if (!formatter || !symbolResolver)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
*symbolResolver = formatter->symbolResolver;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ZydisStatus ZydisFormatterSetSymbolResolver(ZydisInstructionFormatter* formatter,
|
||||
ZydisCustomSymbolResolver* symbolResolver)
|
||||
{
|
||||
if (!formatter)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
formatter->symbolResolver = symbolResolver;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ZydisStatus ZydisFormatterFormatInstruction(ZydisInstructionFormatter* formatter,
|
||||
const ZydisInstructionInfo* info, char* buffer, size_t bufferLen)
|
||||
{
|
||||
if (!formatter || !info || !buffer || (bufferLen == 0))
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
switch (formatter->style)
|
||||
{
|
||||
case ZYDIS_FORMATTER_STYLE_INTEL:
|
||||
return ZydisFormatterFormatInstructionIntel(formatter, info, buffer, bufferLen);
|
||||
default:
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
|
@ -0,0 +1,100 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <Zydis/Status.h>
|
||||
#include <Zydis/Input.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Memory input */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Internal functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
static bool ZydisMemoryInputNext(ZydisMemoryInput* context, uint8_t* data)
|
||||
{
|
||||
if (context->inputBufferPos >= context->inputBufferLen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*data = context->inputBuffer[context->inputBufferPos++];
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZydisStatus ZydisInputInitMemoryInput(ZydisMemoryInput* input, const void* buffer, uint64_t length)
|
||||
{
|
||||
if (!input || !buffer || (length == 0))
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
input->input.inputNext = (ZydisInputNextFunc)&ZydisMemoryInputNext;
|
||||
input->inputBuffer = (uint8_t*)buffer;
|
||||
input->inputBufferLen = length;
|
||||
input->inputBufferPos = 0;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* File input */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Internal functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
static bool ZydisFileInputNext(ZydisFileInput* context, uint8_t* data)
|
||||
{
|
||||
int c = fgetc(context->file);
|
||||
*data = (uint8_t)c;
|
||||
return (c != EOF);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZydisStatus ZydisInputInitFileInput(ZydisFileInput* input, FILE* file)
|
||||
{
|
||||
if (!file)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
input->input.inputNext = (ZydisInputNextFunc)&ZydisFileInputNext;
|
||||
input->file = file;
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
|
@ -1,14 +1,8 @@
|
|||
/**************************************************************************************************
|
||||
/***************************************************************************************************
|
||||
|
||||
Verteron Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
Modifications :
|
||||
|
||||
Last change : 29. 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
|
||||
|
@ -28,13 +22,33 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
**************************************************************************************************/
|
||||
#include <tchar.h>
|
||||
#include "PugiXML/pugixml.hpp"
|
||||
#include "VXDisassemblerTypes.h"
|
||||
***************************************************************************************************/
|
||||
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
{
|
||||
// TODO:
|
||||
return 0;
|
||||
}
|
||||
#include <Zydis/Internal/InstructionTable.h>
|
||||
|
||||
#define ZYDIS_INVALID { ZYDIS_NODETYPE_INVALID, 0x00000000 }
|
||||
#define ZYDIS_FILTER(type, id) { type, id }
|
||||
#define ZYDIS_DEFINITION(id) { ZYDIS_NODETYPE_DEFINITION, id }
|
||||
|
||||
#include <Zydis/Internal/InstructionTable.inc>
|
||||
|
||||
#undef ZYDIS_INVALID
|
||||
#undef ZYDIS_FILTER
|
||||
#undef ZYDIS_DEFINITION
|
||||
|
||||
#define ZYDIS_MAKE_OPERAND(type, encoding, access) \
|
||||
(((uint16_t)type) << 8) | ((((uint16_t)encoding) & 0x3F) << 2) | (access & 0x03)
|
||||
|
||||
#define ZYDIS_MAKE_AVX512INFO(hasEvexB, hasEvexAAA, hasEvexZ) \
|
||||
((((uint8_t)hasEvexB & 0x03) << 2) | (((uint8_t)hasEvexAAA & 0x01) << 1) | (hasEvexZ & 0x01))
|
||||
|
||||
//#define ZYDIS_MAKE_DEFINITION(mnemonic, op1, op2, op3, op4, avx512info) \
|
||||
// { (((uint16_t)mnemonic & 0xFFF) << 4) | (avx512info & 0xF), { op1, op2, op3, op4 } }
|
||||
#define ZYDIS_MAKE_DEFINITION(mnemonic, operandsId, avx512info) \
|
||||
{ (((uint16_t)mnemonic & 0xFFF) << 4) | (avx512info & 0xF), operandsId }
|
||||
|
||||
#include <Zydis/Internal/InstructionDefinitions.inc>
|
||||
|
||||
#undef ZYDIS_MAKE_OPERAND
|
||||
#undef ZYDIS_MAKE_AVX512INFO
|
||||
#undef ZYDIS_MAKE_DEFINITION
|
|
@ -1,12 +1,8 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
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
|
||||
|
@ -28,46 +24,38 @@
|
|||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include "ZydisUtils.hpp"
|
||||
#include <cassert>
|
||||
#include <stddef.h>
|
||||
#include <Zydis/Defines.h>
|
||||
#include <Zydis/Mnemonic.h>
|
||||
|
||||
namespace Zydis
|
||||
/* ============================================================================================== */
|
||||
/* Mnemonic strings */
|
||||
/* ============================================================================================== */
|
||||
|
||||
static const char* mnemonicStrings[] =
|
||||
{
|
||||
#include <Zydis/Internal/MnemonicStrings.inc>
|
||||
};
|
||||
|
||||
uint64_t CalcAbsoluteTarget(const InstructionInfo& info, const OperandInfo& operand)
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
const char* ZydisMnemonicGetString(ZydisInstructionMnemonic mnemonic)
|
||||
{
|
||||
assert((operand.type == OperandType::REL_IMMEDIATE) ||
|
||||
((operand.type == OperandType::MEMORY) && (operand.base == Register::RIP)));
|
||||
|
||||
uint64_t truncMask = 0xFFFFFFFFFFFFFFFFull;
|
||||
if (!(info.flags & IF_DISASSEMBLER_MODE_64))
|
||||
if (mnemonic > (sizeof(mnemonicStrings) / sizeof(mnemonicStrings[0])) - 1)
|
||||
{
|
||||
truncMask >>= (64 - info.operand_mode);
|
||||
return NULL;
|
||||
}
|
||||
uint16_t size = operand.size;
|
||||
if ((operand.type == OperandType::MEMORY) && (operand.base == Register::RIP))
|
||||
{
|
||||
size = operand.offset;
|
||||
}
|
||||
switch (size)
|
||||
{
|
||||
case 8:
|
||||
return (info.instrPointer + operand.lval.sbyte) & truncMask;
|
||||
case 16:
|
||||
{
|
||||
uint32_t delta = operand.lval.sword & truncMask;
|
||||
if ((info.instrPointer + delta) > 0xFFFF)
|
||||
{
|
||||
return (info.instrPointer& 0xF0000) + ((info.instrPointer + delta) & 0xFFFF);
|
||||
}
|
||||
return info.instrPointer + delta;
|
||||
}
|
||||
case 32:
|
||||
return (info.instrPointer + operand.lval.sdword) & truncMask;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return 0;
|
||||
return mnemonicStrings[mnemonic];
|
||||
}
|
||||
|
||||
ZydisStatus ZydisMnemonicReplaceString(ZydisInstructionMnemonic mnemonic,
|
||||
const char* mnemonicString)
|
||||
{
|
||||
(void)mnemonic;
|
||||
(void)mnemonicString;
|
||||
return ZYDIS_STATUS_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
|
@ -0,0 +1,435 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <Zydis/Register.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Register strings */
|
||||
/* ============================================================================================== */
|
||||
|
||||
const char* registerStrings[] =
|
||||
{
|
||||
"none",
|
||||
// General purpose registers 64-bit
|
||||
"rax", "rcx", "rdx", "rbx",
|
||||
"rsp", "rbp", "rsi", "rdi",
|
||||
"r8", "r9", "r10", "r11",
|
||||
"r12", "r13", "r14", "r15",
|
||||
// General purpose registers 32-bit
|
||||
"eax", "ecx", "edx", "ebx",
|
||||
"esp", "ebp", "esi", "edi",
|
||||
"r8d", "r9d", "r10d", "r11d",
|
||||
"r12d", "r13d", "r14d", "r15d",
|
||||
// General purpose registers 16-bit
|
||||
"ax", "cx", "dx", "bx",
|
||||
"sp", "bp", "si", "di",
|
||||
"r8w", "r9w", "r10w", "r11w",
|
||||
"r12w", "r13w", "r14w", "r15w",
|
||||
// General purpose registers 8-bit
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh",
|
||||
"spl", "bpl", "sil", "dil",
|
||||
"r8b", "r9b", "r10b", "r11b",
|
||||
"r12b", "r13b", "r14b", "r15b",
|
||||
// Floating point legacy registers
|
||||
"st0", "st1", "st2", "st3",
|
||||
"st4", "st5", "st6", "st7",
|
||||
// Floating point multimedia registers
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7",
|
||||
// Floating point vector registers 512-bit
|
||||
"zmm0", "zmm1", "zmm2", "zmm3",
|
||||
"zmm4", "zmm5", "zmm6", "zmm7",
|
||||
"zmm8", "zmm9", "zmm10", "zmm11",
|
||||
"zmm12", "zmm13", "zmm14", "zmm15",
|
||||
"zmm16", "zmm17", "zmm18", "zmm19",
|
||||
"zmm20", "zmm21", "zmm22", "zmm23",
|
||||
"zmm24", "zmm25", "zmm26", "zmm27",
|
||||
"zmm28", "zmm29", "zmm30", "zmm31",
|
||||
// Floating point vector registers 256-bit
|
||||
"ymm0", "ymm1", "ymm2", "ymm3",
|
||||
"ymm4", "ymm5", "ymm6", "ymm7",
|
||||
"ymm8", "ymm9", "ymm10", "ymm11",
|
||||
"ymm12", "ymm13", "ymm14", "ymm15",
|
||||
"ymm16", "ymm17", "ymm18", "ymm19",
|
||||
"ymm20", "ymm21", "ymm22", "ymm23",
|
||||
"ymm24", "ymm25", "ymm26", "ymm27",
|
||||
"ymm28", "ymm29", "ymm30", "ymm31",
|
||||
// Floating point vector registers 128-bit
|
||||
"xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7",
|
||||
"xmm8", "xmm9", "xmm10", "xmm11",
|
||||
"xmm12", "xmm13", "xmm14", "xmm15",
|
||||
"xmm16", "xmm17", "xmm18", "xmm19",
|
||||
"xmm20", "xmm21", "xmm22", "xmm23",
|
||||
"xmm24", "xmm25", "xmm26", "xmm27",
|
||||
"xmm28", "xmm29", "xmm30", "xmm31",
|
||||
// Special registers
|
||||
"rflags", "eflags", "flags", "rip",
|
||||
"eip", "ip",
|
||||
// Segment registers
|
||||
"es", "ss", "cs", "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",
|
||||
// Mask registers
|
||||
"k0", "k1", "k2", "k3",
|
||||
"k4", "k5", "k6", "k7",
|
||||
// Bounds registers
|
||||
"bnd0", "bnd1", "bnd2", "bnd3"
|
||||
};
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
ZydisRegister ZydisRegisterGetById(ZydisRegisterClass registerClass, uint8_t id)
|
||||
{
|
||||
switch (registerClass)
|
||||
{
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
|
||||
if (id > 19)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_AL + id;
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
|
||||
if (id > 15)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_AX + id;
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32:
|
||||
if (id > 15)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_EAX + id;
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64:
|
||||
if (id > 15)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_RAX + id;
|
||||
case ZYDIS_REGISTERCLASS_FLOATING_POINT:
|
||||
if (id > 7)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_ST0 + id;
|
||||
case ZYDIS_REGISTERCLASS_MULTIMEDIA:
|
||||
if (id > 7)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_MM0 + id;
|
||||
case ZYDIS_REGISTERCLASS_VECTOR128:
|
||||
if (id > 31)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_XMM0 + id;
|
||||
case ZYDIS_REGISTERCLASS_VECTOR256:
|
||||
if (id > 31)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_YMM0 + id;
|
||||
case ZYDIS_REGISTERCLASS_VECTOR512:
|
||||
if (id > 31)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_ZMM0 + id;
|
||||
case ZYDIS_REGISTERCLASS_SEGMENT:
|
||||
if (id > 5)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_ES + id;
|
||||
case ZYDIS_REGISTERCLASS_CONTROL:
|
||||
if (id > 15)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_CR0 + id;
|
||||
case ZYDIS_REGISTERCLASS_DEBUG:
|
||||
if (id > 15)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_DR0 + id;
|
||||
case ZYDIS_REGISTERCLASS_MASK:
|
||||
if (id > 7)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_K0 + id;
|
||||
case ZYDIS_REGISTERCLASS_BOUNDS:
|
||||
if (id > 3)
|
||||
{
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
return ZYDIS_REGISTER_BND0 + id;
|
||||
case ZYDIS_REGISTERCLASS_FLAGS:
|
||||
case ZYDIS_REGISTERCLASS_IP:
|
||||
// These registers are unique
|
||||
break;
|
||||
}
|
||||
return ZYDIS_REGISTER_NONE;
|
||||
}
|
||||
|
||||
const char* ZydisRegisterGetString(ZydisRegister reg)
|
||||
{
|
||||
if ((reg == 0) || (reg > (sizeof(registerStrings) / sizeof(registerStrings[0])) - 1))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return registerStrings[reg];
|
||||
}
|
||||
|
||||
ZydisRegisterClass ZydisRegisterGetClass(ZydisRegister reg)
|
||||
{
|
||||
if ((reg >= ZYDIS_REGISTER_RAX) && (reg <= ZYDIS_REGISTER_R15))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_EAX) && (reg <= ZYDIS_REGISTER_R15D))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_AX) && (reg <= ZYDIS_REGISTER_R15W))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_AL) && (reg <= ZYDIS_REGISTER_R15B))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_ST0) && (reg <= ZYDIS_REGISTER_ST7))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_FLOATING_POINT;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_ZMM0) && (reg <= ZYDIS_REGISTER_ZMM31))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_VECTOR512;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_YMM0) && (reg <= ZYDIS_REGISTER_YMM31))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_VECTOR256;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_XMM0) && (reg <= ZYDIS_REGISTER_XMM31))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_VECTOR128;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_RFLAGS) && (reg <= ZYDIS_REGISTER_FLAGS))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_FLAGS;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_RIP) && (reg <= ZYDIS_REGISTER_IP))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_IP;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_ES) && (reg <= ZYDIS_REGISTER_GS))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_SEGMENT;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_CR0) && (reg <= ZYDIS_REGISTER_CR15))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_CONTROL;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_DR0) && (reg <= ZYDIS_REGISTER_DR15))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_DEBUG;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_K0) && (reg <= ZYDIS_REGISTER_K7))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_MASK;
|
||||
}
|
||||
if ((reg >= ZYDIS_REGISTER_BND0) && (reg <= ZYDIS_REGISTER_BND3))
|
||||
{
|
||||
return ZYDIS_REGISTERCLASS_BOUNDS;
|
||||
}
|
||||
return ZYDIS_REGISTERCLASS_INVALID;
|
||||
}
|
||||
|
||||
ZydisRegisterSize ZydisRegisterGetSize(ZydisRegister reg)
|
||||
{
|
||||
ZydisRegisterClass registerClass = ZydisRegisterGetClass(reg);
|
||||
switch (registerClass)
|
||||
{
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
|
||||
return ZYDIS_REGISTERSIZE_8;
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
|
||||
return ZYDIS_REGISTERSIZE_16;
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32:
|
||||
return ZYDIS_REGISTERSIZE_32;
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64:
|
||||
return ZYDIS_REGISTERSIZE_64;
|
||||
case ZYDIS_REGISTERCLASS_FLOATING_POINT:
|
||||
return ZYDIS_REGISTERSIZE_80;
|
||||
case ZYDIS_REGISTERCLASS_MULTIMEDIA:
|
||||
return ZYDIS_REGISTERSIZE_64;
|
||||
case ZYDIS_REGISTERCLASS_VECTOR128:
|
||||
return ZYDIS_REGISTERSIZE_128;
|
||||
case ZYDIS_REGISTERCLASS_VECTOR256:
|
||||
return ZYDIS_REGISTERSIZE_256;
|
||||
case ZYDIS_REGISTERCLASS_VECTOR512:
|
||||
return ZYDIS_REGISTERSIZE_512;
|
||||
case ZYDIS_REGISTERCLASS_FLAGS:
|
||||
return ZYDIS_REGISTERSIZE_DYNAMIC;
|
||||
case ZYDIS_REGISTERCLASS_IP:
|
||||
return ZYDIS_REGISTERSIZE_DYNAMIC;
|
||||
case ZYDIS_REGISTERCLASS_SEGMENT:
|
||||
return ZYDIS_REGISTERSIZE_16;
|
||||
case ZYDIS_REGISTERCLASS_CONTROL:
|
||||
return ZYDIS_REGISTERSIZE_DYNAMIC;
|
||||
case ZYDIS_REGISTERCLASS_DEBUG:
|
||||
return ZYDIS_REGISTERSIZE_DYNAMIC;
|
||||
case ZYDIS_REGISTERCLASS_MASK:
|
||||
return ZYDIS_REGISTERSIZE_64;
|
||||
case ZYDIS_REGISTERCLASS_BOUNDS:
|
||||
return ZYDIS_REGISTERSIZE_128;
|
||||
}
|
||||
return ZYDIS_REGISTERSIZE_INVALID;
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR(ZydisRegister reg)
|
||||
{
|
||||
switch (ZydisRegisterGetClass(reg))
|
||||
{
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64:
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32:
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16:
|
||||
case ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR8(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE8);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR16(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE16);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR32(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE32);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsGPR64(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_GENERAL_PURPOSE64);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsFPRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLOATING_POINT);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsMMRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MULTIMEDIA);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR(ZydisRegister reg)
|
||||
{
|
||||
switch (ZydisRegisterGetClass(reg))
|
||||
{
|
||||
case ZYDIS_REGISTERCLASS_VECTOR512:
|
||||
case ZYDIS_REGISTERCLASS_VECTOR256:
|
||||
case ZYDIS_REGISTERCLASS_VECTOR128:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR128(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR128);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR256(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR256);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsVR512(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_VECTOR512);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsFlagsRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_FLAGS);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsIPRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_IP);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsSegmentRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_SEGMENT);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsCR(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_CONTROL);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsDR(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_DEBUG);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsMaskRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_MASK);
|
||||
}
|
||||
|
||||
bool ZydisRegisterIsBoundsRegister(ZydisRegister reg)
|
||||
{
|
||||
return (ZydisRegisterGetClass(reg) == ZYDIS_REGISTERCLASS_BOUNDS);
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <Zydis/Utils.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Operand utils */
|
||||
/* ============================================================================================== */
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
/* Exported functions */
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
ZydisStatus ZydisUtilsCalcAbsoluteTargetAddress(const ZydisInstructionInfo* info,
|
||||
const ZydisOperandInfo* operand, uint64_t* address)
|
||||
{
|
||||
if (!info || !operand || !address)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
switch (operand->type)
|
||||
{
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY:
|
||||
if (operand->mem.disp.size == 0)
|
||||
{
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (operand->mem.base == ZYDIS_REGISTER_EIP)
|
||||
{
|
||||
*address = (uint64_t)((uint32_t)info->instrPointer + operand->mem.disp.value.sdword);
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
if (operand->mem.base == ZYDIS_REGISTER_RIP)
|
||||
{
|
||||
*address = (uint64_t)(info->instrPointer + operand->mem.disp.value.sqword);
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case ZYDIS_OPERAND_TYPE_IMMEDIATE:
|
||||
if (operand->imm.isSigned || operand->imm.isRelative)
|
||||
{
|
||||
*address = (uint64_t)((int64_t)info->instrPointer + operand->imm.value.sqword);
|
||||
switch (info->operandMode)
|
||||
{
|
||||
case 16:
|
||||
*address = (uint16_t)*address;
|
||||
break;
|
||||
case 32:
|
||||
if (info->mode != ZYDIS_DISASSEMBLER_MODE_64BIT)
|
||||
{
|
||||
*address = (uint32_t)*address;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ZYDIS_STATUS_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ZYDIS_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------- */
|
||||
|
||||
/* ============================================================================================== */
|
Binary file not shown.
|
@ -1,12 +1,8 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine
|
||||
Version 1.0
|
||||
|
||||
Remarks : Freeware, Copyright must be included
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
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
|
||||
|
@ -28,28 +24,15 @@
|
|||
|
||||
***************************************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Utility functions.
|
||||
*/
|
||||
#include <Zydis/Zydis.h>
|
||||
|
||||
#ifndef _ZYDIS_UTILS_HPP_
|
||||
#define _ZYDIS_UTILS_HPP_
|
||||
/* ============================================================================================== */
|
||||
/* Exported functions */
|
||||
/* ============================================================================================== */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ZydisTypes.hpp"
|
||||
|
||||
namespace Zydis
|
||||
uint64_t ZydisGetVersion()
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Calculates the absolute target address of a relative instruction operand.
|
||||
* @param info The instruction info.
|
||||
* @param operand The operand.
|
||||
* @return The absolute target address.
|
||||
*/
|
||||
uint64_t CalcAbsoluteTarget(const InstructionInfo& info, const OperandInfo& operand);
|
||||
|
||||
return ZYDIS_VERSION;
|
||||
}
|
||||
|
||||
#endif /* _ZYDIS_UTILS_HPP_ */
|
||||
/* ============================================================================================== */
|
|
@ -0,0 +1,92 @@
|
|||
/***************************************************************************************************
|
||||
|
||||
Zyan Disassembler Engine (Zydis)
|
||||
|
||||
Original Author : Florian Bernd, Joel Höner
|
||||
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <Zydis/Zydis.h>
|
||||
|
||||
/* ============================================================================================== */
|
||||
/* Entry point */
|
||||
/* ============================================================================================== */
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <input file>\n", (argc > 0 ? argv[0] : "ZydisDisasm"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
FILE* file = fopen(argv[1], "rb");
|
||||
if (!file)
|
||||
{
|
||||
fprintf(stderr, "Can not open file: %s\n", strerror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ZydisFileInput input;
|
||||
if (!ZYDIS_SUCCESS(ZydisInputInitFileInput(&input, file)))
|
||||
{
|
||||
fputs("Failed to initialize file-input\n", stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ZydisInstructionFormatter formatter;
|
||||
if (!ZYDIS_SUCCESS(ZydisFormatterInitInstructionFormatterEx(&formatter,
|
||||
ZYDIS_FORMATTER_STYLE_INTEL, ZYDIS_FORMATTER_FLAG_ALWAYS_DISPLAY_MEMORY_SEGMENT)))
|
||||
{
|
||||
fputs("Failed to initialized instruction-formatter\n", stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ZydisInstructionDecoder decoder;
|
||||
if (!ZYDIS_SUCCESS(ZydisDecoderInitInstructionDecoderEx(&decoder, ZYDIS_DISASSEMBLER_MODE_64BIT,
|
||||
(ZydisCustomInput*)&input, ZYDIS_DECODER_FLAG_SKIP_DATA)))
|
||||
{
|
||||
fputs("Failed to initialize instruction-decoder\n", stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
char buffer[256];
|
||||
ZydisInstructionInfo info;
|
||||
while (ZYDIS_SUCCESS(ZydisDecoderDecodeNextInstruction(&decoder, &info)))
|
||||
{
|
||||
if (info.flags & ZYDIS_IFLAG_ERROR_MASK)
|
||||
{
|
||||
printf("db %02X\n", info.data[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
ZydisFormatterFormatInstruction(&formatter, &info, buffer, sizeof(buffer));
|
||||
printf("%s\n", &buffer[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================================== */
|
Loading…
Reference in New Issue