mirror of
https://github.com/DarthTon/Blackbone.git
synced 2026-10-28 19:36:34 +08:00
ntdll pattern scan separation
This commit is contained in:
@@ -618,9 +618,9 @@
|
||||
<ClCompile Include="ManualMap\MExcept.cpp" />
|
||||
<ClCompile Include="ManualMap\MMap.cpp" />
|
||||
<ClCompile Include="ManualMap\Native\NtLoader.cpp" />
|
||||
<ClCompile Include="Misc\DynImport.cpp" />
|
||||
<ClCompile Include="Misc\InitOnce.cpp" />
|
||||
<ClCompile Include="Misc\NameResolve.cpp" />
|
||||
<ClCompile Include="Misc\PattrernLoader.cpp" />
|
||||
<ClCompile Include="Misc\Utils.cpp" />
|
||||
<ClCompile Include="Patterns\PatternSearch.cpp" />
|
||||
<ClCompile Include="PE\ImageNET.cpp" />
|
||||
@@ -717,6 +717,7 @@
|
||||
<ClInclude Include="Misc\DynImport.h" />
|
||||
<ClInclude Include="Misc\InitOnce.h" />
|
||||
<ClInclude Include="Misc\NameResolve.h" />
|
||||
<ClInclude Include="Misc\PattrernLoader.h" />
|
||||
<ClInclude Include="Misc\Thunk.hpp" />
|
||||
<ClInclude Include="Misc\Trace.hpp" />
|
||||
<ClInclude Include="Misc\Utils.h" />
|
||||
|
||||
@@ -90,9 +90,6 @@
|
||||
<ClCompile Include="Patterns\PatternSearch.cpp">
|
||||
<Filter>Patterns</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Misc\DynImport.cpp">
|
||||
<Filter>Misc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Misc\NameResolve.cpp">
|
||||
<Filter>Misc</Filter>
|
||||
</ClCompile>
|
||||
@@ -195,6 +192,9 @@
|
||||
<ClCompile Include="..\..\contrib\rewolf-wow64ext\src\wow64ext.cpp">
|
||||
<Filter>Subsystem</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Misc\PattrernLoader.cpp">
|
||||
<Filter>Misc</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Config.h" />
|
||||
@@ -450,5 +450,8 @@
|
||||
<ClInclude Include="Asm\AsmFactory.h">
|
||||
<Filter>AsmJit\Helpers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Misc\PattrernLoader.h">
|
||||
<Filter>Misc</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "NtLoader.h"
|
||||
#include "../../Process/Process.h"
|
||||
#include "../../Patterns/PatternSearch.h"
|
||||
#include "../../Misc/Utils.h"
|
||||
#include "../../Include/Macro.h"
|
||||
#include "../../Misc/Utils.h"
|
||||
#include "../../Misc/DynImport.h"
|
||||
#include "../../Misc/trace.hpp"
|
||||
#include "../../Misc/PattrernLoader.h"
|
||||
|
||||
#include "../contrib/VersionHelpers.h"
|
||||
|
||||
@@ -35,9 +35,7 @@ bool NtLdr::Init()
|
||||
ScanPatterns();
|
||||
_nodeMap.clear();
|
||||
|
||||
//
|
||||
// Report errors
|
||||
//
|
||||
#ifndef BLACBONE_NO_TRACE
|
||||
auto barrier = _process.barrier().type;
|
||||
if (_LdrpHashTable == 0)
|
||||
@@ -46,24 +44,6 @@ bool NtLdr::Init()
|
||||
BLACKBONE_TRACE( "NativeLdr: LdrpModuleIndexBase not found" );
|
||||
if (_LdrHeapBase == 0 && (barrier == wow_32_32 || barrier == wow_64_64))
|
||||
BLACKBONE_TRACE( "NativeLdr: LdrHeapBase not found" );
|
||||
if (_LdrpHandleTlsData == 0)
|
||||
BLACKBONE_TRACE( "NativeLdr: LdrpHandleTlsData not found" );
|
||||
#ifdef USE64
|
||||
if (IsWindows7OrGreater() && !IsWindows8OrGreater())
|
||||
{
|
||||
if (_LdrKernel32PatchAddress == 0)
|
||||
BLACKBONE_TRACE( "NativeLdr: LdrKernel32PatchAddress not found" );
|
||||
if (_APC64PatchAddress == 0)
|
||||
BLACKBONE_TRACE( "NativeLdr: APC64PatchAddress not found" );
|
||||
}
|
||||
#else
|
||||
if (_LdrpInvertedFunctionTable == 0)
|
||||
BLACKBONE_TRACE( "NativeLdr: LdrpInvertedFunctionTable not found" );
|
||||
if (_RtlInsertInvertedFunctionTable == 0)
|
||||
BLACKBONE_TRACE( "NativeLdr: RtlInsertInvertedFunctionTable not found" );
|
||||
if (IsWindows8Point1OrGreater() && _LdrProtectMrdata == 0)
|
||||
BLACKBONE_TRACE( "NativeLdr: LdrProtectMrdata not found" );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -752,15 +732,14 @@ ULONG NtLdr::HashString( const std::wstring& str )
|
||||
/// Find LdrpHashTable[] variable
|
||||
/// </summary>
|
||||
/// <returns>true on success</returns>
|
||||
bool NtLdr::FindLdrpHashTable( )
|
||||
bool NtLdr::FindLdrpHashTable()
|
||||
{
|
||||
PEB_LDR_DATA_T *Ldr =
|
||||
reinterpret_cast<PEB_LDR_DATA_T*>(
|
||||
reinterpret_cast<PEB_T*>(
|
||||
reinterpret_cast<TEB_T*>(NtCurrentTeb())->ProcessEnvironmentBlock)->Ldr);
|
||||
|
||||
LDR_DATA_TABLE_ENTRY_BASE_T *Ntdll = CONTAINING_RECORD( Ldr->InInitializationOrderModuleList.Flink,
|
||||
LDR_DATA_TABLE_ENTRY_BASE_T, InInitializationOrderLinks );
|
||||
auto Ntdll = CONTAINING_RECORD( Ldr->InInitializationOrderModuleList.Flink, LDR_DATA_TABLE_ENTRY_BASE_T, InInitializationOrderLinks );
|
||||
|
||||
ULONG NtdllHashIndex = HashString( reinterpret_cast<wchar_t*>(Ntdll->BaseDllName.Buffer) ) & 0x1F;
|
||||
|
||||
@@ -768,26 +747,21 @@ bool NtLdr::FindLdrpHashTable( )
|
||||
ULONG_PTR NtdllEndAddress = NtdllBase + Ntdll->SizeOfImage - 1;
|
||||
|
||||
// scan hash list to the head (head is located within ntdll)
|
||||
bool bHeadFound = false;
|
||||
PLIST_ENTRY pNtdllHashHead = NULL;
|
||||
PLIST_ENTRY pNtdllHashHead = nullptr;
|
||||
|
||||
for (PLIST_ENTRY e = reinterpret_cast<PLIST_ENTRY>(Ntdll->HashLinks.Flink);
|
||||
e != reinterpret_cast<PLIST_ENTRY>(&Ntdll->HashLinks);
|
||||
e = e->Flink)
|
||||
for (auto e = reinterpret_cast<PLIST_ENTRY>(Ntdll->HashLinks.Flink); e != reinterpret_cast<PLIST_ENTRY>(&Ntdll->HashLinks); e = e->Flink)
|
||||
{
|
||||
if (reinterpret_cast<ULONG_PTR>(e) >= NtdllBase &&
|
||||
reinterpret_cast<ULONG_PTR>(e) < NtdllEndAddress)
|
||||
if (reinterpret_cast<ULONG_PTR>(e) >= NtdllBase && reinterpret_cast<ULONG_PTR>(e) < NtdllEndAddress)
|
||||
{
|
||||
bHeadFound = true;
|
||||
pNtdllHashHead = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bHeadFound)
|
||||
if (pNtdllHashHead != nullptr)
|
||||
_LdrpHashTable = reinterpret_cast<uintptr_t>(pNtdllHashHead - NtdllHashIndex);
|
||||
|
||||
return bHeadFound;
|
||||
return _LdrpHashTable != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -795,16 +769,15 @@ bool NtLdr::FindLdrpHashTable( )
|
||||
/// Find LdrpModuleIndex variable under win8
|
||||
/// </summary>
|
||||
/// <returns>true on success</returns>
|
||||
bool NtLdr::FindLdrpModuleIndexBase( )
|
||||
bool NtLdr::FindLdrpModuleIndexBase()
|
||||
{
|
||||
PEB_T* pPeb = reinterpret_cast<PEB_T*>(reinterpret_cast<TEB_T*>(NtCurrentTeb())->ProcessEnvironmentBlock);
|
||||
|
||||
if(pPeb)
|
||||
{
|
||||
PRTL_BALANCED_NODE lastNode = 0;
|
||||
PEB_LDR_DATA_T* Ldr = reinterpret_cast<PEB_LDR_DATA_T*>(pPeb->Ldr);
|
||||
_LDR_DATA_TABLE_ENTRY_W8 *Ntdll = CONTAINING_RECORD( Ldr->InInitializationOrderModuleList.Flink,
|
||||
_LDR_DATA_TABLE_ENTRY_W8, InInitializationOrderLinks );
|
||||
auto Ldr = reinterpret_cast<PEB_LDR_DATA_T*>(pPeb->Ldr);
|
||||
auto Ntdll = CONTAINING_RECORD( Ldr->InInitializationOrderModuleList.Flink, _LDR_DATA_TABLE_ENTRY_W8, InInitializationOrderLinks );
|
||||
|
||||
PRTL_BALANCED_NODE pNode = &Ntdll->BaseAddressIndexNode;
|
||||
|
||||
@@ -851,275 +824,23 @@ bool NtLdr::FindLdrpModuleIndexBase( )
|
||||
/// <returns>true on success</returns>
|
||||
bool NtLdr::ScanPatterns( )
|
||||
{
|
||||
std::vector<ptr_t> foundData;
|
||||
pe::PEImage ntdll;
|
||||
void* pStart = nullptr;
|
||||
size_t scanSize = 0;
|
||||
auto& data = g_PatternLoader->data();
|
||||
|
||||
HMODULE hNtdll = GetModuleHandleW( L"ntdll.dll" );
|
||||
ntdll.Parse( hNtdll );
|
||||
_LdrKernel32PatchAddress = static_cast<uintptr_t>(data.LdrKernel32PatchAddress);
|
||||
_APC64PatchAddress = static_cast<uintptr_t>(data.APC64PatchAddress);
|
||||
_LdrProtectMrdata = static_cast<uintptr_t>(data.LdrProtectMrdata);
|
||||
|
||||
// Find ntdll code section
|
||||
for (auto& section : ntdll.sections())
|
||||
if (_process.core().isWow64())
|
||||
{
|
||||
if (_stricmp( reinterpret_cast<LPCSTR>(section.Name), ".text" ) == 0)
|
||||
{
|
||||
pStart = reinterpret_cast<void*>(reinterpret_cast<size_t>(hNtdll) + section.VirtualAddress);
|
||||
scanSize = section.Misc.VirtualSize;
|
||||
|
||||
break;
|
||||
}
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(data.LdrpHandleTlsData32);
|
||||
_LdrpInvertedFunctionTable = static_cast<uintptr_t>(data.LdrpInvertedFunctionTable32);
|
||||
_RtlInsertInvertedFunctionTable = static_cast<uintptr_t>(data.RtlInsertInvertedFunctionTable32);
|
||||
}
|
||||
|
||||
// Code section not found
|
||||
if(pStart == nullptr)
|
||||
return false;
|
||||
|
||||
// Win10 update 2
|
||||
if (IsWindows10CreatorsOrGreater())
|
||||
else
|
||||
{
|
||||
#ifdef USE64
|
||||
// LdrpHandleTlsData
|
||||
// 74 33 44 8D 43 09
|
||||
PatternSearch ps( "\x74\x33\x44\x8d\x43\x09" );
|
||||
ps.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0x43);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FA 49 8D 43 20
|
||||
PatternSearch ps2( "\x8b\xfa\x49\x8d\x43\x20" );
|
||||
ps2.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_RtlInsertInvertedFunctionTable = static_cast<uintptr_t>(foundData.front() - 0x10);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// RtlpInsertInvertedFunctionTableEntry
|
||||
// 49 8B E8 48 8B FA 0F 84
|
||||
PatternSearch ps3( "\x49\x8b\xe8\x48\x8b\xfa\x0f\x84" );
|
||||
ps3.Search( pStart, scanSize, foundData );
|
||||
if (!foundData.empty())
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<int32_t*>(foundData.front() - 0xF + 2) + (foundData.front() - 0xF + 6);
|
||||
#else
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8D 45 F0 89 55 F8 50 8D 55 F4
|
||||
PatternSearch ps1( "\x8d\x45\xf0\x89\x55\xf8\x50\x8d\x55\xf4" );
|
||||
ps1.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_RtlInsertInvertedFunctionTable = static_cast<size_t>(foundData.front() - 0xB);
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<uintptr_t*>(foundData.front() + 0x4C);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B C1 8D 4D BC 51
|
||||
PatternSearch ps2( "\x8b\xc1\x8d\x4d\xbc\x51" );
|
||||
ps2.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0x18);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 75 24 85 F6 75 08
|
||||
PatternSearch ps3( "\x75\x24\x85\xf6\x75\x08" );
|
||||
ps3.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
_LdrProtectMrdata = static_cast<uintptr_t>(foundData.front() - 0x1C);
|
||||
#endif
|
||||
}
|
||||
// Win 8.1 and later
|
||||
else if (IsWindows8Point1OrGreater())
|
||||
{
|
||||
#ifdef USE64
|
||||
// LdrpHandleTlsData
|
||||
// 44 8D 43 09 4C 8D 4C 24 38
|
||||
PatternSearch ps( "\x44\x8d\x43\x09\x4c\x8d\x4c\x24\x38" );
|
||||
ps.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0x43);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B C3 2B D3 48 8D 48 01
|
||||
PatternSearch ps2( "\x8B\xC3\x2B\xD3\x48\x8D\x48\x01" );
|
||||
ps2.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_RtlInsertInvertedFunctionTable = static_cast<uintptr_t>(foundData.front() - 0x84);
|
||||
if (IsWindows10OrGreater())
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<int32_t*>(foundData.front() - 0x27 + 3) + (foundData.front() - 0x27 + 7);
|
||||
}
|
||||
#else
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 53 56 57 8B DA 8B F9 50
|
||||
PatternSearch ps1( "\x53\x56\x57\x8b\xda\x8b\xf9\x50" );
|
||||
ps1.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_RtlInsertInvertedFunctionTable = static_cast<size_t>(foundData.front() - 0xB);
|
||||
|
||||
if (IsWindows10OrGreater())
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<uintptr_t*>(foundData.front() + 0x22);
|
||||
else
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<uintptr_t*>(foundData.front() + 0x23);
|
||||
|
||||
foundData.clear();
|
||||
}
|
||||
// Rescan using old pattern
|
||||
else
|
||||
{
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8D 45 F4 89 55 F8 50 8D 55 FC
|
||||
PatternSearch ps12( "\x8d\x45\xf4\x89\x55\xf8\x50\x8d\x55\xfc" );
|
||||
ps12.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_RtlInsertInvertedFunctionTable = static_cast<uintptr_t>(foundData.front() - 0xB);
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<uintptr_t*>(foundData.front() + 0x1D);
|
||||
foundData.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8D 45 ?? 50 6A 09 6A 01 8B C1
|
||||
PatternSearch ps2( "\x8d\x45\xcc\x50\x6a\x09\x6a\x01\x8b\xc1" );
|
||||
ps2.Search( 0xCC, pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0x18);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// LdrProtectMrdata
|
||||
// 83 7D 08 00 8B 35
|
||||
PatternSearch ps3( "\x83\x7d\x08\x00\x8b\x35", 6 );
|
||||
ps3.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
_LdrProtectMrdata = static_cast<uintptr_t>(foundData.front() - 0x12);
|
||||
#endif
|
||||
}
|
||||
// Win 8
|
||||
else if (IsWindows8OrGreater())
|
||||
{
|
||||
#ifdef USE64
|
||||
// LdrpHandleTlsData
|
||||
// 48 8B 79 30 45 8D 66 01
|
||||
PatternSearch ps( "\x48\x8b\x79\x30\x45\x8d\x66\x01" );
|
||||
ps.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0x49);
|
||||
#else
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FF 55 8B EC 51 51 53 57 8B 7D 08 8D
|
||||
PatternSearch ps1( "\x8b\xff\x55\x8b\xec\x51\x51\x53\x57\x8b\x7d\x08\x8d" );
|
||||
ps1.Search( pStart, scanSize, foundData );
|
||||
|
||||
if(!foundData.empty())
|
||||
{
|
||||
_RtlInsertInvertedFunctionTable = static_cast<uintptr_t>(foundData.front());
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<uintptr_t*>(_RtlInsertInvertedFunctionTable + 0x26);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 8B 45 08 89 45 A0
|
||||
PatternSearch ps2( "\x8b\x45\x08\x89\x45\xa0" );
|
||||
ps2.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0xC);
|
||||
#endif
|
||||
}
|
||||
// Win 7
|
||||
else if(IsWindows7OrGreater())
|
||||
{
|
||||
#ifdef USE64
|
||||
// LdrpHandleTlsData
|
||||
// 41 B8 09 00 00 00 48 8D 44 24 38
|
||||
PatternSearch ps1( "\x41\xb8\x09\x00\x00\x00\x48\x8d\x44\x24\x38", 11 );
|
||||
ps1.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0x27);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// LdrpFindOrMapDll patch address
|
||||
// 48 8D 8C 24 98 00 00 00 41 b0 01
|
||||
PatternSearch ps2( "\x48\x8D\x8C\x24\x98\x00\x00\x00\x41\xb0\x01", 11 );
|
||||
ps2.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_LdrKernel32PatchAddress = static_cast<uintptr_t>(foundData.front() + 0x12);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// KiUserApcDispatcher patch address
|
||||
// 48 8B 4C 24 18 48 8B C1 4C
|
||||
PatternSearch ps3( "\x48\x8b\x4c\x24\x18\x48\x8b\xc1\x4c");
|
||||
ps3.Search( pStart, scanSize, foundData );
|
||||
|
||||
if (!foundData.empty())
|
||||
{
|
||||
_APC64PatchAddress = static_cast<uintptr_t>(foundData.front());
|
||||
foundData.clear();
|
||||
}
|
||||
#else
|
||||
// RtlInsertInvertedFunctionTable
|
||||
// 8B FF 55 8B EC 56 68
|
||||
PatternSearch ps1( "\x8b\xff\x55\x8b\xec\x56\x68" );
|
||||
ps1.Search( pStart, scanSize, foundData);
|
||||
|
||||
if(!foundData.empty())
|
||||
{
|
||||
_RtlInsertInvertedFunctionTable = static_cast<size_t>(foundData.front( ));
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// RtlLookupFunctionTable + 0x11
|
||||
// 89 5D E0 38
|
||||
PatternSearch ps2( "\x89\x5D\xE0\x38" );
|
||||
ps2.Search( pStart, scanSize, foundData );
|
||||
|
||||
if(!foundData.empty())
|
||||
{
|
||||
_LdrpInvertedFunctionTable = *reinterpret_cast<uintptr_t*>(foundData.front() + 0x1B);
|
||||
foundData.clear();
|
||||
}
|
||||
|
||||
// LdrpHandleTlsData
|
||||
// 74 20 8D 45 D4 50 6A 09
|
||||
PatternSearch ps3( "\x74\x20\x8d\x45\xd4\x50\x6a\x09" );
|
||||
ps3.Search( pStart, scanSize, foundData );
|
||||
|
||||
if(!foundData.empty())
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(foundData.front() - 0x14);
|
||||
|
||||
#endif
|
||||
_LdrpHandleTlsData = static_cast<uintptr_t>(data.LdrpHandleTlsData64);
|
||||
_LdrpInvertedFunctionTable = static_cast<uintptr_t>(data.LdrpInvertedFunctionTable64);
|
||||
_RtlInsertInvertedFunctionTable = static_cast<uintptr_t>(data.RtlInsertInvertedFunctionTable64);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#include "DynImport.h"
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Load function into database
|
||||
/// </summary>
|
||||
/// <param name="name">Function name</param>
|
||||
/// <param name="module">Module name</param>
|
||||
/// <returns>true on success</returns>
|
||||
FARPROC DynImport::load( const std::string& name, const std::wstring& module )
|
||||
{
|
||||
auto mod = GetModuleHandleW( module.c_str() );
|
||||
return load( name, mod );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load function into database
|
||||
/// </summary>
|
||||
/// <param name="name">Function name</param>
|
||||
/// <param name="hMod">Module base</param>
|
||||
/// <returns>true on success</returns>
|
||||
FARPROC blackbone::DynImport::load( const std::string& name, HMODULE hMod )
|
||||
{
|
||||
CSLock lck( _mapGuard );
|
||||
|
||||
auto proc = GetProcAddress( hMod, name.c_str() );
|
||||
if (proc)
|
||||
{
|
||||
_funcs.insert( std::make_pair( name, proc ) );
|
||||
return proc;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -72,7 +72,11 @@ public:
|
||||
/// <param name="name">Function name</param>
|
||||
/// <param name="module">Module name</param>
|
||||
/// <returns>true on success</returns>
|
||||
BLACKBONE_API FARPROC load( const std::string& name, const std::wstring& module );
|
||||
BLACKBONE_API FARPROC load( const std::string& name, const std::wstring& module )
|
||||
{
|
||||
auto mod = GetModuleHandleW( module.c_str() );
|
||||
return load( name, mod );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load function into database
|
||||
@@ -80,7 +84,19 @@ public:
|
||||
/// <param name="name">Function name</param>
|
||||
/// <param name="hMod">Module base</param>
|
||||
/// <returns>true on success</returns>
|
||||
BLACKBONE_API FARPROC load( const std::string& name, HMODULE hMod );
|
||||
BLACKBONE_API FARPROC load( const std::string& name, HMODULE hMod )
|
||||
{
|
||||
CSLock lck( _mapGuard );
|
||||
|
||||
auto proc = GetProcAddress( hMod, name.c_str() );
|
||||
if (proc)
|
||||
{
|
||||
_funcs.insert( std::make_pair( name, proc ) );
|
||||
return proc;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
DynImport() = default;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "../Include/Winheaders.h"
|
||||
#include "../Include/Macro.h"
|
||||
#include "DynImport.h"
|
||||
#include "PattrernLoader.h"
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
@@ -19,6 +20,10 @@ public:
|
||||
GrantPriviledge( L"SeDebugPrivilege" );
|
||||
GrantPriviledge( L"SeLoadDriverPrivilege" );
|
||||
LoadFuncs();
|
||||
|
||||
g_PatternLoader.reset( new PatternLoader );
|
||||
g_PatternLoader->DoSearch();
|
||||
|
||||
_done = true;
|
||||
}
|
||||
|
||||
@@ -115,7 +120,8 @@ private:
|
||||
static bool _done;
|
||||
};
|
||||
|
||||
std::unique_ptr<PatternLoader> g_PatternLoader;
|
||||
|
||||
bool InitOnce::_done = false;
|
||||
const bool g_Initialized = InitOnce::Exec();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
#include "PattrernLoader.h"
|
||||
#include "../PE/PEImage.h"
|
||||
#include "../Include/Winheaders.h"
|
||||
#include "../Misc/Trace.hpp"
|
||||
#include "../../../contrib/VersionHelpers.h"
|
||||
|
||||
namespace blackbone
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// System32 helper
|
||||
/// </summary>
|
||||
class FsRedirector
|
||||
{
|
||||
public:
|
||||
FsRedirector( bool wow64 )
|
||||
: _wow64( wow64 )
|
||||
{
|
||||
if (wow64)
|
||||
Wow64DisableWow64FsRedirection( &_fsRedirection );
|
||||
}
|
||||
|
||||
~FsRedirector()
|
||||
{
|
||||
if (_wow64)
|
||||
Wow64RevertWow64FsRedirection( _fsRedirection );
|
||||
}
|
||||
|
||||
private:
|
||||
PVOID _fsRedirection = nullptr;
|
||||
bool _wow64;
|
||||
};
|
||||
|
||||
/// <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 BLACBONE_NO_TRACE
|
||||
if (_data.LdrpHandleTlsData64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpHandleTlsData64 not found" );
|
||||
if (_data.LdrpHandleTlsData32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpHandleTlsData32 not found" );
|
||||
if (_data.LdrpInvertedFunctionTable64 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpInvertedFunctionTable64 not found" );
|
||||
if (_data.LdrpInvertedFunctionTable32 == 0)
|
||||
BLACKBONE_TRACE( "PatternData: LdrpInvertedFunctionTable32 not found" );
|
||||
if (_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 (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{ "\x83\x7d\x08\x00\x8b\x35", 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 } );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
#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;
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../../Include/NativeStructures.h"
|
||||
#include "../../Include/CallResult.h"
|
||||
#include "../../Include/Types.h"
|
||||
#include "../../Misc/Utils.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ call_result_t<ThreadPtr> ProcessThreads::CreateNew( ptr_t threadProc, ptr_t arg,
|
||||
if (!NT_SUCCESS( status ))
|
||||
return status;
|
||||
|
||||
std::lock_guard<std::mutex> lg( _lock );
|
||||
CSLock lg( _lock );
|
||||
_threads.emplace_back( new Thread( hThd, &_core ) );
|
||||
return _threads.back();
|
||||
}
|
||||
@@ -75,7 +75,7 @@ std::vector<ThreadPtr>& ProcessThreads::getAll( bool dontUpdate /*= false*/ )
|
||||
if (tEntry.th32OwnerProcessID != _core.pid())
|
||||
continue;
|
||||
|
||||
std::lock_guard<std::mutex> lg( _lock );
|
||||
CSLock lg( _lock );
|
||||
_threads.emplace_back( new Thread( tEntry.th32ThreadID, &_core ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ private:
|
||||
private:
|
||||
class ProcessCore& _core; // Core process functions
|
||||
std::vector<ThreadPtr> _threads; // Process thread snapshot
|
||||
std::mutex _lock; // Update lock
|
||||
CriticalSection _lock; // Update lock
|
||||
};
|
||||
|
||||
}
|
||||
@@ -131,7 +131,7 @@ TEST_CASE( "05. Local hooks" )
|
||||
|
||||
REQUIRE( det.Hook( &CloseHandle, &MyMook::hkCloseHandle, &mh, HookType::HWBP ) );
|
||||
REQUIRE( det2.Hook( &TestFastcall, &hkTestFastcall, HookType::Inline ) );
|
||||
REQUIRE( det3.Hook( ptr, &::hkTest, HookType::Inline ) );
|
||||
REQUIRE( det3.Hook( ptr, &::hkTest, HookType::Int3 ) );
|
||||
REQUIRE( det4.Hook( (void**)&testClass, 0, &MyMook::hkVFunc, &mh ) );
|
||||
|
||||
int a = args[0];
|
||||
|
||||
Reference in New Issue
Block a user