Vendor distorm and scylla_wrapper

This commit is contained in:
Duncan Ogilvie 2026-04-12 13:13:31 +02:00
parent 1232bce7f6
commit 95f332cacd
58 changed files with 25862 additions and 1159 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "scylla_wrapper_dll"]
path = scylla_wrapper_dll
url = https://bitbucket.org/cypherpunk/scylla_wrapper_dll

View File

@ -1,12 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36915.13 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TitanEngine", "TitanEngine\TitanEngine.vcxproj", "{9C7B8246-FDDA-48C7-9634-044969701E40}"
ProjectSection(ProjectDependencies) = postProject
{F874B1B3-8EF7-4DF1-9889-57098E08A51C} = {F874B1B3-8EF7-4DF1-9889-57098E08A51C}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scylla_wrapper", "scylla_wrapper_dll\scylla_wrapper\scylla_wrapper.vcxproj", "{F874B1B3-8EF7-4DF1-9889-57098E08A51C}"
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scylla_wrapper", "scylla_wrapper\scylla_wrapper.vcxproj", "{F874B1B3-8EF7-4DF1-9889-57098E08A51C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "distorm", "distorm\distorm.vcxproj", "{25FF4A19-7088-4687-AA32-76E61BD62E51}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -24,14 +28,22 @@ Global
{9C7B8246-FDDA-48C7-9634-044969701E40}.Release|Win32.Build.0 = Release|Win32
{9C7B8246-FDDA-48C7-9634-044969701E40}.Release|x64.ActiveCfg = Release|x64
{9C7B8246-FDDA-48C7-9634-044969701E40}.Release|x64.Build.0 = Release|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|Win32.ActiveCfg = Release-Lib|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|Win32.Build.0 = Release-Lib|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|x64.ActiveCfg = Release-Lib|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|x64.Build.0 = Release-Lib|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|Win32.ActiveCfg = Release-Lib|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|Win32.Build.0 = Release-Lib|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|x64.ActiveCfg = Release-Lib|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|x64.Build.0 = Release-Lib|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|Win32.ActiveCfg = Debug|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|Win32.Build.0 = Debug|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|x64.ActiveCfg = Debug|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Debug|x64.Build.0 = Debug|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|Win32.ActiveCfg = Release|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|Win32.Build.0 = Release|Win32
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|x64.ActiveCfg = Release|x64
{F874B1B3-8EF7-4DF1-9889-57098E08A51C}.Release|x64.Build.0 = Release|x64
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Debug|Win32.ActiveCfg = Debug|Win32
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Debug|Win32.Build.0 = Debug|Win32
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Debug|x64.ActiveCfg = Debug|x64
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Debug|x64.Build.0 = Debug|x64
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Release|Win32.ActiveCfg = Release|Win32
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Release|Win32.Build.0 = Release|Win32
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Release|x64.ActiveCfg = Release|x64
{25FF4A19-7088-4687-AA32-76E61BD62E51}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -482,10 +482,10 @@ __declspec(dllexport) void* TITCALL InitNativeDebugW(wchar_t* szFileName, wchar_
RtlZeroMemory(&CreateInfo, sizeof(CreateInfo));
CreateInfo.Size = sizeof(CreateInfo);
CreateInfo.State = PsCreateInitialState;
CreateInfo.InitState.u1.s1.WriteOutputOnExit = TRUE;
CreateInfo.InitState.u1.s1.DetectManifest = TRUE;
CreateInfo.InitState.u1.s1.ProhibitedImageCharacteristics = 0; // Normally: IMAGE_FILE_DLL (disallow executing DLLs)
CreateInfo.InitState.AdditionalFileAccess = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
CreateInfo.u1.InitState.u2.s1.WriteOutputOnExit = TRUE;
CreateInfo.u1.InitState.u2.s1.DetectManifest = TRUE;
CreateInfo.u1.InitState.u2.s1.ProhibitedImageCharacteristics = 0; // Normally: IMAGE_FILE_DLL (disallow executing DLLs)
CreateInfo.u1.InitState.AdditionalFileAccess = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
// Initialize the PS_ATTRIBUTE_LIST that contains the process creation attributes
const SIZE_T NumAttributes = 3;
@ -554,8 +554,8 @@ finished:
if(ProcessHandle != NULL)
{
// Close the file and section handles we got back from the kernel
NtClose(CreateInfo.SuccessState.FileHandle);
NtClose(CreateInfo.SuccessState.SectionHandle);
NtClose(CreateInfo.u1.SuccessState.FileHandle);
NtClose(CreateInfo.u1.SuccessState.SectionHandle);
// If we failed, terminate the process
if(!NT_SUCCESS(Status))

View File

@ -1,158 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="TitanEngine" />
<Option pch_mode="2" />
<Option compiler="msvc10" />
<Build>
<Target title="x32">
<Option output="../Release/x32/TitanEngine" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/x32" />
<Option type="3" />
<Option compiler="msvc10" />
<Option createDefFile="1" />
<Option createStaticLib="1" />
<Compiler>
<Add option="/DWIN32" />
<Add option="/DNDEBUG" />
<Add option="/D_WINDOWS" />
<Add option="/D_USRDLL" />
<Add option="/DUNPACKERENGINE_EXPORTS" />
</Compiler>
<Linker>
<Add option="/DEF:TitanEngine.def" />
<Add library=".\scylla_wrapper_x86.lib" />
<Add library=".\distorm_x86.lib" />
<Add library="Imagehlp.lib" />
<Add library="psapi.lib" />
</Linker>
</Target>
<Target title="x64">
<Option output="../Release/x64/TitanEngine" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/x64" />
<Option type="3" />
<Option compiler="microsoft_visual_c_2010_x64" />
<Option createDefFile="1" />
<Option createStaticLib="1" />
<Compiler>
<Add option="/DWIN32" />
<Add option="/DNDEBUG" />
<Add option="/D_WINDOWS" />
<Add option="/D_USRDLL" />
<Add option="/DUNPACKERENGINE_EXPORTS" />
</Compiler>
<Linker>
<Add library=".\scylla_wrapper_x64.lib" />
<Add library=".\distorm_x64.lib" />
<Add library="Imagehlp.lib" />
<Add library="psapi.lib" />
</Linker>
</Target>
</Build>
<Linker>
<Add library="user32" />
<Add library="advapi32" />
<Add library="comdlg32" />
<Add library="shell32" />
</Linker>
<Unit filename="Global.Breakpoints.cpp" />
<Unit filename="Global.Breakpoints.h" />
<Unit filename="Global.Debugger.cpp" />
<Unit filename="Global.Debugger.h" />
<Unit filename="Global.Engine.Extension.cpp" />
<Unit filename="Global.Engine.Extension.h" />
<Unit filename="Global.Engine.GUI.cpp" />
<Unit filename="Global.Engine.GUI.h" />
<Unit filename="Global.Engine.Hash.cpp" />
<Unit filename="Global.Engine.Hash.h" />
<Unit filename="Global.Engine.Hider.cpp" />
<Unit filename="Global.Engine.Hider.h" />
<Unit filename="Global.Engine.Hook.cpp" />
<Unit filename="Global.Engine.Hook.h" />
<Unit filename="Global.Engine.Importer.cpp" />
<Unit filename="Global.Engine.Importer.h" />
<Unit filename="Global.Engine.Simplification.cpp" />
<Unit filename="Global.Engine.Simplification.h" />
<Unit filename="Global.Engine.Threading.cpp" />
<Unit filename="Global.Engine.Threading.h" />
<Unit filename="Global.Engine.cpp" />
<Unit filename="Global.Engine.h" />
<Unit filename="Global.Garbage.cpp" />
<Unit filename="Global.Garbage.h" />
<Unit filename="Global.Handle.cpp" />
<Unit filename="Global.Handle.h" />
<Unit filename="Global.Helper.cpp" />
<Unit filename="Global.Helper.h" />
<Unit filename="Global.Injector.cpp" />
<Unit filename="Global.Injector.h" />
<Unit filename="Global.Librarian.cpp" />
<Unit filename="Global.Librarian.h" />
<Unit filename="Global.Mapping.cpp" />
<Unit filename="Global.Mapping.h" />
<Unit filename="Global.OEPFinder.cpp" />
<Unit filename="Global.OEPFinder.h" />
<Unit filename="Global.Realigner.cpp" />
<Unit filename="Global.Realigner.h" />
<Unit filename="Global.TLS.cpp" />
<Unit filename="Global.TLS.h" />
<Unit filename="Global.Threader.cpp" />
<Unit filename="Global.Threader.h" />
<Unit filename="LzmaDec.cpp" />
<Unit filename="LzmaDec.h" />
<Unit filename="LzmaTypes.h" />
<Unit filename="TitanEngine.Breakpoints.cpp" />
<Unit filename="TitanEngine.Debugger.Context.cpp" />
<Unit filename="TitanEngine.Debugger.Control.cpp" />
<Unit filename="TitanEngine.Debugger.Data.cpp" />
<Unit filename="TitanEngine.Debugger.DebugLoop.cpp" />
<Unit filename="TitanEngine.Debugger.Helper.cpp" />
<Unit filename="TitanEngine.Debugger.Memory.cpp" />
<Unit filename="TitanEngine.Debugger.cpp" />
<Unit filename="TitanEngine.Disassembler.cpp" />
<Unit filename="TitanEngine.Dumper.cpp" />
<Unit filename="TitanEngine.Engine.Simplification.cpp" />
<Unit filename="TitanEngine.Engine.cpp" />
<Unit filename="TitanEngine.Exporter.cpp" />
<Unit filename="TitanEngine.Handler.cpp" />
<Unit filename="TitanEngine.Hider.cpp" />
<Unit filename="TitanEngine.Hooks.cpp" />
<Unit filename="TitanEngine.Importer.cpp" />
<Unit filename="TitanEngine.Injector.cpp" />
<Unit filename="TitanEngine.Librarian.cpp" />
<Unit filename="TitanEngine.OEPFinder.cpp" />
<Unit filename="TitanEngine.PE.Convert.cpp" />
<Unit filename="TitanEngine.PE.Data.cpp" />
<Unit filename="TitanEngine.PE.Fixer.cpp" />
<Unit filename="TitanEngine.PE.Overlay.cpp" />
<Unit filename="TitanEngine.PE.Section.cpp" />
<Unit filename="TitanEngine.PE.cpp" />
<Unit filename="TitanEngine.Process.cpp" />
<Unit filename="TitanEngine.Realigner.cpp" />
<Unit filename="TitanEngine.Relocator.cpp" />
<Unit filename="TitanEngine.Resourcer.cpp" />
<Unit filename="TitanEngine.Static.cpp" />
<Unit filename="TitanEngine.TLS.cpp" />
<Unit filename="TitanEngine.Threader.cpp" />
<Unit filename="TitanEngine.Tracer.cpp" />
<Unit filename="TitanEngine.TranslateName.cpp" />
<Unit filename="TitanEngine.cpp" />
<Unit filename="TitanEngine.rc">
<Option compilerVar="WINDRES" />
</Unit>
<Unit filename="aplib.h" />
<Unit filename="definitions.h" />
<Unit filename="distorm.h" />
<Unit filename="ntdll.h" />
<Unit filename="resource.h" />
<Unit filename="scylla_wrapper.h" />
<Unit filename="stdafx.cpp" />
<Unit filename="stdafx.h" />
<Unit filename="targetver.h" />
<Extensions>
<code_completion />
<envvars />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -1,521 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="TitanEngine"
ProjectGUID="{9C7B8246-FDDA-48C7-9634-044969701E40}"
RootNamespace="TitanEngine"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
EnableIntrinsicFunctions="false"
FavorSizeOrSpeed="1"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;UNPACKERENGINE_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="0"
StructMemberAlignment="1"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="4"
CallingConvention="0"
CompileAs="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="&quot;$(ProjectDir)distorm_x86.lib&quot; Imagehlp.lib psapi.lib"
OutputFile="$(OutDir)\TitanEngine.dll"
LinkIncremental="2"
IgnoreAllDefaultLibraries="false"
ModuleDefinitionFile="$(ProjectDir)TitanEngine.def"
AddModuleNamesToAssembly=""
GenerateDebugInformation="true"
GenerateMapFile="false"
MapExports="false"
SubSystem="2"
OptimizeReferences="0"
ResourceOnlyDLL="false"
SetChecksum="false"
TargetMachine="1"
CLRThreadAttribute="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;UNPACKERENGINE_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
StructMemberAlignment="1"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
CallingConvention="2"
CompileAs="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="&quot;$(ProjectDir)distorm_x64.lib&quot; Imagehlp.lib psapi.lib"
OutputFile="$(OutDir)\TitanEngine.dll"
LinkIncremental="2"
IgnoreAllDefaultLibraries="false"
ModuleDefinitionFile="$(ProjectDir)TitanEngine.def"
GenerateDebugInformation="true"
GenerateMapFile="false"
MapExports="false"
SubSystem="2"
ResourceOnlyDLL="false"
SetChecksum="false"
TargetMachine="17"
CLRThreadAttribute="2"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
EnableIntrinsicFunctions="false"
WholeProgramOptimization="false"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;UNPACKERENGINE_EXPORTS"
RuntimeLibrary="0"
StructMemberAlignment="1"
EnableFunctionLevelLinking="false"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
CallingConvention="0"
CompileAs="2"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="&quot;$(ProjectDir)distorm_x86.lib&quot; Imagehlp.lib psapi.lib"
ModuleDefinitionFile="$(ProjectDir)TitanEngine.def"
GenerateDebugInformation="false"
LinkTimeCodeGeneration="0"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;UNPACKERENGINE_EXPORTS"
RuntimeLibrary="0"
StructMemberAlignment="1"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="&quot;$(ProjectDir)distorm_x64.lib&quot; Imagehlp.lib psapi.lib"
OutputFile="$(OutDir)\TitanEngine.dll"
LinkIncremental="1"
IgnoreAllDefaultLibraries="false"
ModuleDefinitionFile="$(ProjectDir)TitanEngine.def"
GenerateDebugInformation="false"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
SetChecksum="true"
FixedBaseAddress="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\dllmain.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\TitanEngine.cpp"
>
</File>
<Filter
Name="ThirdParty"
>
<File
RelativePath=".\LzmaDec.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\resource.h"
>
</File>
<File
RelativePath=".\stdafx.h"
>
</File>
<File
RelativePath=".\targetver.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\TitanEngine.rc"
>
</File>
<Filter
Name="Binary"
>
<File
RelativePath="..\TitanEngineLoaders\LibraryLoader\x64\Release\LibraryLoader.exe"
>
</File>
<File
RelativePath="..\TitanEngineLoaders\LibraryLoader\Release\LibraryLoader.exe"
>
</File>
<File
RelativePath="..\TitanEngineLoaders\ReserveLibrary\Release\ReserveLibrary.dll"
>
</File>
<File
RelativePath="..\TitanEngineLoaders\ReserveLibrary\x64\Release\ReserveLibrary.dll"
>
</File>
</Filter>
<Filter
Name="Images"
>
<File
RelativePath=".\HEADER.BMP"
>
</File>
<File
RelativePath=".\LOGO.bmp"
>
</File>
<File
RelativePath=".\MAINICON.ico"
>
</File>
</Filter>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -22,7 +22,7 @@
<ProjectGuid>{9C7B8246-FDDA-48C7-9634-044969701E40}</ProjectGuid>
<RootNamespace>TitanEngine</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>7.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@ -67,14 +67,14 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(IntDir)x32\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(IntDir)x32\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\x32\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\x32\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)\x64\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Configuration)\x64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\x64\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\x64\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
@ -92,6 +92,18 @@
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>Full</Optimization>
@ -113,11 +125,12 @@
<AdditionalOptions>/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)ntdll_x86.lib;$(SolutionDir)$(Platform)\Release-Lib\scylla_wrapper_x86.lib;$(ProjectDir)distorm_x86.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(ProjectDir)ntdll_x86.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>$(ProjectDir)TitanEngine.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalOptions>/ignore:4197 /PDBALTPATH:%_PDB% %(AdditionalOptions)</AdditionalOptions>
<SubSystem>Windows</SubSystem>
</Link>
<Manifest>
<AdditionalManifestFiles>manifest.xml</AdditionalManifestFiles>
@ -128,7 +141,7 @@
<Optimization>Disabled</Optimization>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PreprocessorDefinitions>WINVER=0x0501;_WIN32_WINNT=0x0501;NTDDI_VERSION=0x05010000;WIN32;NDEBUG;_WINDOWS;_USRDLL;UNPACKERENGINE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<StructMemberAlignment>Default</StructMemberAlignment>
<FunctionLevelLinking>false</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
@ -143,11 +156,12 @@
<AdditionalOptions>/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)ntdll_x86.lib;$(SolutionDir)$(Platform)\Release-Lib\scylla_wrapper_x86.lib;$(ProjectDir)distorm_x86.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(ProjectDir)ntdll_x86.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>$(ProjectDir)TitanEngine.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
<AdditionalOptions>/ignore:4197 /PDBALTPATH:%_PDB% %(AdditionalOptions)</AdditionalOptions>
<SubSystem>Windows</SubSystem>
</Link>
<Manifest>
<AdditionalManifestFiles>manifest.xml</AdditionalManifestFiles>
@ -173,7 +187,7 @@
<AdditionalOptions>/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)ntdll_x64.lib;$(SolutionDir)$(Platform)\Release-Lib\scylla_wrapper_x64.lib;$(ProjectDir)distorm_x64.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(ProjectDir)ntdll_x64.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)TitanEngine.dll</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>$(ProjectDir)TitanEngine.def</ModuleDefinitionFile>
@ -200,7 +214,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WINVER=0x0502;_WIN32_WINNT=0x0502;NTDDI_VERSION=0x05020000;_AMD64_;_WIN64;NDEBUG;_WINDOWS;_USRDLL;UNPACKERENGINE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<StructMemberAlignment>Default</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
@ -212,7 +226,7 @@
<AdditionalOptions>/Zc:threadSafeInit- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>$(ProjectDir)ntdll_x64.lib;$(SolutionDir)$(Platform)\Release-Lib\scylla_wrapper_x64.lib;$(ProjectDir)distorm_x64.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(ProjectDir)ntdll_x64.lib;Imagehlp.lib;psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)TitanEngine.dll</OutputFile>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>$(ProjectDir)TitanEngine.def</ModuleDefinitionFile>
@ -300,7 +314,6 @@
<ClInclude Include="..\SDK\C\TitanEngine.h" />
<ClInclude Include="aplib.h" />
<ClInclude Include="definitions.h" />
<ClInclude Include="distorm.h" />
<ClInclude Include="Global.Breakpoints.h" />
<ClInclude Include="Global.Debugger.h" />
<ClInclude Include="Global.Engine.Context.h" />
@ -350,7 +363,10 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\scylla_wrapper_dll\scylla_wrapper\scylla_wrapper.vcxproj">
<ProjectReference Include="..\distorm\distorm.vcxproj">
<Project>{25ff4a19-7088-4687-aa32-76e61bd62e51}</Project>
</ProjectReference>
<ProjectReference Include="..\scylla_wrapper\scylla_wrapper.vcxproj">
<Project>{f874b1b3-8ef7-4df1-9889-57098e08a51c}</Project>
</ProjectReference>
</ItemGroup>

View File

@ -296,9 +296,6 @@
<ClInclude Include="aplib.h">
<Filter>Header Files\ThirdParty</Filter>
</ClInclude>
<ClInclude Include="distorm.h">
<Filter>Header Files\ThirdParty</Filter>
</ClInclude>
<ClInclude Include="LzmaDec.h">
<Filter>Header Files\ThirdParty</Filter>
</ClInclude>

View File

@ -42,7 +42,7 @@ inline unsigned int APLIB_CONVENTION aP_depack_asm_safe(const void* source,
void* destination,
unsigned int dstlen)
{
return 0;
return APLIB_ERROR;
}
unsigned int APLIB_CONVENTION aP_crc32(const void* source, unsigned int length);
@ -63,7 +63,7 @@ inline unsigned int APLIB_CONVENTION aPsafe_depack(const void* source,
void* destination,
unsigned int dstlen)
{
return 0;
return APLIB_ERROR;
}
#ifdef __cplusplus

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -7,9 +7,6 @@ const BYTE SCY_ERROR_IATWRITE = -2;
const BYTE SCY_ERROR_IATSEARCH = -3;
const BYTE SCY_ERROR_IATNOTFOUND = -4;
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
//iat exports
int scylla_searchIAT(DWORD pid, DWORD_PTR & iatStart, DWORD & iatSize, DWORD_PTR searchStart, bool advancedSearch);
int scylla_getImports(DWORD_PTR iatAddr, DWORD iatSize, DWORD pid, LPVOID invalidImportCallback = NULL);
@ -35,8 +32,5 @@ bool scylla_dumpProcessA(DWORD_PTR pid, const char* fileToDump, DWORD_PTR imageb
//rebuilder exports
bool scylla_rebuildFileW(const WCHAR* fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup);
bool scylla_rebuildFileA(const char* fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup);
#ifdef __cplusplus
}
#endif /*__cplusplus*/
/* Scylla definitions */

26
distorm/COPYING Normal file
View File

@ -0,0 +1,26 @@
:[diStorm3}:
The ultimate disassembler library.
Copyright (c) 2003-2021, Gil Dabah
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Gil Dabah nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL GIL DABAH BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

