mirror of
https://github.com/DarthTon/Blackbone.git
synced 2026-10-16 20:50:50 +08:00
Unexported symbols resolve using MSDIA
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -8525,7 +8525,7 @@ namespace Catch {
|
||||
Section::~Section() {
|
||||
if( m_sectionIncluded ) {
|
||||
SectionEndInfo endInfo( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
||||
if( std::uncaught_exception() )
|
||||
if( std::uncaught_exceptions() )
|
||||
getResultCapture().sectionEndedEarly( endInfo );
|
||||
else
|
||||
getResultCapture().sectionEnded( endInfo );
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "../Config.h"
|
||||
#pragma warning(disable : 4100)
|
||||
#include "../../../contrib/AsmJit/AsmJit.h"
|
||||
#include <AsmJit/AsmJit.h>
|
||||
#pragma warning(default : 4100)
|
||||
|
||||
#include <vector>
|
||||
|
||||
+107
-18
@@ -180,7 +180,6 @@
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
<EnableCppCoreCheck>true</EnableCppCoreCheck>
|
||||
<CodeAnalysisRuleSet>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Team Tools\Static Analysis Tools\Rule Sets\NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
@@ -189,19 +188,16 @@
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug(DLL)|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
<EnableCppCoreCheck>true</EnableCppCoreCheck>
|
||||
<CodeAnalysisRuleSet>C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Team Tools\Static Analysis Tools\Rule Sets\NativeRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
@@ -210,50 +206,42 @@
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug(DLL)|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(XP)|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(DLL)|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(XP)|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(DLL)|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(ProjectDir)..\..\contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -270,6 +258,7 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -278,6 +267,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug(XP)|Win32'">
|
||||
<ClCompile>
|
||||
@@ -293,6 +290,7 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -301,6 +299,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug(DLL)|Win32'">
|
||||
<ClCompile>
|
||||
@@ -316,17 +322,23 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(ProjectDir)..\..\contrib\BeaEngine\Win32\Dll\BeaEngineCheetah.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;$(ProjectDir)..\..\contrib\BeaEngine\Win32\Dll\BeaEngineCheetah.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -342,6 +354,7 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -350,6 +363,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib\amd64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug(XP)|x64'">
|
||||
<ClCompile>
|
||||
@@ -363,6 +384,7 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -371,6 +393,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib\amd64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug(DLL)|x64'">
|
||||
<ClCompile>
|
||||
@@ -384,15 +414,21 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>$(ProjectDir)..\..\contrib\BeaEngine\Win64\Dll\BeaEngineCheetah64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;$(ProjectDir)..\..\contrib\BeaEngine\Win64\Dll\BeaEngineCheetah64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib\amd64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@@ -412,6 +448,7 @@
|
||||
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -422,6 +459,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release(XP)|Win32'">
|
||||
<ClCompile>
|
||||
@@ -441,6 +486,7 @@
|
||||
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -451,6 +497,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release(DLL)|Win32'">
|
||||
<ClCompile>
|
||||
@@ -470,20 +524,26 @@
|
||||
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>$(ProjectDir)..\..\contrib\BeaEngine\Win32\Dll\BeaEngineCheetah.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;$(ProjectDir)..\..\contrib\BeaEngine\Win32\Dll\BeaEngineCheetah.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -499,6 +559,7 @@
|
||||
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -509,6 +570,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib\amd64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release(XP)|x64'">
|
||||
<ClCompile>
|
||||
@@ -524,6 +593,7 @@
|
||||
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -534,6 +604,14 @@
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib\amd64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Lib>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release(DLL)|x64'">
|
||||
<ClCompile>
|
||||
@@ -549,17 +627,23 @@
|
||||
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(VsInstallDir)DIA SDK\include;$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>$(ProjectDir)..\..\contrib\BeaEngine\Win64\Dll\BeaEngineCheetah64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>diaguids.lib;Ole32.lib;$(ProjectDir)..\..\contrib\BeaEngine\Win64\Dll\BeaEngineCheetah64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(VsInstallDir)DIA SDK\lib\amd64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy "$(SolutionDir)DIA\$(Platform)\msdia140.dll" "$(TargetDir)" /Y
|
||||
xcopy "$(SolutionDir)DIA\$(Platform)\symsrv.dll" "$(TargetDir)" /Y</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\contrib\AsmJit\base\assembler.cpp" />
|
||||
@@ -621,7 +705,6 @@
|
||||
<ClCompile Include="ManualMap\Native\NtLoader.cpp" />
|
||||
<ClCompile Include="Misc\InitOnce.cpp" />
|
||||
<ClCompile Include="Misc\NameResolve.cpp" />
|
||||
<ClCompile Include="Misc\PatternLoader.cpp" />
|
||||
<ClCompile Include="Misc\Utils.cpp" />
|
||||
<ClCompile Include="Patterns\PatternSearch.cpp" />
|
||||
<ClCompile Include="PE\ImageNET.cpp" />
|
||||
@@ -650,6 +733,9 @@
|
||||
<ClCompile Include="Subsystem\NativeSubsystem.cpp" />
|
||||
<ClCompile Include="Subsystem\Wow64Subsystem.cpp" />
|
||||
<ClCompile Include="Subsystem\x86Subsystem.cpp" />
|
||||
<ClCompile Include="Symbols\PatternLoader.cpp" />
|
||||
<ClCompile Include="Symbols\PDBHelper.cpp" />
|
||||
<ClCompile Include="Symbols\SymbolLoader.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\contrib\AsmJit\apibegin.h" />
|
||||
@@ -730,7 +816,6 @@
|
||||
<ClInclude Include="Misc\DynImport.h" />
|
||||
<ClInclude Include="Misc\InitOnce.h" />
|
||||
<ClInclude Include="Misc\NameResolve.h" />
|
||||
<ClInclude Include="Misc\PatternLoader.h" />
|
||||
<ClInclude Include="Misc\Thunk.hpp" />
|
||||
<ClInclude Include="Misc\Trace.hpp" />
|
||||
<ClInclude Include="Misc\Utils.h" />
|
||||
@@ -754,6 +839,10 @@
|
||||
<ClInclude Include="Subsystem\NativeSubsystem.h" />
|
||||
<ClInclude Include="Subsystem\Wow64Subsystem.h" />
|
||||
<ClInclude Include="Subsystem\x86Subsystem.h" />
|
||||
<ClInclude Include="Symbols\PatternLoader.h" />
|
||||
<ClInclude Include="Symbols\PDBHelper.h" />
|
||||
<ClInclude Include="Symbols\SymbolLoader.h" />
|
||||
<ClInclude Include="Symbols\SymbolData.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
<Filter Include="Subsystem">
|
||||
<UniqueIdentifier>{7eb59189-daeb-47d1-9fa8-c9e246b22039}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Symbols">
|
||||
<UniqueIdentifier>{e666a795-e3de-4277-9223-b220c8d109ed}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Subsystem\NativeSubsystem.cpp">
|
||||
@@ -192,10 +195,16 @@
|
||||
<ClCompile Include="..\..\contrib\rewolf-wow64ext\src\wow64ext.cpp">
|
||||
<Filter>Subsystem</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Misc\PatternLoader.cpp">
|
||||
<Filter>Misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DllMain.cpp" />
|
||||
<ClCompile Include="Symbols\SymbolLoader.cpp">
|
||||
<Filter>Symbols</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Symbols\PatternLoader.cpp">
|
||||
<Filter>Symbols</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Symbols\PDBHelper.cpp">
|
||||
<Filter>Symbols</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Config.h" />
|
||||
@@ -454,11 +463,20 @@
|
||||
<ClInclude Include="Include\NativeEnums.h">
|
||||
<Filter>Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Misc\PatternLoader.h">
|
||||
<Filter>Misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Include\HandleGuard.h">
|
||||
<Filter>Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Symbols\SymbolData.h">
|
||||
<Filter>Symbols</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Symbols\SymbolLoader.h">
|
||||
<Filter>Symbols</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Symbols\PatternLoader.h">
|
||||
<Filter>Symbols</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Symbols\PDBHelper.h">
|
||||
<Filter>Symbols</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "../Process/Process.h"
|
||||
#include "../Include/Macro.h"
|
||||
#include "../Misc/Trace.hpp"
|
||||
#include "../Misc/PatternLoader.h"
|
||||
#include "../Symbols/SymbolData.h"
|
||||
#include "../Asm/LDasm.h"
|
||||
|
||||
namespace blackbone
|
||||
@@ -284,11 +284,9 @@ NTSTATUS MExcept::CreateVEH( Process& proc, ModuleData& mod, bool partial )
|
||||
if (!pDecode)
|
||||
return pDecode.status;
|
||||
|
||||
auto& data = g_PatternLoader->data();
|
||||
|
||||
replaceStub( newHandler, handlerSize, 0xDEADDA7A, static_cast<uint32_t>(data.LdrpInvertedFunctionTable32) );
|
||||
replaceStub( newHandler, handlerSize, 0xDEADDA7A, static_cast<uint32_t>(g_symbols.LdrpInvertedFunctionTable32) );
|
||||
replaceStub( newHandler, handlerSize, 0xDEADC0DE, static_cast<uint32_t>(pDecode->procAddress) );
|
||||
replaceStub( newHandler, handlerSize, 0xDEADC0D2, static_cast<uint32_t>(data.LdrProtectMrdata) );
|
||||
replaceStub( newHandler, handlerSize, 0xDEADC0D2, static_cast<uint32_t>(g_symbols.LdrProtectMrdata) );
|
||||
}
|
||||
|
||||
// Write handler data into target process
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "../../Misc/Utils.h"
|
||||
#include "../../Misc/DynImport.h"
|
||||
#include "../../Misc/trace.hpp"
|
||||
#include "../../Misc/PatternLoader.h"
|
||||
#include "../../Symbols/SymbolData.h"
|
||||
|
||||
#include "../contrib/VersionHelpers.h"
|
||||
|
||||
@@ -163,12 +163,12 @@ NTSTATUS NtLdr::AddStaticTLSEntry( const NtLdrEntry& mod, ptr_t tlsPtr )
|
||||
ptr_t LdrpHandleTlsData = 0;
|
||||
if (mod.type == mt_mod64)
|
||||
{
|
||||
LdrpHandleTlsData = g_PatternLoader->data().LdrpHandleTlsData64;
|
||||
LdrpHandleTlsData = g_symbols.LdrpHandleTlsData64;
|
||||
pNode = SetNode<_LDR_DATA_TABLE_ENTRY_BASE64>( pNode, mod.baseAddress );
|
||||
}
|
||||
else
|
||||
{
|
||||
LdrpHandleTlsData = g_PatternLoader->data().LdrpHandleTlsData32;
|
||||
LdrpHandleTlsData = g_symbols.LdrpHandleTlsData32;
|
||||
pNode = SetNode<_LDR_DATA_TABLE_ENTRY_BASE32>( pNode, mod.baseAddress );
|
||||
}
|
||||
|
||||
@@ -231,12 +231,12 @@ NTSTATUS NtLdr::AddStaticTLSEntry( const NtLdrEntry& mod, ptr_t tlsPtr )
|
||||
/// <returns>true on success</returns>
|
||||
bool NtLdr::InsertInvertedFunctionTable( NtLdrEntry& mod )
|
||||
{
|
||||
ptr_t RtlInsertInvertedFunctionTable = g_PatternLoader->data().RtlInsertInvertedFunctionTable64;
|
||||
ptr_t LdrpInvertedFunctionTable = g_PatternLoader->data().LdrpInvertedFunctionTable64;
|
||||
ptr_t RtlInsertInvertedFunctionTable = g_symbols.RtlInsertInvertedFunctionTable64;
|
||||
ptr_t LdrpInvertedFunctionTable = g_symbols.LdrpInvertedFunctionTable64;
|
||||
if (mod.type == mt_mod32)
|
||||
{
|
||||
RtlInsertInvertedFunctionTable = g_PatternLoader->data().RtlInsertInvertedFunctionTable32;
|
||||
LdrpInvertedFunctionTable = g_PatternLoader->data().LdrpInvertedFunctionTable32;
|
||||
RtlInsertInvertedFunctionTable = g_symbols.RtlInsertInvertedFunctionTable32;
|
||||
LdrpInvertedFunctionTable = g_symbols.LdrpInvertedFunctionTable32;
|
||||
}
|
||||
|
||||
// Invalid addresses. Probably pattern scan has failed
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "../../../contrib/VersionHelpers.h"
|
||||
|
||||
#include "DynImport.h"
|
||||
#include "PatternLoader.h"
|
||||
#include "../Symbols/SymbolLoader.h"
|
||||
#include "NameResolve.h"
|
||||
|
||||
#include <string>
|
||||
@@ -33,8 +33,8 @@ public:
|
||||
GrantPriviledge( L"SeLoadDriverPrivilege" );
|
||||
LoadFuncs();
|
||||
|
||||
g_PatternLoader = std::make_unique<PatternLoader>();
|
||||
g_PatternLoader->DoSearch();
|
||||
SymbolLoader sl;
|
||||
sl.Load( g_symbols );
|
||||
|
||||
NameResolve::Instance().Initialize();
|
||||
}
|
||||
@@ -121,8 +121,6 @@ private:
|
||||
static volatile long _done;
|
||||
};
|
||||
|
||||
std::unique_ptr<PatternLoader> g_PatternLoader;
|
||||
|
||||
/// <summary>
|
||||
/// Exported InitOnce wrapper
|
||||
/// </summary>
|
||||
|
||||
@@ -1,301 +0,0 @@
|
||||
#include "PatternLoader.h"
|
||||
#include "../PE/PEImage.h"
|
||||
#include "../Include/Winheaders.h"
|
||||
#include "../Misc/Trace.hpp"
|
||||
#include "../../../contrib/VersionHelpers.h"
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
/// <summary>
|
||||
/// Scan ntdll for internal loader data
|
||||
/// </summary>
|
||||
/// <returns>Found data</returns>
|
||||
const PatternData& PatternLoader::DoSearch()
|
||||
{
|
||||
CheckSystem();
|
||||
|
||||
pe::PEImage ntdll32;
|
||||
pe::PEImage ntdll64;
|
||||
ptr_t scanStart32 = 0, scanSize32 = 0;
|
||||
ptr_t scanStart64 = 0, scanSize64 = 0;
|
||||
int64_t diff32 = 0, diff64 = 0;
|
||||
|
||||
wchar_t buf[MAX_PATH] = { 0 };
|
||||
GetWindowsDirectoryW( buf, MAX_PATH );
|
||||
|
||||
std::wstring windir( buf );
|
||||
|
||||
// Load ntdlls
|
||||
if (_x86OS)
|
||||
{
|
||||
ntdll32.Load( std::wstring( windir + L"\\System32\\ntdll.dll" ), true );
|
||||
diff32 = static_cast<int64_t>(ntdll32.imageBase()) - reinterpret_cast<int64_t>(ntdll32.base());
|
||||
}
|
||||
else
|
||||
{
|
||||
FsRedirector fsr( _wow64Process );
|
||||
ntdll64.Load( std::wstring( windir + L"\\System32\\ntdll.dll" ), true );
|
||||
ntdll32.Load( std::wstring( windir + L"\\SysWOW64\\ntdll.dll" ), true );
|
||||
|
||||
diff32 = static_cast<int64_t>(ntdll32.imageBase()) - reinterpret_cast<int64_t>(ntdll32.base());
|
||||
diff64 = static_cast<int64_t>(ntdll64.imageBase()) - reinterpret_cast<int64_t>(ntdll64.base());
|
||||
}
|
||||
|
||||
auto fillRanges = []( const pe::PEImage& file, ptr_t& start, ptr_t& size )
|
||||
{
|
||||
for (auto& sec : file.sections())
|
||||
if (_stricmp( reinterpret_cast<const char*>(sec.Name), ".text" ) == 0)
|
||||
{
|
||||
start = reinterpret_cast<ptr_t>(file.base()) + sec.VirtualAddress;
|
||||
size = sec.Misc.VirtualSize;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Get code section bounds
|
||||
fillRanges( ntdll32, scanStart32, scanSize32 );
|
||||
if (!_x86OS)
|
||||
fillRanges( ntdll64, scanStart64, scanSize64 );
|
||||
|
||||
auto scan = [&]( OffsetData& rule, auto& result )
|
||||
{
|
||||
ptr_t scanStart = 0, scanSize = 0;
|
||||
int64_t diff = 0;
|
||||
std::vector<ptr_t> found;
|
||||
|
||||
if (rule.bit64)
|
||||
{
|
||||
scanStart = scanStart64;
|
||||
scanSize = scanSize64;
|
||||
diff = diff64;
|
||||
}
|
||||
else
|
||||
{
|
||||
scanStart = scanStart32;
|
||||
scanSize = scanSize32;
|
||||
diff = diff32;
|
||||
}
|
||||
|
||||
rule.pattern.Search( reinterpret_cast<void*>(scanStart), static_cast<size_t>(scanSize), found );
|
||||
if (!found.empty())
|
||||
{
|
||||
// Plain pointer sum
|
||||
if (rule.functionOffset != -1)
|
||||
{
|
||||
result = found.front() - rule.functionOffset + diff;
|
||||
}
|
||||
// Pointer dereference inside instruction
|
||||
else if (rule.dataStartOffset != 0)
|
||||
{
|
||||
if (rule.bit64)
|
||||
{
|
||||
result = *reinterpret_cast<int32_t*>(found.front() + (rule.dataStartOffset + rule.dataOperandOffset)) +
|
||||
(found.front() + rule.dataStartOffset + rule.dataInstructionSize) + diff;
|
||||
}
|
||||
else
|
||||
result = *reinterpret_cast<int32_t*>(found.front() + rule.dataStartOffset);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::unordered_map<ptr_t*, OffsetData> patterns;
|
||||
OSFillPatterns( patterns );
|
||||
|
||||
// Final search
|
||||
for (auto& e : patterns)
|
||||
scan( e.second, *e.first );
|
||||
|
||||
// Retry with old patterns
|
||||
if (_data.RtlInsertInvertedFunctionTable32 == 0 && IsWindows8Point1OrGreater() && !IsWindows10CreatorsOrGreater())
|
||||
{
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8D 45 F4 89 55 F8 50 8D 55 FC
|
||||
OffsetData rule1{ "\x8d\x45\xf4\x89\x55\xf8\x50\x8d\x55\xfc", false, 0xB };
|
||||
OffsetData rule2{ "\x8d\x45\xf4\x89\x55\xf8\x50\x8d\x55\xfc", false, -1, 0x1D };
|
||||
|
||||
scan( rule1, _data.RtlInsertInvertedFunctionTable32 );
|
||||
scan( rule2, _data.LdrpInvertedFunctionTable32 );
|
||||
}
|
||||
|
||||
// Report errors
|
||||
#ifndef BLACKBONE_NO_TRACE
|
||||
if (_data.LdrpHandleTlsData64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpHandleTlsData64 not found" );
|
||||
if (_data.LdrpHandleTlsData32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpHandleTlsData32 not found" );
|
||||
if (IsWindows8Point1OrGreater() && _data.LdrpInvertedFunctionTable64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpInvertedFunctionTable64 not found" );
|
||||
if (_data.LdrpInvertedFunctionTable32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpInvertedFunctionTable32 not found" );
|
||||
if (IsWindows8Point1OrGreater() && _data.RtlInsertInvertedFunctionTable64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: RtlInsertInvertedFunctionTable64 not found" );
|
||||
if (_data.RtlInsertInvertedFunctionTable32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: RtlInsertInvertedFunctionTable32 not found" );
|
||||
if (IsWindows8Point1OrGreater() && _data.LdrProtectMrdata == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrProtectMrdata not found" );
|
||||
if (IsWindows7OrGreater() && !IsWindows8OrGreater())
|
||||
{
|
||||
if (_data.LdrKernel32PatchAddress == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrKernel32PatchAddress not found" );
|
||||
if (_data.APC64PatchAddress == 0)
|
||||
BLACKBONE_TRACE( "PatternData: APC64PatchAddress not found" );
|
||||
}
|
||||
#endif
|
||||
return _data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detect process and OS architecture
|
||||
/// </summary>
|
||||
void PatternLoader::CheckSystem()
|
||||
{
|
||||
SYSTEM_INFO info = { { 0 } };
|
||||
GetNativeSystemInfo( &info );
|
||||
|
||||
if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
|
||||
{
|
||||
_x86OS = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL wowSrc = FALSE;
|
||||
IsWow64Process( GetCurrentProcess(), &wowSrc );
|
||||
_wow64Process = wowSrc != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill OS-dependent patterns
|
||||
/// </summary>
|
||||
/// <param name="patterns">Pattern collection</param>
|
||||
void PatternLoader::OSFillPatterns( std::unordered_map<ptr_t*, OffsetData>& patterns )
|
||||
{
|
||||
if (IsWindows10FallCreatorsOrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 74 33 44 8D 43 09
|
||||
patterns.emplace( &_data.LdrpHandleTlsData64, OffsetData{ "\x74\x33\x44\x8d\x43\x09", true, 0x43 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FA 49 8D 43 20
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable64, OffsetData{ "\x8b\xfa\x49\x8d\x43\x20", true, 0x10 } );
|
||||
|
||||
// RtlpInsertInvertedFunctionTableEntry
|
||||
// 49 8B E8 48 8B FA 0F 84
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable64, OffsetData{ "\x49\x8b\xe8\x48\x8b\xfa\x0f\x84", true, -1, -0xF, 2, 6 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 53 56 57 8D 45 F8 8B FA
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8d\x45\xf8\x8b\xfa", false, 0x8 } );
|
||||
|
||||
// RtlpInsertInvertedFunctionTableEntry
|
||||
// 33 F6 46 3B C6
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable32, OffsetData{ "\x33\xF6\x46\x3B\xC6", false, -1, -0x1B } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B C1 8D 4D BC 51
|
||||
patterns.emplace( &_data.LdrpHandleTlsData32, OffsetData{ "\x8b\xc1\x8d\x4d\xbc\x51", false, 0x18 } );
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 75 24 85 F6 75 08
|
||||
patterns.emplace( &_data.LdrProtectMrdata, OffsetData{ "\x75\x24\x85\xf6\x75\x08", false, 0x1C } );
|
||||
}
|
||||
else if (IsWindows10CreatorsOrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 74 33 44 8D 43 09
|
||||
patterns.emplace( &_data.LdrpHandleTlsData64, OffsetData{ "\x74\x33\x44\x8d\x43\x09", true, 0x43 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FA 49 8D 43 20
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable64, OffsetData{ "\x8b\xfa\x49\x8d\x43\x20", true, 0x10 } );
|
||||
|
||||
// RtlpInsertInvertedFunctionTableEntry
|
||||
// 49 8B E8 48 8B FA 0F 84
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable64, OffsetData{ "\x49\x8b\xe8\x48\x8b\xfa\x0f\x84", true, -1, -0xF, 2, 6 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8D 45 F0 89 55 F8 50 8D 55 F4
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable32, OffsetData{ "\x8d\x45\xf0\x89\x55\xf8\x50\x8d\x55\xf4", false, 0xB } );
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable32, OffsetData{ "\x8d\x45\xf0\x89\x55\xf8\x50\x8d\x55\xf4", false, -1, 0x4C } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B C1 8D 4D BC 51
|
||||
patterns.emplace( &_data.LdrpHandleTlsData32, OffsetData{ "\x8b\xc1\x8d\x4d\xbc\x51", false, 0x18 } );
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 75 24 85 F6 75 08
|
||||
patterns.emplace( &_data.LdrProtectMrdata, OffsetData{ "\x75\x24\x85\xf6\x75\x08", false, 0x1C } );
|
||||
}
|
||||
else if (IsWindows8Point1OrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 44 8D 43 09 4C 8D 4C 24 38
|
||||
patterns.emplace( &_data.LdrpHandleTlsData64, OffsetData{ "\x44\x8d\x43\x09\x4c\x8d\x4c\x24\x38", true, 0x43 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B C3 2B D3 48 8D 48 01
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable64, OffsetData{ "\x8b\xc3\x2b\xd3\x48\x8d\x48\x01", true, 0x84 } );
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable64, OffsetData{ "\x8b\xc3\x2b\xd3\x48\x8d\x48\x01", true, -1, -0x27, 3, 7 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 53 56 57 8B DA 8B F9 50
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8b\xda\x8b\xf9\x50", false, 0xB } );
|
||||
|
||||
if (IsWindows10OrGreater())
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8b\xda\x8b\xf9\x50", false, -1, 0x22 } );
|
||||
else
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8b\xda\x8b\xf9\x50", false, -1, 0x23 } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 50 6A 09 6A 01 8B C1
|
||||
patterns.emplace( &_data.LdrpHandleTlsData32, OffsetData{ "\x50\x6a\x09\x6a\x01\x8b\xc1", false, 0x1B } );
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 83 7D 08 00 8B 35
|
||||
patterns.emplace( &_data.LdrProtectMrdata, OffsetData{ PatternSearch( "\x83\x7d\x08\x00\x8b\x35", 6 ), false, 0x12 } );
|
||||
}
|
||||
else if (IsWindows8OrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 48 8B 79 30 45 8D 66 01
|
||||
patterns.emplace( &_data.LdrpHandleTlsData64, OffsetData{ "\x48\x8b\x79\x30\x45\x8d\x66\x01", true, 0x49 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FF 55 8B EC 51 51 53 57 8B 7D 08 8D
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable32, OffsetData{ "\x8b\xff\x55\x8b\xec\x51\x51\x53\x57\x8b\x7d\x08\x8d", false, 0 } );
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable32, OffsetData{ "\x8b\xff\x55\x8b\xec\x51\x51\x53\x57\x8b\x7d\x08\x8d", false, -1, 0x26 } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B 45 08 89 45 A0
|
||||
patterns.emplace( &_data.LdrpHandleTlsData32, OffsetData{ "\x8b\x45\x08\x89\x45\xa0", false, 0xC } );
|
||||
}
|
||||
else if (IsWindows7OrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 41 B8 09 00 00 00 48 8D 44 24 38
|
||||
patterns.emplace( &_data.LdrpHandleTlsData64, OffsetData{ PatternSearch( "\x41\xb8\x09\x00\x00\x00\x48\x8d\x44\x24\x38", 11 ), true, 0x27 } );
|
||||
|
||||
// LdrpFindOrMapDll patch address
|
||||
// 48 8D 8C 24 98 00 00 00 41 b0 01
|
||||
patterns.emplace( &_data.LdrKernel32PatchAddress, OffsetData{ PatternSearch( "\x48\x8D\x8C\x24\x98\x00\x00\x00\x41\xb0\x01", 11 ), true, -0x12 } );
|
||||
|
||||
// KiUserApcDispatcher patch address
|
||||
// 48 8B 4C 24 18 48 8B C1 4C
|
||||
patterns.emplace( &_data.APC64PatchAddress, OffsetData{ "\x48\x8b\x4c\x24\x18\x48\x8b\xc1\x4c", true, 0 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FF 55 8B EC 56 68
|
||||
patterns.emplace( &_data.RtlInsertInvertedFunctionTable32, OffsetData{ "\x8b\xff\x55\x8b\xec\x56\x68", false, 0 } );
|
||||
|
||||
// RtlLookupFunctionTable + 0x11
|
||||
// 89 5D E0 38
|
||||
patterns.emplace( &_data.LdrpInvertedFunctionTable32, OffsetData{ "\x89\x5D\xE0\x38", false, -1, 0x1B } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 74 20 8D 45 D4 50 6A 09
|
||||
patterns.emplace( &_data.LdrpHandleTlsData32, OffsetData{ "\x74\x20\x8d\x45\xd4\x50\x6a\x09", false, 0x14 } );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
#pragma once
|
||||
#include "../Include/Types.h"
|
||||
#include "../Patterns/PatternSearch.h"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Ntdll internal pointers
|
||||
/// </summary>
|
||||
struct PatternData
|
||||
{
|
||||
ptr_t LdrKernel32PatchAddress = 0; // Address to patch to enable kernel32 loading under win7
|
||||
ptr_t APC64PatchAddress = 0; // Address to patch for x64->WOW64 APC dispatching under win7
|
||||
ptr_t LdrpHandleTlsData32 = 0; // LdrpHandleTlsData address
|
||||
ptr_t LdrpHandleTlsData64 = 0; // LdrpHandleTlsData address
|
||||
ptr_t LdrpInvertedFunctionTable32 = 0; // LdrpInvertedFunctionTable address
|
||||
ptr_t LdrpInvertedFunctionTable64 = 0; // LdrpInvertedFunctionTable address
|
||||
ptr_t RtlInsertInvertedFunctionTable32 = 0; // RtlInsertInvertedFunctionTable address
|
||||
ptr_t RtlInsertInvertedFunctionTable64 = 0; // RtlInsertInvertedFunctionTable address
|
||||
ptr_t LdrProtectMrdata = 0; // LdrProtectMrdata address
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Ntdll scanner
|
||||
/// </summary>
|
||||
class PatternLoader
|
||||
{
|
||||
struct OffsetData
|
||||
{
|
||||
PatternSearch pattern;
|
||||
bool bit64;
|
||||
int32_t functionOffset;
|
||||
int32_t dataStartOffset;
|
||||
int32_t dataOperandOffset;
|
||||
int32_t dataInstructionSize;
|
||||
};
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Scan ntdll for internal loader data
|
||||
/// </summary>
|
||||
/// <returns>Found data</returns>
|
||||
const PatternData& DoSearch();
|
||||
|
||||
/// <summary>
|
||||
/// Get internal loader data
|
||||
/// </summary>
|
||||
/// <returns>Internal loader data</returns>
|
||||
inline const PatternData& data() const { return _data; }
|
||||
private:
|
||||
/// <summary>
|
||||
/// Detect process and OS architecture
|
||||
/// </summary>
|
||||
void CheckSystem();
|
||||
|
||||
/// <summary>
|
||||
/// Fill OS-dependent patterns
|
||||
/// </summary>
|
||||
/// <param name="patterns">Pattern collection</param>
|
||||
void OSFillPatterns( std::unordered_map<ptr_t*, OffsetData>& patterns );
|
||||
|
||||
private:
|
||||
bool _x86OS = false; // x86 OS
|
||||
bool _wow64Process = false; // Current process is wow64 process
|
||||
PatternData _data; // Ntdll internal loader data
|
||||
};
|
||||
|
||||
extern std::unique_ptr<PatternLoader> g_PatternLoader;
|
||||
|
||||
}
|
||||
@@ -136,11 +136,14 @@ std::wstring Utils::GetExeDirectory()
|
||||
/// </summary>
|
||||
/// <param name="length">Desired length. 0 - random length from 5 to 15</param>
|
||||
/// <returns>Generated string</returns>
|
||||
|
||||
// VS 15.5 update crashes on "alphabet[dist( rd )]" in x64 release build
|
||||
#pragma optimize("", off)
|
||||
std::wstring Utils::RandomANString( int length /*= 0*/ )
|
||||
{
|
||||
static const wchar_t alphabet[] = L"ABCDEFGHIJKLMNOPQRSTUVWXYZbcdefghijklmnopqrstuvwxyz1234567890";
|
||||
static constexpr wchar_t alphabet[] = L"ABCDEFGHIJKLMNOPQRSTUVWXYZbcdefghijklmnopqrstuvwxyz1234567890";
|
||||
static std::random_device rd;
|
||||
static std::uniform_int_distribution<> dist( 0, ARRAYSIZE(alphabet) - 2 );
|
||||
static std::uniform_int_distribution<> dist( 0, _countof( alphabet ) - 2 );
|
||||
static std::uniform_int_distribution<> dist_len( 5, 15 );
|
||||
std::wstring result;
|
||||
|
||||
@@ -149,10 +152,13 @@ std::wstring Utils::RandomANString( int length /*= 0*/ )
|
||||
length = dist_len( rd );
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
result.push_back( alphabet[dist( rd )] );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#pragma optimize("", on)
|
||||
|
||||
/// <summary>
|
||||
/// Cast string characters to lower case
|
||||
|
||||
@@ -34,10 +34,6 @@ PatternSearch::PatternSearch( const uint8_t* pattern, size_t len /*= 0*/ )
|
||||
{
|
||||
}
|
||||
|
||||
PatternSearch::~PatternSearch()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default pattern matching with wildcards.
|
||||
/// std::search is approximately 2x faster than naive approach.
|
||||
@@ -48,16 +44,25 @@ PatternSearch::~PatternSearch()
|
||||
/// <param name="out">Found results</param>
|
||||
/// <param name="value_offset">Value that will be added to resulting addresses</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
size_t PatternSearch::Search( uint8_t wildcard, void* scanStart, size_t scanSize, std::vector<ptr_t>& out, ptr_t value_offset /*= 0*/ )
|
||||
size_t PatternSearch::Search(
|
||||
uint8_t wildcard,
|
||||
void* scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out,
|
||||
ptr_t value_offset /*= 0*/
|
||||
) const
|
||||
{
|
||||
const uint8_t* cstart = (const uint8_t*)scanStart;
|
||||
const uint8_t* cend = cstart + scanSize;
|
||||
|
||||
auto comparer = [&wildcard]( uint8_t val1, uint8_t val2 )
|
||||
{
|
||||
return (val1 == val2 || val2 == wildcard);
|
||||
};
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const uint8_t* res = std::search( cstart, cend, _pattern.begin(), _pattern.end(),
|
||||
[&wildcard]( uint8_t val1, uint8_t val2 ){ return (val1 == val2 || val2 == wildcard); } );
|
||||
|
||||
const uint8_t* res = std::search( cstart, cend, _pattern.begin(), _pattern.end(), comparer );
|
||||
if (res >= cend)
|
||||
break;
|
||||
|
||||
@@ -81,7 +86,12 @@ size_t PatternSearch::Search( uint8_t wildcard, void* scanStart, size_t scanSize
|
||||
/// <param name="out">Found results</param>
|
||||
/// <param name="value_offset">Value that will be added to resulting addresses</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
size_t PatternSearch::Search( void* scanStart, size_t scanSize, std::vector<ptr_t>& out, ptr_t value_offset /*= 0*/ )
|
||||
size_t PatternSearch::Search(
|
||||
void* scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out,
|
||||
ptr_t value_offset /*= 0*/
|
||||
) const
|
||||
{
|
||||
size_t bad_char_skip[UCHAR_MAX + 1];
|
||||
|
||||
@@ -134,7 +144,13 @@ size_t PatternSearch::Search( void* scanStart, size_t scanSize, std::vector<ptr_
|
||||
/// <param name="scanSize">Size of region to scan</param>
|
||||
/// <param name="out">Found results</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
size_t PatternSearch::SearchRemote( Process& remote, uint8_t wildcard, ptr_t scanStart, size_t scanSize, std::vector<ptr_t>& out )
|
||||
size_t PatternSearch::SearchRemote(
|
||||
Process& remote,
|
||||
uint8_t wildcard,
|
||||
ptr_t scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out
|
||||
) const
|
||||
{
|
||||
uint8_t *pBuffer = reinterpret_cast<uint8_t*>(VirtualAlloc( NULL, scanSize, MEM_COMMIT, PAGE_READWRITE ));
|
||||
|
||||
@@ -155,7 +171,12 @@ size_t PatternSearch::SearchRemote( Process& remote, uint8_t wildcard, ptr_t sca
|
||||
/// <param name="scanSize">Size of region to scan</param>
|
||||
/// <param name="out">Found results</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
size_t PatternSearch::SearchRemote( Process& remote, ptr_t scanStart, size_t scanSize, std::vector<ptr_t>& out )
|
||||
size_t PatternSearch::SearchRemote(
|
||||
Process& remote,
|
||||
ptr_t scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out
|
||||
) const
|
||||
{
|
||||
uint8_t *pBuffer = reinterpret_cast<uint8_t*>(VirtualAlloc( NULL, scanSize, MEM_COMMIT, PAGE_READWRITE ));
|
||||
|
||||
@@ -176,7 +197,12 @@ size_t PatternSearch::SearchRemote( Process& remote, ptr_t scanStart, size_t sca
|
||||
/// <param name="wildcard">Pattern wildcard</param>
|
||||
/// <param name="out">Found results</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
size_t PatternSearch::SearchRemoteWhole( Process& remote, bool useWildcard, uint8_t wildcard, std::vector<ptr_t>& out )
|
||||
size_t PatternSearch::SearchRemoteWhole(
|
||||
Process& remote,
|
||||
bool useWildcard,
|
||||
uint8_t wildcard,
|
||||
std::vector<ptr_t>& out
|
||||
) const
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION64 mbi = { 0 };
|
||||
size_t bufsize = 1 * 1024 * 1024; // 1 MB
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
BLACKBONE_API PatternSearch( const char* pattern, size_t len = 0 );
|
||||
BLACKBONE_API PatternSearch( const uint8_t* pattern, size_t len = 0 );
|
||||
|
||||
BLACKBONE_API ~PatternSearch();
|
||||
BLACKBONE_API ~PatternSearch() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Default pattern matching with wildcards.
|
||||
@@ -30,7 +30,13 @@ public:
|
||||
/// <param name="out">Found results</param>
|
||||
/// <param name="value_offset">Value that will be added to resulting addresses</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
BLACKBONE_API size_t Search( uint8_t wildcard, void* scanStart, size_t scanSize, std::vector<ptr_t>& out, ptr_t value_offset = 0 );
|
||||
BLACKBONE_API size_t Search(
|
||||
uint8_t wildcard,
|
||||
void* scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out,
|
||||
ptr_t value_offset = 0
|
||||
) const;
|
||||
|
||||
/// <summary>
|
||||
/// Full pattern match, no wildcards.
|
||||
@@ -41,7 +47,12 @@ public:
|
||||
/// <param name="out">Found results</param>
|
||||
/// <param name="value_offset">Value that will be added to resulting addresses</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
BLACKBONE_API size_t Search( void* scanStart, size_t scanSize, std::vector<ptr_t>& out, ptr_t value_offset = 0 );
|
||||
BLACKBONE_API size_t Search(
|
||||
void* scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out,
|
||||
ptr_t value_offset = 0
|
||||
) const;
|
||||
|
||||
/// <summary>
|
||||
/// Search pattern in remote process
|
||||
@@ -52,7 +63,13 @@ public:
|
||||
/// <param name="scanSize">Size of region to scan</param>
|
||||
/// <param name="out">Found results</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
BLACKBONE_API size_t SearchRemote( class Process& remote, uint8_t wildcard, ptr_t scanStart, size_t scanSize, std::vector<ptr_t>& out );
|
||||
BLACKBONE_API size_t SearchRemote(
|
||||
class Process& remote,
|
||||
uint8_t wildcard,
|
||||
ptr_t scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out
|
||||
) const;
|
||||
|
||||
/// <summary>
|
||||
/// Search pattern in remote process
|
||||
@@ -62,7 +79,12 @@ public:
|
||||
/// <param name="scanSize">Size of region to scan</param>
|
||||
/// <param name="out">Found results</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
BLACKBONE_API size_t SearchRemote( class Process& remote, ptr_t scanStart, size_t scanSize, std::vector<ptr_t>& out );
|
||||
BLACKBONE_API size_t SearchRemote(
|
||||
class Process& remote,
|
||||
ptr_t scanStart,
|
||||
size_t scanSize,
|
||||
std::vector<ptr_t>& out
|
||||
) const;
|
||||
|
||||
/// <summary>
|
||||
/// Search pattern in whole address space of remote process
|
||||
@@ -72,7 +94,12 @@ public:
|
||||
/// <param name="wildcard">Pattern wildcard</param>
|
||||
/// <param name="out">Found results</param>
|
||||
/// <returns>Number of found addresses</returns>
|
||||
BLACKBONE_API size_t SearchRemoteWhole( class Process& remote, bool useWildcard, uint8_t wildcard, std::vector<ptr_t>& out );
|
||||
BLACKBONE_API size_t SearchRemoteWhole(
|
||||
class Process& remote,
|
||||
bool useWildcard,
|
||||
uint8_t wildcard,
|
||||
std::vector<ptr_t>& out
|
||||
) const;
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> _pattern; // Pattern to search
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "RPC/RemoteExec.h"
|
||||
#include "../Misc/NameResolve.h"
|
||||
#include "../Misc/Utils.h"
|
||||
#include "../Misc/PatternLoader.h"
|
||||
#include "../Symbols/SymbolData.h"
|
||||
#include "../Asm/AsmFactory.h"
|
||||
|
||||
#include <memory>
|
||||
@@ -445,7 +445,7 @@ call_result_t<ModuleDataPtr> ProcessModules::Inject( const std::wstring& path, T
|
||||
if (switchMode == ForceSwitch && !_ldrPatched && IsWindows7OrGreater() && !IsWindows8OrGreater())
|
||||
{
|
||||
uint8_t patch[] = { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
|
||||
auto patchBase = g_PatternLoader->data().LdrKernel32PatchAddress;
|
||||
auto patchBase = g_symbols.LdrKernel32PatchAddress;
|
||||
|
||||
if (patchBase != 0)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "RemoteExec.h"
|
||||
#include "../Process.h"
|
||||
#include "../../Misc/DynImport.h"
|
||||
#include "../../Misc/PatternLoader.h"
|
||||
#include "../../Symbols/SymbolData.h"
|
||||
|
||||
#include <VersionHelpers.h>
|
||||
#include <sddl.h>
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
// Manually set argument to custom value
|
||||
void set( int pos, const AsmVariant& newVal )
|
||||
{
|
||||
if (arguments.size() > (size_t)pos)
|
||||
if (arguments.size() > static_cast<size_t>(pos))
|
||||
arguments[pos] = newVal;
|
||||
}
|
||||
|
||||
@@ -46,8 +46,8 @@ public:
|
||||
, _conv( conv )
|
||||
{
|
||||
static_assert(
|
||||
!std::disjunction_v<std::is_reference<Args>...>,
|
||||
"Please replace reference type to pointer type in function type specification"
|
||||
(... && !std::is_reference_v<Args>),
|
||||
"Please replace reference type with pointer type in function type specification"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
#include "PDBHelper.h"
|
||||
#include "../Misc/Trace.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
|
||||
#define CHECK_SUCCESS(e)\
|
||||
{ \
|
||||
HRESULT hresult = (e); \
|
||||
if(FAILED(hresult)) \
|
||||
{ \
|
||||
BLACKBONE_TRACE( "PDB: %s: (%s) failed with HRESULT 0x%08x", __FUNCTION__, #e , hresult ); \
|
||||
return hresult; \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
PDBHelper::PDBHelper()
|
||||
{
|
||||
CoInitialize( nullptr );
|
||||
|
||||
// If _NT_SYMBOL_PATH exists, use it
|
||||
wchar_t path[MAX_PATH] = { };
|
||||
if (GetEnvironmentVariableW( L"_NT_SYMBOL_PATH", path, _countof( path ) ) == -1)
|
||||
{
|
||||
if (GetTempPathW( _countof( path ), path ) != -1)
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << L"srv*" << path << L"Symbols*https://msdl.microsoft.com/download/symbols";
|
||||
_sympath = wss.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PDBHelper::~PDBHelper()
|
||||
{
|
||||
// Must be released before CoUninitialize
|
||||
_global.Release();
|
||||
_session.Release();
|
||||
_source.Release();
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize symbols for target file
|
||||
/// </summary>
|
||||
/// <param name="file">Fully qualified path to target PE file</param>
|
||||
/// <param name="base">Base ptr to add to RVAs</param>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT PDBHelper::Init( const std::wstring& file, ptr_t base /*= 0*/ )
|
||||
{
|
||||
CHECK_SUCCESS( CoCreateDiaDataSource() );
|
||||
CHECK_SUCCESS( _source->loadDataForExe( file.c_str(), _sympath.empty() ? nullptr : _sympath.c_str(), nullptr ) );
|
||||
CHECK_SUCCESS( _source->openSession( &_session ) );
|
||||
CHECK_SUCCESS( _session->get_globalScope( &_global ) );
|
||||
|
||||
_base = base;
|
||||
return PopulateSymbols();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get symbol RVA
|
||||
/// </summary>
|
||||
/// <param name="symName">Symbol name</param>
|
||||
/// <param name="result">Resulting RVA</param>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT PDBHelper::GetSymAddress( const std::wstring& symName, ptr_t& result )
|
||||
{
|
||||
auto found = _cache.find( symName );
|
||||
if (found != _cache.end())
|
||||
{
|
||||
result = _base + found->second;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_PDB_DBG_NOT_FOUND;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize DIA
|
||||
/// </summary>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT PDBHelper::CoCreateDiaDataSource()
|
||||
{
|
||||
const auto pSource = reinterpret_cast<void**>(&_source);
|
||||
|
||||
// Try to get from COM
|
||||
HRESULT hr = CoCreateInstance( CLSID_DiaSource, nullptr, CLSCTX_INPROC_SERVER, __uuidof(IDiaDataSource), pSource );
|
||||
|
||||
// Retry with direct export call
|
||||
if (hr == REGDB_E_CLASSNOTREG)
|
||||
{
|
||||
HMODULE hMod = LoadLibraryW( L"msdia140.dll" );
|
||||
if (!hMod)
|
||||
{
|
||||
BLACKBONE_TRACE( "PDB: Failed to load msdia140.dll, error 0x08%x", GetLastError() );
|
||||
return HRESULT_FROM_WIN32( GetLastError() );
|
||||
}
|
||||
|
||||
auto DllGetClassObject = reinterpret_cast<BOOL( WINAPI* )(REFCLSID, REFIID, LPVOID)>(GetProcAddress( hMod, "DllGetClassObject" ));
|
||||
if (!DllGetClassObject)
|
||||
{
|
||||
BLACKBONE_TRACE( "PDB: Failed to get DllGetClassObject from msdia140.dll" );
|
||||
return HRESULT_FROM_WIN32( GetLastError() );
|
||||
}
|
||||
|
||||
CComPtr<IClassFactory> classFactory;
|
||||
CHECK_SUCCESS( DllGetClassObject( CLSID_DiaSource, IID_IClassFactory, &classFactory ) );
|
||||
hr = classFactory->CreateInstance( nullptr, IID_IDiaDataSource, pSource );
|
||||
}
|
||||
|
||||
if (FAILED( hr ))
|
||||
{
|
||||
BLACKBONE_TRACE( "PDB: %s failed with HRESULT 0x08%x", __FUNCTION__, hr );
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build module symbol map
|
||||
/// </summary>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT PDBHelper::PopulateSymbols()
|
||||
{
|
||||
CComPtr<IDiaEnumSymbols> symbols;
|
||||
CHECK_SUCCESS( _global->findChildren( SymTagNull, nullptr, nsNone, &symbols ) );
|
||||
|
||||
ULONG count = 0;
|
||||
CComPtr<IDiaSymbol> symbol;
|
||||
while (SUCCEEDED( symbols->Next( 1, &symbol, &count ) ) && count != 0)
|
||||
{
|
||||
DWORD rva = 0;
|
||||
BSTR name = nullptr;
|
||||
|
||||
symbol->get_relativeVirtualAddress( &rva );
|
||||
symbol->get_undecoratedName( &name );
|
||||
|
||||
if (name && rva)
|
||||
{
|
||||
std::wstring wname( name );
|
||||
|
||||
// Remove x86 __stdcall decoration
|
||||
if (wname[0] == L'@' || wname[0] == L'_')
|
||||
{
|
||||
wname.erase( 0, 1 );
|
||||
}
|
||||
|
||||
auto pos = wname.rfind( L'@' );
|
||||
if (pos != wname.npos)
|
||||
{
|
||||
wname.erase( pos );
|
||||
}
|
||||
|
||||
_cache.emplace( std::move( wname ), rva );
|
||||
}
|
||||
|
||||
symbol.Release();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include "../include/Types.h"
|
||||
#include <dia2.h>
|
||||
#include <Objbase.h>
|
||||
#include <atlcomcli.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
class PDBHelper
|
||||
{
|
||||
public:
|
||||
PDBHelper();
|
||||
~PDBHelper();
|
||||
|
||||
/// <summary>
|
||||
/// Initialize symbols for target file
|
||||
/// </summary>
|
||||
/// <param name="file">Fully qualified path to target PE file</param>
|
||||
/// <param name="base">Base ptr to add to RVAs</param>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT Init( const std::wstring& file, ptr_t base = 0 );
|
||||
|
||||
/// <summary>
|
||||
/// Get symbol RVA
|
||||
/// </summary>
|
||||
/// <param name="symName">Symbol name</param>
|
||||
/// <param name="result">Resulting RVA</param>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT GetSymAddress( const std::wstring& symName, ptr_t& result );
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
/// Initialize DIA
|
||||
/// </summary>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT CoCreateDiaDataSource();
|
||||
|
||||
/// <summary>
|
||||
/// Build module symbol map
|
||||
/// </summary>
|
||||
/// <returns>Status code</returns>
|
||||
HRESULT PopulateSymbols();
|
||||
|
||||
private:
|
||||
// DIA interfaces
|
||||
CComPtr<IDiaDataSource> _source;
|
||||
CComPtr<IDiaSession> _session;
|
||||
CComPtr<IDiaSymbol> _global;
|
||||
|
||||
uint64_t _base = 0; // Base ptr to add to RVAs
|
||||
std::wstring _sympath; // Symbol cache directory
|
||||
std::unordered_map<std::wstring, uint32_t> _cache; // Symbol name <--> RVA map
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
#include "PatternLoader.h"
|
||||
#include "../Include/Winheaders.h"
|
||||
#include "../Patterns/PatternSearch.h"
|
||||
#include "../Misc/Trace.hpp"
|
||||
#include "VersionHelpers.h"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
struct OffsetData
|
||||
{
|
||||
PatternSearch pattern;
|
||||
bool bit64;
|
||||
int32_t functionOffset;
|
||||
int32_t dataStartOffset;
|
||||
int32_t dataOperandOffset;
|
||||
int32_t dataInstructionSize;
|
||||
};
|
||||
|
||||
struct ScanParams
|
||||
{
|
||||
ptr_t start = 0;
|
||||
ptr_t size = 0;
|
||||
ptr_t diff = 0;
|
||||
};
|
||||
|
||||
void FindPattern( const ScanParams& scan32, const ScanParams& scan64, const OffsetData& rule, ptr_t& result )
|
||||
{
|
||||
// Skip if already found
|
||||
if (result != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ScanParams& scan = rule.bit64 ? scan64 : scan32;
|
||||
|
||||
std::vector<ptr_t> found;
|
||||
rule.pattern.Search( reinterpret_cast<void*>(scan.start), static_cast<size_t>(scan.size), found );
|
||||
if (!found.empty())
|
||||
{
|
||||
// Plain pointer sum
|
||||
if (rule.functionOffset != -1)
|
||||
{
|
||||
result = found.front() - rule.functionOffset + scan.diff;
|
||||
}
|
||||
// Pointer dereference inside instruction
|
||||
else if (rule.dataStartOffset != 0)
|
||||
{
|
||||
if (rule.bit64)
|
||||
{
|
||||
result = *reinterpret_cast<int32_t*>(found.front() + (rule.dataStartOffset + rule.dataOperandOffset)) +
|
||||
(found.front() + rule.dataStartOffset + rule.dataInstructionSize) + scan.diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = *reinterpret_cast<int32_t*>(found.front() + rule.dataStartOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Fill OS-dependent patterns
|
||||
/// </summary>
|
||||
/// <param name="patterns">Pattern collection</param>
|
||||
/// <param name="result">Result</param>
|
||||
void OSFillPatterns( std::unordered_map<ptr_t*, OffsetData>& patterns, SymbolData& result )
|
||||
{
|
||||
if (IsWindows10FallCreatorsOrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 74 33 44 8D 43 09
|
||||
patterns.emplace( &result.LdrpHandleTlsData64, OffsetData{ "\x74\x33\x44\x8d\x43\x09", true, 0x43 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FA 49 8D 43 20
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable64, OffsetData{ "\x8b\xfa\x49\x8d\x43\x20", true, 0x10 } );
|
||||
|
||||
// RtlpInsertInvertedFunctionTableEntry
|
||||
// 49 8B E8 48 8B FA 0F 84
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable64, OffsetData{ "\x49\x8b\xe8\x48\x8b\xfa\x0f\x84", true, -1, -0xF, 2, 6 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 53 56 57 8D 45 F8 8B FA
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8d\x45\xf8\x8b\xfa", false, 0x8 } );
|
||||
|
||||
// RtlpInsertInvertedFunctionTableEntry
|
||||
// 33 F6 46 3B C6
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable32, OffsetData{ "\x33\xF6\x46\x3B\xC6", false, -1, -0x1B } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B C1 8D 4D BC 51
|
||||
patterns.emplace( &result.LdrpHandleTlsData32, OffsetData{ "\x8b\xc1\x8d\x4d\xbc\x51", false, 0x18 } );
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 75 24 85 F6 75 08
|
||||
patterns.emplace( &result.LdrProtectMrdata, OffsetData{ "\x75\x24\x85\xf6\x75\x08", false, 0x1C } );
|
||||
}
|
||||
else if (IsWindows10CreatorsOrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 74 33 44 8D 43 09
|
||||
patterns.emplace( &result.LdrpHandleTlsData64, OffsetData{ "\x74\x33\x44\x8d\x43\x09", true, 0x43 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FA 49 8D 43 20
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable64, OffsetData{ "\x8b\xfa\x49\x8d\x43\x20", true, 0x10 } );
|
||||
|
||||
// RtlpInsertInvertedFunctionTableEntry
|
||||
// 49 8B E8 48 8B FA 0F 84
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable64, OffsetData{ "\x49\x8b\xe8\x48\x8b\xfa\x0f\x84", true, -1, -0xF, 2, 6 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8D 45 F0 89 55 F8 50 8D 55 F4
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable32, OffsetData{ "\x8d\x45\xf0\x89\x55\xf8\x50\x8d\x55\xf4", false, 0xB } );
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable32, OffsetData{ "\x8d\x45\xf0\x89\x55\xf8\x50\x8d\x55\xf4", false, -1, 0x4C } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B C1 8D 4D BC 51
|
||||
patterns.emplace( &result.LdrpHandleTlsData32, OffsetData{ "\x8b\xc1\x8d\x4d\xbc\x51", false, 0x18 } );
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 75 24 85 F6 75 08
|
||||
patterns.emplace( &result.LdrProtectMrdata, OffsetData{ "\x75\x24\x85\xf6\x75\x08", false, 0x1C } );
|
||||
}
|
||||
else if (IsWindows8Point1OrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 44 8D 43 09 4C 8D 4C 24 38
|
||||
patterns.emplace( &result.LdrpHandleTlsData64, OffsetData{ "\x44\x8d\x43\x09\x4c\x8d\x4c\x24\x38", true, 0x43 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B C3 2B D3 48 8D 48 01
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable64, OffsetData{ "\x8b\xc3\x2b\xd3\x48\x8d\x48\x01", true, 0x84 } );
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable64, OffsetData{ "\x8b\xc3\x2b\xd3\x48\x8d\x48\x01", true, -1, -0x27, 3, 7 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 53 56 57 8B DA 8B F9 50
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8b\xda\x8b\xf9\x50", false, 0xB } );
|
||||
|
||||
if (IsWindows10OrGreater())
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8b\xda\x8b\xf9\x50", false, -1, 0x22 } );
|
||||
else
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable32, OffsetData{ "\x53\x56\x57\x8b\xda\x8b\xf9\x50", false, -1, 0x23 } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 50 6A 09 6A 01 8B C1
|
||||
patterns.emplace( &result.LdrpHandleTlsData32, OffsetData{ "\x50\x6a\x09\x6a\x01\x8b\xc1", false, 0x1B } );
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 83 7D 08 00 8B 35
|
||||
patterns.emplace( &result.LdrProtectMrdata, OffsetData{ PatternSearch( "\x83\x7d\x08\x00\x8b\x35", 6 ), false, 0x12 } );
|
||||
}
|
||||
else if (IsWindows8OrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 48 8B 79 30 45 8D 66 01
|
||||
patterns.emplace( &result.LdrpHandleTlsData64, OffsetData{ "\x48\x8b\x79\x30\x45\x8d\x66\x01", true, 0x49 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FF 55 8B EC 51 51 53 57 8B 7D 08 8D
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable32, OffsetData{ "\x8b\xff\x55\x8b\xec\x51\x51\x53\x57\x8b\x7d\x08\x8d", false, 0 } );
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable32, OffsetData{ "\x8b\xff\x55\x8b\xec\x51\x51\x53\x57\x8b\x7d\x08\x8d", false, -1, 0x26 } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B 45 08 89 45 A0
|
||||
patterns.emplace( &result.LdrpHandleTlsData32, OffsetData{ "\x8b\x45\x08\x89\x45\xa0", false, 0xC } );
|
||||
}
|
||||
else if (IsWindows7OrGreater())
|
||||
{
|
||||
// LdrpHandleTlsData
|
||||
// 41 B8 09 00 00 00 48 8D 44 24 38
|
||||
patterns.emplace( &result.LdrpHandleTlsData64, OffsetData{ PatternSearch( "\x41\xb8\x09\x00\x00\x00\x48\x8d\x44\x24\x38", 11 ), true, 0x27 } );
|
||||
|
||||
// LdrpFindOrMapDll patch address
|
||||
// 48 8D 8C 24 98 00 00 00 41 b0 01
|
||||
patterns.emplace( &result.LdrKernel32PatchAddress, OffsetData{ PatternSearch( "\x48\x8D\x8C\x24\x98\x00\x00\x00\x41\xb0\x01", 11 ), true, -0x12 } );
|
||||
|
||||
// KiUserApcDispatcher patch address
|
||||
// 48 8B 4C 24 18 48 8B C1 4C
|
||||
patterns.emplace( &result.APC64PatchAddress, OffsetData{ "\x48\x8b\x4c\x24\x18\x48\x8b\xc1\x4c", true, 0 } );
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FF 55 8B EC 56 68
|
||||
patterns.emplace( &result.RtlInsertInvertedFunctionTable32, OffsetData{ "\x8b\xff\x55\x8b\xec\x56\x68", false, 0 } );
|
||||
|
||||
// RtlLookupFunctionTable + 0x11
|
||||
// 89 5D E0 38
|
||||
patterns.emplace( &result.LdrpInvertedFunctionTable32, OffsetData{ "\x89\x5D\xE0\x38", false, -1, 0x1B } );
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 74 20 8D 45 D4 50 6A 09
|
||||
patterns.emplace( &result.LdrpHandleTlsData32, OffsetData{ "\x74\x20\x8d\x45\xd4\x50\x6a\x09", false, 0x14 } );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scan ntdll for internal loader data
|
||||
/// </summary>
|
||||
/// <param name="ntdll32">Mapped x86 ntdll</param>
|
||||
/// <param name="ntdll64">Mapped x64 ntdll</param>
|
||||
/// <param name="result">Result</param>
|
||||
/// <returns>Status code</returns>
|
||||
NTSTATUS ScanSymbolPatterns( const pe::PEImage& ntdll32, const pe::PEImage& ntdll64, SymbolData& result )
|
||||
{
|
||||
ScanParams scan32, scan64;
|
||||
|
||||
scan32.diff = static_cast<int64_t>(ntdll32.imageBase()) - reinterpret_cast<int64_t>(ntdll32.base());
|
||||
scan64.diff = static_cast<int64_t>(ntdll64.imageBase()) - reinterpret_cast<int64_t>(ntdll64.base());
|
||||
|
||||
auto fillRanges = []( const pe::PEImage& file, ScanParams& params )
|
||||
{
|
||||
for (const auto& sec : file.sections())
|
||||
{
|
||||
if (_stricmp( reinterpret_cast<const char*>(sec.Name), ".text" ) == 0)
|
||||
{
|
||||
params.start = reinterpret_cast<ptr_t>(file.base()) + sec.VirtualAddress;
|
||||
params.size = sec.Misc.VirtualSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Get code section bounds
|
||||
fillRanges( ntdll32, scan32 );
|
||||
if (ntdll64.base())
|
||||
{
|
||||
fillRanges( ntdll64, scan64 );
|
||||
}
|
||||
|
||||
std::unordered_map<ptr_t*, OffsetData> patterns;
|
||||
OSFillPatterns( patterns, result );
|
||||
|
||||
// Final search
|
||||
for (const auto& e : patterns)
|
||||
{
|
||||
FindPattern( scan32, scan64, e.second, *e.first );
|
||||
}
|
||||
|
||||
// Retry with old patterns
|
||||
if (result.RtlInsertInvertedFunctionTable32 == 0 && IsWindows8Point1OrGreater() && !IsWindows10CreatorsOrGreater())
|
||||
{
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8D 45 F4 89 55 F8 50 8D 55 FC
|
||||
OffsetData rule1{ "\x8d\x45\xf4\x89\x55\xf8\x50\x8d\x55\xfc", false, 0xB };
|
||||
OffsetData rule2{ "\x8d\x45\xf4\x89\x55\xf8\x50\x8d\x55\xfc", false, -1, 0x1D };
|
||||
|
||||
FindPattern( scan32, scan64, rule1, result.RtlInsertInvertedFunctionTable32 );
|
||||
FindPattern( scan32, scan64, rule2, result.LdrpInvertedFunctionTable32 );
|
||||
}
|
||||
|
||||
// Report errors
|
||||
#ifndef BLACKBONE_NO_TRACE
|
||||
if (result.LdrpHandleTlsData64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpHandleTlsData64 not found" );
|
||||
if (result.LdrpHandleTlsData32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpHandleTlsData32 not found" );
|
||||
if (IsWindows8Point1OrGreater() && result.LdrpInvertedFunctionTable64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpInvertedFunctionTable64 not found" );
|
||||
if (result.LdrpInvertedFunctionTable32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpInvertedFunctionTable32 not found" );
|
||||
if (IsWindows8Point1OrGreater() && result.RtlInsertInvertedFunctionTable64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: RtlInsertInvertedFunctionTable64 not found" );
|
||||
if (result.RtlInsertInvertedFunctionTable32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: RtlInsertInvertedFunctionTable32 not found" );
|
||||
if (IsWindows8Point1OrGreater() && result.LdrProtectMrdata == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrProtectMrdata not found" );
|
||||
if (IsWindows7OrGreater() && !IsWindows8OrGreater())
|
||||
{
|
||||
if (result.LdrKernel32PatchAddress == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrKernel32PatchAddress not found" );
|
||||
if (result.APC64PatchAddress == 0)
|
||||
BLACKBONE_TRACE( "PatternData: APC64PatchAddress not found" );
|
||||
}
|
||||
#endif
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "../Symbols/SymbolData.h"
|
||||
#include "../PE/PEImage.h"
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Scan ntdll for internal loader data
|
||||
/// </summary>
|
||||
/// <param name="ntdll32">Mapped x86 ntdll</param>
|
||||
/// <param name="ntdll64">Mapped x64 ntdll</param>
|
||||
/// <param name="result">Result</param>
|
||||
/// <returns>Status code</returns>
|
||||
NTSTATUS ScanSymbolPatterns( const pe::PEImage& ntdll32, const pe::PEImage& ntdll64, SymbolData& result );
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "../include/Types.h"
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Ntdll internal pointers
|
||||
/// </summary>
|
||||
struct SymbolData
|
||||
{
|
||||
ptr_t LdrKernel32PatchAddress = 0; // Address to patch to enable kernel32 loading under win7
|
||||
ptr_t APC64PatchAddress = 0; // Address to patch for x64->WOW64 APC dispatching under win7
|
||||
ptr_t LdrpHandleTlsData32 = 0; // LdrpHandleTlsData address
|
||||
ptr_t LdrpHandleTlsData64 = 0; // LdrpHandleTlsData address
|
||||
ptr_t LdrpInvertedFunctionTable32 = 0; // LdrpInvertedFunctionTable address
|
||||
ptr_t LdrpInvertedFunctionTable64 = 0; // LdrpInvertedFunctionTable address
|
||||
ptr_t RtlInsertInvertedFunctionTable32 = 0; // RtlInsertInvertedFunctionTable address
|
||||
ptr_t RtlInsertInvertedFunctionTable64 = 0; // RtlInsertInvertedFunctionTable address
|
||||
ptr_t LdrProtectMrdata = 0; // LdrProtectMrdata address
|
||||
};
|
||||
|
||||
inline SymbolData g_symbols;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "SymbolLoader.h"
|
||||
#include "PDBHelper.h"
|
||||
#include "../Symbols/PatternLoader.h"
|
||||
#include "../PE/PEImage.h"
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
SymbolLoader::SymbolLoader()
|
||||
: _x86OS( false )
|
||||
, _wow64Process( false )
|
||||
{
|
||||
SYSTEM_INFO info = { };
|
||||
GetNativeSystemInfo( &info );
|
||||
|
||||
if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
|
||||
{
|
||||
_x86OS = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL wowSrc = FALSE;
|
||||
IsWow64Process( GetCurrentProcess(), &wowSrc );
|
||||
_wow64Process = wowSrc != 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load symbol addresses from PDB or and pattern scans
|
||||
/// </summary>
|
||||
/// <param name="result">Found symbols</param>
|
||||
/// <returns>Status code</returns>
|
||||
NTSTATUS SymbolLoader::Load( SymbolData& result )
|
||||
{
|
||||
pe::PEImage ntdll32, ntdll64;
|
||||
PDBHelper sym32, sym64;
|
||||
|
||||
wchar_t buf[MAX_PATH] = { 0 };
|
||||
GetWindowsDirectoryW( buf, MAX_PATH );
|
||||
|
||||
std::wstring windir( buf );
|
||||
|
||||
if (_x86OS)
|
||||
{
|
||||
ntdll32.Load( std::wstring( windir + L"\\System32\\ntdll.dll" ), true );
|
||||
}
|
||||
else
|
||||
{
|
||||
FsRedirector fsr( _wow64Process );
|
||||
|
||||
ntdll64.Load( std::wstring( windir + L"\\System32\\ntdll.dll" ), true );
|
||||
ntdll32.Load( std::wstring( windir + L"\\SysWOW64\\ntdll.dll" ), true );
|
||||
}
|
||||
|
||||
HRESULT hr = sym32.Init( ntdll32.path(), ntdll32.imageBase() );
|
||||
if (!_x86OS && SUCCEEDED( hr ))
|
||||
{
|
||||
hr = sym64.Init( ntdll64.path(), ntdll64.imageBase() );
|
||||
}
|
||||
|
||||
// Get addresses from pdb
|
||||
/*if (SUCCEEDED( hr ))
|
||||
{
|
||||
sym32.GetSymAddress( L"LdrpHandleTlsData", result.LdrpHandleTlsData32 );
|
||||
sym64.GetSymAddress( L"LdrpHandleTlsData", result.LdrpHandleTlsData64 );
|
||||
|
||||
sym32.GetSymAddress( L"LdrpInvertedFunctionTable", result.LdrpInvertedFunctionTable32 );
|
||||
sym64.GetSymAddress( L"LdrpInvertedFunctionTable", result.LdrpInvertedFunctionTable64 );
|
||||
|
||||
sym32.GetSymAddress( L"RtlInsertInvertedFunctionTable", result.RtlInsertInvertedFunctionTable32 );
|
||||
sym64.GetSymAddress( L"RtlInsertInvertedFunctionTable", result.RtlInsertInvertedFunctionTable64 );
|
||||
|
||||
sym32.GetSymAddress( L"LdrProtectMrdata", result.LdrProtectMrdata );
|
||||
}*/
|
||||
|
||||
// Fill missing symbols from patterns
|
||||
return ScanSymbolPatterns( ntdll32, ntdll64, result );;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "SymbolData.h"
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
class SymbolLoader
|
||||
{
|
||||
public:
|
||||
SymbolLoader();
|
||||
|
||||
/// <summary>
|
||||
/// Load symbol addresses from PDB or and pattern scans
|
||||
/// </summary>
|
||||
/// <param name="result">Found symbols</param>
|
||||
/// <returns>Status code</returns>
|
||||
NTSTATUS Load( SymbolData& result );
|
||||
|
||||
private:
|
||||
bool _x86OS; // x86 OS
|
||||
bool _wow64Process; // Current process is wow64 process
|
||||
};
|
||||
|
||||
}
|
||||
+12
-12
@@ -179,26 +179,22 @@
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
<EnableCppCoreCheck>true</EnableCppCoreCheck>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug(XP)|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug(DLL)|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
<EnableCppCoreCheck>true</EnableCppCoreCheck>
|
||||
</PropertyGroup>
|
||||
@@ -206,53 +202,45 @@
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug(DLL)|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(XP)|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(DLL)|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(XP)|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release(DLL)|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)\$(Platform)\$(Configuration)\</IntDir>
|
||||
<IncludePath>$(SolutionDir)contrib;$(IncludePath)</IncludePath>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
@@ -267,6 +255,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -294,6 +283,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -321,6 +311,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -348,6 +339,7 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -374,6 +366,7 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -400,6 +393,7 @@
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -430,6 +424,7 @@
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -459,6 +454,7 @@
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -488,6 +484,7 @@
|
||||
<OmitFramePointers>false</OmitFramePointers>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -514,6 +511,7 @@
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -540,6 +538,7 @@
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -566,6 +565,7 @@
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\contrib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
Reference in New Issue
Block a user