157
distorm/distorm.vcxproj Normal file
View File

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\distorm.h" />
<ClInclude Include="include\mnemonics.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\distorm.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{25ff4a19-7088-4687-aa32-76e61bd62e51}</ProjectGuid>
<RootNamespace>distorm</RootNamespace>
<WindowsTargetPlatformVersion>7.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</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 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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<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|x64'">
<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'">
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\distorm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="include\mnemonics.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\distorm.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -1,4 +1,4 @@
/* diStorm3 3.3 */
/* diStorm 3.5.3 */
/*
distorm.h
@ -6,20 +6,8 @@ distorm.h
diStorm3 - Powerful disassembler for X86/AMD64
http://ragestorm.net/distorm/
distorm at gmail dot com
Copyright (C) 2003-2012 Gil Dabah
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
Copyright (C) 2003-2021 Gil Dabah
This library is licensed under the BSD license. See the file COPYING.
*/
@ -45,29 +33,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#undef SUPPORT_64BIT_OFFSET
#endif
/* If your compiler doesn't support stdint.h, define your own 64 bits type. */
#ifdef SUPPORT_64BIT_OFFSET
#ifdef _MSC_VER
#define OFFSET_INTEGER unsigned __int64
#else
#ifndef _MSC_VER
#include <stdint.h>
#define OFFSET_INTEGER uint64_t
#endif
#else
/* 32 bit offsets are used. */
#define OFFSET_INTEGER unsigned long
/* Since MSVC < 2010 isn't shipped with stdint.h,
* here are those from MSVC 2017, which also match
* those in tinycc/libc. */
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
#endif
#ifdef _MSC_VER
/* Since MSVC isn't shipped with stdint.h, we will have our own: */
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
#ifdef SUPPORT_64BIT_OFFSET
#define OFFSET_INTEGER uint64_t
#else
/* 32 bit offsets are used. */
#define OFFSET_INTEGER uint32_t
#endif
/* Support C++ compilers */
@ -79,10 +65,10 @@ extern "C" {
/* *** Helper Macros *** */
/* Get the ISC of the instruction, used with the definitions below. */
#define META_GET_ISC(meta) (((meta) >> 3) & 0x1f)
#define META_SET_ISC(di, isc) (((di)->meta) |= ((isc) << 3))
#define META_GET_ISC(meta) (((meta) >> 8) & 0x1f)
#define META_SET_ISC(di, isc) (((di)->meta) |= ((isc) << 8))
/* Get the flow control flags of the instruction, see 'features for decompose' below. */
#define META_GET_FC(meta) ((meta) & 0x7)
#define META_GET_FC(meta) ((meta) & 0xf)
/* Get the target address of a branching instruction. O_PC operand type. */
#define INSTRUCTION_GET_TARGET(di) ((_OffsetType)(((di)->addr + (di)->imm.addr + (di)->size)))
@ -91,10 +77,10 @@ extern "C" {
/*
* Operand Size or Adderss size are stored inside the flags:
* 0 - 16 bits
* 1 - 32 bits
* 2 - 64 bits
* 3 - reserved
* 00 - 16 bits
* 01 - 32 bits
* 10 - 64 bits
* 11 - reserved
*
* If you call these set-macros more than once, you will have to clean the bits before doing so.
*/
@ -103,29 +89,28 @@ extern "C" {
#define FLAG_GET_OPSIZE(flags) (((flags) >> 8) & 3)
#define FLAG_GET_ADDRSIZE(flags) (((flags) >> 10) & 3)
/* To get the LOCK/REPNZ/REP prefixes. */
#define FLAG_GET_PREFIX(flags) ((flags) & 7)
#define FLAG_GET_PREFIX(flags) (((unsigned int)((int16_t)flags)) & 7)
/* Indicates whether the instruction is privileged. */
#define FLAG_GET_PRIVILEGED(flags) (((flags) & FLAG_PRIVILEGED_INSTRUCTION) != 0)
/*
* Macros to extract segment registers from 'segment':
*/
#define SEGMENT_DEFAULT 0x80
#define SEGMENT_SET(di, seg) ((di->segment) |= seg)
#define SEGMENT_GET(segment) (((segment) == R_NONE) ? R_NONE : ((segment) & 0x7f))
#define SEGMENT_IS_DEFAULT(segment) (((segment) & SEGMENT_DEFAULT) == SEGMENT_DEFAULT)
#define SEGMENT_GET_UNSAFE(segment) ((segment) & 0x7f)
#define SEGMENT_IS_DEFAULT(segment) (((int8_t)segment) < -1) /* Quick check it's a negative number that isn't -1, so it's (0x80 | SEGREG). */
#define SEGMENT_IS_DEFAULT_OR_NONE(segment) (((uint8_t)(segment)) > 0x80)
/* Decodes modes of the disassembler, 16 bits or 32 bits or 64 bits for AMD64, x86-64. */
typedef enum
{
Decode16Bits = 0, Decode32Bits = 1, Decode64Bits = 2
}
_DecodeType;
typedef enum { Decode16Bits = 0, Decode32Bits = 1, Decode64Bits = 2 } _DecodeType;
typedef OFFSET_INTEGER _OffsetType;
typedef struct
{
_OffsetType codeOffset, nextOffset; /* nextOffset is OUT only. */
_OffsetType codeOffset, addrMask;
_OffsetType nextOffset; /* nextOffset is OUT only. */
const uint8_t* code;
int codeLen; /* Using signed integer makes it easier to detect an underflow. */
_DecodeType dt;
@ -188,7 +173,7 @@ typedef struct
*/
uint8_t index;
/* Size of:
/* Size in bits of:
O_REG: register
O_IMM: instruction.imm
O_IMM1: instruction.imm.ex.i1
@ -215,13 +200,18 @@ typedef struct
#define FLAG_HINT_TAKEN (1 << 3)
/* Indicates there is a hint non-taken for Jcc instructions only. */
#define FLAG_HINT_NOT_TAKEN (1 << 4)
/* The Imm value is signed extended. */
/* The Imm value is signed extended (E.G in 64 bit decoding mode, a 32 bit imm is usually sign extended into 64 bit imm). */
#define FLAG_IMM_SIGNED (1 << 5)
/* The destination operand is writable. */
#define FLAG_DST_WR (1 << 6)
/* The instruction uses RIP-relative indirection. */
#define FLAG_RIP_RELATIVE (1 << 7)
/* See flag FLAG_GET_XXX macros above. */
/* The instruction is privileged and can only be used from Ring0. */
#define FLAG_PRIVILEGED_INSTRUCTION (1 << 15)
/* No register was defined. */
#define R_NONE ((uint8_t)-1)
@ -253,12 +243,14 @@ typedef struct
/* Unused prefixes mask, for each bit that is set that prefix is not used (LSB is byte [addr + 0]). */
uint16_t unusedPrefixesMask;
/* Mask of registers that were used in the operands, only used for quick look up, in order to know *some* operand uses that register class. */
uint16_t usedRegistersMask;
uint32_t usedRegistersMask;
/* ID of opcode in the global opcode table. Use for mnemonic look up. */
uint16_t opcode;
/* Up to four operands per instruction, ignored if ops[n].type == O_NONE. */
_Operand ops[OPERANDS_NO];
/* Size of the whole instruction. */
/* Number of valid ops entries. */
uint8_t opsNo;
/* Size of the whole instruction in bytes. */
uint8_t size;
/* Segment information of memory indirection, default segment, or overriden one, can be -1. Use SEGMENT macros. */
uint8_t segment;
@ -266,9 +258,9 @@ typedef struct
uint8_t base, scale;
uint8_t dispSize;
/* Meta defines the instruction set class, and the flow control flags. Use META macros. */
uint8_t meta;
/* The CPU flags that the instruction operates upon. */
uint8_t modifiedFlagsMask, testedFlagsMask, undefinedFlagsMask;
uint16_t meta;
/* The CPU flags that the instruction operates upon, set only with DF_FILL_EFLAGS enabled, otherwise 0. */
uint16_t modifiedFlagsMask, testedFlagsMask, undefinedFlagsMask;
} _DInst;
#ifndef DISTORM_LIGHT
@ -288,11 +280,11 @@ typedef struct
*/
typedef struct
{
_OffsetType offset; /* Start offset of the decoded instruction. */
unsigned int size; /* Size of decoded instruction in bytes. */
_WString mnemonic; /* Mnemonic of decoded instruction, prefixed if required by REP, LOCK etc. */
_WString operands; /* Operands of the decoded instruction, up to 3 operands, comma-seperated. */
_WString instructionHex; /* Hex dump - little endian, including prefixes. */
unsigned int size; /* Size of decoded instruction. */
_OffsetType offset; /* Start offset of the decoded instruction. */
} _DecodedInst;
#endif /* DISTORM_LIGHT */
@ -312,20 +304,30 @@ typedef struct
#define RM_AVX 0x800 /* YMM0 - YMM15 */
#define RM_CR 0x1000 /* CR0, CR2, CR3, CR4, CR8 */
#define RM_DR 0x2000 /* DR0, DR1, DR2, DR3, DR6, DR7 */
#define RM_R8 0x4000 /* R8B, R8W, R8D, R8 */
#define RM_R9 0x8000 /* R9B, R9W, R9D, R9 */
#define RM_R10 0x10000 /* R10B, R10W, R10D, R10 */
#define RM_R11 0x20000 /* R11B, R11W, R11D, R11 */
#define RM_R12 0x40000 /* R12B, R12W, R12D, R12 */
#define RM_R13 0x80000 /* R13B, R13W, R13D, R13 */
#define RM_R14 0x100000 /* R14B, R14W, R14D, R14 */
#define RM_R15 0x200000 /* R15B, R15W, R15D, R15 */
#define RM_SEG 0x400000 /* CS, SS, DS, ES, FS, GS */
/* RIP should be checked using the 'flags' field and FLAG_RIP_RELATIVE.
* Segments should be checked using the segment macros.
* For now R8 - R15 are not supported and non general purpose registers map into same RM.
*/
/* CPU Flags that instructions modify, test or undefine. */
#define D_ZF 1 /* Zero */
#define D_SF 2 /* Sign */
#define D_CF 4 /* Carry */
#define D_OF 8 /* Overflow */
#define D_PF 0x10 /* Parity */
#define D_AF 0x20 /* Auxilary */
#define D_DF 0x40 /* Direction */
#define D_IF 0x80 /* Interrupt */
/* CPU flags that instructions modify, test or undefine (are EFLAGS compatible!). */
#define D_CF 1 /* Carry */
#define D_PF 4 /* Parity */
#define D_AF 0x10 /* Auxiliary */
#define D_ZF 0x40 /* Zero */
#define D_SF 0x80 /* Sign */
#define D_IF 0x200 /* Interrupt */
#define D_DF 0x400 /* Direction */
#define D_OF 0x800 /* Overflow */
/*
* Instructions Set classes:
@ -392,8 +394,21 @@ typedef struct
#define DF_STOP_ON_INT 0x100
/* The decoder will stop and return to the caller when any of the 'CMOVxx' instruction was decoded. */
#define DF_STOP_ON_CMOV 0x200
/* The decoder will stop and return to the caller when it encounters the HLT instruction. */
#define DF_STOP_ON_HLT 0x400
/* The decoder will stop and return to the caller when it encounters a privileged instruction. */
#define DF_STOP_ON_PRIVILEGED 0x800
/* The decoder will stop and return to the caller when an instruction couldn't be decoded. */
#define DF_STOP_ON_UNDECODEABLE 0x1000
/* The decoder will not synchronize to the next byte after the previosuly decoded instruction, instead it will start decoding at the next byte. */
#define DF_SINGLE_BYTE_STEP 0x2000
/* The decoder will fill in the eflags fields for the decoded instruction. */
#define DF_FILL_EFLAGS 0x4000
/* The decoder will use the addrMask in CodeInfo structure instead of DF_MAXIMUM_ADDR16/32. */
#define DF_USE_ADDR_MASK 0x8000
/* The decoder will stop and return to the caller when any flow control instruction was decoded. */
#define DF_STOP_ON_FLOW_CONTROL (DF_STOP_ON_CALL | DF_STOP_ON_RET | DF_STOP_ON_SYS | DF_STOP_ON_UNC_BRANCH | DF_STOP_ON_CND_BRANCH | DF_STOP_ON_INT | DF_STOP_ON_CMOV)
#define DF_STOP_ON_FLOW_CONTROL (DF_STOP_ON_CALL | DF_STOP_ON_RET | DF_STOP_ON_SYS | DF_STOP_ON_UNC_BRANCH | DF_STOP_ON_CND_BRANCH | DF_STOP_ON_INT | DF_STOP_ON_CMOV | DF_STOP_ON_HLT)
/* Indicates the instruction is not a flow-control instruction. */
#define FC_NONE 0
@ -414,9 +429,11 @@ typedef struct
#define FC_INT 6
/* Indicates the instruction is one of: CMOVxx. */
#define FC_CMOV 7
/* Indicates the instruction is HLT. */
#define FC_HLT 8
/* Return code of the decoding function. */
typedef enum { DECRES_NONE, DECRES_SUCCESS, DECRES_MEMORYERR, DECRES_INPUTERR, DECRES_FILTERED } _DecodeResult;
typedef enum { DECRES_NONE, DECRES_SUCCESS, DECRES_MEMORYERR, DECRES_INPUTERR } _DecodeResult;
/* Define the following interface functions only for outer projects. */
#if !(defined(DISTORM_STATIC) || defined(DISTORM_DYNAMIC))
@ -439,6 +456,11 @@ typedef enum { DECRES_NONE, DECRES_SUCCESS, DECRES_MEMORYERR, DECRES_INPUTERR, D
* Notes: 1)The minimal size of maxInstructions is 15.
* 2)You will have to synchronize the offset,code and length by yourself if you pass code fragments and not a complete code block!
*/
/* distorm_decompose
* See more documentation online at the GitHub project's wiki.
*
*/
#ifdef SUPPORT_64BIT_OFFSET
_DecodeResult distorm_decompose64(_CodeInfo* ci, _DInst result[], unsigned int maxInstructions, unsigned int* usedInstructionsCount);
@ -474,7 +496,7 @@ void distorm_format32(const _CodeInfo* ci, const _DInst* di, _DecodedInst* resul
*
* Output: unsigned int - version of compiled library.
*/
unsigned int distorm_version();
unsigned int distorm_version(void);
#endif /* DISTORM_STATIC */

305
distorm/include/mnemonics.h Normal file
View File

@ -0,0 +1,305 @@
/*
mnemonics.h
diStorm3 - Powerful disassembler for X86/AMD64
http://ragestorm.net/distorm/
distorm at gmail dot com
Copyright (C) 2003-2021 Gil Dabah
This library is licensed under the BSD license. See the file COPYING.
*/
#ifndef MNEMONICS_H
#define MNEMONICS_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DISTORM_LIGHT
typedef struct WMnemonic
{
unsigned char length;
unsigned char p[1]; /* p is a null terminated string, which contains 'length' characters. */
} _WMnemonic;
typedef struct WRegister
{
unsigned int length;
unsigned char p[6]; /* p is a null terminated string. */
} _WRegister;
extern const unsigned char _MNEMONICS[];
extern const _WRegister _REGISTERS[];
#endif /* DISTORM_LIGHT */
#ifdef __cplusplus
} /* End Of Extern */
#endif
#define GET_REGISTER_NAME(r) (unsigned char*)_REGISTERS[(r)].p
#define GET_MNEMONIC_NAME(m) ((_WMnemonic*)&_MNEMONICS[(m)])->p
typedef enum
{
I_UNDEFINED = 0, I_AAA = 66, I_AAD = 388, I_AAM = 383, I_AAS = 76, I_ADC = 31, I_ADD = 11, I_ADDPD = 3143,
I_ADDPS = 3136, I_ADDSD = 3157, I_ADDSS = 3150, I_ADDSUBPD = 6427, I_ADDSUBPS = 6437,
I_AESDEC = 9242, I_AESDECLAST = 9259, I_AESENC = 9200, I_AESENCLAST = 9217,
I_AESIMC = 9183, I_AESKEYGENASSIST = 9828, I_AND = 41, I_ANDNPD = 3054, I_ANDNPS = 3046,
I_ANDPD = 3023, I_ANDPS = 3016, I_ARPL = 111, I_BLENDPD = 9405, I_BLENDPS = 9386,
I_BLENDVPD = 7652, I_BLENDVPS = 7642, I_BOUND = 104, I_BSF = 4379, I_BSR = 4391,
I_BSWAP = 959, I_BT = 871, I_BTC = 933, I_BTR = 911, I_BTS = 886, I_CALL = 455,
I_CALL_FAR = 260, I_CBW = 228, I_CDQ = 250, I_CDQE = 239, I_CLAC = 1786, I_CLC = 491,
I_CLD = 511, I_CLFLUSH = 4362, I_CLGI = 1866, I_CLI = 501, I_CLTS = 540, I_CMC = 486,
I_CMOVA = 693, I_CMOVAE = 662, I_CMOVB = 655, I_CMOVBE = 685, I_CMOVG = 753,
I_CMOVGE = 737, I_CMOVL = 730, I_CMOVLE = 745, I_CMOVNO = 647, I_CMOVNP = 722,
I_CMOVNS = 707, I_CMOVNZ = 677, I_CMOVO = 640, I_CMOVP = 715, I_CMOVS = 700,
I_CMOVZ = 670, I_CMP = 71, I_CMPEQPD = 4482, I_CMPEQPS = 4403, I_CMPEQSD = 4640,
I_CMPEQSS = 4561, I_CMPLEPD = 4500, I_CMPLEPS = 4421, I_CMPLESD = 4658, I_CMPLESS = 4579,
I_CMPLTPD = 4491, I_CMPLTPS = 4412, I_CMPLTSD = 4649, I_CMPLTSS = 4570, I_CMPNEQPD = 4521,
I_CMPNEQPS = 4442, I_CMPNEQSD = 4679, I_CMPNEQSS = 4600, I_CMPNLEPD = 4541,
I_CMPNLEPS = 4462, I_CMPNLESD = 4699, I_CMPNLESS = 4620, I_CMPNLTPD = 4531,
I_CMPNLTPS = 4452, I_CMPNLTSD = 4689, I_CMPNLTSS = 4610, I_CMPORDPD = 4551,
I_CMPORDPS = 4472, I_CMPORDSD = 4709, I_CMPORDSS = 4630, I_CMPS = 301, I_CMPUNORDPD = 4509,
I_CMPUNORDPS = 4430, I_CMPUNORDSD = 4667, I_CMPUNORDSS = 4588, I_CMPXCHG = 897,
I_CMPXCHG16B = 6406, I_CMPXCHG8B = 6395, I_COMISD = 2812, I_COMISS = 2804,
I_CPUID = 864, I_CQO = 255, I_CRC32 = 9291, I_CVTDQ2PD = 6820, I_CVTDQ2PS = 3340,
I_CVTPD2DQ = 6830, I_CVTPD2PI = 2714, I_CVTPD2PS = 3266, I_CVTPH2PS = 4194,
I_CVTPI2PD = 2528, I_CVTPI2PS = 2518, I_CVTPS2DQ = 3350, I_CVTPS2PD = 3256,
I_CVTPS2PH = 4204, I_CVTPS2PI = 2704, I_CVTSD2SI = 2734, I_CVTSD2SS = 3286,
I_CVTSI2SD = 2548, I_CVTSI2SS = 2538, I_CVTSS2SD = 3276, I_CVTSS2SI = 2724,
I_CVTTPD2DQ = 6809, I_CVTTPD2PI = 2647, I_CVTTPS2DQ = 3360, I_CVTTPS2PI = 2636,
I_CVTTSD2SI = 2669, I_CVTTSS2SI = 2658, I_CWD = 245, I_CWDE = 233, I_DAA = 46,
I_DAS = 56, I_DEC = 86, I_DIV = 1645, I_DIVPD = 3532, I_DIVPS = 3525, I_DIVSD = 3546,
I_DIVSS = 3539, I_DPPD = 9648, I_DPPS = 9635, I_EMMS = 4133, I_ENTER = 340,
I_EXTRACTPS = 9513, I_EXTRQ = 4169, I_F2XM1 = 1191, I_FABS = 1122, I_FADD = 1022,
I_FADDP = 1548, I_FBLD = 1600, I_FBSTP = 1606, I_FCHS = 1116, I_FCLEX = 7322,
I_FCMOVB = 1375, I_FCMOVBE = 1391, I_FCMOVE = 1383, I_FCMOVNB = 1444, I_FCMOVNBE = 1462,
I_FCMOVNE = 1453, I_FCMOVNU = 1472, I_FCMOVU = 1400, I_FCOM = 1034, I_FCOMI = 1511,
I_FCOMIP = 1622, I_FCOMP = 1040, I_FCOMPP = 1562, I_FCOS = 1310, I_FDECSTP = 1237,
I_FDIV = 1060, I_FDIVP = 1593, I_FDIVR = 1066, I_FDIVRP = 1585, I_FEDISI = 1487,
I_FEMMS = 573, I_FENI = 1481, I_FFREE = 1526, I_FIADD = 1316, I_FICOM = 1330,
I_FICOMP = 1337, I_FIDIV = 1360, I_FIDIVR = 1367, I_FILD = 1417, I_FIMUL = 1323,
I_FINCSTP = 1246, I_FINIT = 7337, I_FIST = 1431, I_FISTP = 1437, I_FISTTP = 1423,
I_FISUB = 1345, I_FISUBR = 1352, I_FLD = 1073, I_FLD1 = 1140, I_FLDCW = 1097,
I_FLDENV = 1089, I_FLDL2E = 1154, I_FLDL2T = 1146, I_FLDLG2 = 1169, I_FLDLN2 = 1177,
I_FLDPI = 1162, I_FLDZ = 1185, I_FMUL = 1028, I_FMULP = 1555, I_FNCLEX = 7314,
I_FNINIT = 7329, I_FNOP = 1110, I_FNSAVE = 7344, I_FNSTCW = 7299, I_FNSTENV = 7282,
I_FNSTSW = 7359, I_FPATAN = 1212, I_FPREM = 1255, I_FPREM1 = 1229, I_FPTAN = 1205,
I_FRNDINT = 1287, I_FRSTOR = 1518, I_FSAVE = 7352, I_FSCALE = 1296, I_FSETPM = 1495,
I_FSIN = 1304, I_FSINCOS = 1278, I_FSQRT = 1271, I_FST = 1078, I_FSTCW = 7307,
I_FSTENV = 7291, I_FSTP = 1083, I_FSTSW = 7367, I_FSUB = 1047, I_FSUBP = 1578,
I_FSUBR = 1053, I_FSUBRP = 1570, I_FTST = 1128, I_FUCOM = 1533, I_FUCOMI = 1503,
I_FUCOMIP = 1613, I_FUCOMP = 1540, I_FUCOMPP = 1408, I_FXAM = 1134, I_FXCH = 1104,
I_FXRSTOR = 9925, I_FXRSTOR64 = 9934, I_FXSAVE = 9897, I_FXSAVE64 = 9905,
I_FXTRACT = 1220, I_FYL2X = 1198, I_FYL2XP1 = 1262, I_GETSEC = 632, I_HADDPD = 4214,
I_HADDPS = 4222, I_HLT = 481, I_HSUBPD = 4248, I_HSUBPS = 4256, I_IDIV = 1650,
I_IMUL = 117, I_IN = 446, I_INC = 81, I_INS = 123, I_INSERTPS = 9580, I_INSERTQ = 4176,
I_INT = 366, I_INT1 = 475, I_INT3 = 360, I_INTO = 371, I_INVD = 554, I_INVEPT = 8317,
I_INVLPG = 1726, I_INVLPGA = 1880, I_INVPCID = 8334, I_INVVPID = 8325, I_IRET = 377,
I_JA = 166, I_JAE = 147, I_JB = 143, I_JBE = 161, I_JCXZ = 426, I_JECXZ = 432,
I_JG = 202, I_JGE = 192, I_JL = 188, I_JLE = 197, I_JMP = 461, I_JMP_FAR = 466,
I_JNO = 138, I_JNP = 183, I_JNS = 174, I_JNZ = 156, I_JO = 134, I_JP = 179,
I_JRCXZ = 439, I_JS = 170, I_JZ = 152, I_LAHF = 289, I_LAR = 521, I_LDDQU = 7027,
I_LDMXCSR = 9955, I_LDS = 335, I_LEA = 223, I_LEAVE = 347, I_LES = 330, I_LFENCE = 4298,
I_LFS = 916, I_LGDT = 1702, I_LGS = 921, I_LIDT = 1708, I_LLDT = 1667, I_LMSW = 1720,
I_LODS = 313, I_LOOP = 420, I_LOOPNZ = 405, I_LOOPZ = 413, I_LSL = 526, I_LSS = 906,
I_LTR = 1673, I_LZCNT = 4396, I_MASKMOVDQU = 7152, I_MASKMOVQ = 7142, I_MAXPD = 3592,
I_MAXPS = 3585, I_MAXSD = 3606, I_MAXSS = 3599, I_MFENCE = 4324, I_MINPD = 3472,
I_MINPS = 3465, I_MINSD = 3486, I_MINSS = 3479, I_MONITOR = 1770, I_MOV = 218,
I_MOVAPD = 2492, I_MOVAPS = 2484, I_MOVBE = 9284, I_MOVD = 3953, I_MOVDDUP = 2219,
I_MOVDQ2Q = 6555, I_MOVDQA = 3979, I_MOVDQU = 3987, I_MOVHLPS = 2184, I_MOVHPD = 2378,
I_MOVHPS = 2370, I_MOVLHPS = 2361, I_MOVLPD = 2201, I_MOVLPS = 2193, I_MOVMSKPD = 2848,
I_MOVMSKPS = 2838, I_MOVNTDQ = 6882, I_MOVNTDQA = 7928, I_MOVNTI = 951, I_MOVNTPD = 2589,
I_MOVNTPS = 2580, I_MOVNTQ = 6874, I_MOVNTSD = 2607, I_MOVNTSS = 2598, I_MOVQ = 3959,
I_MOVQ2DQ = 6546, I_MOVS = 295, I_MOVSD = 2143, I_MOVSHDUP = 2386, I_MOVSLDUP = 2209,
I_MOVSS = 2136, I_MOVSX = 938, I_MOVSXD = 10038, I_MOVUPD = 2128, I_MOVUPS = 2120,
I_MOVZX = 926, I_MPSADBW = 9661, I_MUL = 1640, I_MULPD = 3203, I_MULPS = 3196,
I_MULSD = 3217, I_MULSS = 3210, I_MWAIT = 1779, I_NEG = 1635, I_NOP = 580,
I_NOT = 1630, I_OR = 27, I_ORPD = 3086, I_ORPS = 3080, I_OUT = 450, I_OUTS = 128,
I_PABSB = 7721, I_PABSD = 7751, I_PABSW = 7736, I_PACKSSDW = 3882, I_PACKSSWB = 3714,
I_PACKUSDW = 7949, I_PACKUSWB = 3792, I_PADDB = 7237, I_PADDD = 7267, I_PADDQ = 6514,
I_PADDSB = 6963, I_PADDSW = 6980, I_PADDUSB = 6653, I_PADDUSW = 6672, I_PADDW = 7252,
I_PALIGNR = 9443, I_PAND = 6640, I_PANDN = 6698, I_PAUSE = 10046, I_PAVGB = 6713,
I_PAVGUSB = 2111, I_PAVGW = 6758, I_PBLENDVB = 7632, I_PBLENDW = 9424, I_PCLMULQDQ = 9680,
I_PCMPEQB = 4076, I_PCMPEQD = 4114, I_PCMPEQQ = 7909, I_PCMPEQW = 4095, I_PCMPESTRI = 9759,
I_PCMPESTRM = 9736, I_PCMPGTB = 3735, I_PCMPGTD = 3773, I_PCMPGTQ = 8120,
I_PCMPGTW = 3754, I_PCMPISTRI = 9805, I_PCMPISTRM = 9782, I_PEXTRB = 9462,
I_PEXTRD = 9479, I_PEXTRQ = 9487, I_PEXTRW = 6344, I_PF2ID = 1947, I_PF2IW = 1940,
I_PFACC = 2061, I_PFADD = 2010, I_PFCMPEQ = 2068, I_PFCMPGE = 1971, I_PFCMPGT = 2017,
I_PFMAX = 2026, I_PFMIN = 1980, I_PFMUL = 2077, I_PFNACC = 1954, I_PFPNACC = 1962,
I_PFRCP = 1987, I_PFRCPIT1 = 2033, I_PFRCPIT2 = 2084, I_PFRSQIT1 = 2043, I_PFRSQRT = 1994,
I_PFSUB = 2003, I_PFSUBR = 2053, I_PHADDD = 7408, I_PHADDSW = 7425, I_PHADDW = 7391,
I_PHMINPOSUW = 8292, I_PHSUBD = 7484, I_PHSUBSW = 7501, I_PHSUBW = 7467, I_PI2FD = 1933,
I_PI2FW = 1926, I_PINSRB = 9563, I_PINSRD = 9601, I_PINSRQ = 9609, I_PINSRW = 6327,
I_PMADDUBSW = 7444, I_PMADDWD = 7106, I_PMAXSB = 8207, I_PMAXSD = 8224, I_PMAXSW = 6997,
I_PMAXUB = 6681, I_PMAXUD = 8258, I_PMAXUW = 8241, I_PMINSB = 8139, I_PMINSD = 8156,
I_PMINSW = 6935, I_PMINUB = 6623, I_PMINUD = 8190, I_PMINUW = 8173, I_PMOVMSKB = 6564,
I_PMOVSXBD = 7787, I_PMOVSXBQ = 7808, I_PMOVSXBW = 7766, I_PMOVSXDQ = 7871,
I_PMOVSXWD = 7829, I_PMOVSXWQ = 7850, I_PMOVZXBD = 8015, I_PMOVZXBQ = 8036,
I_PMOVZXBW = 7994, I_PMOVZXDQ = 8099, I_PMOVZXWD = 8057, I_PMOVZXWQ = 8078,
I_PMULDQ = 7892, I_PMULHRSW = 7571, I_PMULHRW = 2094, I_PMULHUW = 6773, I_PMULHW = 6792,
I_PMULLD = 8275, I_PMULLW = 6529, I_PMULUDQ = 7087, I_POP = 22, I_POPA = 98,
I_POPCNT = 4371, I_POPF = 277, I_POR = 6952, I_PREFETCH = 1905, I_PREFETCHNTA = 2435,
I_PREFETCHT0 = 2448, I_PREFETCHT1 = 2460, I_PREFETCHT2 = 2472, I_PREFETCHW = 1915,
I_PSADBW = 7125, I_PSHUFB = 7374, I_PSHUFD = 4021, I_PSHUFHW = 4029, I_PSHUFLW = 4038,
I_PSHUFW = 4013, I_PSIGNB = 7520, I_PSIGND = 7554, I_PSIGNW = 7537, I_PSLLD = 7057,
I_PSLLDQ = 9880, I_PSLLQ = 7072, I_PSLLW = 7042, I_PSRAD = 6743, I_PSRAW = 6728,
I_PSRLD = 6484, I_PSRLDQ = 9863, I_PSRLQ = 6499, I_PSRLW = 6469, I_PSUBB = 7177,
I_PSUBD = 7207, I_PSUBQ = 7222, I_PSUBSB = 6901, I_PSUBSW = 6918, I_PSUBUSB = 6585,
I_PSUBUSW = 6604, I_PSUBW = 7192, I_PSWAPD = 2103, I_PTEST = 7662, I_PUNPCKHBW = 3813,
I_PUNPCKHDQ = 3859, I_PUNPCKHQDQ = 3928, I_PUNPCKHWD = 3836, I_PUNPCKLBW = 3645,
I_PUNPCKLDQ = 3691, I_PUNPCKLQDQ = 3903, I_PUNPCKLWD = 3668, I_PUSH = 16,
I_PUSHA = 91, I_PUSHF = 270, I_PXOR = 7014, I_RCL = 976, I_RCPPS = 2986, I_RCPSS = 2993,
I_RCR = 981, I_RDFSBASE = 9915, I_RDGSBASE = 9945, I_RDMSR = 599, I_RDPMC = 606,
I_RDRAND = 10059, I_RDTSC = 592, I_RDTSCP = 1897, I_RET = 325, I_RETF = 354,
I_ROL = 966, I_ROR = 971, I_ROUNDPD = 9329, I_ROUNDPS = 9310, I_ROUNDSD = 9367,
I_ROUNDSS = 9348, I_RSM = 881, I_RSQRTPS = 2948, I_RSQRTSS = 2957, I_SAHF = 283,
I_SAL = 996, I_SALC = 393, I_SAR = 1001, I_SBB = 36, I_SCAS = 319, I_SETA = 806,
I_SETAE = 779, I_SETB = 773, I_SETBE = 799, I_SETG = 858, I_SETGE = 844, I_SETL = 838,
I_SETLE = 851, I_SETNO = 766, I_SETNP = 831, I_SETNS = 818, I_SETNZ = 792,
I_SETO = 760, I_SETP = 825, I_SETS = 812, I_SETZ = 786, I_SFENCE = 4354, I_SGDT = 1690,
I_SHL = 986, I_SHLD = 875, I_SHR = 991, I_SHRD = 891, I_SHUFPD = 6369, I_SHUFPS = 6361,
I_SIDT = 1696, I_SKINIT = 1872, I_SLDT = 1656, I_SMSW = 1714, I_SQRTPD = 2888,
I_SQRTPS = 2880, I_SQRTSD = 2904, I_SQRTSS = 2896, I_STAC = 1792, I_STC = 496,
I_STD = 516, I_STGI = 1860, I_STI = 506, I_STMXCSR = 9984, I_STOS = 307, I_STR = 1662,
I_SUB = 51, I_SUBPD = 3412, I_SUBPS = 3405, I_SUBSD = 3426, I_SUBSS = 3419,
I_SWAPGS = 1889, I_SYSCALL = 531, I_SYSENTER = 613, I_SYSEXIT = 623, I_SYSRET = 546,
I_TEST = 206, I_TZCNT = 4384, I_UCOMISD = 2775, I_UCOMISS = 2766, I_UD2 = 568,
I_UNPCKHPD = 2329, I_UNPCKHPS = 2319, I_UNPCKLPD = 2287, I_UNPCKLPS = 2277,
I_VADDPD = 3172, I_VADDPS = 3164, I_VADDSD = 3188, I_VADDSS = 3180, I_VADDSUBPD = 6447,
I_VADDSUBPS = 6458, I_VAESDEC = 9250, I_VAESDECLAST = 9271, I_VAESENC = 9208,
I_VAESENCLAST = 9229, I_VAESIMC = 9191, I_VAESKEYGENASSIST = 9845, I_VANDNPD = 3071,
I_VANDNPS = 3062, I_VANDPD = 3038, I_VANDPS = 3030, I_VBLENDPD = 9414, I_VBLENDPS = 9395,
I_VBLENDVPD = 9714, I_VBLENDVPS = 9703, I_VBROADCASTF128 = 7705, I_VBROADCASTSD = 7691,
I_VBROADCASTSS = 7677, I_VCMPEQPD = 5121, I_VCMPEQPS = 4719, I_VCMPEQSD = 5925,
I_VCMPEQSS = 5523, I_VCMPEQ_OSPD = 5302, I_VCMPEQ_OSPS = 4900, I_VCMPEQ_OSSD = 6106,
I_VCMPEQ_OSSS = 5704, I_VCMPEQ_UQPD = 5208, I_VCMPEQ_UQPS = 4806, I_VCMPEQ_UQSD = 6012,
I_VCMPEQ_UQSS = 5610, I_VCMPEQ_USPD = 5411, I_VCMPEQ_USPS = 5009, I_VCMPEQ_USSD = 6215,
I_VCMPEQ_USSS = 5813, I_VCMPFALSEPD = 5243, I_VCMPFALSEPS = 4841, I_VCMPFALSESD = 6047,
I_VCMPFALSESS = 5645, I_VCMPFALSE_OSPD = 5452, I_VCMPFALSE_OSPS = 5050, I_VCMPFALSE_OSSD = 6256,
I_VCMPFALSE_OSSS = 5854, I_VCMPGEPD = 5270, I_VCMPGEPS = 4868, I_VCMPGESD = 6074,
I_VCMPGESS = 5672, I_VCMPGE_OQPD = 5482, I_VCMPGE_OQPS = 5080, I_VCMPGE_OQSD = 6286,
I_VCMPGE_OQSS = 5884, I_VCMPGTPD = 5280, I_VCMPGTPS = 4878, I_VCMPGTSD = 6084,
I_VCMPGTSS = 5682, I_VCMPGT_OQPD = 5495, I_VCMPGT_OQPS = 5093, I_VCMPGT_OQSD = 6299,
I_VCMPGT_OQSS = 5897, I_VCMPLEPD = 5141, I_VCMPLEPS = 4739, I_VCMPLESD = 5945,
I_VCMPLESS = 5543, I_VCMPLE_OQPD = 5328, I_VCMPLE_OQPS = 4926, I_VCMPLE_OQSD = 6132,
I_VCMPLE_OQSS = 5730, I_VCMPLTPD = 5131, I_VCMPLTPS = 4729, I_VCMPLTSD = 5935,
I_VCMPLTSS = 5533, I_VCMPLT_OQPD = 5315, I_VCMPLT_OQPS = 4913, I_VCMPLT_OQSD = 6119,
I_VCMPLT_OQSS = 5717, I_VCMPNEQPD = 5164, I_VCMPNEQPS = 4762, I_VCMPNEQSD = 5968,
I_VCMPNEQSS = 5566, I_VCMPNEQ_OQPD = 5256, I_VCMPNEQ_OQPS = 4854, I_VCMPNEQ_OQSD = 6060,
I_VCMPNEQ_OQSS = 5658, I_VCMPNEQ_OSPD = 5468, I_VCMPNEQ_OSPS = 5066, I_VCMPNEQ_OSSD = 6272,
I_VCMPNEQ_OSSS = 5870, I_VCMPNEQ_USPD = 5356, I_VCMPNEQ_USPS = 4954, I_VCMPNEQ_USSD = 6160,
I_VCMPNEQ_USSS = 5758, I_VCMPNGEPD = 5221, I_VCMPNGEPS = 4819, I_VCMPNGESD = 6025,
I_VCMPNGESS = 5623, I_VCMPNGE_UQPD = 5424, I_VCMPNGE_UQPS = 5022, I_VCMPNGE_UQSD = 6228,
I_VCMPNGE_UQSS = 5826, I_VCMPNGTPD = 5232, I_VCMPNGTPS = 4830, I_VCMPNGTSD = 6036,
I_VCMPNGTSS = 5634, I_VCMPNGT_UQPD = 5438, I_VCMPNGT_UQPS = 5036, I_VCMPNGT_UQSD = 6242,
I_VCMPNGT_UQSS = 5840, I_VCMPNLEPD = 5186, I_VCMPNLEPS = 4784, I_VCMPNLESD = 5990,
I_VCMPNLESS = 5588, I_VCMPNLE_UQPD = 5384, I_VCMPNLE_UQPS = 4982, I_VCMPNLE_UQSD = 6188,
I_VCMPNLE_UQSS = 5786, I_VCMPNLTPD = 5175, I_VCMPNLTPS = 4773, I_VCMPNLTSD = 5979,
I_VCMPNLTSS = 5577, I_VCMPNLT_UQPD = 5370, I_VCMPNLT_UQPS = 4968, I_VCMPNLT_UQSD = 6174,
I_VCMPNLT_UQSS = 5772, I_VCMPORDPD = 5197, I_VCMPORDPS = 4795, I_VCMPORDSD = 6001,
I_VCMPORDSS = 5599, I_VCMPORD_SPD = 5398, I_VCMPORD_SPS = 4996, I_VCMPORD_SSD = 6202,
I_VCMPORD_SSS = 5800, I_VCMPTRUEPD = 5290, I_VCMPTRUEPS = 4888, I_VCMPTRUESD = 6094,
I_VCMPTRUESS = 5692, I_VCMPTRUE_USPD = 5508, I_VCMPTRUE_USPS = 5106, I_VCMPTRUE_USSD = 6312,
I_VCMPTRUE_USSS = 5910, I_VCMPUNORDPD = 5151, I_VCMPUNORDPS = 4749, I_VCMPUNORDSD = 5955,
I_VCMPUNORDSS = 5553, I_VCMPUNORD_SPD = 5341, I_VCMPUNORD_SPS = 4939, I_VCMPUNORD_SSD = 6145,
I_VCMPUNORD_SSS = 5743, I_VCOMISD = 2829, I_VCOMISS = 2820, I_VCVTDQ2PD = 6852,
I_VCVTDQ2PS = 3371, I_VCVTPD2DQ = 6863, I_VCVTPD2PS = 3307, I_VCVTPS2DQ = 3382,
I_VCVTPS2PD = 3296, I_VCVTSD2SI = 2755, I_VCVTSD2SS = 3329, I_VCVTSI2SD = 2569,
I_VCVTSI2SS = 2558, I_VCVTSS2SD = 3318, I_VCVTSS2SI = 2744, I_VCVTTPD2DQ = 6840,
I_VCVTTPS2DQ = 3393, I_VCVTTSD2SI = 2692, I_VCVTTSS2SI = 2680, I_VDIVPD = 3561,
I_VDIVPS = 3553, I_VDIVSD = 3577, I_VDIVSS = 3569, I_VDPPD = 9654, I_VDPPS = 9641,
I_VERR = 1678, I_VERW = 1684, I_VEXTRACTF128 = 9549, I_VEXTRACTPS = 9524,
I_VFMADD132PD = 8420, I_VFMADD132PS = 8407, I_VFMADD132SD = 8446, I_VFMADD132SS = 8433,
I_VFMADD213PD = 8700, I_VFMADD213PS = 8687, I_VFMADD213SD = 8726, I_VFMADD213SS = 8713,
I_VFMADD231PD = 8980, I_VFMADD231PS = 8967, I_VFMADD231SD = 9006, I_VFMADD231SS = 8993,
I_VFMADDSUB132PD = 8359, I_VFMADDSUB132PS = 8343, I_VFMADDSUB213PD = 8639,
I_VFMADDSUB213PS = 8623, I_VFMADDSUB231PD = 8919, I_VFMADDSUB231PS = 8903,
I_VFMSUB132PD = 8472, I_VFMSUB132PS = 8459, I_VFMSUB132SD = 8498, I_VFMSUB132SS = 8485,
I_VFMSUB213PD = 8752, I_VFMSUB213PS = 8739, I_VFMSUB213SD = 8778, I_VFMSUB213SS = 8765,
I_VFMSUB231PD = 9032, I_VFMSUB231PS = 9019, I_VFMSUB231SD = 9058, I_VFMSUB231SS = 9045,
I_VFMSUBADD132PD = 8391, I_VFMSUBADD132PS = 8375, I_VFMSUBADD213PD = 8671,
I_VFMSUBADD213PS = 8655, I_VFMSUBADD231PD = 8951, I_VFMSUBADD231PS = 8935,
I_VFNMADD132PD = 8525, I_VFNMADD132PS = 8511, I_VFNMADD132SD = 8553, I_VFNMADD132SS = 8539,
I_VFNMADD213PD = 8805, I_VFNMADD213PS = 8791, I_VFNMADD213SD = 8833, I_VFNMADD213SS = 8819,
I_VFNMADD231PD = 9085, I_VFNMADD231PS = 9071, I_VFNMADD231SD = 9113, I_VFNMADD231SS = 9099,
I_VFNMSUB132PD = 8581, I_VFNMSUB132PS = 8567, I_VFNMSUB132SD = 8609, I_VFNMSUB132SS = 8595,
I_VFNMSUB213PD = 8861, I_VFNMSUB213PS = 8847, I_VFNMSUB213SD = 8889, I_VFNMSUB213SS = 8875,
I_VFNMSUB231PD = 9141, I_VFNMSUB231PS = 9127, I_VFNMSUB231SD = 9169, I_VFNMSUB231SS = 9155,
I_VHADDPD = 4230, I_VHADDPS = 4239, I_VHSUBPD = 4264, I_VHSUBPS = 4273, I_VINSERTF128 = 9536,
I_VINSERTPS = 9590, I_VLDDQU = 7034, I_VLDMXCSR = 9974, I_VMASKMOVDQU = 7164,
I_VMASKMOVPD = 7982, I_VMASKMOVPS = 7970, I_VMAXPD = 3621, I_VMAXPS = 3613,
I_VMAXSD = 3637, I_VMAXSS = 3629, I_VMCALL = 1734, I_VMCLEAR = 10022, I_VMFUNC = 1814,
I_VMINPD = 3501, I_VMINPS = 3493, I_VMINSD = 3517, I_VMINSS = 3509, I_VMLAUNCH = 1742,
I_VMLOAD = 1844, I_VMMCALL = 1835, I_VMOVAPD = 2509, I_VMOVAPS = 2500, I_VMOVD = 3965,
I_VMOVDDUP = 2267, I_VMOVDQA = 3995, I_VMOVDQU = 4004, I_VMOVHLPS = 2228,
I_VMOVHPD = 2415, I_VMOVHPS = 2406, I_VMOVLHPS = 2396, I_VMOVLPD = 2247, I_VMOVLPS = 2238,
I_VMOVMSKPD = 2869, I_VMOVMSKPS = 2858, I_VMOVNTDQ = 6891, I_VMOVNTDQA = 7938,
I_VMOVNTPD = 2626, I_VMOVNTPS = 2616, I_VMOVQ = 3972, I_VMOVSD = 2176, I_VMOVSHDUP = 2424,
I_VMOVSLDUP = 2256, I_VMOVSS = 2168, I_VMOVUPD = 2159, I_VMOVUPS = 2150, I_VMPSADBW = 9670,
I_VMPTRLD = 10013, I_VMPTRST = 6418, I_VMREAD = 4161, I_VMRESUME = 1752, I_VMRUN = 1828,
I_VMSAVE = 1852, I_VMULPD = 3232, I_VMULPS = 3224, I_VMULSD = 3248, I_VMULSS = 3240,
I_VMWRITE = 4185, I_VMXOFF = 1762, I_VMXON = 10031, I_VORPD = 3099, I_VORPS = 3092,
I_VPABSB = 7728, I_VPABSD = 7758, I_VPABSW = 7743, I_VPACKSSDW = 3892, I_VPACKSSWB = 3724,
I_VPACKUSDW = 7959, I_VPACKUSWB = 3802, I_VPADDB = 7244, I_VPADDD = 7274,
I_VPADDQ = 6521, I_VPADDSB = 6971, I_VPADDSW = 6988, I_VPADDUSW = 6662, I_VPADDW = 7259,
I_VPALIGNR = 9452, I_VPAND = 6646, I_VPANDN = 6705, I_VPAVGB = 6720, I_VPAVGW = 6765,
I_VPBLENDVB = 9725, I_VPBLENDW = 9433, I_VPCLMULQDQ = 9691, I_VPCMPEQB = 4085,
I_VPCMPEQD = 4123, I_VPCMPEQQ = 7918, I_VPCMPEQW = 4104, I_VPCMPESTRI = 9770,
I_VPCMPESTRM = 9747, I_VPCMPGTB = 3744, I_VPCMPGTD = 3782, I_VPCMPGTQ = 8129,
I_VPCMPGTW = 3763, I_VPCMPISTRI = 9816, I_VPCMPISTRM = 9793, I_VPERM2F128 = 9298,
I_VPERMILPD = 7603, I_VPERMILPS = 7592, I_VPEXTRB = 9470, I_VPEXTRD = 9495,
I_VPEXTRQ = 9504, I_VPEXTRW = 6352, I_VPHADDD = 7416, I_VPHADDSW = 7434, I_VPHADDW = 7399,
I_VPHMINPOSUW = 8304, I_VPHSUBD = 7492, I_VPHSUBSW = 7510, I_VPHSUBW = 7475,
I_VPINSRB = 9571, I_VPINSRD = 9617, I_VPINSRQ = 9626, I_VPINSRW = 6335, I_VPMADDUBSW = 7455,
I_VPMADDWD = 7115, I_VPMAXSB = 8215, I_VPMAXSD = 8232, I_VPMAXSW = 7005, I_VPMAXUB = 6689,
I_VPMAXUD = 8266, I_VPMAXUW = 8249, I_VPMINSB = 8147, I_VPMINSD = 8164, I_VPMINSW = 6943,
I_VPMINUB = 6631, I_VPMINUD = 8198, I_VPMINUW = 8181, I_VPMOVMSKB = 6574,
I_VPMOVSXBD = 7797, I_VPMOVSXBQ = 7818, I_VPMOVSXBW = 7776, I_VPMOVSXDQ = 7881,
I_VPMOVSXWD = 7839, I_VPMOVSXWQ = 7860, I_VPMOVZXBD = 8025, I_VPMOVZXBQ = 8046,
I_VPMOVZXBW = 8004, I_VPMOVZXDQ = 8109, I_VPMOVZXWD = 8067, I_VPMOVZXWQ = 8088,
I_VPMULDQ = 7900, I_VPMULHRSW = 7581, I_VPMULHUW = 6782, I_VPMULHW = 6800,
I_VPMULLD = 8283, I_VPMULLW = 6537, I_VPMULUDQ = 7096, I_VPOR = 6957, I_VPSADBW = 7133,
I_VPSHUFB = 7382, I_VPSHUFD = 4047, I_VPSHUFHW = 4056, I_VPSHUFLW = 4066,
I_VPSIGNB = 7528, I_VPSIGND = 7562, I_VPSIGNW = 7545, I_VPSLLD = 7064, I_VPSLLDQ = 9888,
I_VPSLLQ = 7079, I_VPSLLW = 7049, I_VPSRAD = 6750, I_VPSRAW = 6735, I_VPSRLD = 6491,
I_VPSRLDQ = 9871, I_VPSRLQ = 6506, I_VPSRLW = 6476, I_VPSUBB = 7184, I_VPSUBD = 7214,
I_VPSUBQ = 7229, I_VPSUBSB = 6909, I_VPSUBSW = 6926, I_VPSUBUSB = 6594, I_VPSUBUSW = 6613,
I_VPSUBW = 7199, I_VPTEST = 7669, I_VPUNPCKHBW = 3824, I_VPUNPCKHDQ = 3870,
I_VPUNPCKHQDQ = 3940, I_VPUNPCKHWD = 3847, I_VPUNPCKLBW = 3656, I_VPUNPCKLDQ = 3702,
I_VPUNPCKLQDQ = 3915, I_VPUNPCKLWD = 3679, I_VPXOR = 7020, I_VRCPPS = 3000,
I_VRCPSS = 3008, I_VROUNDPD = 9338, I_VROUNDPS = 9319, I_VROUNDSD = 9376,
I_VROUNDSS = 9357, I_VRSQRTPS = 2966, I_VRSQRTSS = 2976, I_VSHUFPD = 6386,
I_VSHUFPS = 6377, I_VSQRTPD = 2921, I_VSQRTPS = 2912, I_VSQRTSD = 2939, I_VSQRTSS = 2930,
I_VSTMXCSR = 10003, I_VSUBPD = 3441, I_VSUBPS = 3433, I_VSUBSD = 3457, I_VSUBSS = 3449,
I_VTESTPD = 7623, I_VTESTPS = 7614, I_VUCOMISD = 2794, I_VUCOMISS = 2784,
I_VUNPCKHPD = 2350, I_VUNPCKHPS = 2339, I_VUNPCKLPD = 2308, I_VUNPCKLPS = 2297,
I_VXORPD = 3128, I_VXORPS = 3120, I_VZEROALL = 4151, I_VZEROUPPER = 4139,
I_WAIT = 10053, I_WBINVD = 560, I_WRFSBASE = 9964, I_WRGSBASE = 9993, I_WRMSR = 585,
I_XABORT = 1006, I_XADD = 945, I_XBEGIN = 1014, I_XCHG = 212, I_XEND = 1822,
I_XGETBV = 1798, I_XLAT = 399, I_XOR = 61, I_XORPD = 3113, I_XORPS = 3106,
I_XRSTOR = 4306, I_XRSTOR64 = 4314, I_XSAVE = 4282, I_XSAVE64 = 4289, I_XSAVEOPT = 4332,
I_XSAVEOPT64 = 4342, I_XSETBV = 1806, I__3DNOW = 10067
} _InstructionType;
typedef enum
{
R_RAX, R_RCX, R_RDX, R_RBX, R_RSP, R_RBP, R_RSI, R_RDI, R_R8, R_R9, R_R10, R_R11, R_R12, R_R13, R_R14, R_R15,
R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI, R_R8D, R_R9D, R_R10D, R_R11D, R_R12D, R_R13D, R_R14D, R_R15D,
R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI, R_R8W, R_R9W, R_R10W, R_R11W, R_R12W, R_R13W, R_R14W, R_R15W,
R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH, R_R8B, R_R9B, R_R10B, R_R11B, R_R12B, R_R13B, R_R14B, R_R15B,
R_SPL, R_BPL, R_SIL, R_DIL,
R_ES, R_CS, R_SS, R_DS, R_FS, R_GS,
R_RIP,
R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, R_ST6, R_ST7,
R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7, R_XMM8, R_XMM9, R_XMM10, R_XMM11, R_XMM12, R_XMM13, R_XMM14, R_XMM15,
R_YMM0, R_YMM1, R_YMM2, R_YMM3, R_YMM4, R_YMM5, R_YMM6, R_YMM7, R_YMM8, R_YMM9, R_YMM10, R_YMM11, R_YMM12, R_YMM13, R_YMM14, R_YMM15,
R_CR0, R_UNUSED0, R_CR2, R_CR3, R_CR4, R_UNUSED1, R_UNUSED2, R_UNUSED3, R_CR8,
R_DR0, R_DR1, R_DR2, R_DR3, R_UNUSED4, R_UNUSED5, R_DR6, R_DR7
} _RegisterType;
#endif /* MNEMONICS_H */

13911
distorm/src/distorm.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,16 @@
@echo off
setlocal enableextensions
set "SRC32=bin\Release\Win32"
if not exist "%SRC32%\TitanEngine.dll" set "SRC32=Release\x32"
set "SRC64=bin\Release\x64"
if not exist "%SRC64%\TitanEngine.dll" set "SRC64=Release\x64"
if exist deps rmdir /s /q deps
mkdir deps\x32
mkdir deps\x64
copy /y Release\x32\TitanEngine.dll deps\x32\TitanEngine.dll
copy /y Release\x32\TitanEngine.pdb deps\x32\TitanEngine.pdb
copy /y Release\x64\TitanEngine.dll deps\x64\TitanEngine.dll
copy /y Release\x64\TitanEngine.pdb deps\x64\TitanEngine.pdb
copy /y "%SRC32%\TitanEngine.dll" deps\x32\TitanEngine.dll
copy /y "%SRC32%\TitanEngine.pdb" deps\x32\TitanEngine.pdb
copy /y "%SRC64%\TitanEngine.dll" deps\x64\TitanEngine.dll
copy /y "%SRC64%\TitanEngine.pdb" deps\x64\TitanEngine.pdb

1218
scylla_wrapper/ApiReader.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
#pragma once
#include <windows.h>
#include <map>
#include <unordered_map>
#include "ProcessAccessHelp.h"
#include "Thunks.h"
typedef std::pair<DWORD_PTR, ApiInfo*> API_Pair;
class ApiReader : public ProcessAccessHelp
{
public:
static std::unordered_multimap<DWORD_PTR, ApiInfo*> apiList; //api look up table
static std::map<DWORD_PTR, ImportModuleThunk>* moduleThunkList; //store found apis
static DWORD_PTR minApiAddress;
static DWORD_PTR maxApiAddress;
/*
* Read all APIs from target process
*/
void readApisFromModuleList();
bool isApiAddressValid(DWORD_PTR virtualAddress);
ApiInfo* getApiByVirtualAddress(DWORD_PTR virtualAddress, bool* isSuspect);
void readAndParseIAT(DWORD_PTR addressIAT, DWORD sizeIAT, std::map<DWORD_PTR, ImportModuleThunk> & moduleListNew);
void addFoundApiToModuleList(DWORD_PTR iatAddress, ApiInfo* apiFound, bool isNewModule, bool isSuspect);
bool addModuleToModuleList(const WCHAR* moduleName, DWORD_PTR firstThunk);
void clearAll();
bool isInvalidMemoryForIat(DWORD_PTR address);
private:
bool readExportTableAlwaysFromDisk;
void parseIAT(DWORD_PTR addressIAT, BYTE* iatBuffer, SIZE_T size);
void addApi(char* functionName, WORD hint, WORD ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo* moduleInfo);
void addApiWithoutName(WORD ordinal, DWORD_PTR va, DWORD_PTR rva, bool isForwarded, ModuleInfo* moduleInfo);
inline bool isApiForwarded(DWORD_PTR rva, PIMAGE_NT_HEADERS pNtHeader);
void handleForwardedApi(DWORD_PTR vaStringPointer, char* functionNameParent, DWORD_PTR rvaParent, WORD ordinalParent, ModuleInfo* moduleParent);
void parseModule(ModuleInfo* module);
void parseModuleWithProcess(ModuleInfo* module);
void parseExportTable(ModuleInfo* module, PIMAGE_NT_HEADERS pNtHeader, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress);
ModuleInfo* findModuleByName(WCHAR* name);
void findApiByModuleAndOrdinal(ModuleInfo* module, WORD ordinal, DWORD_PTR* vaApi, DWORD_PTR* rvaApi);
void findApiByModuleAndName(ModuleInfo* module, char* searchFunctionName, DWORD_PTR* vaApi, DWORD_PTR* rvaApi);
void findApiByModule(ModuleInfo* module, char* searchFunctionName, WORD ordinal, DWORD_PTR* vaApi, DWORD_PTR* rvaApi);
bool isModuleLoadedInOwnProcess(ModuleInfo* module);
void parseModuleWithOwnProcess(ModuleInfo* module);
bool isPeAndExportTableValid(PIMAGE_NT_HEADERS pNtHeader);
void findApiInProcess(ModuleInfo* module, char* searchFunctionName, WORD ordinal, DWORD_PTR* vaApi, DWORD_PTR* rvaApi);
bool findApiInExportTable(ModuleInfo* module, PIMAGE_EXPORT_DIRECTORY pExportDir, DWORD_PTR deltaAddress, char* searchFunctionName, WORD ordinal, DWORD_PTR* vaApi, DWORD_PTR* rvaApi);
BYTE* getHeaderFromProcess(ModuleInfo* module);
BYTE* getExportTableFromProcess(ModuleInfo* module, PIMAGE_NT_HEADERS pNtHeader);
void setModulePriority(ModuleInfo* module);
void setMinMaxApiAddress(DWORD_PTR virtualAddress);
void parseModuleWithMapping(ModuleInfo* moduleInfo); //not used
bool addFunctionToModuleList(ApiInfo* apiFound, DWORD_PTR va, DWORD_PTR rva, WORD ordinal, bool valid, bool suspect);
bool addNotFoundApiToModuleList(DWORD_PTR iatAddressVA, DWORD_PTR apiAddress);
void addUnknownModuleToModuleList(DWORD_PTR firstThunk);
bool isApiBlacklisted(const char* functionName);
bool isWinSxSModule(ModuleInfo* module);
ApiInfo* getScoredApi(std::unordered_map<DWORD_PTR, ApiInfo*>::iterator it1, size_t countDuplicates, bool hasName, bool hasUnicodeAnsiName, bool hasNoUnderlineInName, bool hasPrioDll, bool hasPrio0Dll, bool hasPrio1Dll, bool hasPrio2Dll, bool firstWin);
};

View File

@ -0,0 +1,24 @@
#include "stdafx.h"
#include "Architecture.h"
/*
#ifdef _WIN64
const WCHAR Architecture::NAME[] = L"x64";
const WCHAR Architecture::PRINTF_DWORD_PTR[] = L"%I64X";
const WCHAR Architecture::PRINTF_DWORD_PTR_FULL[] = L"%016I64X";
const WCHAR Architecture::PRINTF_DWORD_PTR_HALF[] = L"%08I64X";
const WCHAR Architecture::PRINTF_INTEGER[] = L"%I64u";
#else
const WCHAR Architecture::NAME[] = L"x86";
const WCHAR Architecture::PRINTF_DWORD_PTR[] = L"%X";
const WCHAR Architecture::PRINTF_DWORD_PTR_FULL[] = L"%08X";
const WCHAR Architecture::PRINTF_DWORD_PTR_HALF[] = L"%08X";
const WCHAR Architecture::PRINTF_INTEGER[] = L"%u";
#endif
*/

View File

@ -0,0 +1,27 @@
#pragma once
#include <windows.h>
#ifdef _WIN64
#define ARCHITECTURE_S "x64"
#define PRINTF_DWORD_PTR_S "%I64X"
#define PRINTF_DWORD_PTR_FULL_S "%016I64X"
#define PRINTF_DWORD_PTR_HALF_S "%08I64X"
#define PRINTF_INTEGER_S "%I64u"
#else
#define ARCHITECTURE_S "x86"
#define PRINTF_DWORD_PTR_S "%X"
#define PRINTF_DWORD_PTR_FULL_S "%08X"
#define PRINTF_DWORD_PTR_HALF_S "%08X"
#define PRINTF_INTEGER_S "%u"
#endif
#define ARCHITECTURE TEXT(ARCHITECTURE_S)
#define PRINTF_DWORD_PTR TEXT(PRINTF_DWORD_PTR_S)
#define PRINTF_DWORD_PTR_FULL TEXT(PRINTF_DWORD_PTR_FULL_S)
#define PRINTF_DWORD_PTR_HALF TEXT(PRINTF_DWORD_PTR_HALF_S)
#define PRINTF_INTEGER TEXT(PRINTF_INTEGER_S)

View File

@ -0,0 +1,102 @@
#include "stdafx.h"
#include "DeviceNameResolver.h"
#include "NativeWinApi.h"
DeviceNameResolver::DeviceNameResolver()
{
NativeWinApi::initialize();
initDeviceNameList();
}
DeviceNameResolver::~DeviceNameResolver()
{
deviceNameList.clear();
}
void DeviceNameResolver::initDeviceNameList()
{
TCHAR shortName[3] = {0};
TCHAR longName[MAX_PATH] = {0};
HardDisk hardDisk;
shortName[1] = TEXT(':');
deviceNameList.reserve(3);
for(TCHAR shortD = TEXT('a'); shortD < TEXT('z'); shortD++)
{
shortName[0] = shortD;
if(QueryDosDevice(shortName, longName, MAX_PATH) > 0)
{
hardDisk.shortName[0] = _totupper(shortD);
hardDisk.shortName[1] = TEXT(':');
hardDisk.shortName[2] = 0;
hardDisk.longNameLength = _tcslen(longName);
_tcscpy_s(hardDisk.longName, longName);
deviceNameList.push_back(hardDisk);
}
}
fixVirtualDevices();
}
bool DeviceNameResolver::resolveDeviceLongNameToShort(const TCHAR* sourcePath, TCHAR* targetPath)
{
for(unsigned int i = 0; i < deviceNameList.size(); i++)
{
if(!_tcsnicmp(deviceNameList[i].longName, sourcePath, deviceNameList[i].longNameLength))
{
_tcscpy_s(targetPath, MAX_PATH, deviceNameList[i].shortName);
_tcscat_s(targetPath, MAX_PATH, sourcePath + deviceNameList[i].longNameLength);
return true;
}
}
return false;
}
void DeviceNameResolver::fixVirtualDevices()
{
const USHORT BufferSize = MAX_PATH * 2 * sizeof(WCHAR);
WCHAR longCopy[MAX_PATH] = {0};
OBJECT_ATTRIBUTES oa = {0};
UNICODE_STRING unicodeInput = {0};
UNICODE_STRING unicodeOutput = {0};
HANDLE hFile = 0;
ULONG retLen = 0;
HardDisk hardDisk;
unicodeOutput.Buffer = (PWSTR)malloc(BufferSize);
if(!unicodeOutput.Buffer)
return;
for(unsigned int i = 0; i < deviceNameList.size(); i++)
{
wcscpy_s(longCopy, deviceNameList[i].longName);
NativeWinApi::RtlInitUnicodeString(&unicodeInput, longCopy);
InitializeObjectAttributes(&oa, &unicodeInput, 0, 0, 0);
if(NT_SUCCESS(NativeWinApi::NtOpenSymbolicLinkObject(&hFile, SYMBOLIC_LINK_QUERY, &oa)))
{
unicodeOutput.Length = BufferSize;
unicodeOutput.MaximumLength = unicodeOutput.Length;
ZeroMemory(unicodeOutput.Buffer, unicodeOutput.Length);
if(NT_SUCCESS(NativeWinApi::NtQuerySymbolicLinkObject(hFile, &unicodeOutput, &retLen)))
{
hardDisk.longNameLength = wcslen(unicodeOutput.Buffer);
wcscpy_s(hardDisk.shortName, deviceNameList[i].shortName);
wcscpy_s(hardDisk.longName, unicodeOutput.Buffer);
deviceNameList.push_back(hardDisk);
}
NativeWinApi::NtClose(hFile);
}
}
free(unicodeOutput.Buffer);
}

View File

@ -0,0 +1,31 @@
#include <Windows.h>
#pragma once
#include <Windows.h>
#include <vector>
#include <tchar.h>
class HardDisk
{
public:
TCHAR shortName[3];
TCHAR longName[MAX_PATH];
size_t longNameLength;
};
class DeviceNameResolver
{
public:
DeviceNameResolver();
~DeviceNameResolver();
bool resolveDeviceLongNameToShort(const TCHAR* sourcePath, TCHAR* targetPath);
private:
std::vector<HardDisk> deviceNameList;
void initDeviceNameList();
void fixVirtualDevices();
};

View File

@ -0,0 +1,738 @@
#include "stdafx.h"
#include "IATReferenceScan.h"
#include "Architecture.h"
#include <set>
//#define DEBUG_COMMENTS
//FileLog IATReferenceScan::directImportLog(L"Scylla_direct_imports.log");
int IATReferenceScan::numberOfFoundDirectImports()
{
return (int)iatDirectImportList.size();
}
int IATReferenceScan::numberOfFoundUniqueDirectImports()
{
std::set<DWORD_PTR> apiPointers;
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference* ref = &(*iter);
apiPointers.insert(ref->targetAddressInIat);
}
return (int)apiPointers.size();
}
int IATReferenceScan::numberOfDirectImportApisNotInIat()
{
std::set<DWORD_PTR> apiPointers;
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference* ref = &(*iter);
if(ref->targetPointer == 0)
{
apiPointers.insert(ref->targetAddressInIat);
}
}
return (int)apiPointers.size();
}
int IATReferenceScan::getSizeInBytesOfJumpTableInSection()
{
return (numberOfFoundUniqueDirectImports() * 6); //for x86 and x64 the same size, FF25 00000000
}
void IATReferenceScan::startScan(DWORD_PTR imageBase, DWORD imageSize, DWORD_PTR iatAddress, DWORD iatSize)
{
MEMORY_BASIC_INFORMATION memBasic = {0};
IatAddressVA = iatAddress;
IatSize = iatSize;
ImageBase = imageBase;
ImageSize = imageSize;
if(ScanForNormalImports)
{
iatReferenceList.clear();
iatReferenceList.reserve(200);
}
if(ScanForDirectImports)
{
iatDirectImportList.clear();
iatDirectImportList.reserve(50);
}
DWORD_PTR section = imageBase;
do
{
if(!VirtualQueryEx(ProcessAccessHelp::hProcess, (LPCVOID)section, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"VirtualQueryEx failed %d", GetLastError());
#endif
break;
}
else
{
if(ProcessAccessHelp::isPageExecutable(memBasic.Protect))
{
//do read and scan
scanMemoryPage(memBasic.BaseAddress, memBasic.RegionSize);
}
}
section = (DWORD_PTR)((SIZE_T)section + memBasic.RegionSize);
}
while(section < (imageBase + imageSize));
}
//void IATReferenceScan::patchNewIatBaseMemory(DWORD_PTR newIatBaseAddress)
//{
// NewIatAddressVA = newIatBaseAddress;
//
// for (std::vector<IATReference>::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++)
// {
// patchReferenceInMemory(&(*iter));
// }
//}
//
//void IATReferenceScan::patchNewIatBaseFile(DWORD_PTR newIatBaseAddress)
//{
// NewIatAddressVA = newIatBaseAddress;
//
// for (std::vector<IATReference>::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++)
// {
// patchReferenceInFile(&(*iter));
// }
//}
void IATReferenceScan::patchDirectImportsMemory(bool junkByteAfterInstruction)
{
JunkByteAfterInstruction = junkByteAfterInstruction;
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
patchDirectImportInMemory(&(*iter));
}
}
void IATReferenceScan::scanMemoryPage(PVOID BaseAddress, SIZE_T RegionSize)
{
BYTE* dataBuffer = (BYTE*)calloc(RegionSize, 1);
BYTE* currentPos = dataBuffer;
int currentSize = (int)RegionSize;
DWORD_PTR currentOffset = (DWORD_PTR)BaseAddress;
_DecodeResult res;
unsigned int instructionsCount = 0, next = 0;
if(!dataBuffer)
return;
if(ProcessAccessHelp::readMemoryFromProcess((DWORD_PTR)BaseAddress, RegionSize, (LPVOID)dataBuffer))
{
while(1)
{
ZeroMemory(&ProcessAccessHelp::decomposerCi, sizeof(_CodeInfo));
ProcessAccessHelp::decomposerCi.code = currentPos;
ProcessAccessHelp::decomposerCi.codeLen = currentSize;
ProcessAccessHelp::decomposerCi.dt = ProcessAccessHelp::dt;
ProcessAccessHelp::decomposerCi.codeOffset = currentOffset;
instructionsCount = 0;
res = distorm_decompose(&ProcessAccessHelp::decomposerCi, ProcessAccessHelp::decomposerResult, sizeof(ProcessAccessHelp::decomposerResult) / sizeof(ProcessAccessHelp::decomposerResult[0]), &instructionsCount);
if(res == DECRES_INPUTERR)
{
break;
}
for(unsigned int i = 0; i < instructionsCount; i++)
{
if(ProcessAccessHelp::decomposerResult[i].flags != FLAG_NOT_DECODABLE)
{
analyzeInstruction(&ProcessAccessHelp::decomposerResult[i]);
}
}
if(res == DECRES_SUCCESS) break; // All instructions were decoded.
else if(instructionsCount == 0) break;
next = (unsigned long)(ProcessAccessHelp::decomposerResult[instructionsCount - 1].addr - ProcessAccessHelp::decomposerResult[0].addr);
if(ProcessAccessHelp::decomposerResult[instructionsCount - 1].flags != FLAG_NOT_DECODABLE)
{
next += ProcessAccessHelp::decomposerResult[instructionsCount - 1].size;
}
currentPos += next;
currentOffset += next;
currentSize -= next;
}
}
free(dataBuffer);
}
void IATReferenceScan::analyzeInstruction(_DInst* instruction)
{
if(ScanForNormalImports)
{
findNormalIatReference(instruction);
}
if(ScanForDirectImports)
{
findDirectIatReferenceMov(instruction);
#ifndef _WIN64
findDirectIatReferenceCallJmp(instruction);
findDirectIatReferenceLea(instruction);
findDirectIatReferencePush(instruction);
#endif
}
}
void IATReferenceScan::findNormalIatReference(_DInst* instruction)
{
#ifdef DEBUG_COMMENTS
_DecodedInst inst;
#endif
IATReference ref;
if(META_GET_FC(instruction->meta) == FC_CALL || META_GET_FC(instruction->meta) == FC_UNC_BRANCH)
{
if(instruction->size >= 5)
{
if(META_GET_FC(instruction->meta) == FC_CALL)
{
ref.type = IAT_REFERENCE_PTR_CALL;
}
else
{
ref.type = IAT_REFERENCE_PTR_JMP;
}
ref.addressVA = (DWORD_PTR)instruction->addr;
ref.instructionSize = instruction->size;
#ifdef _WIN64
if(instruction->flags & FLAG_RIP_RELATIVE)
{
#ifdef DEBUG_COMMENTS
distorm_format(&ProcessAccessHelp::decomposerCi, instruction, &inst);
Scylla::debugLog.log(PRINTF_DWORD_PTR_FULL L" " PRINTF_DWORD_PTR_FULL L" %S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, (DWORD_PTR)instruction->addr, ImageBase, inst.mnemonic.p, inst.operands.p, instruction->ops[0].type, instruction->size, INSTRUCTION_GET_RIP_TARGET(instruction));
#endif
if(INSTRUCTION_GET_RIP_TARGET(instruction) >= IatAddressVA && INSTRUCTION_GET_RIP_TARGET(instruction) < (IatAddressVA + IatSize))
{
ref.targetPointer = INSTRUCTION_GET_RIP_TARGET(instruction);
getIatEntryAddress(&ref);
//Scylla::debugLog.log(L"iat entry "PRINTF_DWORD_PTR_FULL,ref.targetAddressInIat);
iatReferenceList.push_back(ref);
}
}
#else
if(instruction->ops[0].type == O_DISP)
{
//jmp dword ptr || call dword ptr
#ifdef DEBUG_COMMENTS
distorm_format(&ProcessAccessHelp::decomposerCi, instruction, &inst);
Scylla::debugLog.log(PRINTF_DWORD_PTR_FULL L" " PRINTF_DWORD_PTR_FULL L" %S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, (DWORD_PTR)instruction->addr, ImageBase, inst.mnemonic.p, inst.operands.p, instruction->ops[0].type, instruction->size, instruction->disp);
#endif
if(instruction->disp >= IatAddressVA && instruction->disp < (IatAddressVA + IatSize))
{
ref.targetPointer = (DWORD_PTR)instruction->disp;
getIatEntryAddress(&ref);
//Scylla::debugLog.log(L"iat entry "PRINTF_DWORD_PTR_FULL,ref.targetAddressInIat);
iatReferenceList.push_back(ref);
}
}
#endif
}
}
}
void IATReferenceScan::getIatEntryAddress(IATReference* ref)
{
if(!ProcessAccessHelp::readMemoryFromProcess(ref->targetPointer, sizeof(DWORD_PTR), &ref->targetAddressInIat))
{
ref->targetAddressInIat = 0;
}
}
bool IATReferenceScan::isAddressValidImageMemory(DWORD_PTR address)
{
MEMORY_BASIC_INFORMATION memBasic = {0};
if(!VirtualQueryEx(ProcessAccessHelp::hProcess, (LPCVOID)address, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)))
{
return false;
}
return (memBasic.Type == MEM_IMAGE && ProcessAccessHelp::isPageExecutable(memBasic.Protect));
}
void IATReferenceScan::patchReferenceInMemory(IATReference* ref)
{
DWORD_PTR newIatAddressPointer = ref->targetPointer - IatAddressVA + NewIatAddressRVA;
DWORD patchBytes = 0;
#ifdef _WIN64
patchBytes = (DWORD)(newIatAddressPointer - ref->addressVA - 6);
#else
patchBytes = newIatAddressPointer;
#endif
ProcessAccessHelp::writeMemoryToProcess(ref->addressVA + 2, sizeof(DWORD), &patchBytes);
}
void IATReferenceScan::patchDirectImportInMemory(IATReference* ref)
{
DWORD patchBytes = 0;
BYTE patchPreBytes[2];
if(ref->targetPointer)
{
patchPreBytes[0] = 0xFF;
if(ref->type == IAT_REFERENCE_DIRECT_CALL) //FF15
{
patchPreBytes[1] = 0x15;
}
else if(ref->type == IAT_REFERENCE_DIRECT_JMP) //FF25
{
patchPreBytes[1] = 0x25;
}
else
{
return;
}
if(!JunkByteAfterInstruction)
{
ref->addressVA -= 1;
}
ProcessAccessHelp::writeMemoryToProcess(ref->addressVA, 2, patchPreBytes);
#ifdef _WIN64
patchBytes = (DWORD)(ref->targetPointer - ref->addressVA - 6);
#else
patchBytes = ref->targetPointer;
#endif
ProcessAccessHelp::writeMemoryToProcess(ref->addressVA + 2, sizeof(DWORD), &patchBytes);
}
}
DWORD_PTR IATReferenceScan::lookUpIatForPointer(DWORD_PTR addr)
{
if(!iatBackup)
{
iatBackup = (DWORD_PTR*)calloc(IatSize + sizeof(DWORD_PTR), 1);
if(!iatBackup)
{
return 0;
}
if(!ProcessAccessHelp::readMemoryFromProcess(IatAddressVA, IatSize, iatBackup))
{
free(iatBackup);
iatBackup = 0;
return 0;
}
}
for(int i = 0; i < ((int)IatSize / (int)sizeof(DWORD_PTR)); i++)
{
if(iatBackup[i] == addr)
{
return (DWORD_PTR)&iatBackup[i] - (DWORD_PTR)iatBackup + IatAddressVA;
}
}
return 0;
}
void IATReferenceScan::patchNewIat(DWORD_PTR stdImagebase, DWORD_PTR newIatBaseAddress, PeParser* peParser)
{
NewIatAddressRVA = newIatBaseAddress;
DWORD patchBytes = 0;
for(std::vector<IATReference>::iterator iter = iatReferenceList.begin(); iter != iatReferenceList.end(); iter++)
{
IATReference* ref = &(*iter);
DWORD_PTR newIatAddressPointer = (ref->targetPointer - IatAddressVA) + NewIatAddressRVA + stdImagebase;
#ifdef _WIN64
patchBytes = (DWORD)(newIatAddressPointer - (ref->addressVA - ImageBase + stdImagebase) - 6);
#else
patchBytes = newIatAddressPointer;
#endif
DWORD_PTR patchOffset = peParser->convertRVAToOffsetRelative(ref->addressVA - ImageBase);
int index = peParser->convertRVAToOffsetVectorIndex(ref->addressVA - ImageBase);
BYTE* memory = peParser->getSectionMemoryByIndex(index);
DWORD memorySize = peParser->getSectionMemorySizeByIndex(index);
if(memorySize < (DWORD)(patchOffset + 6))
{
// Scylla::debugLog.log(L"Error - Cannot fix IAT reference RVA: " PRINTF_DWORD_PTR_FULL, ref->addressVA - ImageBase);
}
else
{
memory += patchOffset + 2;
*((DWORD*)memory) = patchBytes;
}
//Scylla::debugLog.log(L"address %X old %X new %X",ref->addressVA, ref->targetPointer, newIatAddressPointer);
}
}
void IATReferenceScan::printDirectImportLog()
{
// IATReferenceScan::directImportLog.log(L"------------------------------------------------------------");
// IATReferenceScan::directImportLog.log(L"ImageBase " PRINTF_DWORD_PTR_FULL L" ImageSize %08X IATAddress " PRINTF_DWORD_PTR_FULL L" IATSize 0x%X", ImageBase, ImageSize, IatAddressVA, IatSize);
int count = 0;
bool isSuspect = false;
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference* ref = &(*iter);
ApiInfo* apiInfo = apiReader->getApiByVirtualAddress(ref->targetAddressInIat, &isSuspect);
count++;
WCHAR* type = L"U";
if(ref->type == IAT_REFERENCE_DIRECT_CALL)
{
type = L"CALL";
}
else if(ref->type == IAT_REFERENCE_DIRECT_JMP)
{
type = L"JMP";
}
else if(ref->type == IAT_REFERENCE_DIRECT_MOV)
{
type = L"MOV";
}
else if(ref->type == IAT_REFERENCE_DIRECT_PUSH)
{
type = L"PUSH";
}
else if(ref->type == IAT_REFERENCE_DIRECT_LEA)
{
type = L"LEA";
}
//IATReferenceScan::directImportLog.log(L"%04d AddrVA " PRINTF_DWORD_PTR_FULL L" Type %s Value " PRINTF_DWORD_PTR_FULL L" IatRefPointer " PRINTF_DWORD_PTR_FULL L" Api %s %S", count, ref->addressVA, type, ref->targetAddressInIat, ref->targetPointer,apiInfo->module->getFilename(), apiInfo->name);
}
//IATReferenceScan::directImportLog.log(L"------------------------------------------------------------");
}
void IATReferenceScan::findDirectIatReferenceCallJmp(_DInst* instruction)
{
IATReference ref;
if(META_GET_FC(instruction->meta) == FC_CALL || META_GET_FC(instruction->meta) == FC_UNC_BRANCH)
{
if((instruction->size >= 5) && (instruction->ops[0].type == O_PC)) //CALL/JMP 0x00000000
{
if(META_GET_FC(instruction->meta) == FC_CALL)
{
ref.type = IAT_REFERENCE_DIRECT_CALL;
}
else
{
ref.type = IAT_REFERENCE_DIRECT_JMP;
}
ref.targetAddressInIat = (DWORD_PTR)INSTRUCTION_GET_TARGET(instruction);
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
}
void IATReferenceScan::findDirectIatReferenceMov(_DInst* instruction)
{
IATReference ref;
ref.type = IAT_REFERENCE_DIRECT_MOV;
if(instruction->opcode == I_MOV)
{
#ifdef _WIN64
if(instruction->size >= 7) //MOV REGISTER, 0xFFFFFFFFFFFFFFFF
#else
if(instruction->size >= 5) //MOV REGISTER, 0xFFFFFFFF
#endif
{
if(instruction->ops[0].type == O_REG && instruction->ops[1].type == O_IMM)
{
ref.targetAddressInIat = (DWORD_PTR)instruction->imm.qword;
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
}
}
void IATReferenceScan::findDirectIatReferencePush(_DInst* instruction)
{
IATReference ref;
ref.type = IAT_REFERENCE_DIRECT_PUSH;
if(instruction->size >= 5 && instruction->opcode == I_PUSH)
{
ref.targetAddressInIat = (DWORD_PTR)instruction->imm.qword;
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
void IATReferenceScan::findDirectIatReferenceLea(_DInst* instruction)
{
IATReference ref;
ref.type = IAT_REFERENCE_DIRECT_LEA;
if(instruction->size >= 5 && instruction->opcode == I_LEA)
{
if(instruction->ops[0].type == O_REG && instruction->ops[1].type == O_DISP) //LEA EDX, [0xb58bb8]
{
ref.targetAddressInIat = (DWORD_PTR)instruction->disp;
checkMemoryRangeAndAddToList(&ref, instruction);
}
}
}
void IATReferenceScan::checkMemoryRangeAndAddToList(IATReference* ref, _DInst* instruction)
{
#ifdef DEBUG_COMMENTS
_DecodedInst inst;
#endif
if(ref->targetAddressInIat > 0x000FFFFF && ref->targetAddressInIat != (DWORD_PTR) - 1)
{
if((ref->targetAddressInIat < ImageBase) || (ref->targetAddressInIat > (ImageBase + ImageSize))) //outside pe image
{
//if (isAddressValidImageMemory(ref->targetAddressInIat))
{
bool isSuspect = false;
if(apiReader->getApiByVirtualAddress(ref->targetAddressInIat, &isSuspect) != 0)
{
ref->addressVA = (DWORD_PTR)instruction->addr;
ref->instructionSize = instruction->size;
ref->targetPointer = lookUpIatForPointer(ref->targetAddressInIat);
#ifdef DEBUG_COMMENTS
distorm_format(&ProcessAccessHelp::decomposerCi, instruction, &inst);
Scylla::debugLog.log(PRINTF_DWORD_PTR_FULL L" " PRINTF_DWORD_PTR_FULL L" %S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, (DWORD_PTR)instruction->addr, ImageBase, inst.mnemonic.p, inst.operands.p, instruction->ops[0].type, instruction->size, ref->targetAddressInIat);
#endif
iatDirectImportList.push_back(*ref);
}
}
}
}
}
void IATReferenceScan::patchDirectJumpTableEntry(DWORD_PTR targetIatPointer, DWORD_PTR stdImagebase, DWORD directImportsJumpTableRVA, PeParser* peParser, BYTE* jmpTableMemory, DWORD newIatBase)
{
DWORD patchBytes = 0;
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference* ref = &(*iter);
//only one jmp in table for different direct imports with same iat address
if(ref->targetPointer == targetIatPointer)
{
//patch dump
DWORD patchOffset = (DWORD)peParser->convertRVAToOffsetRelative(ref->addressVA - ImageBase);
int index = peParser->convertRVAToOffsetVectorIndex(ref->addressVA - ImageBase);
BYTE* memory = peParser->getSectionMemoryByIndex(index);
DWORD memorySize = peParser->getSectionMemorySizeByIndex(index);
DWORD sectionRVA = peParser->getSectionAddressRVAByIndex(index);
if(ref->type == IAT_REFERENCE_DIRECT_CALL || ref->type == IAT_REFERENCE_DIRECT_JMP)
{
#ifndef _WIN64
if(ref->instructionSize == 5)
{
patchBytes = directImportsJumpTableRVA - (ref->addressVA - ImageBase) - 5;
patchDirectImportInDump32(1, 5, patchBytes, memory, memorySize, false, patchOffset, sectionRVA);
}
#endif
}
else if(ref->type == IAT_REFERENCE_DIRECT_PUSH || ref->type == IAT_REFERENCE_DIRECT_MOV)
{
#ifndef _WIN64
if(ref->instructionSize == 5) //for x86
{
patchBytes = directImportsJumpTableRVA + stdImagebase;
patchDirectImportInDump32(1, 5, patchBytes, memory, memorySize, true, patchOffset, sectionRVA);
}
#else
if(ref->instructionSize == 10) //for x64
{
DWORD_PTR patchBytes64 = directImportsJumpTableRVA + stdImagebase;
patchDirectImportInDump64(2, 10, patchBytes64, memory, memorySize, true, patchOffset, sectionRVA);
}
#endif
}
else if(ref->type == IAT_REFERENCE_DIRECT_LEA)
{
#ifndef _WIN64
if(ref->instructionSize == 6)
{
patchBytes = directImportsJumpTableRVA + stdImagebase;
patchDirectImportInDump32(2, 6, patchBytes, memory, memorySize, true, patchOffset, sectionRVA);
}
#endif
}
}
}
}
void IATReferenceScan::patchDirectJumpTable(DWORD_PTR stdImagebase, DWORD directImportsJumpTableRVA, PeParser* peParser, BYTE* jmpTableMemory, DWORD newIatBase)
{
std::set<DWORD_PTR> apiPointers;
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference* ref = &(*iter);
apiPointers.insert(ref->targetPointer);
}
DWORD patchBytes;
for(std::set<DWORD_PTR>::iterator apiIter = apiPointers.begin(); apiIter != apiPointers.end(); apiIter++)
{
DWORD_PTR refTargetPointer = *apiIter;
if(newIatBase) //create new iat in section
{
refTargetPointer = (*apiIter - IatAddressVA) + newIatBase + ImageBase;
}
//create jump table in section
DWORD_PTR newIatAddressPointer = refTargetPointer - ImageBase + stdImagebase;
#ifdef _WIN64
patchBytes = (DWORD)(newIatAddressPointer - (directImportsJumpTableRVA + stdImagebase) - 6);
#else
patchBytes = newIatAddressPointer;
DWORD relocOffset = (directImportsJumpTableRVA + 2);
//directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Type HIGHLOW Offset %04X RelocTableEntry %04X", relocOffset & 0xFFFFF000, relocOffset & 0x00000FFF, (IMAGE_REL_BASED_HIGHLOW << 12) + (relocOffset & 0x00000FFF));
#endif
jmpTableMemory[0] = 0xFF;
jmpTableMemory[1] = 0x25;
*((DWORD*)&jmpTableMemory[2]) = patchBytes;
patchDirectJumpTableEntry(*apiIter, stdImagebase, directImportsJumpTableRVA, peParser, jmpTableMemory, newIatBase);
jmpTableMemory += 6;
directImportsJumpTableRVA += 6;
}
}
void IATReferenceScan::patchDirectImportInDump32(int patchPreFixBytes, int instructionSize, DWORD patchBytes, BYTE* memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA)
{
if(memorySize < (DWORD)(patchOffset + instructionSize))
{
//Scylla::debugLog.log(L"Error - Cannot fix direct import reference RVA: %X", sectionRVA + patchOffset);
}
else
{
memory += patchOffset + patchPreFixBytes;
if(generateReloc)
{
DWORD relocOffset = sectionRVA + patchOffset + patchPreFixBytes;
// directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Type HIGHLOW Offset %04X RelocTableEntry %04X", relocOffset & 0xFFFFF000, relocOffset & 0x00000FFF, (IMAGE_REL_BASED_HIGHLOW << 12) + (relocOffset & 0x00000FFF));
}
*((DWORD*)memory) = patchBytes;
}
}
void IATReferenceScan::patchDirectImportInDump64(int patchPreFixBytes, int instructionSize, DWORD_PTR patchBytes, BYTE* memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA)
{
if(memorySize < (DWORD)(patchOffset + instructionSize))
{
// Scylla::debugLog.log(L"Error - Cannot fix direct import reference RVA: %X", sectionRVA + patchOffset);
}
else
{
memory += patchOffset + patchPreFixBytes;
if(generateReloc)
{
DWORD relocOffset = sectionRVA + patchOffset + patchPreFixBytes;
// directImportLog.log(L"Relocation direct imports fix: Base RVA %08X Type DIR64 Offset %04X RelocTableEntry %04X", relocOffset & 0xFFFFF000, relocOffset & 0x00000FFF, (IMAGE_REL_BASED_DIR64 << 12) + (relocOffset & 0x00000FFF));
}
*((DWORD_PTR*)memory) = patchBytes;
}
}
DWORD IATReferenceScan::addAdditionalApisToList()
{
std::set<DWORD_PTR> apiPointers;
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference* ref = &(*iter);
if(ref->targetPointer == 0)
{
apiPointers.insert(ref->targetAddressInIat);
}
}
DWORD_PTR iatAddy = IatAddressVA + IatSize;
DWORD newIatSize = IatSize;
bool isSuspect = false;
for(std::set<DWORD_PTR>::iterator apiIter = apiPointers.begin(); apiIter != apiPointers.end(); apiIter++)
{
for(std::vector<IATReference>::iterator iter = iatDirectImportList.begin(); iter != iatDirectImportList.end(); iter++)
{
IATReference* ref = &(*iter);
if(ref->targetPointer == 0 && ref->targetAddressInIat == *apiIter)
{
ref->targetPointer = iatAddy;
ApiInfo* apiInfo = apiReader->getApiByVirtualAddress(ref->targetAddressInIat, &isSuspect);
apiReader->addFoundApiToModuleList(iatAddy, apiInfo, true, isSuspect);
}
}
iatAddy += sizeof(DWORD_PTR);
newIatSize += sizeof(DWORD_PTR);
}
return newIatSize;
}

View File

@ -0,0 +1,126 @@
#pragma once
#include <vector>
#include "ProcessAccessHelp.h"
#include "PeParser.h"
#include "ApiReader.h"
enum IATReferenceType
{
IAT_REFERENCE_PTR_JMP,
IAT_REFERENCE_PTR_CALL,
IAT_REFERENCE_DIRECT_JMP,
IAT_REFERENCE_DIRECT_CALL,
IAT_REFERENCE_DIRECT_MOV,
IAT_REFERENCE_DIRECT_PUSH,
IAT_REFERENCE_DIRECT_LEA
};
class IATReference
{
public:
DWORD_PTR addressVA; //Address of reference
DWORD_PTR targetPointer; //Place inside IAT
DWORD_PTR targetAddressInIat; //WIN API?
BYTE instructionSize;
IATReferenceType type;
};
class IATReferenceScan
{
public:
IATReferenceScan()
{
apiReader = 0;
IatAddressVA = 0;
IatSize = 0;
ImageBase = 0;
ImageSize = 0;
iatBackup = 0;
ScanForDirectImports = false;
ScanForNormalImports = true;
}
~IATReferenceScan()
{
iatReferenceList.clear();
iatDirectImportList.clear();
if(iatBackup)
{
free(iatBackup);
}
}
bool ScanForDirectImports;
bool ScanForNormalImports;
bool JunkByteAfterInstruction;
ApiReader* apiReader;
void startScan(DWORD_PTR imageBase, DWORD imageSize, DWORD_PTR iatAddress, DWORD iatSize);
//void patchNewIatBaseMemory(DWORD_PTR newIatBaseAddress);
//void patchNewIatBaseFile(DWORD_PTR newIatBaseAddress);
void patchNewIat(DWORD_PTR stdImagebase, DWORD_PTR newIatBaseAddress, PeParser* peParser);
void patchDirectJumpTable(DWORD_PTR imageBase, DWORD directImportsJumpTableRVA, PeParser* peParser, BYTE* jmpTableMemory, DWORD newIatBase);
void patchDirectImportsMemory(bool junkByteAfterInstruction);
int numberOfFoundDirectImports();
int numberOfFoundUniqueDirectImports();
int numberOfDirectImportApisNotInIat();
int getSizeInBytesOfJumpTableInSection();
//static FileLog directImportLog;
void printDirectImportLog();
void changeIatBaseOfDirectImports(DWORD newIatBaseAddressRVA);
DWORD addAdditionalApisToList();
private:
DWORD_PTR NewIatAddressRVA;
DWORD_PTR IatAddressVA;
DWORD IatSize;
DWORD_PTR ImageBase;
DWORD ImageSize;
DWORD_PTR* iatBackup;
std::vector<IATReference> iatReferenceList;
std::vector<IATReference> iatDirectImportList;
void scanMemoryPage(PVOID BaseAddress, SIZE_T RegionSize);
void analyzeInstruction(_DInst* instruction);
void findNormalIatReference(_DInst* instruction);
void getIatEntryAddress(IATReference* ref);
void findDirectIatReferenceCallJmp(_DInst* instruction);
bool isAddressValidImageMemory(DWORD_PTR address);
void patchReferenceInMemory(IATReference* ref);
void patchReferenceInFile(IATReference* ref);
void patchDirectImportInMemory(IATReference* iter);
DWORD_PTR lookUpIatForPointer(DWORD_PTR addr);
void findDirectIatReferenceMov(_DInst* instruction);
void findDirectIatReferencePush(_DInst* instruction);
void checkMemoryRangeAndAddToList(IATReference* ref, _DInst* instruction);
void findDirectIatReferenceLea(_DInst* instruction);
void patchDirectImportInDump32(int patchPreFixBytes, int instructionSize, DWORD patchBytes, BYTE* memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA);
void patchDirectImportInDump64(int patchPreFixBytes, int instructionSize, DWORD_PTR patchBytes, BYTE* memory, DWORD memorySize, bool generateReloc, DWORD patchOffset, DWORD sectionRVA);
void patchDirectJumpTableEntry(DWORD_PTR targetIatPointer, DWORD_PTR stdImagebase, DWORD directImportsJumpTableRVA, PeParser* peParser, BYTE* jmpTableMemory, DWORD newIatBase);
};
/*
PE64
----------
000000013FF82D87 FF15 137C0A00 CALL QWORD [RIP+0xA7C13]
Result: 000000014002A9A0
000000013F65C952 FF25 F8EA0B00 JMP QWORD [RIP+0xBEAF8]
Result: 000000013F71B450
PE32
----------
0120FFA5 FF15 8C6D2601 CALL DWORD [0x01266D8C]
0120FF52 FF25 D4722601 JMP DWORD [0x012672D4]
*/

View File

@ -0,0 +1,547 @@
#include "stdafx.h"
#include "IATSearch.h"
#include "Architecture.h"
//#define DEBUG_COMMENTS
bool IATSearch::searchImportAddressTableInProcess(DWORD_PTR startAddress, DWORD_PTR* addressIAT, DWORD* sizeIAT, bool advanced)
{
DWORD_PTR addressInIAT = 0;
*addressIAT = 0;
*sizeIAT = 0;
if(advanced)
{
return findIATAdvanced(startAddress, addressIAT, sizeIAT);
}
addressInIAT = findAPIAddressInIAT(startAddress);
if(!addressInIAT)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"searchImportAddressTableInProcess :: addressInIAT not found, startAddress " PRINTF_DWORD_PTR_FULL, startAddress);
#endif
return false;
}
else
{
return findIATStartAndSize(addressInIAT, addressIAT, sizeIAT);
}
}
bool IATSearch::findIATAdvanced(DWORD_PTR startAddress, DWORD_PTR* addressIAT, DWORD* sizeIAT)
{
BYTE* dataBuffer;
DWORD_PTR baseAddress;
SIZE_T memorySize;
findExecutableMemoryPagesByStartAddress(startAddress, &baseAddress, &memorySize);
if(memorySize == 0)
return false;
dataBuffer = new BYTE[memorySize];
if(!readMemoryFromProcess((DWORD_PTR)baseAddress, memorySize, dataBuffer))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findAPIAddressInIAT2 :: error reading memory");
#endif
return false;
}
std::set<DWORD_PTR> iatPointers;
DWORD_PTR next;
BYTE* tempBuf = dataBuffer;
while(decomposeMemory(tempBuf, memorySize, (DWORD_PTR)baseAddress) && decomposerInstructionsCount != 0)
{
findIATPointers(iatPointers);
next = (DWORD_PTR)(decomposerResult[decomposerInstructionsCount - 1].addr - baseAddress);
next += decomposerResult[decomposerInstructionsCount - 1].size;
// Advance ptr and recalc offset.
tempBuf += next;
if(memorySize <= next)
{
break;
}
memorySize -= next;
baseAddress += next;
}
if(iatPointers.size() == 0)
return false;
filterIATPointersList(iatPointers);
*addressIAT = *(iatPointers.begin());
*sizeIAT = (DWORD)(*(--iatPointers.end()) - * (iatPointers.begin()) + sizeof(DWORD_PTR));
//Scylla::windowLog.log(L"IAT Search Advanced: Found %d (0x%X) possible IAT entries.", iatPointers.size(), iatPointers.size());
//Scylla::windowLog.log(L"IAT Search Advanced: Possible IAT first " PRINTF_DWORD_PTR_FULL L" last " PRINTF_DWORD_PTR_FULL L" entry.", *(iatPointers.begin()), *(--iatPointers.end()));
delete [] dataBuffer;
return true;
}
DWORD_PTR IATSearch::findAPIAddressInIAT(DWORD_PTR startAddress)
{
const size_t MEMORY_READ_SIZE = 200;
BYTE dataBuffer[MEMORY_READ_SIZE];
DWORD_PTR iatPointer = 0;
int counter = 0;
// to detect stolen api
memoryAddress = 0;
memorySize = 0;
do
{
counter++;
if(!readMemoryFromProcess(startAddress, sizeof(dataBuffer), dataBuffer))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findAPIAddressInIAT :: error reading memory " PRINTF_DWORD_PTR_FULL, startAddress);
#endif
return 0;
}
if(decomposeMemory(dataBuffer, sizeof(dataBuffer), startAddress))
{
iatPointer = findIATPointer();
if(iatPointer)
{
if(isIATPointerValid(iatPointer, true))
{
return iatPointer;
}
}
}
startAddress = findNextFunctionAddress();
//printf("startAddress %08X\n",startAddress);
}
while(startAddress != 0 && counter != 8);
return 0;
}
DWORD_PTR IATSearch::findNextFunctionAddress()
{
#ifdef DEBUG_COMMENTS
_DecodedInst inst;
#endif
for(unsigned int i = 0; i < decomposerInstructionsCount; i++)
{
if(decomposerResult[i].flags != FLAG_NOT_DECODABLE)
{
if(META_GET_FC(decomposerResult[i].meta) == FC_CALL || META_GET_FC(decomposerResult[i].meta) == FC_UNC_BRANCH)
{
if(decomposerResult[i].size >= 5)
{
if(decomposerResult[i].ops[0].type == O_PC)
{
#ifdef DEBUG_COMMENTS
distorm_format(&decomposerCi, &decomposerResult[i], &inst);
Scylla::debugLog.log(L"%S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, inst.mnemonic.p, inst.operands.p, decomposerResult[i].ops[0].type, decomposerResult[i].size, INSTRUCTION_GET_TARGET(&decomposerResult[i]));
#endif
return (DWORD_PTR)INSTRUCTION_GET_TARGET(&decomposerResult[i]);
}
}
}
}
}
return 0;
}
DWORD_PTR IATSearch::findIATPointer()
{
#ifdef DEBUG_COMMENTS
_DecodedInst inst;
#endif
for(unsigned int i = 0; i < decomposerInstructionsCount; i++)
{
if(decomposerResult[i].flags != FLAG_NOT_DECODABLE)
{
if(META_GET_FC(decomposerResult[i].meta) == FC_CALL || META_GET_FC(decomposerResult[i].meta) == FC_UNC_BRANCH)
{
if(decomposerResult[i].size >= 5)
{
#ifdef _WIN64
if(decomposerResult[i].flags & FLAG_RIP_RELATIVE)
{
#ifdef DEBUG_COMMENTS
distorm_format(&decomposerCi, &decomposerResult[i], &inst);
Scylla::debugLog.log(L"%S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, inst.mnemonic.p, inst.operands.p, decomposerResult[i].ops[0].type, decomposerResult[i].size, INSTRUCTION_GET_RIP_TARGET(&decomposerResult[i]));
#endif
return INSTRUCTION_GET_RIP_TARGET(&decomposerResult[i]);
}
#else
if(decomposerResult[i].ops[0].type == O_DISP)
{
//jmp dword ptr || call dword ptr
#ifdef DEBUG_COMMENTS
distorm_format(&decomposerCi, &decomposerResult[i], &inst);
Scylla::debugLog.log(L"%S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, inst.mnemonic.p, inst.operands.p, decomposerResult[i].ops[0].type, decomposerResult[i].size, decomposerResult[i].disp);
#endif
return (DWORD_PTR)decomposerResult[i].disp;
}
#endif
}
}
}
}
return 0;
}
bool IATSearch::isIATPointerValid(DWORD_PTR iatPointer, bool checkRedirects)
{
DWORD_PTR apiAddress = 0;
if(!readMemoryFromProcess(iatPointer, sizeof(DWORD_PTR), &apiAddress))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"isIATPointerValid :: error reading memory");
#endif
return false;
}
//printf("Win api ? %08X\n",apiAddress);
if(isApiAddressValid(apiAddress) != 0)
{
return true;
}
else
{
if(checkRedirects)
{
//maybe redirected import?
//if the address is 2 times inside a memory region it is possible a redirected api
if(apiAddress > memoryAddress && apiAddress < (memoryAddress + memorySize))
{
return true;
}
else
{
getMemoryRegionFromAddress(apiAddress, &memoryAddress, &memorySize);
}
}
}
return false;
}
bool IATSearch::findIATStartAndSize(DWORD_PTR address, DWORD_PTR* addressIAT, DWORD* sizeIAT)
{
BYTE* dataBuffer = 0;
DWORD_PTR baseAddress = 0;
DWORD baseSize = 0;
getMemoryBaseAndSizeForIat(address, &baseAddress, &baseSize);
if(!baseAddress)
return false;
dataBuffer = new BYTE[baseSize * (sizeof(DWORD_PTR) * 3)];
if(!dataBuffer)
return false;
ZeroMemory(dataBuffer, baseSize * (sizeof(DWORD_PTR) * 3));
if(!readMemoryFromProcess(baseAddress, baseSize, dataBuffer))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findIATStartAddress :: error reading memory");
#endif
return false;
}
//printf("address %X memBasic.BaseAddress %X memBasic.RegionSize %X\n",address,memBasic.BaseAddress,memBasic.RegionSize);
*addressIAT = findIATStartAddress(baseAddress, address, dataBuffer);
*sizeIAT = findIATSize(baseAddress, *addressIAT, dataBuffer, baseSize);
delete [] dataBuffer;
return true;
}
DWORD_PTR IATSearch::findIATStartAddress(DWORD_PTR baseAddress, DWORD_PTR startAddress, BYTE* dataBuffer)
{
DWORD_PTR* pIATAddress = 0;
pIATAddress = (DWORD_PTR*)((startAddress - baseAddress) + (DWORD_PTR)dataBuffer);
while((DWORD_PTR)pIATAddress != (DWORD_PTR)dataBuffer)
{
if(isInvalidMemoryForIat(*pIATAddress))
{
if((DWORD_PTR)(pIATAddress - 1) >= (DWORD_PTR)dataBuffer)
{
if(isInvalidMemoryForIat(*(pIATAddress - 1)))
{
if((DWORD_PTR)(pIATAddress - 2) >= (DWORD_PTR)dataBuffer)
{
if(!isApiAddressValid(*(pIATAddress - 2)))
{
return (((DWORD_PTR)pIATAddress - (DWORD_PTR)dataBuffer) + baseAddress);
}
}
}
}
}
pIATAddress--;
}
return baseAddress;
}
DWORD IATSearch::findIATSize(DWORD_PTR baseAddress, DWORD_PTR iatAddress, BYTE* dataBuffer, DWORD bufferSize)
{
DWORD_PTR* pIATAddress = 0;
pIATAddress = (DWORD_PTR*)((iatAddress - baseAddress) + (DWORD_PTR)dataBuffer);
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findIATSize :: baseAddress %X iatAddress %X dataBuffer %X pIATAddress %X", baseAddress, iatAddress, dataBuffer, pIATAddress);
#endif
while((DWORD_PTR)pIATAddress < ((DWORD_PTR)dataBuffer + bufferSize - 1))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findIATSize :: %X %X %X", pIATAddress, *pIATAddress, *(pIATAddress + 1));
#endif
if(isInvalidMemoryForIat(*pIATAddress)) //normal is 0
{
if(isInvalidMemoryForIat(*(pIATAddress + 1)))
{
//IAT end
if(!isApiAddressValid(*(pIATAddress + 2)))
{
return (DWORD)((DWORD_PTR)pIATAddress - (DWORD_PTR)dataBuffer - (iatAddress - baseAddress));
}
}
}
pIATAddress++;
}
return bufferSize;
}
void IATSearch::findIATPointers(std::set<DWORD_PTR> & iatPointers)
{
#ifdef DEBUG_COMMENTS
_DecodedInst inst;
#endif
for(unsigned int i = 0; i < decomposerInstructionsCount; i++)
{
if(decomposerResult[i].flags != FLAG_NOT_DECODABLE)
{
if(META_GET_FC(decomposerResult[i].meta) == FC_CALL || META_GET_FC(decomposerResult[i].meta) == FC_UNC_BRANCH)
{
if(decomposerResult[i].size >= 5)
{
#ifdef _WIN64
if(decomposerResult[i].flags & FLAG_RIP_RELATIVE)
{
#ifdef DEBUG_COMMENTS
distorm_format(&decomposerCi, &decomposerResult[i], &inst);
Scylla::debugLog.log(L"%S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, inst.mnemonic.p, inst.operands.p, decomposerResult[i].ops[0].type, decomposerResult[i].size, INSTRUCTION_GET_RIP_TARGET(&decomposerResult[i]));
#endif
iatPointers.insert(INSTRUCTION_GET_RIP_TARGET(&decomposerResult[i]));
}
#else
if(decomposerResult[i].ops[0].type == O_DISP)
{
//jmp dword ptr || call dword ptr
#ifdef DEBUG_COMMENTS
distorm_format(&decomposerCi, &decomposerResult[i], &inst);
Scylla::debugLog.log(L"%S %S %d %d - target address: " PRINTF_DWORD_PTR_FULL, inst.mnemonic.p, inst.operands.p, decomposerResult[i].ops[0].type, decomposerResult[i].size, decomposerResult[i].disp);
#endif
iatPointers.insert((DWORD_PTR)decomposerResult[i].disp);
}
#endif
}
}
}
}
}
void IATSearch::findExecutableMemoryPagesByStartAddress(DWORD_PTR startAddress, DWORD_PTR* baseAddress, SIZE_T* memorySize)
{
MEMORY_BASIC_INFORMATION memBasic = {0};
DWORD_PTR tempAddress;
*memorySize = 0;
*baseAddress = 0;
if(VirtualQueryEx(hProcess, (LPCVOID)startAddress, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"findIATStartAddress :: VirtualQueryEx error %u", GetLastError());
#endif
return;
}
//search down
do
{
*memorySize = memBasic.RegionSize;
*baseAddress = (DWORD_PTR)memBasic.BaseAddress;
tempAddress = (DWORD_PTR)memBasic.BaseAddress - 1;
if(VirtualQueryEx(hProcess, (LPCVOID)tempAddress, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION))
{
break;
}
}
while(isPageExecutable(memBasic.Protect));
tempAddress = *baseAddress;
memBasic.RegionSize = *memorySize;
*memorySize = 0;
//search up
do
{
tempAddress += memBasic.RegionSize;
*memorySize += memBasic.RegionSize;
if(VirtualQueryEx(hProcess, (LPCVOID)tempAddress, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION))
{
break;
}
}
while(isPageExecutable(memBasic.Protect));
}
void IATSearch::filterIATPointersList(std::set<DWORD_PTR> & iatPointers)
{
std::set<DWORD_PTR>::iterator iter;
if(iatPointers.size() <= 2)
{
return;
}
iter = iatPointers.begin();
std::advance(iter, iatPointers.size() / 2); //start in the middle, important!
DWORD_PTR lastPointer = *iter;
iter++;
for(; iter != iatPointers.end(); iter++)
{
if((*iter - lastPointer) > 0x100) //check difference
{
if(isIATPointerValid(lastPointer, false) == false || isIATPointerValid(*iter, false) == false)
{
iatPointers.erase(iter, iatPointers.end());
break;
}
else
{
lastPointer = *iter;
}
}
else
{
lastPointer = *iter;
}
}
bool erased = true;
while(erased)
{
iter = iatPointers.begin();
lastPointer = *iter;
iter++;
for(; iter != iatPointers.end(); iter++)
{
if((*iter - lastPointer) > 0x100) //check difference
{
if(isIATPointerValid(lastPointer, false) == false || isIATPointerValid(*iter, false) == false)
{
iter--;
iatPointers.erase(iter);
erased = true;
break;
}
else
{
erased = false;
lastPointer = *iter;
}
}
else
{
erased = false;
lastPointer = *iter;
}
}
}
}
void IATSearch::getMemoryBaseAndSizeForIat(DWORD_PTR address, DWORD_PTR* baseAddress, DWORD* baseSize)
{
MEMORY_BASIC_INFORMATION memBasic1 = {0};
MEMORY_BASIC_INFORMATION memBasic2 = {0};
MEMORY_BASIC_INFORMATION memBasic3 = {0};
DWORD_PTR start = 0, end = 0;
*baseAddress = 0;
*baseSize = 0;
if(!VirtualQueryEx(hProcess, (LPCVOID)address, &memBasic2, sizeof(MEMORY_BASIC_INFORMATION)))
{
return;
}
*baseAddress = (DWORD_PTR)memBasic2.BaseAddress;
*baseSize = (DWORD)memBasic2.RegionSize;
//Get the neighbours
if(!VirtualQueryEx(hProcess, (LPCVOID)((DWORD_PTR)memBasic2.BaseAddress - 1), &memBasic1, sizeof(MEMORY_BASIC_INFORMATION)))
{
return;
}
if(!VirtualQueryEx(hProcess, (LPCVOID)((DWORD_PTR)memBasic2.BaseAddress + (DWORD_PTR)memBasic2.RegionSize), &memBasic3, sizeof(MEMORY_BASIC_INFORMATION)))
{
return;
}
if(memBasic3.State != MEM_COMMIT || memBasic1.State != MEM_COMMIT)
{
return;
}
start = (DWORD_PTR)memBasic1.BaseAddress;
end = (DWORD_PTR)memBasic3.BaseAddress + (DWORD_PTR)memBasic3.RegionSize;
*baseAddress = start;
*baseSize = (DWORD)(end - start);
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "ApiReader.h"
#include <set>
class IATSearch : protected ApiReader
{
public:
DWORD_PTR memoryAddress;
SIZE_T memorySize;
bool searchImportAddressTableInProcess(DWORD_PTR startAddress, DWORD_PTR* addressIAT, DWORD* sizeIAT, bool advanced);
private:
DWORD_PTR findAPIAddressInIAT(DWORD_PTR startAddress);
bool findIATAdvanced(DWORD_PTR startAddress, DWORD_PTR* addressIAT, DWORD* sizeIAT);
DWORD_PTR findNextFunctionAddress();
DWORD_PTR findIATPointer();
//DWORD_PTR findAddressFromWORDString(char * stringBuffer);
//DWORD_PTR findAddressFromNormalCALLString(char * stringBuffer);
bool isIATPointerValid(DWORD_PTR iatPointer, bool checkRedirects);
bool findIATStartAndSize(DWORD_PTR address, DWORD_PTR* addressIAT, DWORD* sizeIAT);
DWORD_PTR findIATStartAddress(DWORD_PTR baseAddress, DWORD_PTR startAddress, BYTE* dataBuffer);
DWORD findIATSize(DWORD_PTR baseAddress, DWORD_PTR iatAddress, BYTE* dataBuffer, DWORD bufferSize);
void findIATPointers(std::set<DWORD_PTR> & iatPointers);
void findExecutableMemoryPagesByStartAddress(DWORD_PTR startAddress, DWORD_PTR* baseAddress, SIZE_T* memorySize);
void filterIATPointersList(std::set<DWORD_PTR> & iatPointers);
void getMemoryBaseAndSizeForIat(DWORD_PTR address, DWORD_PTR* baseAddress, DWORD* baseSize);
};

View File

@ -0,0 +1,550 @@
#include "stdafx.h"
#include "ImportRebuilder.h"
#include "StringConversion.h"
//#define DEBUG_COMMENTS
/*
New Scylla section contains:
1. (optional) direct imports jump table
2. (optional) new iat
3. (optional) OFT
4. Normal IAT entries
*/
bool ImportRebuilder::rebuildImportTable(const WCHAR* newFilePath, std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
bool retValue = false;
std::map<DWORD_PTR, ImportModuleThunk> copyModule;
copyModule.insert(moduleList.begin(), moduleList.end());
if(isValidPeFile())
{
if(readPeSectionsFromFile())
{
setDefaultFileAlignment();
retValue = buildNewImportTable(copyModule);
if(retValue)
{
alignAllSectionHeaders();
fixPeHeader();
if(newIatInSection)
{
patchFileForNewIatLocation();
}
if(BuildDirectImportsJumpTable)
{
patchFileForDirectImportJumpTable();
}
retValue = savePeFileToDisk(newFilePath);
}
}
}
return retValue;
}
bool ImportRebuilder::rebuildMappedImportTable(DWORD_PTR iatVA, std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
bool retValue = false;
if(isValidPeFile())
{
if(readPeSectionsFromMappedFile())
{
retValue = buildNewMappedImportTable(moduleList);
//destructor of PEParser deletes .data so we need to remove our pointer to FileMapping
for(WORD i = 0; i < getNumberOfSections(); i++)
{
listPeSection[i].data = NULL;
}
}
}
return retValue;
}
bool ImportRebuilder::buildNewImportTable(std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
createNewImportSection(moduleList);
importSectionIndex = listPeSection.size() - 1;
if(BuildDirectImportsJumpTable)
{
directImportsJumpTableRVA = listPeSection[importSectionIndex].sectionHeader.VirtualAddress;
JMPTableMemory = listPeSection[importSectionIndex].data;
}
if(newIatInSection)
{
newIatBaseAddressRVA = listPeSection[importSectionIndex].sectionHeader.VirtualAddress;
if(BuildDirectImportsJumpTable)
{
newIatBaseAddressRVA += iatReferenceScan->getSizeInBytesOfJumpTableInSection();
}
changeIatBaseAddress(moduleList);
}
DWORD dwSize = fillImportSection(moduleList);
if(!dwSize)
{
return false;
}
setFlagToIATSection((*moduleList.begin()).second.firstThunk);
DWORD vaImportAddress = listPeSection[importSectionIndex].sectionHeader.VirtualAddress;
if(useOFT)
{
//OFT array is at the beginning of the import section
vaImportAddress += (DWORD)sizeOfOFTArray;
}
if(newIatInSection)
{
vaImportAddress += (DWORD)IatSize;
}
if(BuildDirectImportsJumpTable)
{
vaImportAddress += (DWORD)iatReferenceScan->getSizeInBytesOfJumpTableInSection();
}
if(isPE32())
{
pNTHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = vaImportAddress;
pNTHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)(numberOfImportDescriptors * sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
else
{
pNTHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = vaImportAddress;
pNTHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)(numberOfImportDescriptors * sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
return true;
}
bool ImportRebuilder::buildNewMappedImportTable(std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
calculateImportSizes(moduleList);
importSectionIndex = listPeSection.size() - 1;
DWORD dwSize = fillImportSection(moduleList);
if(!dwSize)
{
return false;
}
DWORD vaImportAddress = listPeSection[importSectionIndex].sectionHeader.VirtualAddress;
if(useOFT)
{
//OFT array is at the beginning of the import section
vaImportAddress += (DWORD)sizeOfOFTArray;
}
DWORD headerOffset = sizeof(IMAGE_DOS_HEADER);
if(dosStubSize && pDosStub)
{
headerOffset += dosStubSize;
}
if(isPE32())
{
PIMAGE_NT_HEADERS32 pMappedNTHeader32 = (PIMAGE_NT_HEADERS32)(fileMapVA + headerOffset);
pMappedNTHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = vaImportAddress;
pMappedNTHeader32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)(numberOfImportDescriptors * sizeof(IMAGE_IMPORT_DESCRIPTOR));
headerOffset += sizeof(IMAGE_NT_HEADERS32);
}
else
{
PIMAGE_NT_HEADERS64 pMappedNTHeader64 = (PIMAGE_NT_HEADERS64)(fileMapVA + headerOffset);
pMappedNTHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = vaImportAddress;
pMappedNTHeader64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = (DWORD)(numberOfImportDescriptors * sizeof(IMAGE_IMPORT_DESCRIPTOR));
headerOffset += sizeof(IMAGE_NT_HEADERS64);
}
//setFlagToIATSection
headerOffset += sizeof(IMAGE_SECTION_HEADER) * importSectionIndex;
PIMAGE_SECTION_HEADER pImportSection = (PIMAGE_SECTION_HEADER)(fileMapVA + headerOffset);
pImportSection->Characteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
return true;
}
bool ImportRebuilder::createNewImportSection(std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
char sectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {0};
StringConversion::ToASCII(this->sectionName, sectionName, IMAGE_SIZEOF_SHORT_NAME + 1);
calculateImportSizes(moduleList);
if(newIatInSection)
{
sizeOfImportSection += IatSize;
}
if(BuildDirectImportsJumpTable)
{
sizeOfImportSection += iatReferenceScan->getSizeInBytesOfJumpTableInSection();
}
return addNewLastSection(sectionName, (DWORD)sizeOfImportSection, 0);
}
void ImportRebuilder::setFlagToIATSection(DWORD_PTR iatAddress)
{
for(size_t i = 0; i < listPeSection.size(); i++)
{
if((listPeSection[i].sectionHeader.VirtualAddress <= iatAddress) && ((listPeSection[i].sectionHeader.VirtualAddress + listPeSection[i].sectionHeader.Misc.VirtualSize) > iatAddress))
{
//section must be read and writeable
listPeSection[i].sectionHeader.Characteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
}
}
}
DWORD ImportRebuilder::fillImportSection(std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator mapIt;
std::map<DWORD_PTR, ImportThunk>::iterator mapIt2;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = 0;
PIMAGE_IMPORT_BY_NAME pImportByName = 0;
PIMAGE_THUNK_DATA pThunk = 0;
ImportModuleThunk* importModuleThunk = 0;
ImportThunk* importThunk = 0;
size_t stringLength = 0;
DWORD_PTR lastRVA = 0;
BYTE* sectionData = listPeSection[importSectionIndex].data;
DWORD offset = 0;
DWORD offsetOFTArray = 0;
/*
New Scylla section contains:
1. (optional) direct imports jump table
2. (optional) new iat
3. (optional) OFT
4. Normal IAT entries
*/
if(BuildDirectImportsJumpTable)
{
offset += iatReferenceScan->getSizeInBytesOfJumpTableInSection();
offsetOFTArray += iatReferenceScan->getSizeInBytesOfJumpTableInSection();
}
if(newIatInSection)
{
offset += IatSize; //new iat at the beginning
offsetOFTArray += IatSize;
memset(sectionData, 0xFF, offset);
}
if(useOFT)
{
offset += (DWORD)sizeOfOFTArray; //size includes null termination
}
pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)sectionData + offset);
//skip the IMAGE_IMPORT_DESCRIPTOR
offset += (DWORD)(numberOfImportDescriptors * sizeof(IMAGE_IMPORT_DESCRIPTOR));
for(mapIt = moduleList.begin() ; mapIt != moduleList.end(); mapIt++)
{
importModuleThunk = &((*mapIt).second);
stringLength = addImportDescriptor(importModuleThunk, offset, offsetOFTArray);
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"fillImportSection :: importDesc.Name %X", pImportDescriptor->Name);
#endif
offset += (DWORD)stringLength; //stringLength has null termination char
pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)sectionData + offset);
//pThunk = (PIMAGE_THUNK_DATA)(getMemoryPointerFromRVA(importModuleThunk->firstThunk));
lastRVA = importModuleThunk->firstThunk - sizeof(DWORD_PTR);
for(mapIt2 = (*mapIt).second.thunkList.begin() ; mapIt2 != (*mapIt).second.thunkList.end(); mapIt2++)
{
importThunk = &((*mapIt2).second);
if(useOFT)
{
pThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)sectionData + offsetOFTArray);
offsetOFTArray += sizeof(DWORD_PTR); //increase OFT array index
}
else
{
pThunk = (PIMAGE_THUNK_DATA)(getMemoryPointerFromRVA(importThunk->rva));
}
//check wrong iat pointer
if(!pThunk)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"fillImportSection :: Failed to get pThunk RVA: %X", importThunk->rva);
#endif
return 0;
}
if((lastRVA + sizeof(DWORD_PTR)) != importThunk->rva)
{
//add additional import desc
addSpecialImportDescriptor(importThunk->rva, offsetOFTArray);
if(useOFT)
{
pThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)sectionData + offsetOFTArray);
offsetOFTArray += sizeof(DWORD_PTR); //increase OFT array index, next module
}
}
lastRVA = importThunk->rva;
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"fillImportSection :: importThunk %X pThunk %X pImportByName %X offset %X", importThunk, pThunk, pImportByName, offset);
#endif
stringLength = addImportToImportTable(importThunk, pThunk, pImportByName, offset);
offset += (DWORD)stringLength; //is 0 bei import by ordinal
pImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)pImportByName + stringLength);
}
offsetOFTArray += sizeof(DWORD_PTR); //increase OFT array index, next module
pImportDescriptor++;
}
return offset;
}
size_t ImportRebuilder::addImportDescriptor(ImportModuleThunk* pImportModule, DWORD sectionOffset, DWORD sectionOffsetOFTArray)
{
char dllName[MAX_PATH];
StringConversion::ToASCII(pImportModule->moduleName, dllName, _countof(dllName));
size_t stringLength = strlen(dllName) + 1;
/*
Warning: stringLength MUST include null termination char
*/
memcpy((listPeSection[importSectionIndex].data + sectionOffset), dllName, stringLength); //copy module name to section
pImportDescriptor->FirstThunk = (DWORD)pImportModule->firstThunk;
pImportDescriptor->Name = (DWORD)convertOffsetToRVAVector(listPeSection[importSectionIndex].sectionHeader.PointerToRawData + sectionOffset);
if(useOFT)
{
pImportDescriptor->OriginalFirstThunk = (DWORD)convertOffsetToRVAVector(listPeSection[importSectionIndex].sectionHeader.PointerToRawData + sectionOffsetOFTArray);
}
return stringLength;
}
void ImportRebuilder::addSpecialImportDescriptor(DWORD_PTR rvaFirstThunk, DWORD sectionOffsetOFTArray)
{
PIMAGE_IMPORT_DESCRIPTOR oldID = pImportDescriptor;
pImportDescriptor++;
pImportDescriptor->FirstThunk = (DWORD)rvaFirstThunk;
pImportDescriptor->Name = oldID->Name;
if(useOFT)
{
pImportDescriptor->OriginalFirstThunk = (DWORD)convertOffsetToRVAVector(listPeSection[importSectionIndex].sectionHeader.PointerToRawData + sectionOffsetOFTArray);
}
}
void ImportRebuilder::calculateImportSizes(std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator mapIt;
std::map<DWORD_PTR, ImportThunk>::iterator mapIt2;
DWORD_PTR lastRVA = 0;
sizeOfImportSection = 0;
sizeOfApiAndModuleNames = 0;
sizeOfOFTArray = 0;
numberOfImportDescriptors = moduleList.size() + 1; //last is zero'd
for(mapIt = moduleList.begin() ; mapIt != moduleList.end(); mapIt++)
{
lastRVA = (*mapIt).second.firstThunk - sizeof(DWORD_PTR);
sizeOfApiAndModuleNames += (DWORD)(wcslen((*mapIt).second.moduleName) + 1);
for(mapIt2 = (*mapIt).second.thunkList.begin() ; mapIt2 != (*mapIt).second.thunkList.end(); mapIt2++)
{
if((lastRVA + sizeof(DWORD_PTR)) != (*mapIt2).second.rva)
{
numberOfImportDescriptors++; //add additional import desc
sizeOfOFTArray += sizeof(DWORD_PTR) + sizeof(DWORD_PTR);
}
if((*mapIt2).second.name[0] != '\0')
{
sizeOfApiAndModuleNames += sizeof(WORD); //Hint from IMAGE_IMPORT_BY_NAME
sizeOfApiAndModuleNames += (DWORD)(strlen((*mapIt2).second.name) + 1);
}
//OriginalFirstThunk Array in Import Section: value
sizeOfOFTArray += sizeof(DWORD_PTR);
lastRVA = (*mapIt2).second.rva;
}
//OriginalFirstThunk Array in Import Section: NULL termination
sizeOfOFTArray += sizeof(DWORD_PTR);
}
sizeOfImportSection = sizeOfOFTArray + sizeOfApiAndModuleNames + (numberOfImportDescriptors * sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
size_t ImportRebuilder::addImportToImportTable(ImportThunk* pImport, PIMAGE_THUNK_DATA pThunk, PIMAGE_IMPORT_BY_NAME pImportByName, DWORD sectionOffset)
{
size_t stringLength = 0;
if(pImport->name[0] == '\0')
{
pThunk->u1.AddressOfData = (IMAGE_ORDINAL(pImport->ordinal) | IMAGE_ORDINAL_FLAG);
}
else
{
pImportByName->Hint = pImport->hint;
stringLength = strlen(pImport->name) + 1;
memcpy(pImportByName->Name, pImport->name, stringLength);
pThunk->u1.AddressOfData = convertOffsetToRVAVector(listPeSection[importSectionIndex].sectionHeader.PointerToRawData + sectionOffset);
if(!pThunk->u1.AddressOfData)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"addImportToImportTable :: failed to get AddressOfData %X %X", listPeSection[importSectionIndex].sectionHeader.PointerToRawData, sectionOffset);
#endif
}
//next import should be nulled
pThunk++;
pThunk->u1.AddressOfData = 0;
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"addImportToImportTable :: pThunk->u1.AddressOfData %X %X %X", pThunk->u1.AddressOfData, pThunk, listPeSection[importSectionIndex].sectionHeader.PointerToRawData + sectionOffset);
#endif
stringLength += sizeof(WORD);
}
return stringLength;
}
BYTE* ImportRebuilder::getMemoryPointerFromRVA(DWORD_PTR dwRVA)
{
int peSectionIndex = convertRVAToOffsetVectorIndex(dwRVA);
if(peSectionIndex == -1)
{
return 0;
}
DWORD rvaPointer = ((DWORD)dwRVA - listPeSection[peSectionIndex].sectionHeader.VirtualAddress);
DWORD minSectionSize = rvaPointer + (sizeof(DWORD_PTR) * 2); //add space for 1 IAT address
if(listPeSection[peSectionIndex].data == 0 || listPeSection[peSectionIndex].dataSize == 0)
{
listPeSection[peSectionIndex].dataSize = minSectionSize;
listPeSection[peSectionIndex].normalSize = minSectionSize;
listPeSection[peSectionIndex].data = new BYTE[listPeSection[peSectionIndex].dataSize];
listPeSection[peSectionIndex].sectionHeader.SizeOfRawData = listPeSection[peSectionIndex].dataSize;
}
else if(listPeSection[peSectionIndex].dataSize < minSectionSize)
{
BYTE* temp = new BYTE[minSectionSize];
memcpy(temp, listPeSection[peSectionIndex].data, listPeSection[peSectionIndex].dataSize);
delete [] listPeSection[peSectionIndex].data;
listPeSection[peSectionIndex].data = temp;
listPeSection[peSectionIndex].dataSize = minSectionSize;
listPeSection[peSectionIndex].normalSize = minSectionSize;
listPeSection[peSectionIndex].sectionHeader.SizeOfRawData = listPeSection[peSectionIndex].dataSize;
}
return (BYTE*)((DWORD_PTR)listPeSection[peSectionIndex].data + rvaPointer);
}
void ImportRebuilder::enableOFTSupport()
{
useOFT = true;
}
void ImportRebuilder::enableNewIatInSection(DWORD_PTR iatAddress, DWORD iatSize)
{
newIatInSection = true;
IatAddress = iatAddress;
IatSize = iatSize;
iatReferenceScan->ScanForDirectImports = false;
iatReferenceScan->ScanForNormalImports = true;
iatReferenceScan->startScan(ProcessAccessHelp::targetImageBase, (DWORD)ProcessAccessHelp::targetSizeOfImage, IatAddress, IatSize);
}
void ImportRebuilder::patchFileForNewIatLocation()
{
iatReferenceScan->patchNewIat(getStandardImagebase(), newIatBaseAddressRVA, (PeParser*)this);
}
void ImportRebuilder::changeIatBaseAddress(std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator mapIt;
std::map<DWORD_PTR, ImportThunk>::iterator mapIt2;
DWORD_PTR oldIatRva = IatAddress - ProcessAccessHelp::targetImageBase;
for(mapIt = moduleList.begin() ; mapIt != moduleList.end(); mapIt++)
{
(*mapIt).second.firstThunk = (*mapIt).second.firstThunk - oldIatRva + newIatBaseAddressRVA;
for(mapIt2 = (*mapIt).second.thunkList.begin() ; mapIt2 != (*mapIt).second.thunkList.end(); mapIt2++)
{
(*mapIt2).second.rva = (*mapIt2).second.rva - oldIatRva + newIatBaseAddressRVA;
}
}
}
void ImportRebuilder::patchFileForDirectImportJumpTable()
{
if(newIatInSection)
{
iatReferenceScan->patchDirectJumpTable(getStandardImagebase(), directImportsJumpTableRVA, (PeParser*)this, JMPTableMemory, newIatBaseAddressRVA);
}
else
{
iatReferenceScan->patchDirectJumpTable(getStandardImagebase(), directImportsJumpTableRVA, (PeParser*)this, JMPTableMemory, 0);
}
}

View File

@ -0,0 +1,101 @@
#pragma once
#include <map>
#include "PeParser.h"
#include "Thunks.h"
#include "IATReferenceScan.h"
class ImportRebuilder : public PeParser
{
public:
ImportRebuilder(const WCHAR* file, const WCHAR* sectionName) : PeParser(file, true)
{
pImportDescriptor = 0;
pThunkData = 0;
pImportByName = 0;
numberOfImportDescriptors = 0;
sizeOfImportSection = 0;
sizeOfApiAndModuleNames = 0;
importSectionIndex = 0;
useOFT = false;
sizeOfOFTArray = 0;
newIatInSection = false;
BuildDirectImportsJumpTable = false;
sizeOfJumpTable = 0;
this->sectionName = (WCHAR*)sectionName;
}
ImportRebuilder(const DWORD_PTR iatVA, const DWORD_PTR FileMapVA, const HANDLE hFileMap, const WCHAR* sectionName) : PeParser(iatVA, FileMapVA, hFileMap, true)
{
pImportDescriptor = 0;
pThunkData = 0;
pImportByName = 0;
numberOfImportDescriptors = 0;
sizeOfImportSection = 0;
sizeOfApiAndModuleNames = 0;
importSectionIndex = 0;
useOFT = false;
sizeOfOFTArray = 0;
newIatInSection = false;
BuildDirectImportsJumpTable = false;
sizeOfJumpTable = 0;
this->sectionName = (WCHAR*)sectionName;
}
bool rebuildImportTable(const WCHAR* newFilePath, std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
bool rebuildMappedImportTable(DWORD_PTR iatVA, std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
void enableOFTSupport();
void enableNewIatInSection(DWORD_PTR iatAddress, DWORD iatSize);
int getIATSectionSize(std::map<DWORD_PTR, ImportModuleThunk> & moduleList)
{
this->calculateImportSizes(moduleList);
return this->sizeOfImportSection;
} ;
IATReferenceScan* iatReferenceScan;
bool BuildDirectImportsJumpTable;
private:
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
PIMAGE_THUNK_DATA pThunkData;
PIMAGE_IMPORT_BY_NAME pImportByName;
size_t numberOfImportDescriptors;
size_t sizeOfImportSection;
size_t sizeOfApiAndModuleNames;
size_t importSectionIndex;
WCHAR* sectionName;
//OriginalFirstThunk Array in Import Section
size_t sizeOfOFTArray;
bool useOFT;
bool newIatInSection;
DWORD_PTR IatAddress;
DWORD IatSize;
DWORD sizeOfJumpTable;
DWORD directImportsJumpTableRVA;
BYTE* JMPTableMemory;
DWORD newIatBaseAddressRVA;
DWORD fillImportSection(std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
BYTE* getMemoryPointerFromRVA(DWORD_PTR dwRVA);
bool createNewImportSection(std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
bool buildNewImportTable(std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
bool buildNewMappedImportTable(std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
void setFlagToIATSection(DWORD_PTR iatAddress);
size_t addImportToImportTable(ImportThunk* pImport, PIMAGE_THUNK_DATA pThunk, PIMAGE_IMPORT_BY_NAME pImportByName, DWORD sectionOffset);
size_t addImportDescriptor(ImportModuleThunk* pImportModule, DWORD sectionOffset, DWORD sectionOffsetOFTArray);
void calculateImportSizes(std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
void addSpecialImportDescriptor(DWORD_PTR rvaFirstThunk, DWORD sectionOffsetOFTArray);
void patchFileForNewIatLocation();
void changeIatBaseAddress(std::map<DWORD_PTR, ImportModuleThunk> & moduleList);
void patchFileForDirectImportJumpTable();
};

View File

@ -0,0 +1,84 @@
#include "stdafx.h"
#include "NativeWinApi.h"
def_NtCreateThreadEx NativeWinApi::NtCreateThreadEx = 0;
def_NtDuplicateObject NativeWinApi::NtDuplicateObject = 0;
def_NtOpenProcess NativeWinApi::NtOpenProcess = 0;
def_NtOpenThread NativeWinApi::NtOpenThread = 0;
def_NtQueryObject NativeWinApi::NtQueryObject = 0;
def_NtQueryInformationFile NativeWinApi::NtQueryInformationFile = 0;
def_NtQueryInformationProcess NativeWinApi::NtQueryInformationProcess = 0;
def_NtQueryInformationThread NativeWinApi::NtQueryInformationThread = 0;
def_NtQuerySystemInformation NativeWinApi::NtQuerySystemInformation = 0;
def_NtQueryVirtualMemory NativeWinApi::NtQueryVirtualMemory = 0;
def_NtResumeProcess NativeWinApi::NtResumeProcess = 0;
def_NtResumeThread NativeWinApi::NtResumeThread = 0;
def_NtSetInformationThread NativeWinApi::NtSetInformationThread = 0;
def_NtSuspendProcess NativeWinApi::NtSuspendProcess = 0;
def_NtTerminateProcess NativeWinApi::NtTerminateProcess = 0;
def_NtOpenSymbolicLinkObject NativeWinApi::NtOpenSymbolicLinkObject = 0;
def_NtQuerySymbolicLinkObject NativeWinApi::NtQuerySymbolicLinkObject = 0;
def_RtlNtStatusToDosError NativeWinApi::RtlNtStatusToDosError = 0;
def_NtClose NativeWinApi::NtClose = 0;
void NativeWinApi::initialize()
{
if(RtlNtStatusToDosError)
{
return;
}
HMODULE hModuleNtdll = GetModuleHandle(L"ntdll.dll");
if(!hModuleNtdll)
{
return;
}
NtCreateThreadEx = (def_NtCreateThreadEx)GetProcAddress(hModuleNtdll, "NtCreateThreadEx");
NtDuplicateObject = (def_NtDuplicateObject)GetProcAddress(hModuleNtdll, "NtDuplicateObject");
NtOpenProcess = (def_NtOpenProcess)GetProcAddress(hModuleNtdll, "NtOpenProcess");
NtOpenThread = (def_NtOpenThread)GetProcAddress(hModuleNtdll, "NtOpenThread");
NtQueryObject = (def_NtQueryObject)GetProcAddress(hModuleNtdll, "NtQueryObject");
NtQueryInformationFile = (def_NtQueryInformationFile)GetProcAddress(hModuleNtdll, "NtQueryInformationFile");
NtQueryInformationProcess = (def_NtQueryInformationProcess)GetProcAddress(hModuleNtdll, "NtQueryInformationProcess");
NtQueryInformationThread = (def_NtQueryInformationThread)GetProcAddress(hModuleNtdll, "NtQueryInformationThread");
NtQuerySystemInformation = (def_NtQuerySystemInformation)GetProcAddress(hModuleNtdll, "NtQuerySystemInformation");
NtQueryVirtualMemory = (def_NtQueryVirtualMemory)GetProcAddress(hModuleNtdll, "NtQueryVirtualMemory");
NtResumeProcess = (def_NtResumeProcess)GetProcAddress(hModuleNtdll, "NtResumeProcess");
NtResumeThread = (def_NtResumeThread)GetProcAddress(hModuleNtdll, "NtResumeThread");
NtSetInformationThread = (def_NtSetInformationThread)GetProcAddress(hModuleNtdll, "NtSetInformationThread");
NtSuspendProcess = (def_NtSuspendProcess)GetProcAddress(hModuleNtdll, "NtSuspendProcess");
NtTerminateProcess = (def_NtTerminateProcess)GetProcAddress(hModuleNtdll, "NtTerminateProcess");
NtOpenSymbolicLinkObject = (def_NtOpenSymbolicLinkObject)GetProcAddress(hModuleNtdll, "NtOpenSymbolicLinkObject");
NtQuerySymbolicLinkObject = (def_NtQuerySymbolicLinkObject)GetProcAddress(hModuleNtdll, "NtQuerySymbolicLinkObject");
RtlNtStatusToDosError = (def_RtlNtStatusToDosError)GetProcAddress(hModuleNtdll, "RtlNtStatusToDosError");
NtClose = (def_NtClose)GetProcAddress(hModuleNtdll, "NtClose");
}
PPEB NativeWinApi::getCurrentProcessEnvironmentBlock()
{
return getProcessEnvironmentBlockAddress(GetCurrentProcess());
}
PPEB NativeWinApi::getProcessEnvironmentBlockAddress(HANDLE processHandle)
{
ULONG lReturnLength = 0;
PROCESS_BASIC_INFORMATION processBasicInformation;
if((NtQueryInformationProcess(processHandle, ProcessBasicInformation, &processBasicInformation, sizeof(PROCESS_BASIC_INFORMATION), &lReturnLength) >= 0) && (lReturnLength == sizeof(PROCESS_BASIC_INFORMATION)))
{
//printf("NtQueryInformationProcess success %d\n",sizeof(PROCESS_BASIC_INFORMATION));
return processBasicInformation.PebBaseAddress;
}
else
{
//printf("NtQueryInformationProcess failed %d vs %d\n",lReturnLength,sizeof(PROCESS_BASIC_INFORMATION));
return 0;
}
}

View File

@ -0,0 +1,502 @@
#pragma once
#include <windows.h>
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define DUPLICATE_SAME_ATTRIBUTES 0x00000004
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef LONG KPRIORITY;
typedef LONG NTSTATUS;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemNextEventIdInformation,
SystemEventIdsInformation,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemPlugPlayBusInformation,
SystemDockInformation,
SystemPowerInformation2,
SystemProcessorSpeedInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation
} SYSTEM_INFORMATION_CLASS;
typedef struct _IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _FILE_NAME_INFORMATION // Information Classes 9 and 21
{
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION;
typedef enum _FILE_INFORMATION_CLASS
{
FileNameInformation = 9,
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
#define InitializeObjectAttributes(p,n,a,r,s) \
{ \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->ObjectName = n; \
(p)->Attributes = a; \
(p)->RootDirectory = r; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
PVOID RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef struct _MEMORY_REGION_INFORMATION
{
PVOID AllocationBase; //Imagebase
ULONG AllocationProtect;
ULONG RegionType;
SIZE_T RegionSize; //Size of image
} MEMORY_REGION_INFORMATION, *PMEMORY_REGION_INFORMATION;
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectAllInformation,
ObjectDataInformation
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
typedef enum _THREADINFOCLASS
{
ThreadBasicInformation,
ThreadTimes,
ThreadPriority,
ThreadBasePriority,
ThreadAffinityMask,
ThreadImpersonationToken,
ThreadDescriptorTableEntry,
ThreadEnableAlignmentFaultFixup,
ThreadEventPair_Reusable,
ThreadQuerySetWin32StartAddress,
ThreadZeroTlsCell,
ThreadPerformanceCount,
ThreadAmILastThread,
ThreadIdealProcessor,
ThreadPriorityBoost,
ThreadSetTlsArrayAddress,
ThreadIsIoPending,
ThreadHideFromDebugger,
ThreadBreakOnTermination,
MaxThreadInfoClass
} THREADINFOCLASS;
//
// Memory Information Classes for NtQueryVirtualMemory
//
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation,
MemoryWorkingSetInformation,
MemoryMappedFilenameInformation, //MemorySectionName, UNICODE_STRING, Wrapper: GetMappedFileNameW
MemoryRegionInformation, //MemoryBasicVlmInformation, MEMORY_REGION_INFORMATION
MemoryWorkingSetExInformation
} MEMORY_INFORMATION_CLASS;
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers,
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessResourceManagement,
ProcessCookie,
ProcessImageInformation,
MaxProcessInfoClass
} PROCESSINFOCLASS;
typedef struct _PEB_LDR_DATA
{
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB
{
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
BYTE Reserved4[104];
PVOID Reserved5[52];
PVOID PostProcessInitRoutine;
BYTE Reserved6[128];
PVOID Reserved7[1];
ULONG SessionId;
} PEB, *PPEB;
typedef struct _PROCESS_BASIC_INFORMATION
{
PVOID Reserved1;
PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
typedef struct _MEMORY_WORKING_SET_LIST
{
ULONG NumberOfPages;
ULONG WorkingSetList[1];
} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;
typedef struct _MEMORY_SECTION_NAME
{
UNICODE_STRING SectionFileName;
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
typedef struct _SYSTEM_SESSION_PROCESS_INFORMATION
{
ULONG SessionId;
ULONG SizeOfBuf;
PVOID Buffer;
} SYSTEM_SESSION_PROCESS_INFORMATION, *PSYSTEM_SESSION_PROCESS_INFORMATION;
typedef struct _SYSTEM_THREAD_INFORMATION
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
ULONG WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION
{
SYSTEM_THREAD_INFORMATION ThreadInfo;
PVOID StackBase;
PVOID StackLimit;
PVOID Win32StartAddress;
PVOID TebAddress; /* This is only filled in on Vista and above */
ULONG_PTR Reserved2;
ULONG_PTR Reserved3;
ULONG_PTR Reserved4;
} SYSTEM_EXTENDED_THREAD_INFORMATION, *PSYSTEM_EXTENDED_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR PageDirectoryBase;
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_THREAD_INFORMATION Threads[1];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
///////////////////////////////////////////////////////////////////////////////////////
//Evolution of Process Environment Block (PEB) http://blog.rewolf.pl/blog/?p=573
//March 2, 2013 / ReWolf posted in programming, reverse engineering, source code, x64 /
#pragma pack(push)
#pragma pack(1)
template <class T>
struct LIST_ENTRY_T
{
T Flink;
T Blink;
};
template <class T>
struct UNICODE_STRING_T
{
union
{
struct
{
WORD Length;
WORD MaximumLength;
};
T dummy;
};
T _Buffer;
};
template <class T, class NGF, int A>
struct _PEB_T
{
union
{
struct
{
BYTE InheritedAddressSpace;
BYTE ReadImageFileExecOptions;
BYTE BeingDebugged;
BYTE _SYSTEM_DEPENDENT_01;
};
T dummy01;
};
T Mutant;
T ImageBaseAddress;
T Ldr;
T ProcessParameters;
T SubSystemData;
T ProcessHeap;
T FastPebLock;
T _SYSTEM_DEPENDENT_02;
T _SYSTEM_DEPENDENT_03;
T _SYSTEM_DEPENDENT_04;
union
{
T KernelCallbackTable;
T UserSharedInfoPtr;
};
DWORD SystemReserved;
DWORD _SYSTEM_DEPENDENT_05;
T _SYSTEM_DEPENDENT_06;
T TlsExpansionCounter;
T TlsBitmap;
DWORD TlsBitmapBits[2];
T ReadOnlySharedMemoryBase;
T _SYSTEM_DEPENDENT_07;
T ReadOnlyStaticServerData;
T AnsiCodePageData;
T OemCodePageData;
T UnicodeCaseTableData;
DWORD NumberOfProcessors;
union
{
DWORD NtGlobalFlag;
NGF dummy02;
};
LARGE_INTEGER CriticalSectionTimeout;
T HeapSegmentReserve;
T HeapSegmentCommit;
T HeapDeCommitTotalFreeThreshold;
T HeapDeCommitFreeBlockThreshold;
DWORD NumberOfHeaps;
DWORD MaximumNumberOfHeaps;
T ProcessHeaps;
};
typedef _PEB_T<DWORD, DWORD64, 34> PEB32;
typedef _PEB_T<DWORD64, DWORD, 30> PEB64;
#ifdef _WIN64
typedef PEB64 PEB_CURRENT;
#else
typedef PEB32 PEB_CURRENT;
#endif
#pragma pack(pop)
typedef NTSTATUS(WINAPI* def_NtTerminateProcess)(HANDLE ProcessHandle, NTSTATUS ExitStatus);
typedef NTSTATUS(WINAPI* def_NtQueryObject)(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
typedef NTSTATUS(WINAPI* def_NtDuplicateObject)(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, BOOLEAN InheritHandle, ULONG Options);
typedef NTSTATUS(WINAPI* def_NtQueryInformationFile)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
typedef NTSTATUS(WINAPI* def_NtQueryInformationThread)(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength);
typedef NTSTATUS(WINAPI* def_NtQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
typedef NTSTATUS(WINAPI* def_NtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
typedef NTSTATUS(WINAPI* def_NtQueryVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID Buffer, SIZE_T MemoryInformationLength, PSIZE_T ReturnLength);
typedef NTSTATUS(WINAPI* def_NtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK AccessMask, PVOID ObjectAttributes, PCLIENT_ID ClientId);
typedef NTSTATUS(WINAPI* def_NtOpenThread)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId);
typedef NTSTATUS(WINAPI* def_NtResumeThread)(HANDLE ThreadHandle, PULONG SuspendCount);
typedef NTSTATUS(WINAPI* def_NtSetInformationThread)(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength);
typedef NTSTATUS(WINAPI* def_NtCreateThreadEx)(PHANDLE hThread, ACCESS_MASK DesiredAccess, LPVOID ObjectAttributes, HANDLE ProcessHandle, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, int CreateFlags, ULONG StackZeroBits, LPVOID SizeOfStackCommit, LPVOID SizeOfStackReserve, LPVOID lpBytesBuffer);
typedef NTSTATUS(WINAPI* def_NtSuspendProcess)(HANDLE ProcessHandle);
typedef NTSTATUS(WINAPI* def_NtResumeProcess)(HANDLE ProcessHandle);
typedef NTSTATUS(WINAPI* def_NtOpenSymbolicLinkObject)(PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
typedef NTSTATUS(WINAPI* def_NtQuerySymbolicLinkObject)(HANDLE LinkHandle, PUNICODE_STRING LinkTarget, PULONG ReturnedLength);
typedef ULONG(WINAPI* def_RtlNtStatusToDosError)(NTSTATUS Status);
typedef NTSTATUS(WINAPI* def_NtClose)(HANDLE Handle);
//Flags from waliedassar
#define NtCreateThreadExFlagCreateSuspended 0x1
#define NtCreateThreadExFlagSuppressDllMains 0x2
#define NtCreateThreadExFlagHideFromDebugger 0x4
#define SYMBOLIC_LINK_QUERY (0x0001)
class NativeWinApi
{
public:
static def_NtCreateThreadEx NtCreateThreadEx;
static def_NtDuplicateObject NtDuplicateObject;
static def_NtOpenProcess NtOpenProcess;
static def_NtOpenThread NtOpenThread;
static def_NtQueryObject NtQueryObject;
static def_NtQueryInformationFile NtQueryInformationFile;
static def_NtQueryInformationProcess NtQueryInformationProcess;
static def_NtQueryInformationThread NtQueryInformationThread;
static def_NtQuerySystemInformation NtQuerySystemInformation;
static def_NtQueryVirtualMemory NtQueryVirtualMemory;
static def_NtResumeProcess NtResumeProcess;
static def_NtResumeThread NtResumeThread;
static def_NtSetInformationThread NtSetInformationThread;
static def_NtSuspendProcess NtSuspendProcess;
static def_NtTerminateProcess NtTerminateProcess;
static def_NtOpenSymbolicLinkObject NtOpenSymbolicLinkObject;
static def_NtQuerySymbolicLinkObject NtQuerySymbolicLinkObject;
static def_NtClose NtClose;
static def_RtlNtStatusToDosError RtlNtStatusToDosError;
static void RtlInitUnicodeString(PUNICODE_STRING DestinationString, PWSTR SourceString)
{
DestinationString->Buffer = SourceString;
DestinationString->MaximumLength = DestinationString->Length = (USHORT)wcslen(SourceString) * sizeof(WCHAR);
}
static void initialize();
static PPEB getCurrentProcessEnvironmentBlock();
static PPEB getProcessEnvironmentBlockAddress(HANDLE processHandle);
};

1378
scylla_wrapper/PeParser.cpp Normal file

File diff suppressed because it is too large Load Diff

167
scylla_wrapper/PeParser.h Normal file
View File

@ -0,0 +1,167 @@
#pragma once
#include <windows.h>
#include <vector>
class PeSection
{
public:
WCHAR name[IMAGE_SIZEOF_SHORT_NAME + 1];
DWORD_PTR virtualAddress;
DWORD virtualSize;
DWORD rawAddress;
DWORD rawSize;
DWORD characteristics;
bool isDumped;
//highlight big virtual sizes -> anti-dump protection
bool highlightVirtualSize()
{
return (virtualSize > 0x2000000);
};
};
class PeFileSection
{
public:
IMAGE_SECTION_HEADER sectionHeader;
BYTE* data;
DWORD dataSize;
DWORD normalSize;
PeFileSection()
{
ZeroMemory(&sectionHeader, sizeof(IMAGE_SECTION_HEADER));
data = 0;
dataSize = 0;
normalSize = 0;
}
};
class PeParser
{
public:
PeParser(const WCHAR* file, bool readSectionHeaders = true);
PeParser(const DWORD_PTR moduleBase, bool readSectionHeaders = true);
PeParser(const DWORD_PTR iatVA, const DWORD_PTR FileMapVA, const HANDLE hFileMap, bool readSectionHeaders = true);
~PeParser();
bool isValidPeFile();
bool isPE64();
bool isPE32();
bool isTargetFileSamePeFormat();
WORD getNumberOfSections();
std::vector<PeFileSection> & getSectionHeaderList();
bool hasExportDirectory();
bool hasTLSDirectory();
bool hasRelocationDirectory();
bool hasOverlayData();
DWORD getEntryPoint();
bool getSectionNameUnicode(const int sectionIndex, WCHAR* output, const int outputLen);
DWORD getSectionHeaderBasedFileSize();
DWORD getSectionHeaderBasedSizeOfImage();
bool readPeSectionsFromProcess();
bool readPeSectionsFromFile();
bool readPeSectionsFromMappedFile();
bool savePeFileToDisk(const WCHAR* newFile);
void removeDosStub();
void alignAllSectionHeaders();
void fixPeHeader();
void setDefaultFileAlignment();
bool dumpProcess(DWORD_PTR modBase, DWORD_PTR entryPoint, const WCHAR* dumpFilePath);
bool dumpProcess(DWORD_PTR modBase, DWORD_PTR entryPoint, const WCHAR* dumpFilePath, std::vector<PeSection> & sectionList);
void setEntryPointVa(DWORD_PTR entryPoint);
void setEntryPointRva(DWORD entryPoint);
static bool updatePeHeaderChecksum(const WCHAR* targetFile, DWORD fileSize);
BYTE* getSectionMemoryByIndex(int index);
DWORD getSectionMemorySizeByIndex(int index);
int convertRVAToOffsetVectorIndex(DWORD_PTR dwRVA);
DWORD_PTR convertOffsetToRVAVector(DWORD_PTR dwOffset);
DWORD_PTR convertRVAToOffsetVector(DWORD_PTR dwRVA);
DWORD_PTR convertRVAToOffsetRelative(DWORD_PTR dwRVA);
DWORD getSectionAddressRVAByIndex(int index);
PIMAGE_NT_HEADERS getCurrentNtHeader();
protected:
PeParser();
static const DWORD FileAlignmentConstant = 0x200;
const WCHAR* filename;
DWORD_PTR moduleBaseAddress;
DWORD_PTR fileMapVA;
/************************************************************************/
/* PE FILE */
/* */
/* IMAGE_DOS_HEADER 64 0x40 */
/* IMAGE_NT_HEADERS32 248 0xF8 */
/* IMAGE_NT_HEADERS64 264 0x108 */
/* IMAGE_SECTION_HEADER 40 0x28 */
/************************************************************************/
PIMAGE_DOS_HEADER pDosHeader;
BYTE* pDosStub; //between dos header and section header
DWORD dosStubSize;
PIMAGE_NT_HEADERS32 pNTHeader32;
PIMAGE_NT_HEADERS64 pNTHeader64;
std::vector<PeFileSection> listPeSection;
BYTE* overlayData;
DWORD overlaySize;
/************************************************************************/
BYTE* fileMemory;
BYTE* headerMemory;
HANDLE hFile;
DWORD fileSize;
bool readPeHeaderFromFile(bool readSectionHeaders);
bool readPeHeaderFromFileMapping(bool readSectionHeaders);
bool readPeHeaderFromProcess(bool readSectionHeaders);
bool hasDirectory(const int directoryIndex);
bool getSectionHeaders();
void getDosAndNtHeader(BYTE* memory, LONG size);
DWORD calcCorrectPeHeaderSize(bool readSectionHeaders);
DWORD getInitialHeaderReadSize(bool readSectionHeaders);
bool openFileHandle();
void closeFileHandle();
void initClass();
DWORD isMemoryNotNull(BYTE* data, int dataSize);
bool openWriteFileHandle(const WCHAR* newFile);
bool writeZeroMemoryToFile(HANDLE hFile, DWORD fileOffset, DWORD size);
bool readPeSectionFromFile(DWORD readOffset, PeFileSection & peFileSection);
bool readPeSectionFromProcess(DWORD_PTR readOffset, PeFileSection & peFileSection);
bool readPeSectionFromFileMapping(DWORD readOffset, PeFileSection & peFileSection);
bool readSectionFromProcess(const DWORD_PTR readOffset, PeFileSection & peFileSection);
bool readSectionFromFile(const DWORD readOffset, PeFileSection & peFileSection);
bool readSectionFrom(const DWORD_PTR readOffset, PeFileSection & peFileSection, const bool isProcess);
DWORD_PTR getStandardImagebase();
bool addNewLastSection(const CHAR* sectionName, DWORD sectionSize, BYTE* sectionData);
DWORD alignValue(DWORD badValue, DWORD alignTo);
void setNumberOfSections(WORD numberOfSections);
void removeIatDirectory();
bool getFileOverlay();
};

View File

@ -0,0 +1,963 @@
#include "stdafx.h"
#include "ProcessAccessHelp.h"
#include "DeviceNameResolver.h"
#include <Psapi.h>
#include "PeParser.h"
#include "NativeWinApi.h"
HANDLE ProcessAccessHelp::hProcess = 0;
ModuleInfo* ProcessAccessHelp::selectedModule;
DWORD_PTR ProcessAccessHelp::targetImageBase = 0;
DWORD_PTR ProcessAccessHelp::targetSizeOfImage = 0;
DWORD_PTR ProcessAccessHelp::maxValidAddress = 0;
std::vector<ModuleInfo> ProcessAccessHelp::moduleList; //target process module list
std::vector<ModuleInfo> ProcessAccessHelp::ownModuleList; //own module list
_DInst ProcessAccessHelp::decomposerResult[MAX_INSTRUCTIONS];
unsigned int ProcessAccessHelp::decomposerInstructionsCount = 0;
_CodeInfo ProcessAccessHelp::decomposerCi = {0};
_DecodedInst ProcessAccessHelp::decodedInstructions[MAX_INSTRUCTIONS];
unsigned int ProcessAccessHelp::decodedInstructionsCount = 0;
BYTE ProcessAccessHelp::fileHeaderFromDisk[PE_HEADER_BYTES_COUNT];
//#define DEBUG_COMMENTS
bool ProcessAccessHelp::openProcessHandle(DWORD dwPID)
{
if(dwPID > 0)
{
if(hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: There is already a process handle, HANDLE %X", hProcess);
#endif
return false;
}
else
{
//hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE, 0, dwPID);
//if (!NT_SUCCESS(NativeWinApi::NtOpenProcess(&hProcess,PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_VM_WRITE,&ObjectAttributes, &cid)))
hProcess = NativeOpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_SUSPEND_RESUME | PROCESS_TERMINATE, dwPID);
if(hProcess)
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: Failed to open handle, PID %X", dwPID);
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"openProcessHandle :: Wrong PID, PID %X", dwPID);
#endif
return false;
}
}
HANDLE ProcessAccessHelp::NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId)
{
HANDLE hProcess = 0;
CLIENT_ID cid = {0};
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS ntStatus = 0;
InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0);
cid.UniqueProcess = (HANDLE)dwProcessId;
ntStatus = NativeWinApi::NtOpenProcess(&hProcess, dwDesiredAccess, &ObjectAttributes, &cid);
if(NT_SUCCESS(ntStatus))
{
return hProcess;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"NativeOpenProcess :: Failed to open handle, PID %X Error 0x%X", dwProcessId, NativeWinApi::RtlNtStatusToDosError(ntStatus));
#endif
return 0;
}
}
void ProcessAccessHelp::closeProcessHandle()
{
if(hProcess)
{
CloseHandle(hProcess);
hProcess = 0;
}
moduleList.clear();
targetImageBase = 0;
selectedModule = 0;
}
bool ProcessAccessHelp::readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer)
{
DWORD_PTR addressPart = 0;
DWORD_PTR readBytes = 0;
DWORD_PTR bytesToRead = 0;
MEMORY_BASIC_INFORMATION memBasic = {0};
bool returnValue = false;
if(!hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: hProcess == NULL");
#endif
return returnValue;
}
if(!readMemoryFromProcess(address, size, dataBuffer))
{
addressPart = address;
do
{
if(!VirtualQueryEx(ProcessAccessHelp::hProcess, (LPCVOID)addressPart, &memBasic, sizeof(memBasic)))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryPartlyFromProcess :: Error VirtualQueryEx %X %X err: %u", addressPart, size, GetLastError());
#endif
break;
}
bytesToRead = memBasic.RegionSize;
if((readBytes + bytesToRead) > size)
{
bytesToRead = size - readBytes;
}
if(memBasic.State == MEM_COMMIT)
{
if(!readMemoryFromProcess(addressPart, bytesToRead, (LPVOID)((DWORD_PTR)dataBuffer + readBytes)))
{
break;
}
}
else
{
ZeroMemory((LPVOID)((DWORD_PTR)dataBuffer + readBytes), bytesToRead);
}
readBytes += bytesToRead;
addressPart += memBasic.RegionSize;
}
while(readBytes < size);
if(readBytes == size)
{
returnValue = true;
}
}
else
{
returnValue = true;
}
return returnValue;
}
bool ProcessAccessHelp::writeMemoryToProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer)
{
SIZE_T lpNumberOfBytesWritten = 0;
if(!hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: hProcess == NULL");
#endif
return false;
}
return (WriteProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesWritten) != FALSE);
}
bool ProcessAccessHelp::readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer)
{
SIZE_T lpNumberOfBytesRead = 0;
DWORD dwProtect = 0;
bool returnValue = false;
if(!hProcess)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: hProcess == NULL");
#endif
return returnValue;
}
if(!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError());
#endif
if(!VirtualProtectEx(hProcess, (LPVOID)address, size, PAGE_READWRITE, &dwProtect))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error VirtualProtectEx %X %X err: %u", address, size, GetLastError());
#endif
returnValue = false;
}
else
{
if(!ReadProcessMemory(hProcess, (LPVOID)address, dataBuffer, size, &lpNumberOfBytesRead))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory %X %X err: %u", address, size, GetLastError());
#endif
returnValue = false;
}
else
{
returnValue = true;
}
VirtualProtectEx(hProcess, (LPVOID)address, size, dwProtect, &dwProtect);
}
}
else
{
returnValue = true;
}
if(returnValue)
{
if(size != lpNumberOfBytesRead)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromProcess :: Error ReadProcessMemory read %d bytes requested %d bytes", lpNumberOfBytesRead, size);
#endif
returnValue = false;
}
else
{
returnValue = true;
}
}
return returnValue;
}
bool ProcessAccessHelp::decomposeMemory(BYTE* dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress)
{
ZeroMemory(&decomposerCi, sizeof(_CodeInfo));
decomposerCi.code = dataBuffer;
decomposerCi.codeLen = (int)bufferSize;
decomposerCi.dt = dt;
decomposerCi.codeOffset = startAddress;
decomposerInstructionsCount = 0;
if(distorm_decompose(&decomposerCi, decomposerResult, sizeof(decomposerResult) / sizeof(decomposerResult[0]), &decomposerInstructionsCount) == DECRES_INPUTERR)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"decomposeMemory :: distorm_decompose == DECRES_INPUTERR");
#endif
return false;
}
else
{
return true;
}
}
bool ProcessAccessHelp::disassembleMemory(BYTE* dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset)
{
// Holds the result of the decoding.
_DecodeResult res;
// next is used for instruction's offset synchronization.
// decodedInstructionsCount holds the count of filled instructions' array by the decoder.
decodedInstructionsCount = 0;
_OffsetType offset = startOffset;
res = distorm_decode(offset, dataBuffer, (int)bufferSize, dt, decodedInstructions, MAX_INSTRUCTIONS, &decodedInstructionsCount);
/* for (unsigned int i = 0; i < decodedInstructionsCount; i++) {
#ifdef SUPPORT_64BIT_OFFSET
printf("%0*I64x (%02d) %-24s %s%s%s\n", dt != Decode64Bits ? 8 : 16, decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
#else
printf("%08x (%02d) %-24s %s%s%s\n", decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
#endif
}*/
if(res == DECRES_INPUTERR)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"disassembleMemory :: res == DECRES_INPUTERR");
#endif
return false;
}
else if(res == DECRES_SUCCESS)
{
//printf("disassembleMemory :: res == DECRES_SUCCESS\n");
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"disassembleMemory :: res == %d", res);
#endif
return true; //not all instructions fit in buffer
}
}
DWORD_PTR ProcessAccessHelp::findPattern(DWORD_PTR startOffset, DWORD size, BYTE* pattern, const char* mask)
{
DWORD pos = 0;
size_t searchLen = strlen(mask) - 1;
for(DWORD_PTR retAddress = startOffset; retAddress < startOffset + size; retAddress++)
{
if(*(BYTE*)retAddress == pattern[pos] || mask[pos] == '?')
{
if(mask[pos + 1] == 0x00)
{
return (retAddress - searchLen);
}
pos++;
}
else
{
pos = 0;
}
}
return 0;
}
bool ProcessAccessHelp::readHeaderFromCurrentFile(const WCHAR* filePath)
{
return readHeaderFromFile(fileHeaderFromDisk, sizeof(fileHeaderFromDisk), filePath);
}
LONGLONG ProcessAccessHelp::getFileSize(const WCHAR* filePath)
{
LONGLONG fileSize = 0;
HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile != INVALID_HANDLE_VALUE)
{
fileSize = getFileSize(hFile);
CloseHandle(hFile);
}
return fileSize;
}
LONGLONG ProcessAccessHelp::getFileSize(HANDLE hFile)
{
LARGE_INTEGER lpFileSize = {0};
if((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
if(!GetFileSizeEx(hFile, &lpFileSize))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize :: GetFileSizeEx failed %u", GetLastError());
#endif
return 0;
}
else
{
return lpFileSize.QuadPart;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"ProcessAccessHelp::getFileSize hFile invalid");
#endif
return 0;
}
}
bool ProcessAccessHelp::readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer)
{
DWORD lpNumberOfBytesRead = 0;
DWORD retValue = 0;
DWORD dwError = 0;
if(hFile != INVALID_HANDLE_VALUE)
{
retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
dwError = GetLastError();
if((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: SetFilePointer failed error %u", dwError);
#endif
return false;
}
else
{
if(ReadFile(hFile, dataBuffer, size, &lpNumberOfBytesRead, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: ReadFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readMemoryFromFile :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::writeMemoryToNewFile(const WCHAR* file, DWORD size, LPCVOID dataBuffer)
{
HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
if(hFile != INVALID_HANDLE_VALUE)
{
bool resultValue = writeMemoryToFile(hFile, 0, size, dataBuffer);
CloseHandle(hFile);
return resultValue;
}
else
{
return false;
}
}
bool ProcessAccessHelp::writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer)
{
DWORD lpNumberOfBytesWritten = 0;
DWORD retValue = 0;
DWORD dwError = 0;
if((hFile != INVALID_HANDLE_VALUE) && dataBuffer)
{
retValue = SetFilePointer(hFile, offset, NULL, FILE_BEGIN);
dwError = GetLastError();
if((retValue == INVALID_SET_FILE_POINTER) && (dwError != NO_ERROR))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: SetFilePointer failed error %u", dwError);
#endif
return false;
}
else
{
if(WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: WriteFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFile :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer)
{
DWORD lpNumberOfBytesWritten = 0;
DWORD retValue = 0;
if((hFile != INVALID_HANDLE_VALUE) && (hFile != 0))
{
SetFilePointer(hFile, 0, 0, FILE_END);
if(WriteFile(hFile, dataBuffer, size, &lpNumberOfBytesWritten, 0))
{
return true;
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFileEnd :: WriteFile failed - size %d - error %u", size, GetLastError());
#endif
return false;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"writeMemoryToFileEnd :: hFile invalid");
#endif
return false;
}
}
bool ProcessAccessHelp::readHeaderFromFile(BYTE* buffer, DWORD bufferSize, const WCHAR* filePath)
{
DWORD lpNumberOfBytesRead = 0;
LONGLONG fileSize = 0;
DWORD dwSize = 0;
bool returnValue = 0;
HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"readHeaderFromFile :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
returnValue = false;
}
else
{
fileSize = getFileSize(hFile);
if(fileSize > 0)
{
if(fileSize > bufferSize)
{
dwSize = bufferSize;
}
else
{
dwSize = (DWORD)(fileSize - 1);
}
returnValue = readMemoryFromFile(hFile, 0, dwSize, buffer);
}
CloseHandle(hFile);
}
return returnValue;
}
LPVOID ProcessAccessHelp::createFileMappingViewRead(const WCHAR* filePath)
{
return createFileMappingView(filePath, GENERIC_READ, PAGE_READONLY | SEC_IMAGE, FILE_MAP_READ);
}
LPVOID ProcessAccessHelp::createFileMappingViewFull(const WCHAR* filePath)
{
return createFileMappingView(filePath, GENERIC_ALL, PAGE_EXECUTE_READWRITE, FILE_MAP_ALL_ACCESS);
}
LPVOID ProcessAccessHelp::createFileMappingView(const WCHAR* filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap)
{
HANDLE hFile = CreateFile(filePath, accessFile, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: INVALID_HANDLE_VALUE %u", GetLastError());
#endif
return NULL;
}
HANDLE hMappedFile = CreateFileMapping(hFile, NULL, flProtect, 0, 0, NULL);
CloseHandle(hFile);
if(hMappedFile == NULL)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: hMappedFile == NULL");
#endif
return NULL;
}
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: GetLastError() == ERROR_ALREADY_EXISTS");
#endif
return NULL;
}
LPVOID addrMappedDll = MapViewOfFile(hMappedFile, accessMap, 0, 0, 0);
if(addrMappedDll == NULL)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createFileMappingView :: addrMappedDll == NULL");
#endif
CloseHandle(hMappedFile);
return NULL;
}
CloseHandle(hMappedFile);
return addrMappedDll;
}
DWORD ProcessAccessHelp::getProcessByName(const WCHAR* processName)
{
DWORD dwPID = 0;
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W pe32;
pe32.dwSize = sizeof(PROCESSENTRY32W);
if(!Process32FirstW(hProcessSnap, &pe32))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getProcessByName :: Error getting first Process");
#endif
CloseHandle(hProcessSnap);
return 0;
}
do
{
if(!_wcsicmp(pe32.szExeFile, processName))
{
dwPID = pe32.th32ProcessID;
break;
}
}
while(Process32NextW(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return dwPID;
}
bool ProcessAccessHelp::getProcessModules(HANDLE hProcess, std::vector<ModuleInfo> & moduleList)
{
ModuleInfo module;
WCHAR filename[MAX_PATH * 2] = {0};
DWORD cbNeeded = 0;
bool retVal = false;
DeviceNameResolver deviceNameResolver;
moduleList.reserve(20);
EnumProcessModules(hProcess, 0, 0, &cbNeeded);
HMODULE* hMods = (HMODULE*)malloc(cbNeeded * sizeof(HMODULE));
if(hMods)
{
if(EnumProcessModules(hProcess, hMods, cbNeeded, &cbNeeded))
{
for(unsigned int i = 1; i < (cbNeeded / sizeof(HMODULE)); i++) //skip first module!
{
module.modBaseAddr = (DWORD_PTR)hMods[i];
module.modBaseSize = (DWORD)getSizeOfImageProcess(hProcess, module.modBaseAddr);
module.isAlreadyParsed = false;
module.parsing = false;
filename[0] = 0;
module.fullPath[0] = 0;
if(GetMappedFileNameW(hProcess, (LPVOID)module.modBaseAddr, filename, _countof(filename)) > 0)
{
if(!deviceNameResolver.resolveDeviceLongNameToShort(filename, module.fullPath))
{
if(!GetModuleFileNameExW(hProcess, (HMODULE)module.modBaseAddr, module.fullPath, _countof(module.fullPath)))
{
wcscpy_s(module.fullPath, filename);
}
}
}
else
{
GetModuleFileNameExW(hProcess, (HMODULE)module.modBaseAddr, module.fullPath, _countof(module.fullPath));
}
moduleList.push_back(module);
}
retVal = true;
}
free(hMods);
}
return retVal;
}
bool ProcessAccessHelp::getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR* memoryRegionBase, SIZE_T* memoryRegionSize)
{
MEMORY_BASIC_INFORMATION memBasic;
if(VirtualQueryEx(hProcess, (LPCVOID)address, &memBasic, sizeof(MEMORY_BASIC_INFORMATION)) != sizeof(MEMORY_BASIC_INFORMATION))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getMemoryRegionFromAddress :: VirtualQueryEx error %u", GetLastError());
#endif
return false;
}
else
{
*memoryRegionBase = (DWORD_PTR)memBasic.BaseAddress;
*memoryRegionSize = memBasic.RegionSize;
return true;
}
}
bool ProcessAccessHelp::getSizeOfImageCurrentProcess()
{
DWORD_PTR newSizeOfImage = getSizeOfImageProcess(ProcessAccessHelp::hProcess, ProcessAccessHelp::targetImageBase);
if(newSizeOfImage != 0)
{
ProcessAccessHelp::targetSizeOfImage = newSizeOfImage;
return true;
}
else
{
return false;
}
}
SIZE_T ProcessAccessHelp::getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase)
{
SIZE_T sizeOfImage = 0, sizeOfImageNative = 0;
MEMORY_BASIC_INFORMATION lpBuffer = {0};
sizeOfImageNative = getSizeOfImageProcessNative(processHandle, moduleBase);
if(sizeOfImageNative)
{
return sizeOfImageNative;
}
WCHAR filenameOriginal[MAX_PATH * 2] = {0};
WCHAR filenameTest[MAX_PATH * 2] = {0};
GetMappedFileNameW(processHandle, (LPVOID)moduleBase, filenameOriginal, _countof(filenameOriginal));
do
{
moduleBase = (DWORD_PTR)((SIZE_T)moduleBase + lpBuffer.RegionSize);
sizeOfImage += lpBuffer.RegionSize;
if(!VirtualQueryEx(processHandle, (LPCVOID)moduleBase, &lpBuffer, sizeof(MEMORY_BASIC_INFORMATION)))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getSizeOfImageProcess :: VirtualQuery failed %X", GetLastError());
#endif
lpBuffer.Type = 0;
sizeOfImage = 0;
}
GetMappedFileNameW(processHandle, (LPVOID)moduleBase, filenameTest, _countof(filenameTest));
if(_wcsicmp(filenameOriginal, filenameTest) != 0)//problem: 2 modules without free space
{
break;
}
}
while(lpBuffer.Type == MEM_IMAGE);
//if (sizeOfImage != sizeOfImageNative)
//{
// WCHAR temp[1000] = {0};
// wsprintfW(temp, L"0x%X sizeofimage\n0x%X sizeOfImageNative", sizeOfImage, sizeOfImageNative);
// MessageBoxW(0, temp, L"Test", 0);
//}
return sizeOfImage;
}
DWORD ProcessAccessHelp::getEntryPointFromFile(const WCHAR* filePath)
{
PeParser peFile(filePath, false);
return peFile.getEntryPoint();
}
bool ProcessAccessHelp::createBackupFile(const WCHAR* filePath)
{
size_t fileNameLength = wcslen(filePath) + 5; //.bak + null
BOOL retValue = 0;
WCHAR* backupFile = new WCHAR[fileNameLength];
wcscpy_s(backupFile, fileNameLength, filePath);
wcscat_s(backupFile, fileNameLength, L".bak");
retValue = CopyFile(filePath, backupFile, FALSE);
if(!retValue)
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"createBackupFile :: CopyFile failed with error 0x%X", GetLastError());
#endif
}
delete [] backupFile;
return retValue != 0;
}
DWORD ProcessAccessHelp::getModuleHandlesFromProcess(const HANDLE hProcess, HMODULE** hMods)
{
DWORD count = 30;
DWORD cbNeeded = 0;
bool notEnough = true;
*hMods = new HMODULE[count];
do
{
if(!EnumProcessModules(hProcess, *hMods, count * sizeof(HMODULE), &cbNeeded))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getModuleHandlesFromProcess :: EnumProcessModules failed count %d", count);
#endif
delete [] *hMods;
return 0;
}
if((count * sizeof(HMODULE)) < cbNeeded)
{
delete [] *hMods;
count = cbNeeded / sizeof(HMODULE);
*hMods = new HMODULE[count];
}
else
{
notEnough = false;
}
}
while(notEnough);
return cbNeeded / sizeof(HMODULE);
}
void ProcessAccessHelp::setCurrentProcessAsTarget()
{
ProcessAccessHelp::hProcess = GetCurrentProcess();
}
bool ProcessAccessHelp::suspendProcess()
{
if(NativeWinApi::NtSuspendProcess)
{
if(NT_SUCCESS(NativeWinApi::NtSuspendProcess(ProcessAccessHelp::hProcess)))
{
return true;
}
}
return false;
}
bool ProcessAccessHelp::resumeProcess()
{
if(NativeWinApi::NtResumeProcess)
{
if(NT_SUCCESS(NativeWinApi::NtResumeProcess(ProcessAccessHelp::hProcess)))
{
return true;
}
}
return false;
}
bool ProcessAccessHelp::terminateProcess()
{
if(NativeWinApi::NtTerminateProcess)
{
if(NT_SUCCESS(NativeWinApi::NtTerminateProcess(ProcessAccessHelp::hProcess, 0)))
{
return true;
}
}
return false;
}
bool ProcessAccessHelp::isPageAccessable(DWORD Protect)
{
if(Protect & PAGE_NOCACHE) Protect ^= PAGE_NOCACHE;
if(Protect & PAGE_GUARD) Protect ^= PAGE_GUARD;
if(Protect & PAGE_WRITECOMBINE) Protect ^= PAGE_WRITECOMBINE;
if(Protect != PAGE_NOACCESS)
{
return true;
}
else
{
return false;
}
}
bool ProcessAccessHelp::isPageExecutable(DWORD Protect)
{
if(Protect & PAGE_NOCACHE) Protect ^= PAGE_NOCACHE;
if(Protect & PAGE_GUARD) Protect ^= PAGE_GUARD;
if(Protect & PAGE_WRITECOMBINE) Protect ^= PAGE_WRITECOMBINE;
switch(Protect)
{
case PAGE_EXECUTE:
{
return true;
}
case PAGE_EXECUTE_READ:
{
return true;
}
case PAGE_EXECUTE_READWRITE:
{
return true;
}
case PAGE_EXECUTE_WRITECOPY:
{
return true;
}
default:
return false;
}
}
SIZE_T ProcessAccessHelp::getSizeOfImageProcessNative(HANDLE processHandle, DWORD_PTR moduleBase)
{
MEMORY_REGION_INFORMATION memRegion = {0};
SIZE_T retLen = 0;
if(NativeWinApi::NtQueryVirtualMemory(processHandle, (PVOID)moduleBase, MemoryRegionInformation, &memRegion, sizeof(MEMORY_REGION_INFORMATION), &retLen) == STATUS_SUCCESS)
{
return memRegion.RegionSize;
}
return 0;
}

View File

@ -0,0 +1,230 @@
#pragma once
#include <windows.h>
#include <tlhelp32.h>
#include <vector>
/************************************************************************/
/* distorm */
/************************************************************************/
#include "distorm.h"
#include "mnemonics.h"
// The number of the array of instructions the decoder function will use to return the disassembled instructions.
// Play with this value for performance...
#define MAX_INSTRUCTIONS (200)
/************************************************************************/
class ApiInfo;
class ModuleInfo
{
public:
WCHAR fullPath[MAX_PATH];
DWORD_PTR modBaseAddr;
DWORD modBaseSize;
bool isAlreadyParsed;
bool parsing;
/*
for iat rebuilding with duplicate entries:
ntdll = low priority
kernelbase = low priority
SHLWAPI = low priority
kernel32 = high priority
priority = 1 -> normal/high priority
priority = 0 -> low priority
*/
int priority;
std::vector<ApiInfo*> apiList;
ModuleInfo()
{
modBaseAddr = 0;
modBaseSize = 0;
priority = 1;
isAlreadyParsed = false;
parsing = false;
}
const WCHAR* getFilename() const
{
const WCHAR* slash = wcsrchr(fullPath, L'\\');
if(slash)
{
return slash + 1;
}
return fullPath;
}
};
class ApiInfo
{
public:
char name[MAX_PATH];
WORD hint;
DWORD_PTR va;
DWORD_PTR rva;
WORD ordinal;
bool isForwarded;
ModuleInfo* module;
};
class ProcessAccessHelp
{
public:
static HANDLE hProcess; //OpenProcess handle to target process
static DWORD_PTR targetImageBase;
static DWORD_PTR targetSizeOfImage;
static DWORD_PTR maxValidAddress;
static ModuleInfo* selectedModule;
static std::vector<ModuleInfo> moduleList; //target process module list
static std::vector<ModuleInfo> ownModuleList; //own module list
static const size_t PE_HEADER_BYTES_COUNT = 2000;
static BYTE fileHeaderFromDisk[PE_HEADER_BYTES_COUNT];
//for decomposer
static _DInst decomposerResult[MAX_INSTRUCTIONS];
static unsigned int decomposerInstructionsCount;
static _CodeInfo decomposerCi;
//distorm :: Decoded instruction information.
static _DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
static unsigned int decodedInstructionsCount;
#ifdef _WIN64
static const _DecodeType dt = Decode64Bits;
#else
static const _DecodeType dt = Decode32Bits;
#endif
/*
* Open a new process handle
*/
static bool openProcessHandle(DWORD dwPID);
static HANDLE NativeOpenProcess(DWORD dwDesiredAccess, DWORD dwProcessId);
static void closeProcessHandle();
/*
* Get all modules from a process
*/
static bool getProcessModules(HANDLE hProcess, std::vector<ModuleInfo> & moduleList);
/*
* file mapping view with different access level
*/
static LPVOID createFileMappingViewRead(const WCHAR* filePath);
static LPVOID createFileMappingViewFull(const WCHAR* filePath);
/*
* Create a file mapping view of a file
*/
static LPVOID createFileMappingView(const WCHAR* filePath, DWORD accessFile, DWORD flProtect, DWORD accessMap);
/*
* Read memory from target process
*/
static bool readMemoryFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer);
static bool writeMemoryToProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer);
/*
* Read memory from target process and ignore no data pages
*/
static bool readMemoryPartlyFromProcess(DWORD_PTR address, SIZE_T size, LPVOID dataBuffer);
/*
* Read memory from file
*/
static bool readMemoryFromFile(HANDLE hFile, LONG offset, DWORD size, LPVOID dataBuffer);
/*
* Write memory to file
*/
static bool writeMemoryToFile(HANDLE hFile, LONG offset, DWORD size, LPCVOID dataBuffer);
/*
* Write memory to new file
*/
static bool writeMemoryToNewFile(const WCHAR* file, DWORD size, LPCVOID dataBuffer);
/*
* Write memory to file end
*/
static bool writeMemoryToFileEnd(HANDLE hFile, DWORD size, LPCVOID dataBuffer);
/*
* Disassemble Memory
*/
static bool disassembleMemory(BYTE* dataBuffer, SIZE_T bufferSize, DWORD_PTR startOffset);
static bool decomposeMemory(BYTE* dataBuffer, SIZE_T bufferSize, DWORD_PTR startAddress);
/*
* Search for pattern
*/
static DWORD_PTR findPattern(DWORD_PTR startOffset, DWORD size, BYTE* pattern, const char* mask);
/*
* Get process ID by process name
*/
static DWORD getProcessByName(const WCHAR* processName);
/*
* Get memory region from address
*/
static bool getMemoryRegionFromAddress(DWORD_PTR address, DWORD_PTR* memoryRegionBase, SIZE_T* memoryRegionSize);
/*
* Read PE Header from file
*/
static bool readHeaderFromFile(BYTE* buffer, DWORD bufferSize, const WCHAR* filePath);
static bool readHeaderFromCurrentFile(const WCHAR* filePath);
/*
* Get real sizeOfImage value
*/
static SIZE_T getSizeOfImageProcess(HANDLE processHandle, DWORD_PTR moduleBase);
/*
* Get real sizeOfImage value current process
*/
static bool getSizeOfImageCurrentProcess();
static LONGLONG getFileSize(HANDLE hFile);
static LONGLONG getFileSize(const WCHAR* filePath);
static DWORD getEntryPointFromFile(const WCHAR* filePath);
static bool createBackupFile(const WCHAR* filePath);
static DWORD getModuleHandlesFromProcess(const HANDLE hProcess, HMODULE** hMods);
static void setCurrentProcessAsTarget();
static bool suspendProcess();
static bool resumeProcess();
static bool terminateProcess();
static bool isPageExecutable(DWORD Protect);
static bool isPageAccessable(DWORD Protect);
static SIZE_T getSizeOfImageProcessNative(HANDLE processHandle, DWORD_PTR moduleBase);
};

View File

@ -0,0 +1,291 @@
#include "stdafx.h"
#include "ProcessLister.h"
#include "SystemInformation.h"
#include "ProcessAccessHelp.h"
#include <algorithm>
//#define DEBUG_COMMENTS
def_IsWow64Process ProcessLister::_IsWow64Process = 0;
std::vector<Process> & ProcessLister::getProcessList()
{
return processList;
}
bool ProcessLister::isWindows64()
{
#ifdef _WIN64
//compiled 64bit application
return true;
#else
//32bit exe, check wow64
BOOL bIsWow64 = FALSE;
//not available in all windows operating systems
//Minimum supported client: Windows Vista, Windows XP with SP2
//Minimum supported server: Windows Server 2008, Windows Server 2003 with SP1
if(_IsWow64Process)
{
_IsWow64Process(GetCurrentProcess(), &bIsWow64);
if(bIsWow64 != FALSE)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
#endif
}
//only needed in windows xp
DWORD ProcessLister::setDebugPrivileges()
{
DWORD err = 0;
HANDLE hToken = 0;
TOKEN_PRIVILEGES Debug_Privileges = {0};
if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Debug_Privileges.Privileges[0].Luid))
{
return GetLastError();
}
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
err = GetLastError();
if(hToken) CloseHandle(hToken);
return err;
}
Debug_Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
Debug_Privileges.PrivilegeCount = 1;
AdjustTokenPrivileges(hToken, false, &Debug_Privileges, 0, NULL, NULL);
CloseHandle(hToken);
return GetLastError();
}
/************************************************************************/
/* Check if a process is 32 or 64bit */
/************************************************************************/
ProcessType ProcessLister::checkIsProcess64(HANDLE hProcess)
{
BOOL bIsWow64 = FALSE;
if(!hProcess)
{
return PROCESS_MISSING_RIGHTS;
}
if(!isWindows64())
{
//32bit win can only run 32bit process
return PROCESS_32;
}
_IsWow64Process(hProcess, &bIsWow64);
if(bIsWow64 == FALSE)
{
//process not running under wow
return PROCESS_64;
}
else
{
//process running under wow -> 32bit
return PROCESS_32;
}
}
bool ProcessLister::getAbsoluteFilePath(HANDLE hProcess, Process* process)
{
WCHAR processPath[MAX_PATH];
bool retVal = false;
wcscpy_s(process->fullPath, L"Unknown path");
if(!hProcess)
{
//missing rights
return false;
}
if(GetProcessImageFileNameW(hProcess, processPath, _countof(processPath)) > 0)
{
if(!deviceNameResolver->resolveDeviceLongNameToShort(processPath, process->fullPath))
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getAbsoluteFilePath :: resolveDeviceLongNameToShort failed with path %s", processPath);
#endif
//some virtual volumes
if(GetModuleFileNameExW(hProcess, 0, process->fullPath, _countof(process->fullPath)) != 0)
{
retVal = true;
}
}
else
{
retVal = true;
}
}
else
{
#ifdef DEBUG_COMMENTS
Scylla::debugLog.log(L"getAbsoluteFilePath :: GetProcessImageFileName failed %u", GetLastError());
#endif
if(GetModuleFileNameExW(hProcess, 0, process->fullPath, _countof(process->fullPath)) != 0)
{
retVal = true;
}
}
return retVal;
}
std::vector<Process> & ProcessLister::getProcessListSnapshotNative()
{
ULONG retLength = 0;
ULONG bufferLength = 1;
PSYSTEM_PROCESS_INFORMATION pBuffer = (PSYSTEM_PROCESS_INFORMATION)malloc(bufferLength);
PSYSTEM_PROCESS_INFORMATION pIter;
if(!processList.empty())
{
//clear elements, but keep reversed memory
processList.clear();
}
else
{
//first time, reserve memory
processList.reserve(34);
}
if(NativeWinApi::NtQuerySystemInformation(SystemProcessInformation, pBuffer, bufferLength, &retLength) == STATUS_INFO_LENGTH_MISMATCH)
{
free(pBuffer);
bufferLength = retLength + sizeof(SYSTEM_PROCESS_INFORMATION);
pBuffer = (PSYSTEM_PROCESS_INFORMATION)malloc(bufferLength);
if(!pBuffer)
return processList;
if(NativeWinApi::NtQuerySystemInformation(SystemProcessInformation, pBuffer, bufferLength, &retLength) != STATUS_SUCCESS)
{
return processList;
}
}
else
{
return processList;
}
pIter = pBuffer;
while(TRUE)
{
if(pIter->UniqueProcessId > (HANDLE)4) //small filter
{
handleProcessInformationAndAddToList(pIter);
}
if(pIter->NextEntryOffset == 0)
{
break;
}
else
{
pIter = (PSYSTEM_PROCESS_INFORMATION)((DWORD_PTR)pIter + (DWORD_PTR)pIter->NextEntryOffset);
}
}
std::reverse(processList.begin(), processList.end()); //reverse process list
free(pBuffer);
return processList;
}
void ProcessLister::handleProcessInformationAndAddToList(PSYSTEM_PROCESS_INFORMATION pProcess)
{
Process process;
WCHAR tempProcessName[MAX_PATH * 2] = {0};
process.PID = (DWORD)pProcess->UniqueProcessId;
HANDLE hProcess = ProcessAccessHelp::NativeOpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, process.PID);
if(hProcess)
{
ProcessType processType = checkIsProcess64(hProcess);
#ifdef _WIN64
if(processType == PROCESS_64)
#else
if(processType == PROCESS_32)
#endif
{
process.sessionId = pProcess->SessionId;
memcpy(tempProcessName, pProcess->ImageName.Buffer, pProcess->ImageName.Length);
wcscpy_s(process.filename, tempProcessName);
getAbsoluteFilePath(hProcess, &process);
process.pebAddress = getPebAddressFromProcess(hProcess);
getProcessImageInformation(hProcess, &process);
processList.push_back(process);
}
CloseHandle(hProcess);
}
}
void ProcessLister::getProcessImageInformation(HANDLE hProcess, Process* process)
{
DWORD_PTR readImagebase = 0;
process->imageBase = 0;
process->imageSize = 0;
if(hProcess && process->pebAddress)
{
PEB_CURRENT* peb = (PEB_CURRENT*)process->pebAddress;
if(ReadProcessMemory(hProcess, &peb->ImageBaseAddress, &readImagebase, sizeof(DWORD_PTR), 0))
{
process->imageBase = readImagebase;
process->imageSize = (DWORD)ProcessAccessHelp::getSizeOfImageProcess(hProcess, process->imageBase);
}
}
}
DWORD_PTR ProcessLister::getPebAddressFromProcess(HANDLE hProcess)
{
if(hProcess)
{
ULONG RequiredLen = 0;
void* PebAddress = 0;
PROCESS_BASIC_INFORMATION myProcessBasicInformation[5] = {0};
if(NativeWinApi::NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof(PROCESS_BASIC_INFORMATION), &RequiredLen) == STATUS_SUCCESS)
{
PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;
}
else
{
if(NativeWinApi::NtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS)
{
PebAddress = (void*)myProcessBasicInformation->PebBaseAddress;
}
}
return (DWORD_PTR)PebAddress;
}
return 0;
}

View File

@ -0,0 +1,72 @@
#pragma once
#include <windows.h>
#include <tlhelp32.h>
#include <vector>
#include <Psapi.h>
#include "NativeWinApi.h"
#include "DeviceNameResolver.h"
typedef BOOL (WINAPI* def_IsWow64Process)(HANDLE hProcess, PBOOL Wow64Process);
class Process
{
public:
DWORD PID;
DWORD sessionId;
DWORD_PTR imageBase;
DWORD_PTR pebAddress;
DWORD entryPoint; //RVA without imagebase
DWORD imageSize;
WCHAR filename[MAX_PATH];
WCHAR fullPath[MAX_PATH];
Process()
{
PID = 0;
}
};
enum ProcessType
{
PROCESS_UNKNOWN,
PROCESS_MISSING_RIGHTS,
PROCESS_32,
PROCESS_64
};
class ProcessLister
{
public:
static def_IsWow64Process _IsWow64Process;
ProcessLister()
{
deviceNameResolver = new DeviceNameResolver();
_IsWow64Process = (def_IsWow64Process)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process");
}
~ProcessLister()
{
delete deviceNameResolver;
}
std::vector<Process> & getProcessList();
static bool isWindows64();
static DWORD setDebugPrivileges();
std::vector<Process> & getProcessListSnapshotNative();
private:
std::vector<Process> processList;
DeviceNameResolver* deviceNameResolver;
ProcessType checkIsProcess64(HANDLE hProcess);
bool getAbsoluteFilePath(HANDLE hProcess, Process* process);
void handleProcessInformationAndAddToList(PSYSTEM_PROCESS_INFORMATION pProcess);
void getProcessImageInformation(HANDLE hProcess, Process* process);
DWORD_PTR getPebAddressFromProcess(HANDLE hProcess);
};

122
scylla_wrapper/README.md Normal file
View File

@ -0,0 +1,122 @@
Source: https://bitbucket.org/cypherpunk/scylla_wrapper_dll
```
This is a wrapper around Scylla.
It exports functions for IAT fixing, dumping and PE rebuilding.
based on http://github.com/NtQuery/Scylla commit 0f6b7198be (v0.9.6b)
What has been changed:
- stripped all WTL/ATL dependencies
- stripped GUI (obviously)
```
## Exports ##
:::c++
//searches IAT, writes to iatStart, iatSize
int scylla_searchIAT(DWORD pid, DWORD_PTR &iatStart, DWORD &iatSize, DWORD_PTR searchStart, bool advancedSearch);
//reads the imports, iatAddr is VA
int scylla_getImports(DWORD_PTR iatAddr, DWORD iatSize, DWORD pid, LPVOID invalidImportCallback = NULL);
//add a module manually, in case auto-search didnt get it, e.g scattered IAT
bool scylla_addModule(const WCHAR* moduleName, DWORD_PTR firstThunkRVA);
//add API manually, in case auto-search didnt get it, e.g scattered IAT
bool scylla_addImport(const WCHAR* importName, DWORD_PTR thunkVA);
//are all imports valid?
bool scylla_importsValid();
//cut an Import, because its invalid or whatever reason. Calling this from within the invalidImportCallback will crash!
//Call it after scylla_getImports call returned !
bool scylla_cutImport(DWORD_PTR apiAddr);
//fix the dump
int scylla_fixDump(WCHAR* dumpFile, WCHAR* iatFixFile, WCHAR* sectionName = L".scy");
//fix a mapped dump
int scylla_fixMappedDump(DWORD_PTR iatVA, DWORD_PTR FileMapVA, HANDLE hFileMap);
//get imported DLL count
int scylla_getModuleCount();
//get total API Imports count
int scylla_getImportCount();
//enumerate imports tree
void scylla_enumImportTree(LPVOID enumCallBack);
//size which the new IAT will consume
long scylla_estimatedIATSize();
//get thunkVA by API name
DWORD_PTR scylla_findImportWriteLocation(char* importName);
//get thunkVA by ordinal
DWORD_PTR scylla_findOrdinalImportWriteLocation(DWORD_PTR ordinalNumber);
//get API name by thunkVA, cast return to char*
DWORD_PTR scylla_findImportNameByWriteLocation(DWORD_PTR thunkVA);
//get DLL name by thunkVA, cast return to char*
DWORD_PTR scylla_findModuleNameByWriteLocation(DWORD_PTR thunkVA);
//dumps a process
bool scylla_dumpProcessW(DWORD_PTR pid, const WCHAR * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR * fileResult);
bool scylla_dumpProcessA(DWORD_PTR pid, const char * fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const char * fileResult);
//rebuilds a files PE header
bool scylla_rebuildFileW(const WCHAR * fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup);
bool scylla_rebuildFileA(const char * fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup);
## Return Codes ##
:::c++
const BYTE SCY_ERROR_SUCCESS = 0;
const BYTE SCY_ERROR_PROCOPEN = -1;
const BYTE SCY_ERROR_IATWRITE = -2;
const BYTE SCY_ERROR_IATSEARCH = -3;
const BYTE SCY_ERROR_IATNOTFOUND = -4;
## Usage ##
:::c++
typedef int (*SEARCHIAT) (DWORD, DWORD_PTR &, DWORD &, DWORD_PTR, bool);
typedef int (*GETIMPORTS) (DWORD_PTR, DWORD, DWORD, LPVOID);
typedef bool (*IMPORTSVALID) ();
typedef int (*FIXDUMP) (WCHAR*, WCHAR*);
HMODULE lib = LoadLibrary(_T("scylla_wrapper"));
SEARCHIAT searchIAT = (SEARCHIAT) GetProcAddress(lib, "scylla_searchIAT");
GETIMPORTS getImports = (GETIMPORTS) GetProcAddress(lib, "scylla_getImports");
IMPORTSVALID importsValid = (IMPORTSVALID) GetProcAddress(lib, "scylla_importsValid");
FIXDUMP fixDump = (FIXDUMP) GetProcAddress(lib, "scylla_fixDump");
DWORD iatStart = 0xDEADBEEF;
DWORD iatSize = 0xDEADBEEF;
int search = searchIAT(fdProcessInfo->dwProcessId, iatStart, iatSize, eip, false);
if(search==0) int imports = getImports(iatStart, iatSize, pid);
bool valid = importsValid();
if(valid) int fix = fixDump(dumpFileName, IatFixFileName);
## Definitions ##
:::c++
typedef void*(*fCallback)(LPVOID invalidImport);
//e.g.
void* cbInvalidImport(void* apiAddr)
typedef void(*fCallback)(LPVOID importDetail);
typedef struct
{
bool NewDll;
int NumberOfImports;
ULONG_PTR ImageBase;
ULONG_PTR BaseImportThunk;
ULONG_PTR ImportThunk;
char* APIName;
char* DLLName;
} ImportEnumData
//e.g. pointer on this struct used in scylla_enumImportTree as argument
void cbEnumImports(void* importDetail)
{
ImportEnumData* data = (ImportEnumData*)importDetail;
}
## Notes ##
```
The pre-compiled binaries and project standard uses _cdecl calling convention.
For assembly users, this means you have to push arguments from right-to-left onto the stack
and clean the stack yourself after calling.
#pragma pack(push,1) or compiler flag /Zp1 is needed for the struct members to be aligned correctly
```

View File

@ -0,0 +1,27 @@
#include "stdafx.h"
#include "StringConversion.h"
#include <cstdlib>
//#include <atlbase.h>
//#include <atlconv.h>
const char* StringConversion::ToASCII(const wchar_t* str, char* buf, size_t bufsize)
{
wcstombs(buf, str, bufsize);
/*
ATL::CW2A str_a = str;
strncpy_s(buf, bufsize, str_a, bufsize);
buf[bufsize - 1] = '\0';
*/
return buf;
}
const wchar_t* StringConversion::ToUTF16(const char* str, wchar_t* buf, size_t bufsize)
{
mbstowcs(buf, str, bufsize);
/*
ATL::CA2W str_w = str;
wcsncpy_s(buf, bufsize, str_w, bufsize);
buf[bufsize - 1] = L'\0';
*/
return buf;
}

View File

@ -0,0 +1,9 @@
#pragma once
class StringConversion
{
public:
static const char* ToASCII(const wchar_t* str, char* buf, size_t bufsize);
static const wchar_t* ToUTF16(const char* str, wchar_t* buf, size_t bufsize);
};

View File

@ -0,0 +1,77 @@
#include "stdafx.h"
#include "SystemInformation.h"
OPERATING_SYSTEM SystemInformation::currenOS = UNKNOWN_OS;
bool SystemInformation::getSystemInformation()
{
OSVERSIONINFOEX osvi = {0};
SYSTEM_INFO si = {0};
def_GetNativeSystemInfo _GetNativeSystemInfo = 0;
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!GetVersionEx((OSVERSIONINFO*) &osvi))
{
return false;
}
if((osvi.dwMajorVersion < 5) || ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0)))
{
return false;
}
_GetNativeSystemInfo = (def_GetNativeSystemInfo)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetNativeSystemInfo");
if(_GetNativeSystemInfo)
{
_GetNativeSystemInfo(&si);
}
else
{
GetSystemInfo(&si);
}
bool isX64 = si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
bool isX86 = si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL;
DWORD major = osvi.dwMajorVersion;
DWORD minor = osvi.dwMinorVersion;
if(isX64 && major == 5 && minor == 2)
{
currenOS = WIN_XP_64;
}
else if(isX86 && major == 5 && minor == 1)
{
currenOS = WIN_XP_32;
}
else if(isX64 && major == 6 && minor == 0)
{
currenOS = WIN_VISTA_64;
}
else if(isX86 && major == 6 && minor == 0)
{
currenOS = WIN_VISTA_32;
}
else if(isX64 && major == 6 && minor == 1)
{
currenOS = WIN_7_64;
}
else if(isX86 && major == 6 && minor == 1)
{
currenOS = WIN_7_32;
}
else if(isX64 && major == 6 && minor == 2)
{
currenOS = WIN_8_64;
}
else if(isX86 && major == 6 && minor == 2)
{
currenOS = WIN_8_32;
}
else
{
currenOS = UNKNOWN_OS;
}
return (currenOS != UNKNOWN_OS);
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <windows.h>
enum OPERATING_SYSTEM
{
UNKNOWN_OS,
WIN_XP_32,
WIN_XP_64,
WIN_VISTA_32,
WIN_VISTA_64,
WIN_7_32,
WIN_7_64,
WIN_8_32,
WIN_8_64
};
typedef void (WINAPI* def_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
class SystemInformation
{
public:
static OPERATING_SYSTEM currenOS;
static bool getSystemInformation();
};

40
scylla_wrapper/Thunks.cpp Normal file
View File

@ -0,0 +1,40 @@
#include "stdafx.h"
#include "Thunks.h"
void ImportThunk::invalidate()
{
ordinal = 0;
hint = 0;
valid = false;
suspect = false;
moduleName[0] = 0;
name[0] = 0;
}
bool ImportModuleThunk::isValid() const
{
std::map<DWORD_PTR, ImportThunk>::const_iterator iterator = thunkList.begin();
while(iterator != thunkList.end())
{
if(iterator->second.valid == false)
{
return false;
}
iterator++;
}
return true;
}
DWORD_PTR ImportModuleThunk::getFirstThunk() const
{
if(thunkList.size() > 0)
{
const std::map<DWORD_PTR, ImportThunk>::const_iterator iterator = thunkList.begin();
return iterator->first;
}
else
{
return 0;
}
}

36
scylla_wrapper/Thunks.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include <windows.h>
#include <map>
class ImportThunk
{
public:
WCHAR moduleName[MAX_PATH];
char name[MAX_PATH];
DWORD_PTR va;
DWORD_PTR rva;
WORD ordinal;
DWORD_PTR apiAddressVA;
WORD hint;
bool valid;
bool suspect;
DWORD_PTR key;
void invalidate();
};
class ImportModuleThunk
{
public:
WCHAR moduleName[MAX_PATH];
std::map<DWORD_PTR, ImportThunk> thunkList;
DWORD_PTR firstThunk;
DWORD_PTR key;
DWORD_PTR getFirstThunk() const;
bool isValid() const;
};

View File

@ -0,0 +1,18 @@
#include "stdafx.h"
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

316
scylla_wrapper/mnemonics.h Normal file
View File

@ -0,0 +1,316 @@
/*
mnemonics.h
diStorm3 - Powerful disassembler for X86/AMD64
http://ragestorm.net/distorm/
distorm at gmail dot com
Copyright (C) 2003-2012 Gil Dabah
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef MNEMONICS_H
#define MNEMONICS_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DISTORM_LIGHT
typedef struct WMnemonic
{
unsigned char length;
unsigned char p[1]; /* p is a null terminated string, which contains 'length' characters. */
} _WMnemonic;
typedef struct WRegister
{
unsigned int length;
unsigned char p[6]; /* p is a null terminated string. */
} _WRegister;
extern const unsigned char _MNEMONICS[];
extern const _WRegister _REGISTERS[];
#endif /* DISTORM_LIGHT */
#ifdef __cplusplus
} /* End Of Extern */
#endif
#define GET_REGISTER_NAME(r) (unsigned char*)_REGISTERS[(r)].p
#define GET_MNEMONIC_NAME(m) ((_WMnemonic*)&_MNEMONICS[(m)])->p
typedef enum
{
I_UNDEFINED = 0, I_AAA = 66, I_AAD = 389, I_AAM = 384, I_AAS = 76, I_ADC = 31, I_ADD = 11, I_ADDPD = 3110,
I_ADDPS = 3103, I_ADDSD = 3124, I_ADDSS = 3117, I_ADDSUBPD = 6394, I_ADDSUBPS = 6404,
I_AESDEC = 9209, I_AESDECLAST = 9226, I_AESENC = 9167, I_AESENCLAST = 9184,
I_AESIMC = 9150, I_AESKEYGENASSIST = 9795, I_AND = 41, I_ANDNPD = 3021, I_ANDNPS = 3013,
I_ANDPD = 2990, I_ANDPS = 2983, I_ARPL = 111, I_BLENDPD = 9372, I_BLENDPS = 9353,
I_BLENDVPD = 7619, I_BLENDVPS = 7609, I_BOUND = 104, I_BSF = 4346, I_BSR = 4358,
I_BSWAP = 960, I_BT = 872, I_BTC = 934, I_BTR = 912, I_BTS = 887, I_CALL = 456,
I_CALL_FAR = 260, I_CBW = 228, I_CDQ = 250, I_CDQE = 239, I_CLC = 492, I_CLD = 512,
I_CLFLUSH = 4329, I_CLGI = 1833, I_CLI = 502, I_CLTS = 541, I_CMC = 487, I_CMOVA = 694,
I_CMOVAE = 663, I_CMOVB = 656, I_CMOVBE = 686, I_CMOVG = 754, I_CMOVGE = 738,
I_CMOVL = 731, I_CMOVLE = 746, I_CMOVNO = 648, I_CMOVNP = 723, I_CMOVNS = 708,
I_CMOVNZ = 678, I_CMOVO = 641, I_CMOVP = 716, I_CMOVS = 701, I_CMOVZ = 671,
I_CMP = 71, I_CMPEQPD = 4449, I_CMPEQPS = 4370, I_CMPEQSD = 4607, I_CMPEQSS = 4528,
I_CMPLEPD = 4467, I_CMPLEPS = 4388, I_CMPLESD = 4625, I_CMPLESS = 4546, I_CMPLTPD = 4458,
I_CMPLTPS = 4379, I_CMPLTSD = 4616, I_CMPLTSS = 4537, I_CMPNEQPD = 4488, I_CMPNEQPS = 4409,
I_CMPNEQSD = 4646, I_CMPNEQSS = 4567, I_CMPNLEPD = 4508, I_CMPNLEPS = 4429,
I_CMPNLESD = 4666, I_CMPNLESS = 4587, I_CMPNLTPD = 4498, I_CMPNLTPS = 4419,
I_CMPNLTSD = 4656, I_CMPNLTSS = 4577, I_CMPORDPD = 4518, I_CMPORDPS = 4439,
I_CMPORDSD = 4676, I_CMPORDSS = 4597, I_CMPS = 301, I_CMPUNORDPD = 4476, I_CMPUNORDPS = 4397,
I_CMPUNORDSD = 4634, I_CMPUNORDSS = 4555, I_CMPXCHG = 898, I_CMPXCHG16B = 6373,
I_CMPXCHG8B = 6362, I_COMISD = 2779, I_COMISS = 2771, I_CPUID = 865, I_CQO = 255,
I_CRC32 = 9258, I_CVTDQ2PD = 6787, I_CVTDQ2PS = 3307, I_CVTPD2DQ = 6797, I_CVTPD2PI = 2681,
I_CVTPD2PS = 3233, I_CVTPH2PS = 4161, I_CVTPI2PD = 2495, I_CVTPI2PS = 2485,
I_CVTPS2DQ = 3317, I_CVTPS2PD = 3223, I_CVTPS2PH = 4171, I_CVTPS2PI = 2671,
I_CVTSD2SI = 2701, I_CVTSD2SS = 3253, I_CVTSI2SD = 2515, I_CVTSI2SS = 2505,
I_CVTSS2SD = 3243, I_CVTSS2SI = 2691, I_CVTTPD2DQ = 6776, I_CVTTPD2PI = 2614,
I_CVTTPS2DQ = 3327, I_CVTTPS2PI = 2603, I_CVTTSD2SI = 2636, I_CVTTSS2SI = 2625,
I_CWD = 245, I_CWDE = 233, I_DAA = 46, I_DAS = 56, I_DEC = 86, I_DIV = 1630,
I_DIVPD = 3499, I_DIVPS = 3492, I_DIVSD = 3513, I_DIVSS = 3506, I_DPPD = 9615,
I_DPPS = 9602, I_EMMS = 4100, I_ENTER = 340, I_EXTRACTPS = 9480, I_EXTRQ = 4136,
I_F2XM1 = 1176, I_FABS = 1107, I_FADD = 1007, I_FADDP = 1533, I_FBLD = 1585,
I_FBSTP = 1591, I_FCHS = 1101, I_FCLEX = 7289, I_FCMOVB = 1360, I_FCMOVBE = 1376,
I_FCMOVE = 1368, I_FCMOVNB = 1429, I_FCMOVNBE = 1447, I_FCMOVNE = 1438, I_FCMOVNU = 1457,
I_FCMOVU = 1385, I_FCOM = 1019, I_FCOMI = 1496, I_FCOMIP = 1607, I_FCOMP = 1025,
I_FCOMPP = 1547, I_FCOS = 1295, I_FDECSTP = 1222, I_FDIV = 1045, I_FDIVP = 1578,
I_FDIVR = 1051, I_FDIVRP = 1570, I_FEDISI = 1472, I_FEMMS = 574, I_FENI = 1466,
I_FFREE = 1511, I_FIADD = 1301, I_FICOM = 1315, I_FICOMP = 1322, I_FIDIV = 1345,
I_FIDIVR = 1352, I_FILD = 1402, I_FIMUL = 1308, I_FINCSTP = 1231, I_FINIT = 7304,
I_FIST = 1416, I_FISTP = 1422, I_FISTTP = 1408, I_FISUB = 1330, I_FISUBR = 1337,
I_FLD = 1058, I_FLD1 = 1125, I_FLDCW = 1082, I_FLDENV = 1074, I_FLDL2E = 1139,
I_FLDL2T = 1131, I_FLDLG2 = 1154, I_FLDLN2 = 1162, I_FLDPI = 1147, I_FLDZ = 1170,
I_FMUL = 1013, I_FMULP = 1540, I_FNCLEX = 7281, I_FNINIT = 7296, I_FNOP = 1095,
I_FNSAVE = 7311, I_FNSTCW = 7266, I_FNSTENV = 7249, I_FNSTSW = 7326, I_FPATAN = 1197,
I_FPREM = 1240, I_FPREM1 = 1214, I_FPTAN = 1190, I_FRNDINT = 1272, I_FRSTOR = 1503,
I_FSAVE = 7319, I_FSCALE = 1281, I_FSETPM = 1480, I_FSIN = 1289, I_FSINCOS = 1263,
I_FSQRT = 1256, I_FST = 1063, I_FSTCW = 7274, I_FSTENV = 7258, I_FSTP = 1068,
I_FSTSW = 7334, I_FSUB = 1032, I_FSUBP = 1563, I_FSUBR = 1038, I_FSUBRP = 1555,
I_FTST = 1113, I_FUCOM = 1518, I_FUCOMI = 1488, I_FUCOMIP = 1598, I_FUCOMP = 1525,
I_FUCOMPP = 1393, I_FXAM = 1119, I_FXCH = 1089, I_FXRSTOR = 9892, I_FXRSTOR64 = 9901,
I_FXSAVE = 9864, I_FXSAVE64 = 9872, I_FXTRACT = 1205, I_FYL2X = 1183, I_FYL2XP1 = 1247,
I_GETSEC = 633, I_HADDPD = 4181, I_HADDPS = 4189, I_HLT = 482, I_HSUBPD = 4215,
I_HSUBPS = 4223, I_IDIV = 1635, I_IMUL = 117, I_IN = 447, I_INC = 81, I_INS = 123,
I_INSERTPS = 9547, I_INSERTQ = 4143, I_INT = 367, I_INT_3 = 360, I_INT1 = 476,
I_INTO = 372, I_INVD = 555, I_INVEPT = 8284, I_INVLPG = 1711, I_INVLPGA = 1847,
I_INVPCID = 8301, I_INVVPID = 8292, I_IRET = 378, I_JA = 166, I_JAE = 147,
I_JB = 143, I_JBE = 161, I_JCXZ = 427, I_JECXZ = 433, I_JG = 202, I_JGE = 192,
I_JL = 188, I_JLE = 197, I_JMP = 462, I_JMP_FAR = 467, I_JNO = 138, I_JNP = 183,
I_JNS = 174, I_JNZ = 156, I_JO = 134, I_JP = 179, I_JRCXZ = 440, I_JS = 170,
I_JZ = 152, I_LAHF = 289, I_LAR = 522, I_LDDQU = 6994, I_LDMXCSR = 9922, I_LDS = 335,
I_LEA = 223, I_LEAVE = 347, I_LES = 330, I_LFENCE = 4265, I_LFS = 917, I_LGDT = 1687,
I_LGS = 922, I_LIDT = 1693, I_LLDT = 1652, I_LMSW = 1705, I_LODS = 313, I_LOOP = 421,
I_LOOPNZ = 406, I_LOOPZ = 414, I_LSL = 527, I_LSS = 907, I_LTR = 1658, I_LZCNT = 4363,
I_MASKMOVDQU = 7119, I_MASKMOVQ = 7109, I_MAXPD = 3559, I_MAXPS = 3552, I_MAXSD = 3573,
I_MAXSS = 3566, I_MFENCE = 4291, I_MINPD = 3439, I_MINPS = 3432, I_MINSD = 3453,
I_MINSS = 3446, I_MONITOR = 1755, I_MOV = 218, I_MOVAPD = 2459, I_MOVAPS = 2451,
I_MOVBE = 9251, I_MOVD = 3920, I_MOVDDUP = 2186, I_MOVDQ2Q = 6522, I_MOVDQA = 3946,
I_MOVDQU = 3954, I_MOVHLPS = 2151, I_MOVHPD = 2345, I_MOVHPS = 2337, I_MOVLHPS = 2328,
I_MOVLPD = 2168, I_MOVLPS = 2160, I_MOVMSKPD = 2815, I_MOVMSKPS = 2805, I_MOVNTDQ = 6849,
I_MOVNTDQA = 7895, I_MOVNTI = 952, I_MOVNTPD = 2556, I_MOVNTPS = 2547, I_MOVNTQ = 6841,
I_MOVNTSD = 2574, I_MOVNTSS = 2565, I_MOVQ = 3926, I_MOVQ2DQ = 6513, I_MOVS = 295,
I_MOVSD = 2110, I_MOVSHDUP = 2353, I_MOVSLDUP = 2176, I_MOVSS = 2103, I_MOVSX = 939,
I_MOVSXD = 10013, I_MOVUPD = 2095, I_MOVUPS = 2087, I_MOVZX = 927, I_MPSADBW = 9628,
I_MUL = 1625, I_MULPD = 3170, I_MULPS = 3163, I_MULSD = 3184, I_MULSS = 3177,
I_MWAIT = 1764, I_NEG = 1620, I_NOP = 581, I_NOT = 1615, I_OR = 27, I_ORPD = 3053,
I_ORPS = 3047, I_OUT = 451, I_OUTS = 128, I_PABSB = 7688, I_PABSD = 7718, I_PABSW = 7703,
I_PACKSSDW = 3849, I_PACKSSWB = 3681, I_PACKUSDW = 7916, I_PACKUSWB = 3759,
I_PADDB = 7204, I_PADDD = 7234, I_PADDQ = 6481, I_PADDSB = 6930, I_PADDSW = 6947,
I_PADDUSB = 6620, I_PADDUSW = 6639, I_PADDW = 7219, I_PALIGNR = 9410, I_PAND = 6607,
I_PANDN = 6665, I_PAUSE = 10021, I_PAVGB = 6680, I_PAVGUSB = 2078, I_PAVGW = 6725,
I_PBLENDVB = 7599, I_PBLENDW = 9391, I_PCLMULQDQ = 9647, I_PCMPEQB = 4043,
I_PCMPEQD = 4081, I_PCMPEQQ = 7876, I_PCMPEQW = 4062, I_PCMPESTRI = 9726,
I_PCMPESTRM = 9703, I_PCMPGTB = 3702, I_PCMPGTD = 3740, I_PCMPGTQ = 8087,
I_PCMPGTW = 3721, I_PCMPISTRI = 9772, I_PCMPISTRM = 9749, I_PEXTRB = 9429,
I_PEXTRD = 9446, I_PEXTRQ = 9454, I_PEXTRW = 6311, I_PF2ID = 1914, I_PF2IW = 1907,
I_PFACC = 2028, I_PFADD = 1977, I_PFCMPEQ = 2035, I_PFCMPGE = 1938, I_PFCMPGT = 1984,
I_PFMAX = 1993, I_PFMIN = 1947, I_PFMUL = 2044, I_PFNACC = 1921, I_PFPNACC = 1929,
I_PFRCP = 1954, I_PFRCPIT1 = 2000, I_PFRCPIT2 = 2051, I_PFRSQIT1 = 2010, I_PFRSQRT = 1961,
I_PFSUB = 1970, I_PFSUBR = 2020, I_PHADDD = 7375, I_PHADDSW = 7392, I_PHADDW = 7358,
I_PHMINPOSUW = 8259, I_PHSUBD = 7451, I_PHSUBSW = 7468, I_PHSUBW = 7434, I_PI2FD = 1900,
I_PI2FW = 1893, I_PINSRB = 9530, I_PINSRD = 9568, I_PINSRQ = 9576, I_PINSRW = 6294,
I_PMADDUBSW = 7411, I_PMADDWD = 7073, I_PMAXSB = 8174, I_PMAXSD = 8191, I_PMAXSW = 6964,
I_PMAXUB = 6648, I_PMAXUD = 8225, I_PMAXUW = 8208, I_PMINSB = 8106, I_PMINSD = 8123,
I_PMINSW = 6902, I_PMINUB = 6590, I_PMINUD = 8157, I_PMINUW = 8140, I_PMOVMSKB = 6531,
I_PMOVSXBD = 7754, I_PMOVSXBQ = 7775, I_PMOVSXBW = 7733, I_PMOVSXDQ = 7838,
I_PMOVSXWD = 7796, I_PMOVSXWQ = 7817, I_PMOVZXBD = 7982, I_PMOVZXBQ = 8003,
I_PMOVZXBW = 7961, I_PMOVZXDQ = 8066, I_PMOVZXWD = 8024, I_PMOVZXWQ = 8045,
I_PMULDQ = 7859, I_PMULHRSW = 7538, I_PMULHRW = 2061, I_PMULHUW = 6740, I_PMULHW = 6759,
I_PMULLD = 8242, I_PMULLW = 6496, I_PMULUDQ = 7054, I_POP = 22, I_POPA = 98,
I_POPCNT = 4338, I_POPF = 277, I_POR = 6919, I_PREFETCH = 1872, I_PREFETCHNTA = 2402,
I_PREFETCHT0 = 2415, I_PREFETCHT1 = 2427, I_PREFETCHT2 = 2439, I_PREFETCHW = 1882,
I_PSADBW = 7092, I_PSHUFB = 7341, I_PSHUFD = 3988, I_PSHUFHW = 3996, I_PSHUFLW = 4005,
I_PSHUFW = 3980, I_PSIGNB = 7487, I_PSIGND = 7521, I_PSIGNW = 7504, I_PSLLD = 7024,
I_PSLLDQ = 9847, I_PSLLQ = 7039, I_PSLLW = 7009, I_PSRAD = 6710, I_PSRAW = 6695,
I_PSRLD = 6451, I_PSRLDQ = 9830, I_PSRLQ = 6466, I_PSRLW = 6436, I_PSUBB = 7144,
I_PSUBD = 7174, I_PSUBQ = 7189, I_PSUBSB = 6868, I_PSUBSW = 6885, I_PSUBUSB = 6552,
I_PSUBUSW = 6571, I_PSUBW = 7159, I_PSWAPD = 2070, I_PTEST = 7629, I_PUNPCKHBW = 3780,
I_PUNPCKHDQ = 3826, I_PUNPCKHQDQ = 3895, I_PUNPCKHWD = 3803, I_PUNPCKLBW = 3612,
I_PUNPCKLDQ = 3658, I_PUNPCKLQDQ = 3870, I_PUNPCKLWD = 3635, I_PUSH = 16,
I_PUSHA = 91, I_PUSHF = 270, I_PXOR = 6981, I_RCL = 977, I_RCPPS = 2953, I_RCPSS = 2960,
I_RCR = 982, I_RDFSBASE = 9882, I_RDGSBASE = 9912, I_RDMSR = 600, I_RDPMC = 607,
I_RDRAND = 9980, I_RDTSC = 593, I_RDTSCP = 1864, I_RET = 325, I_RETF = 354,
I_ROL = 967, I_ROR = 972, I_ROUNDPD = 9296, I_ROUNDPS = 9277, I_ROUNDSD = 9334,
I_ROUNDSS = 9315, I_RSM = 882, I_RSQRTPS = 2915, I_RSQRTSS = 2924, I_SAHF = 283,
I_SAL = 997, I_SALC = 394, I_SAR = 1002, I_SBB = 36, I_SCAS = 319, I_SETA = 807,
I_SETAE = 780, I_SETB = 774, I_SETBE = 800, I_SETG = 859, I_SETGE = 845, I_SETL = 839,
I_SETLE = 852, I_SETNO = 767, I_SETNP = 832, I_SETNS = 819, I_SETNZ = 793,
I_SETO = 761, I_SETP = 826, I_SETS = 813, I_SETZ = 787, I_SFENCE = 4321, I_SGDT = 1675,
I_SHL = 987, I_SHLD = 876, I_SHR = 992, I_SHRD = 892, I_SHUFPD = 6336, I_SHUFPS = 6328,
I_SIDT = 1681, I_SKINIT = 1839, I_SLDT = 1641, I_SMSW = 1699, I_SQRTPD = 2855,
I_SQRTPS = 2847, I_SQRTSD = 2871, I_SQRTSS = 2863, I_STC = 497, I_STD = 517,
I_STGI = 1827, I_STI = 507, I_STMXCSR = 9951, I_STOS = 307, I_STR = 1647, I_SUB = 51,
I_SUBPD = 3379, I_SUBPS = 3372, I_SUBSD = 3393, I_SUBSS = 3386, I_SWAPGS = 1856,
I_SYSCALL = 532, I_SYSENTER = 614, I_SYSEXIT = 624, I_SYSRET = 547, I_TEST = 206,
I_TZCNT = 4351, I_UCOMISD = 2742, I_UCOMISS = 2733, I_UD2 = 569, I_UNPCKHPD = 2296,
I_UNPCKHPS = 2286, I_UNPCKLPD = 2254, I_UNPCKLPS = 2244, I_VADDPD = 3139,
I_VADDPS = 3131, I_VADDSD = 3155, I_VADDSS = 3147, I_VADDSUBPD = 6414, I_VADDSUBPS = 6425,
I_VAESDEC = 9217, I_VAESDECLAST = 9238, I_VAESENC = 9175, I_VAESENCLAST = 9196,
I_VAESIMC = 9158, I_VAESKEYGENASSIST = 9812, I_VANDNPD = 3038, I_VANDNPS = 3029,
I_VANDPD = 3005, I_VANDPS = 2997, I_VBLENDPD = 9381, I_VBLENDPS = 9362, I_VBLENDVPD = 9681,
I_VBLENDVPS = 9670, I_VBROADCASTF128 = 7672, I_VBROADCASTSD = 7658, I_VBROADCASTSS = 7644,
I_VCMPEQPD = 5088, I_VCMPEQPS = 4686, I_VCMPEQSD = 5892, I_VCMPEQSS = 5490,
I_VCMPEQ_OSPD = 5269, I_VCMPEQ_OSPS = 4867, I_VCMPEQ_OSSD = 6073, I_VCMPEQ_OSSS = 5671,
I_VCMPEQ_UQPD = 5175, I_VCMPEQ_UQPS = 4773, I_VCMPEQ_UQSD = 5979, I_VCMPEQ_UQSS = 5577,
I_VCMPEQ_USPD = 5378, I_VCMPEQ_USPS = 4976, I_VCMPEQ_USSD = 6182, I_VCMPEQ_USSS = 5780,
I_VCMPFALSEPD = 5210, I_VCMPFALSEPS = 4808, I_VCMPFALSESD = 6014, I_VCMPFALSESS = 5612,
I_VCMPFALSE_OSPD = 5419, I_VCMPFALSE_OSPS = 5017, I_VCMPFALSE_OSSD = 6223,
I_VCMPFALSE_OSSS = 5821, I_VCMPGEPD = 5237, I_VCMPGEPS = 4835, I_VCMPGESD = 6041,
I_VCMPGESS = 5639, I_VCMPGE_OQPD = 5449, I_VCMPGE_OQPS = 5047, I_VCMPGE_OQSD = 6253,
I_VCMPGE_OQSS = 5851, I_VCMPGTPD = 5247, I_VCMPGTPS = 4845, I_VCMPGTSD = 6051,
I_VCMPGTSS = 5649, I_VCMPGT_OQPD = 5462, I_VCMPGT_OQPS = 5060, I_VCMPGT_OQSD = 6266,
I_VCMPGT_OQSS = 5864, I_VCMPLEPD = 5108, I_VCMPLEPS = 4706, I_VCMPLESD = 5912,
I_VCMPLESS = 5510, I_VCMPLE_OQPD = 5295, I_VCMPLE_OQPS = 4893, I_VCMPLE_OQSD = 6099,
I_VCMPLE_OQSS = 5697, I_VCMPLTPD = 5098, I_VCMPLTPS = 4696, I_VCMPLTSD = 5902,
I_VCMPLTSS = 5500, I_VCMPLT_OQPD = 5282, I_VCMPLT_OQPS = 4880, I_VCMPLT_OQSD = 6086,
I_VCMPLT_OQSS = 5684, I_VCMPNEQPD = 5131, I_VCMPNEQPS = 4729, I_VCMPNEQSD = 5935,
I_VCMPNEQSS = 5533, I_VCMPNEQ_OQPD = 5223, I_VCMPNEQ_OQPS = 4821, I_VCMPNEQ_OQSD = 6027,
I_VCMPNEQ_OQSS = 5625, I_VCMPNEQ_OSPD = 5435, I_VCMPNEQ_OSPS = 5033, I_VCMPNEQ_OSSD = 6239,
I_VCMPNEQ_OSSS = 5837, I_VCMPNEQ_USPD = 5323, I_VCMPNEQ_USPS = 4921, I_VCMPNEQ_USSD = 6127,
I_VCMPNEQ_USSS = 5725, I_VCMPNGEPD = 5188, I_VCMPNGEPS = 4786, I_VCMPNGESD = 5992,
I_VCMPNGESS = 5590, I_VCMPNGE_UQPD = 5391, I_VCMPNGE_UQPS = 4989, I_VCMPNGE_UQSD = 6195,
I_VCMPNGE_UQSS = 5793, I_VCMPNGTPD = 5199, I_VCMPNGTPS = 4797, I_VCMPNGTSD = 6003,
I_VCMPNGTSS = 5601, I_VCMPNGT_UQPD = 5405, I_VCMPNGT_UQPS = 5003, I_VCMPNGT_UQSD = 6209,
I_VCMPNGT_UQSS = 5807, I_VCMPNLEPD = 5153, I_VCMPNLEPS = 4751, I_VCMPNLESD = 5957,
I_VCMPNLESS = 5555, I_VCMPNLE_UQPD = 5351, I_VCMPNLE_UQPS = 4949, I_VCMPNLE_UQSD = 6155,
I_VCMPNLE_UQSS = 5753, I_VCMPNLTPD = 5142, I_VCMPNLTPS = 4740, I_VCMPNLTSD = 5946,
I_VCMPNLTSS = 5544, I_VCMPNLT_UQPD = 5337, I_VCMPNLT_UQPS = 4935, I_VCMPNLT_UQSD = 6141,
I_VCMPNLT_UQSS = 5739, I_VCMPORDPD = 5164, I_VCMPORDPS = 4762, I_VCMPORDSD = 5968,
I_VCMPORDSS = 5566, I_VCMPORD_SPD = 5365, I_VCMPORD_SPS = 4963, I_VCMPORD_SSD = 6169,
I_VCMPORD_SSS = 5767, I_VCMPTRUEPD = 5257, I_VCMPTRUEPS = 4855, I_VCMPTRUESD = 6061,
I_VCMPTRUESS = 5659, I_VCMPTRUE_USPD = 5475, I_VCMPTRUE_USPS = 5073, I_VCMPTRUE_USSD = 6279,
I_VCMPTRUE_USSS = 5877, I_VCMPUNORDPD = 5118, I_VCMPUNORDPS = 4716, I_VCMPUNORDSD = 5922,
I_VCMPUNORDSS = 5520, I_VCMPUNORD_SPD = 5308, I_VCMPUNORD_SPS = 4906, I_VCMPUNORD_SSD = 6112,
I_VCMPUNORD_SSS = 5710, I_VCOMISD = 2796, I_VCOMISS = 2787, I_VCVTDQ2PD = 6819,
I_VCVTDQ2PS = 3338, I_VCVTPD2DQ = 6830, I_VCVTPD2PS = 3274, I_VCVTPS2DQ = 3349,
I_VCVTPS2PD = 3263, I_VCVTSD2SI = 2722, I_VCVTSD2SS = 3296, I_VCVTSI2SD = 2536,
I_VCVTSI2SS = 2525, I_VCVTSS2SD = 3285, I_VCVTSS2SI = 2711, I_VCVTTPD2DQ = 6807,
I_VCVTTPS2DQ = 3360, I_VCVTTSD2SI = 2659, I_VCVTTSS2SI = 2647, I_VDIVPD = 3528,
I_VDIVPS = 3520, I_VDIVSD = 3544, I_VDIVSS = 3536, I_VDPPD = 9621, I_VDPPS = 9608,
I_VERR = 1663, I_VERW = 1669, I_VEXTRACTF128 = 9516, I_VEXTRACTPS = 9491,
I_VFMADD132PD = 8387, I_VFMADD132PS = 8374, I_VFMADD132SD = 8413, I_VFMADD132SS = 8400,
I_VFMADD213PD = 8667, I_VFMADD213PS = 8654, I_VFMADD213SD = 8693, I_VFMADD213SS = 8680,
I_VFMADD231PD = 8947, I_VFMADD231PS = 8934, I_VFMADD231SD = 8973, I_VFMADD231SS = 8960,
I_VFMADDSUB132PD = 8326, I_VFMADDSUB132PS = 8310, I_VFMADDSUB213PD = 8606,
I_VFMADDSUB213PS = 8590, I_VFMADDSUB231PD = 8886, I_VFMADDSUB231PS = 8870,
I_VFMSUB132PD = 8439, I_VFMSUB132PS = 8426, I_VFMSUB132SD = 8465, I_VFMSUB132SS = 8452,
I_VFMSUB213PD = 8719, I_VFMSUB213PS = 8706, I_VFMSUB213SD = 8745, I_VFMSUB213SS = 8732,
I_VFMSUB231PD = 8999, I_VFMSUB231PS = 8986, I_VFMSUB231SD = 9025, I_VFMSUB231SS = 9012,
I_VFMSUBADD132PD = 8358, I_VFMSUBADD132PS = 8342, I_VFMSUBADD213PD = 8638,
I_VFMSUBADD213PS = 8622, I_VFMSUBADD231PD = 8918, I_VFMSUBADD231PS = 8902,
I_VFNMADD132PD = 8492, I_VFNMADD132PS = 8478, I_VFNMADD132SD = 8520, I_VFNMADD132SS = 8506,
I_VFNMADD213PD = 8772, I_VFNMADD213PS = 8758, I_VFNMADD213SD = 8800, I_VFNMADD213SS = 8786,
I_VFNMADD231PD = 9052, I_VFNMADD231PS = 9038, I_VFNMADD231SD = 9080, I_VFNMADD231SS = 9066,
I_VFNMSUB132PD = 8548, I_VFNMSUB132PS = 8534, I_VFNMSUB132SD = 8576, I_VFNMSUB132SS = 8562,
I_VFNMSUB213PD = 8828, I_VFNMSUB213PS = 8814, I_VFNMSUB213SD = 8856, I_VFNMSUB213SS = 8842,
I_VFNMSUB231PD = 9108, I_VFNMSUB231PS = 9094, I_VFNMSUB231SD = 9136, I_VFNMSUB231SS = 9122,
I_VHADDPD = 4197, I_VHADDPS = 4206, I_VHSUBPD = 4231, I_VHSUBPS = 4240, I_VINSERTF128 = 9503,
I_VINSERTPS = 9557, I_VLDDQU = 7001, I_VLDMXCSR = 9941, I_VMASKMOVDQU = 7131,
I_VMASKMOVPD = 7949, I_VMASKMOVPS = 7937, I_VMAXPD = 3588, I_VMAXPS = 3580,
I_VMAXSD = 3604, I_VMAXSS = 3596, I_VMCALL = 1719, I_VMCLEAR = 9997, I_VMFUNC = 1787,
I_VMINPD = 3468, I_VMINPS = 3460, I_VMINSD = 3484, I_VMINSS = 3476, I_VMLAUNCH = 1727,
I_VMLOAD = 1811, I_VMMCALL = 1802, I_VMOVAPD = 2476, I_VMOVAPS = 2467, I_VMOVD = 3932,
I_VMOVDDUP = 2234, I_VMOVDQA = 3962, I_VMOVDQU = 3971, I_VMOVHLPS = 2195,
I_VMOVHPD = 2382, I_VMOVHPS = 2373, I_VMOVLHPS = 2363, I_VMOVLPD = 2214, I_VMOVLPS = 2205,
I_VMOVMSKPD = 2836, I_VMOVMSKPS = 2825, I_VMOVNTDQ = 6858, I_VMOVNTDQA = 7905,
I_VMOVNTPD = 2593, I_VMOVNTPS = 2583, I_VMOVQ = 3939, I_VMOVSD = 2143, I_VMOVSHDUP = 2391,
I_VMOVSLDUP = 2223, I_VMOVSS = 2135, I_VMOVUPD = 2126, I_VMOVUPS = 2117, I_VMPSADBW = 9637,
I_VMPTRLD = 9988, I_VMPTRST = 6385, I_VMREAD = 4128, I_VMRESUME = 1737, I_VMRUN = 1795,
I_VMSAVE = 1819, I_VMULPD = 3199, I_VMULPS = 3191, I_VMULSD = 3215, I_VMULSS = 3207,
I_VMWRITE = 4152, I_VMXOFF = 1747, I_VMXON = 10006, I_VORPD = 3066, I_VORPS = 3059,
I_VPABSB = 7695, I_VPABSD = 7725, I_VPABSW = 7710, I_VPACKSSDW = 3859, I_VPACKSSWB = 3691,
I_VPACKUSDW = 7926, I_VPACKUSWB = 3769, I_VPADDB = 7211, I_VPADDD = 7241,
I_VPADDQ = 6488, I_VPADDSB = 6938, I_VPADDSW = 6955, I_VPADDUSW = 6629, I_VPADDW = 7226,
I_VPALIGNR = 9419, I_VPAND = 6613, I_VPANDN = 6672, I_VPAVGB = 6687, I_VPAVGW = 6732,
I_VPBLENDVB = 9692, I_VPBLENDW = 9400, I_VPCLMULQDQ = 9658, I_VPCMPEQB = 4052,
I_VPCMPEQD = 4090, I_VPCMPEQQ = 7885, I_VPCMPEQW = 4071, I_VPCMPESTRI = 9737,
I_VPCMPESTRM = 9714, I_VPCMPGTB = 3711, I_VPCMPGTD = 3749, I_VPCMPGTQ = 8096,
I_VPCMPGTW = 3730, I_VPCMPISTRI = 9783, I_VPCMPISTRM = 9760, I_VPERM2F128 = 9265,
I_VPERMILPD = 7570, I_VPERMILPS = 7559, I_VPEXTRB = 9437, I_VPEXTRD = 9462,
I_VPEXTRQ = 9471, I_VPEXTRW = 6319, I_VPHADDD = 7383, I_VPHADDSW = 7401, I_VPHADDW = 7366,
I_VPHMINPOSUW = 8271, I_VPHSUBD = 7459, I_VPHSUBSW = 7477, I_VPHSUBW = 7442,
I_VPINSRB = 9538, I_VPINSRD = 9584, I_VPINSRQ = 9593, I_VPINSRW = 6302, I_VPMADDUBSW = 7422,
I_VPMADDWD = 7082, I_VPMAXSB = 8182, I_VPMAXSD = 8199, I_VPMAXSW = 6972, I_VPMAXUB = 6656,
I_VPMAXUD = 8233, I_VPMAXUW = 8216, I_VPMINSB = 8114, I_VPMINSD = 8131, I_VPMINSW = 6910,
I_VPMINUB = 6598, I_VPMINUD = 8165, I_VPMINUW = 8148, I_VPMOVMSKB = 6541,
I_VPMOVSXBD = 7764, I_VPMOVSXBQ = 7785, I_VPMOVSXBW = 7743, I_VPMOVSXDQ = 7848,
I_VPMOVSXWD = 7806, I_VPMOVSXWQ = 7827, I_VPMOVZXBD = 7992, I_VPMOVZXBQ = 8013,
I_VPMOVZXBW = 7971, I_VPMOVZXDQ = 8076, I_VPMOVZXWD = 8034, I_VPMOVZXWQ = 8055,
I_VPMULDQ = 7867, I_VPMULHRSW = 7548, I_VPMULHUW = 6749, I_VPMULHW = 6767,
I_VPMULLD = 8250, I_VPMULLW = 6504, I_VPMULUDQ = 7063, I_VPOR = 6924, I_VPSADBW = 7100,
I_VPSHUFB = 7349, I_VPSHUFD = 4014, I_VPSHUFHW = 4023, I_VPSHUFLW = 4033,
I_VPSIGNB = 7495, I_VPSIGND = 7529, I_VPSIGNW = 7512, I_VPSLLD = 7031, I_VPSLLDQ = 9855,
I_VPSLLQ = 7046, I_VPSLLW = 7016, I_VPSRAD = 6717, I_VPSRAW = 6702, I_VPSRLD = 6458,
I_VPSRLDQ = 9838, I_VPSRLQ = 6473, I_VPSRLW = 6443, I_VPSUBB = 7151, I_VPSUBD = 7181,
I_VPSUBQ = 7196, I_VPSUBSB = 6876, I_VPSUBSW = 6893, I_VPSUBUSB = 6561, I_VPSUBUSW = 6580,
I_VPSUBW = 7166, I_VPTEST = 7636, I_VPUNPCKHBW = 3791, I_VPUNPCKHDQ = 3837,
I_VPUNPCKHQDQ = 3907, I_VPUNPCKHWD = 3814, I_VPUNPCKLBW = 3623, I_VPUNPCKLDQ = 3669,
I_VPUNPCKLQDQ = 3882, I_VPUNPCKLWD = 3646, I_VPXOR = 6987, I_VRCPPS = 2967,
I_VRCPSS = 2975, I_VROUNDPD = 9305, I_VROUNDPS = 9286, I_VROUNDSD = 9343,
I_VROUNDSS = 9324, I_VRSQRTPS = 2933, I_VRSQRTSS = 2943, I_VSHUFPD = 6353,
I_VSHUFPS = 6344, I_VSQRTPD = 2888, I_VSQRTPS = 2879, I_VSQRTSD = 2906, I_VSQRTSS = 2897,
I_VSTMXCSR = 9970, I_VSUBPD = 3408, I_VSUBPS = 3400, I_VSUBSD = 3424, I_VSUBSS = 3416,
I_VTESTPD = 7590, I_VTESTPS = 7581, I_VUCOMISD = 2761, I_VUCOMISS = 2751,
I_VUNPCKHPD = 2317, I_VUNPCKHPS = 2306, I_VUNPCKLPD = 2275, I_VUNPCKLPS = 2264,
I_VXORPD = 3095, I_VXORPS = 3087, I_VZEROALL = 4118, I_VZEROUPPER = 4106,
I_WAIT = 10028, I_WBINVD = 561, I_WRFSBASE = 9931, I_WRGSBASE = 9960, I_WRMSR = 586,
I_XADD = 946, I_XCHG = 212, I_XGETBV = 1771, I_XLAT = 400, I_XOR = 61, I_XORPD = 3080,
I_XORPS = 3073, I_XRSTOR = 4273, I_XRSTOR64 = 4281, I_XSAVE = 4249, I_XSAVE64 = 4256,
I_XSAVEOPT = 4299, I_XSAVEOPT64 = 4309, I_XSETBV = 1779, I__3DNOW = 10034
} _InstructionType;
typedef enum
{
R_RAX, R_RCX, R_RDX, R_RBX, R_RSP, R_RBP, R_RSI, R_RDI, R_R8, R_R9, R_R10, R_R11, R_R12, R_R13, R_R14, R_R15,
R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI, R_R8D, R_R9D, R_R10D, R_R11D, R_R12D, R_R13D, R_R14D, R_R15D,
R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI, R_R8W, R_R9W, R_R10W, R_R11W, R_R12W, R_R13W, R_R14W, R_R15W,
R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH, R_R8B, R_R9B, R_R10B, R_R11B, R_R12B, R_R13B, R_R14B, R_R15B,
R_SPL, R_BPL, R_SIL, R_DIL,
R_ES, R_CS, R_SS, R_DS, R_FS, R_GS,
R_RIP,
R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, R_ST6, R_ST7,
R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7, R_XMM8, R_XMM9, R_XMM10, R_XMM11, R_XMM12, R_XMM13, R_XMM14, R_XMM15,
R_YMM0, R_YMM1, R_YMM2, R_YMM3, R_YMM4, R_YMM5, R_YMM6, R_YMM7, R_YMM8, R_YMM9, R_YMM10, R_YMM11, R_YMM12, R_YMM13, R_YMM14, R_YMM15,
R_CR0, R_UNUSED0, R_CR2, R_CR3, R_CR4, R_UNUSED1, R_UNUSED2, R_UNUSED3, R_CR8,
R_DR0, R_DR1, R_DR2, R_DR3, R_UNUSED4, R_UNUSED5, R_DR6, R_DR7
} _RegisterType;
#endif /* MNEMONICS_H */

View File

@ -0,0 +1,660 @@
/*
*
* Copyright (c) 2014
*
* cypher <the.cypher@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
#include "scylla_wrapper.h"
#include "ApiReader.h"
#include "ProcessLister.h"
#include "ImportRebuilder.h"
#include "IATSearch.h"
#include "StringConversion.h"
#include "SystemInformation.h"
static std::map<DWORD_PTR, ImportModuleThunk> moduleList;
static int moduleCount = 0;
static int importCount = 0;
void updateCounts()
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
moduleCount = 0;
importCount = 0;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
importCount++;
it_import++;
}
moduleCount++;
it_module++;
}
}
int scylla_searchIAT(DWORD pid, DWORD_PTR & iatStart, DWORD & iatSize, DWORD_PTR searchStart = 0xDEADBEEF, bool advancedSearch = false)
{
ApiReader apiReader;
DWORD_PTR searchAddress = 0;
DWORD_PTR addressIAT = 0, addressIATAdv = 0;
DWORD sizeIAT = 0, sizeIATAdv = 0;
IATSearch iatSearch;
ProcessLister processLister;
NativeWinApi::initialize();
SystemInformation::getSystemInformation();
//need to find correct process by PID
Process* processPtr = 0;
std::vector<Process> & processList = processLister.getProcessListSnapshotNative();
for(std::vector<Process>::iterator it = processList.begin(); it != processList.end(); ++it)
{
if(it->PID == pid)
{
processPtr = &(*it);
break;
}
}
if(!processPtr) return SCY_ERROR_PROCOPEN;
//init process access
ProcessAccessHelp::closeProcessHandle();
apiReader.clearAll();
if(!ProcessAccessHelp::openProcessHandle(processPtr->PID))
{
return SCY_ERROR_PROCOPEN;
}
ProcessAccessHelp::getProcessModules(ProcessAccessHelp::hProcess, ProcessAccessHelp::moduleList);
ProcessAccessHelp::selectedModule = 0;
ProcessAccessHelp::targetSizeOfImage = ProcessAccessHelp::getSizeOfImageProcess(ProcessAccessHelp::hProcess, ProcessAccessHelp::targetImageBase);
ProcessAccessHelp::targetImageBase = processPtr->imageBase;
apiReader.readApisFromModuleList();
int retVal = SCY_ERROR_IATNOTFOUND;
//now actually do some searching
if(searchStart != 0xDEADBEEF)
{
searchAddress = searchStart;
if(searchAddress)
{
if(advancedSearch)
{
if(iatSearch.searchImportAddressTableInProcess(searchAddress, &addressIATAdv, &sizeIATAdv, true))
{
//Scylla::windowLog.log(L"IAT Search Advanced: IAT VA " PRINTF_DWORD_PTR_FULL L" RVA " PRINTF_DWORD_PTR_FULL L" Size 0x%04X (%d)", addressIATAdv, addressIATAdv - ProcessAccessHelp::targetImageBase, sizeIATAdv, sizeIATAdv);
iatStart = addressIATAdv;
iatSize = sizeIATAdv;
retVal = SCY_ERROR_SUCCESS;
}
}
if(iatSearch.searchImportAddressTableInProcess(searchAddress, &addressIAT, &sizeIAT, false))
{
//Scylla::windowLog.log(L"IAT Search Normal: IAT VA " PRINTF_DWORD_PTR_FULL L" RVA " PRINTF_DWORD_PTR_FULL L" Size 0x%04X (%d)", addressIAT, addressIAT - ProcessAccessHelp::targetImageBase, sizeIAT, sizeIAT);
iatStart = addressIAT;
iatSize = sizeIAT;
retVal = SCY_ERROR_SUCCESS;
}
}
}
else
{
return SCY_ERROR_IATSEARCH;
}
processList.clear();
ProcessAccessHelp::closeProcessHandle();
apiReader.clearAll();
return retVal;
}
int scylla_getImports(DWORD_PTR iatAddr, DWORD iatSize, DWORD pid, LPVOID invalidImportCallback)
{
//some things we need
ApiReader apiReader;
ProcessLister processLister;
typedef void* (*fCallback)(LPVOID invalidImport);
fCallback myCallback = (fCallback)invalidImportCallback;
NativeWinApi::initialize();
SystemInformation::getSystemInformation();
//need to find correct process by PID
Process* processPtr = 0;
std::vector<Process> & processList = processLister.getProcessListSnapshotNative();
for(std::vector<Process>::iterator it = processList.begin(); it != processList.end(); ++it)
{
if(it->PID == pid)
{
processPtr = &(*it);
break;
}
}
if(!processPtr) return SCY_ERROR_PROCOPEN;
//init process access
ProcessAccessHelp::closeProcessHandle();
apiReader.clearAll();
if(!ProcessAccessHelp::openProcessHandle(processPtr->PID))
{
return SCY_ERROR_PROCOPEN;
}
ProcessAccessHelp::getProcessModules(ProcessAccessHelp::hProcess, ProcessAccessHelp::moduleList);
ProcessAccessHelp::selectedModule = 0;
ProcessAccessHelp::targetSizeOfImage = ProcessAccessHelp::getSizeOfImageProcess(ProcessAccessHelp::hProcess, ProcessAccessHelp::targetImageBase);
ProcessAccessHelp::targetImageBase = processPtr->imageBase;
apiReader.readApisFromModuleList();
//parse IAT
apiReader.readAndParseIAT(iatAddr, iatSize, moduleList);
//callback for invalid imports
if(invalidImportCallback != NULL)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
if(!importThunk.valid)
{
DWORD_PTR apiAddr = (DWORD_PTR)myCallback((LPVOID)importThunk.apiAddressVA);
//we trust the users return value
if(apiAddr != NULL)
{
importThunk.apiAddressVA = apiAddr;
importThunk.valid = true;
}
}
it_import++;
}
it_module++;
}
}
updateCounts();
return SCY_ERROR_SUCCESS;
}
bool scylla_addModule(const WCHAR* moduleName, DWORD_PTR firstThunk)
{
ApiReader apiReader;
return apiReader.addModuleToModuleList(moduleName, firstThunk);
}
bool scylla_addImport(const WCHAR* importName, DWORD_PTR thunkVA)
{
ApiReader apiReader;
ApiInfo* apiFound = 0;
DWORD apiVA = 0;
bool suspect = false;
if(ProcessAccessHelp::readMemoryFromProcess(thunkVA, sizeof(DWORD_PTR), (LPVOID)&apiVA))
{
apiFound = apiReader.getApiByVirtualAddress(apiVA, &suspect);
apiReader.addFoundApiToModuleList(thunkVA, apiFound, false, suspect);
return true;
}
return false;
}
bool scylla_importsValid()
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
bool valid = true;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
if(!importThunk.valid)
{
valid = false;
break;;
}
it_import++;
}
it_module++;
}
return valid;
}
bool scylla_cutImport(DWORD_PTR apiAddr)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
//we found the API Addr to be cut
if(importThunk.apiAddressVA == apiAddr)
{
moduleThunk.thunkList.erase(it_import);
//whole module empty now?
if(moduleThunk.thunkList.empty())
{
moduleList.erase(it_module);
}
else //maybe the module is valid now?
{
if(moduleThunk.isValid() && moduleThunk.moduleName[0] == L'?')
{
//update module name
wcscpy_s(moduleThunk.moduleName, moduleThunk.thunkList.begin()->second.moduleName);
}
moduleThunk.firstThunk = moduleThunk.thunkList.begin()->second.rva;
}
updateCounts();
return true;
}
it_import++;
}
it_module++;
}
return false;
}
int scylla_fixDump(WCHAR* dumpFile, WCHAR* iatFixFile, WCHAR* sectionName)
{
WCHAR dumpedFilePath[MAX_PATH];
WCHAR fixedFilePath[MAX_PATH];
wcscpy_s(fixedFilePath, iatFixFile);
wcscpy_s(dumpedFilePath, dumpFile);
//add IAT section to dump
ImportRebuilder importRebuild(dumpedFilePath, sectionName);
importRebuild.enableOFTSupport();
if(importRebuild.rebuildImportTable(fixedFilePath, moduleList))
{
return SCY_ERROR_SUCCESS;
}
else
{
return SCY_ERROR_IATWRITE;
}
}
int scylla_fixMappedDump(DWORD_PTR iatVA, DWORD_PTR FileMapVA, HANDLE hFileMap)
{
ImportRebuilder importRebuild(iatVA, FileMapVA, hFileMap, L".test");
importRebuild.enableOFTSupport();
if(importRebuild.rebuildMappedImportTable(iatVA, moduleList))
{
return SCY_ERROR_SUCCESS;
}
else
{
return SCY_ERROR_IATWRITE;
}
return SCY_ERROR_SUCCESS;
}
int scylla_getModuleCount()
{
return moduleCount;
}
int scylla_getImportCount()
{
return importCount;
}
void scylla_enumImportTree(LPVOID enumCallback)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
typedef void(*fCallback)(LPVOID importDetail);
fCallback myCallback = (fCallback)enumCallback;
ImportEnumData myImportEnumData;
myImportEnumData.DLLName = (char*)malloc(sizeof(char) * MAX_PATH);
myImportEnumData.APIName = (char*)malloc(sizeof(char) * MAX_PATH);
if(enumCallback == NULL || moduleList.empty())
{
return;
}
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
//module
myImportEnumData.NewDll = true;
myImportEnumData.NumberOfImports = moduleThunk.thunkList.size();
StringConversion::ToASCII(moduleThunk.moduleName, myImportEnumData.DLLName, sizeof(char)*MAX_PATH);
myImportEnumData.BaseImportThunk = moduleThunk.firstThunk;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
//import
myImportEnumData.ImageBase = 0;
myImportEnumData.ImportThunk = importThunk.apiAddressVA;
strcpy_s(myImportEnumData.APIName, sizeof(char)*MAX_PATH, importThunk.name);
myCallback(&myImportEnumData);
myImportEnumData.NewDll = false;
it_import++;
}
it_module++;
}
}
long scylla_estimatedIATSize()
{
//faking a file to be rebuild
ImportRebuilder importRebuild(L"", L"");
return importRebuild.getIATSectionSize(moduleList);
}
DWORD_PTR scylla_findImportWriteLocation(char* importName)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
if(_stricmp(importName, importThunk.name))
{
//returns VA
return importThunk.va;
}
}
it_import++;
}
it_module++;
return NULL;
}
DWORD_PTR scylla_findOrdinalImportWriteLocation(DWORD_PTR ordinalNumber)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
if(importThunk.ordinal == ordinalNumber)
{
return importThunk.va;
}
}
it_import++;
}
it_module++;
return NULL;
}
DWORD_PTR scylla_findImportNameByWriteLocation(DWORD_PTR thunkVA)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
if(importThunk.va == thunkVA)
{
return (DWORD_PTR)importThunk.name;
}
}
it_import++;
}
it_module++;
return NULL;
}
DWORD_PTR scylla_findModuleNameByWriteLocation(DWORD_PTR thunkVA)
{
std::map<DWORD_PTR, ImportModuleThunk>::iterator it_module;
std::map<DWORD_PTR, ImportThunk>::iterator it_import;
it_module = moduleList.begin();
while(it_module != moduleList.end())
{
ImportModuleThunk & moduleThunk = it_module->second;
it_import = moduleThunk.thunkList.begin();
while(it_import != moduleThunk.thunkList.end())
{
ImportThunk & importThunk = it_import->second;
if(importThunk.va == thunkVA)
{
return (DWORD_PTR)importThunk.moduleName;
}
}
it_import++;
}
it_module++;
return NULL;
}
BOOL DumpProcessW(const WCHAR* fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR* fileResult)
{
PeParser* peFile = 0;
if(fileToDump)
{
peFile = new PeParser(fileToDump, true);
}
else
{
peFile = new PeParser(imagebase, true);
}
return peFile->dumpProcess(imagebase, entrypoint, fileResult);
}
bool scylla_dumpProcessW(DWORD_PTR pid, const WCHAR* fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR* fileResult)
{
//BUGFiX: You need to initialize native WinAPIs before you can actually call them.
//Without this line of code you need to call some other dummy function in order to dump.
NativeWinApi::initialize();
if(ProcessAccessHelp::openProcessHandle((DWORD)pid))
{
return DumpProcessW(fileToDump, imagebase, entrypoint, fileResult);
}
else
{
return FALSE;
}
}
bool scylla_dumpProcessA(DWORD_PTR pid, const char* fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const char* fileResult)
{
WCHAR fileToDumpW[MAX_PATH];
WCHAR fileResultW[MAX_PATH];
if(fileResult == 0)
{
return FALSE;
}
if(MultiByteToWideChar(CP_ACP, 0, fileResult, -1, fileResultW, _countof(fileResultW)) == 0)
{
return FALSE;
}
if(fileToDump != 0)
{
if(MultiByteToWideChar(CP_ACP, 0, fileToDump, -1, fileToDumpW, _countof(fileToDumpW)) == 0)
{
return FALSE;
}
return scylla_dumpProcessW(pid, fileToDumpW, imagebase, entrypoint, fileResultW);
}
else
{
return scylla_dumpProcessW(pid, 0, imagebase, entrypoint, fileResultW);
}
}
bool scylla_rebuildFileW(const WCHAR* fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup)
{
if(createBackup)
{
if(!ProcessAccessHelp::createBackupFile(fileToRebuild))
{
return FALSE;
}
}
PeParser peFile(fileToRebuild, true);
if(peFile.readPeSectionsFromFile())
{
peFile.setDefaultFileAlignment();
if(removeDosStub)
{
peFile.removeDosStub();
}
peFile.alignAllSectionHeaders();
peFile.fixPeHeader();
if(peFile.savePeFileToDisk(fileToRebuild))
{
if(updatePeHeaderChecksum)
{
PeParser::updatePeHeaderChecksum(fileToRebuild, (DWORD)ProcessAccessHelp::getFileSize(fileToRebuild));
}
return TRUE;
}
}
return FALSE;
}
bool scylla_rebuildFileA(const char* fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup)
{
WCHAR fileToRebuildW[MAX_PATH];
if(MultiByteToWideChar(CP_ACP, 0, fileToRebuild, -1, fileToRebuildW, _countof(fileToRebuildW)) == 0)
{
return FALSE;
}
return scylla_rebuildFileW(fileToRebuildW, removeDosStub, updatePeHeaderChecksum, createBackup);
}

View File

@ -0,0 +1,66 @@
/*
*
* Copyright (c) 2014
*
* cypher <the.cypher@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//packing set to 1 needed because TitanEngine uses same
#pragma pack(push, 1)
const BYTE SCY_ERROR_SUCCESS = 0;
const BYTE SCY_ERROR_PROCOPEN = -1;
const BYTE SCY_ERROR_IATWRITE = -2;
const BYTE SCY_ERROR_IATSEARCH = -3;
const BYTE SCY_ERROR_IATNOTFOUND = -4;
typedef struct
{
bool NewDll;
int NumberOfImports;
ULONG_PTR ImageBase;
ULONG_PTR BaseImportThunk;
ULONG_PTR ImportThunk;
char* APIName;
char* DLLName;
} ImportEnumData, *PImportEnumData;
//IAT exports
int scylla_searchIAT(DWORD pid, DWORD_PTR & iatStart, DWORD & iatSize, DWORD_PTR searchStart, bool advancedSearch);
int scylla_getImports(DWORD_PTR iatAddr, DWORD iatSize, DWORD pid, LPVOID invalidImportCallback = NULL);
bool scylla_addModule(const WCHAR* moduleName, DWORD_PTR firstThunkRVA);
bool scylla_addImport(const WCHAR* importName, DWORD_PTR thunkVA);
bool scylla_importsValid();
bool scylla_cutImport(DWORD_PTR apiAddr);
int scylla_fixDump(WCHAR* dumpFile, WCHAR* iatFixFile, WCHAR* sectionName = L".scy");
int scylla_fixMappedDump(DWORD_PTR iatVA, DWORD_PTR FileMapVA, HANDLE hFileMap);
int scylla_getModuleCount();
int scylla_getImportCount();
void scylla_enumImportTree(LPVOID enumCallBack);
long scylla_estimatedIATSize();
DWORD_PTR scylla_findImportWriteLocation(char* importName);
DWORD_PTR scylla_findOrdinalImportWriteLocation(DWORD_PTR ordinalNumber);
DWORD_PTR scylla_findImportNameByWriteLocation(DWORD_PTR thunkVA);
DWORD_PTR scylla_findModuleNameByWriteLocation(DWORD_PTR thunkVA);
//dumper exports
bool scylla_dumpProcessW(DWORD_PTR pid, const WCHAR* fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const WCHAR* fileResult);
bool scylla_dumpProcessA(DWORD_PTR pid, const char* fileToDump, DWORD_PTR imagebase, DWORD_PTR entrypoint, const char* fileResult);
//rebuilder exports
bool scylla_rebuildFileW(const WCHAR* fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup);
bool scylla_rebuildFileA(const char* fileToRebuild, BOOL removeDosStub, BOOL updatePeHeaderChecksum, BOOL createBackup);
#pragma pack(pop)

View File

@ -0,0 +1,229 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.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>{F874B1B3-8EF7-4DF1-9889-57098E08A51C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>scylla_iatfix</RootNamespace>
<ProjectName>scylla_wrapper</ProjectName>
<WindowsTargetPlatformVersion>7.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<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 Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<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>
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(SolutionDir)obj\$(MSBuildProjectName)\$(Configuration)\$(Platform)\</IntDir>
<IncludePath>$(SolutionDir)distorm\include;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<OmitDefaultLibName>false</OmitDefaultLibName>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>distorm.lib;PSAPI.LIB;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<OmitDefaultLibName>false</OmitDefaultLibName>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>distorm.lib;PSAPI.LIB;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>distorm.lib;PSAPI.LIB;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>distorm.lib;PSAPI.LIB;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ApiReader.h" />
<ClInclude Include="Architecture.h" />
<ClInclude Include="DeviceNameResolver.h" />
<ClInclude Include="IATReferenceScan.h" />
<ClInclude Include="IATSearch.h" />
<ClInclude Include="ImportRebuilder.h" />
<ClInclude Include="mnemonics.h" />
<ClInclude Include="NativeWinApi.h" />
<ClInclude Include="PeParser.h" />
<ClInclude Include="ProcessAccessHelp.h" />
<ClInclude Include="ProcessLister.h" />
<ClInclude Include="scylla_wrapper.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="StringConversion.h" />
<ClInclude Include="SystemInformation.h" />
<ClInclude Include="targetver.h" />
<ClInclude Include="Thunks.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ApiReader.cpp" />
<ClCompile Include="Architecture.cpp" />
<ClCompile Include="DeviceNameResolver.cpp" />
<ClCompile Include="dllmain.cpp">
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</CompileAsManaged>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</PrecompiledHeader>
</ClCompile>
<ClCompile Include="IATReferenceScan.cpp" />
<ClCompile Include="IATSearch.cpp" />
<ClCompile Include="ImportRebuilder.cpp" />
<ClCompile Include="NativeWinApi.cpp" />
<ClCompile Include="PeParser.cpp" />
<ClCompile Include="ProcessAccessHelp.cpp" />
<ClCompile Include="ProcessLister.cpp" />
<ClCompile Include="scylla_wrapper.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="StringConversion.cpp" />
<ClCompile Include="SystemInformation.cpp" />
<ClCompile Include="Thunks.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\distorm\distorm.vcxproj">
<Project>{25ff4a19-7088-4687-aa32-76e61bd62e51}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ApiReader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Architecture.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SystemInformation.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ProcessAccessHelp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Thunks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NativeWinApi.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PeParser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="StringConversion.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DeviceNameResolver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ImportRebuilder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ProcessLister.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IATSearch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="scylla_wrapper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IATReferenceScan.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mnemonics.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ApiReader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Architecture.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SystemInformation.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProcessAccessHelp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="NativeWinApi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PeParser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="StringConversion.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DeviceNameResolver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ImportRebuilder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ProcessLister.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IATSearch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Thunks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scylla_wrapper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IATReferenceScan.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
// stdafx.cpp : Quelldatei, die nur die Standard-Includes einbindet.
// scylla_iatfix.pch ist der vorkompilierte Header.
// stdafx.obj enth<74>lt die vorkompilierten Typinformationen.
#include "stdafx.h"
// TODO: Auf zus<75>tzliche Header verweisen, die in STDAFX.H
// und nicht in dieser Datei erforderlich sind.

8
scylla_wrapper/stdafx.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

View File

@ -0,0 +1,8 @@
#pragma once
// Durch Einbeziehen von"SDKDDKVer.h" wird die h<>chste verf<72>gbare Windows-Plattform definiert.
// Wenn Sie die Anwendung f<>r eine fr<66>here Windows-Plattform erstellen m<>chten, schlie<69>en Sie "WinSDKVer.h" ein, und
// legen Sie das _WIN32_WINNT-Makro auf die zu unterst<73>tzende Plattform fest, bevor Sie "SDKDDKVer.h" einschlie<69>en.
#include <SDKDDKVer.h>

@ -1 +0,0 @@
Subproject commit 4f7892b43dfcf4fda041b03b992541cac1367c2c