mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
@@ -438,6 +438,7 @@ NTSTATUS InitializeLockHeld() {
|
||||
status = STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
else {
|
||||
++MmpGlobalDataPtr->ReferenceCount;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -448,6 +449,7 @@ NTSTATUS InitializeLockHeld() {
|
||||
MmpGlobalDataPtr->MajorVersion = MEMORY_MODULE_MAJOR_VERSION;
|
||||
MmpGlobalDataPtr->MinorVersion = MEMORY_MODULE_MINOR_VERSION;
|
||||
MmpGlobalDataPtr->BaseAddress = MmpGlobalDataPtr;
|
||||
MmpGlobalDataPtr->ReferenceCount = 1;
|
||||
|
||||
GetSystemInfo(&MmpGlobalDataPtr->SystemInfo);
|
||||
|
||||
@@ -504,16 +506,74 @@ NTSTATUS InitializeLockHeld() {
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI Initialize() {
|
||||
NTSTATUS NTAPI MmInitialize() {
|
||||
NTSTATUS status;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
status = InitializeLockHeld();
|
||||
RtlReleasePebLock();
|
||||
PVOID cookie;
|
||||
LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie);
|
||||
|
||||
__try {
|
||||
status = InitializeLockHeld();
|
||||
}
|
||||
__finally {
|
||||
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS CleanupLockHeld() {
|
||||
|
||||
PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink;
|
||||
PLDR_DATA_TABLE_ENTRY CurEntry;
|
||||
|
||||
while (ListEntry != ListHead) {
|
||||
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
|
||||
ListEntry = ListEntry->Flink;
|
||||
|
||||
if (IsValidMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase)) {
|
||||
|
||||
//
|
||||
// Make sure all memory module is unloaded.
|
||||
//
|
||||
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (--MmpGlobalDataPtr->ReferenceCount > 0) {
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
MmpTlsCleanup();
|
||||
MmpCleanupDotNetHooks();
|
||||
|
||||
NtUnmapViewOfSection(NtCurrentProcess(), MmpGlobalDataPtr->BaseAddress);
|
||||
MmpGlobalDataPtr = nullptr;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI MmCleanup() {
|
||||
NTSTATUS status;
|
||||
PVOID cookie;
|
||||
LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie);
|
||||
|
||||
__try {
|
||||
|
||||
if (MmpGlobalDataPtr == nullptr) {
|
||||
status = STATUS_ACCESS_VIOLATION;
|
||||
__leave;
|
||||
}
|
||||
|
||||
status = CleanupLockHeld();
|
||||
}
|
||||
__finally {
|
||||
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef _USRDLL
|
||||
extern "C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll(HMODULE hModule) {
|
||||
PIMAGE_NT_HEADERS headers = RtlImageNtHeader(hModule);
|
||||
@@ -542,7 +602,8 @@ extern "C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll(HMODULE hModule) {
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
|
||||
if (NT_SUCCESS(Initialize())) {
|
||||
#ifdef _HAS_AUTO_INITIALIZE
|
||||
if (NT_SUCCESS(MmInitialize())) {
|
||||
if (lpReserved == (PVOID)-1) {
|
||||
if (!ReflectiveMapDll(hModule)) {
|
||||
RtlRaiseStatus(STATUS_NOT_SUPPORTED);
|
||||
@@ -553,10 +614,13 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
const NTSTATUS Initializer = Initialize();
|
||||
#ifdef _HAS_AUTO_INITIALIZE
|
||||
const NTSTATUS Initializer = MmInitialize();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
NTSTATUS NTAPI MmInitialize();
|
||||
NTSTATUS NTAPI MmCleanup();
|
||||
|
||||
//
|
||||
// This function is available only if the MMPP is compiled as a DLL.
|
||||
//
|
||||
BOOL WINAPI ReflectiveMapDll(HMODULE hModule);
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
typedef HMODULE HMEMORYMODULE;
|
||||
#include "Loader.h"
|
||||
#include "Initialize.h"
|
||||
|
||||
#define MemoryModuleToModule(_hMemoryModule_) (_hMemoryModule_)
|
||||
|
||||
@@ -10,25 +11,29 @@ typedef HMODULE HMEMORYMODULE;
|
||||
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
||||
#endif
|
||||
|
||||
HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress);
|
||||
extern "C" {
|
||||
|
||||
HMEMORYMODULE WINAPI LoadLibraryMemoryExA(
|
||||
_In_ PVOID BufferAddress,
|
||||
_In_ size_t Reserved,
|
||||
_In_opt_ LPCSTR DllBaseName,
|
||||
_In_opt_ LPCSTR DllFullName,
|
||||
_In_ DWORD Flags
|
||||
);
|
||||
HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress);
|
||||
|
||||
HMEMORYMODULE WINAPI LoadLibraryMemoryExW(
|
||||
_In_ PVOID BufferAddress,
|
||||
_In_ size_t Reserved,
|
||||
_In_opt_ LPCWSTR DllBaseName,
|
||||
_In_opt_ LPCWSTR DllFullName,
|
||||
_In_ DWORD Flags
|
||||
);
|
||||
HMEMORYMODULE WINAPI LoadLibraryMemoryExA(
|
||||
_In_ PVOID BufferAddress,
|
||||
_In_ size_t Reserved,
|
||||
_In_opt_ LPCSTR DllBaseName,
|
||||
_In_opt_ LPCSTR DllFullName,
|
||||
_In_ DWORD Flags
|
||||
);
|
||||
|
||||
BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule);
|
||||
HMEMORYMODULE WINAPI LoadLibraryMemoryExW(
|
||||
_In_ PVOID BufferAddress,
|
||||
_In_ size_t Reserved,
|
||||
_In_opt_ LPCWSTR DllBaseName,
|
||||
_In_opt_ LPCWSTR DllFullName,
|
||||
_In_ DWORD Flags
|
||||
);
|
||||
|
||||
BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule);
|
||||
|
||||
}
|
||||
|
||||
#define NtLoadDllMemory LdrLoadDllMemory
|
||||
#define NtLoadDllMemoryExA LdrLoadDllMemoryExA
|
||||
|
||||
+13
-1
@@ -61,7 +61,14 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
|
||||
__try {
|
||||
*BaseAddress = nullptr;
|
||||
if (LdrEntry)*LdrEntry = nullptr;
|
||||
if (!RtlIsValidImageBuffer(BufferAddress, &BufferSize) && !(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK))status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
|
||||
if (!RtlIsValidImageBuffer(BufferAddress, &BufferSize) && !(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK)) {
|
||||
status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
|
||||
if (MmpGlobalDataPtr == nullptr) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {
|
||||
status = GetExceptionCode();
|
||||
@@ -229,6 +236,11 @@ NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (MmpGlobalDataPtr == nullptr) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
//Mapping dll failed
|
||||
if (!module->MappedDll) {
|
||||
module->underUnload = true;
|
||||
|
||||
+17
-17
@@ -9,9 +9,6 @@
|
||||
#define MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY 0x00000040
|
||||
#define MEMORY_FEATURE_ALL 0x0000007f
|
||||
|
||||
//Get the implementation of the currently running operating system.
|
||||
NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures);
|
||||
|
||||
|
||||
/*
|
||||
LdrLoadDllMemoryEx dwFlags
|
||||
@@ -47,21 +44,24 @@ NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures);
|
||||
//Hook for dotnet dlls
|
||||
#define LOAD_FLAGS_HOOK_DOT_NET 0x00000010
|
||||
|
||||
|
||||
NTSTATUS NTAPI LdrLoadDllMemoryExW(
|
||||
_Out_ HMEMORYMODULE* BaseAddress, // Output module base address
|
||||
_Out_opt_ PVOID* LdrEntry, // Receive a pointer to the LDR node of the module
|
||||
_In_ DWORD dwFlags, // Flags
|
||||
_In_ LPVOID BufferAddress, // Pointer to the dll file data buffer
|
||||
_In_ size_t Reserved, // Reserved parameter, must be 0
|
||||
_In_opt_ LPCWSTR DllName, // Module file name
|
||||
_In_opt_ LPCWSTR DllFullName // Module file full path
|
||||
);
|
||||
|
||||
//Unload modules previously loaded from memory
|
||||
NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress);
|
||||
|
||||
extern "C" {
|
||||
|
||||
//Get the implementation of the currently running operating system.
|
||||
NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures);
|
||||
|
||||
NTSTATUS NTAPI LdrLoadDllMemoryExW(
|
||||
_Out_ HMEMORYMODULE* BaseAddress, // Output module base address
|
||||
_Out_opt_ PVOID* LdrEntry, // Receive a pointer to the LDR node of the module
|
||||
_In_ DWORD dwFlags, // Flags
|
||||
_In_ LPVOID BufferAddress, // Pointer to the dll file data buffer
|
||||
_In_ size_t Reserved, // Reserved parameter, must be 0
|
||||
_In_opt_ LPCWSTR DllName, // Module file name
|
||||
_In_opt_ LPCWSTR DllFullName // Module file full path
|
||||
);
|
||||
|
||||
//Unload modules previously loaded from memory
|
||||
NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress);
|
||||
|
||||
__declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread(
|
||||
_In_ HMEMORYMODULE BaseAddress,
|
||||
_In_ DWORD dwExitCode
|
||||
|
||||
@@ -152,6 +152,7 @@
|
||||
<ClInclude Include="..\3rdparty\phnt\include\subprocesstag.h" />
|
||||
<ClInclude Include="..\3rdparty\phnt\include\winsta.h" />
|
||||
<ClInclude Include="ImportTable.h" />
|
||||
<ClInclude Include="Initialize.h" />
|
||||
<ClInclude Include="LoadDllMemoryApi.h" />
|
||||
<ClInclude Include="LoaderPrivate.h" />
|
||||
<ClInclude Include="MemoryModule.h" />
|
||||
@@ -419,7 +420,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -437,7 +438,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -456,7 +457,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -475,7 +476,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -494,7 +495,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -512,7 +513,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -531,7 +532,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -550,7 +551,7 @@
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -571,7 +572,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -593,7 +594,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -616,7 +617,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -639,7 +640,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;WIN32;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -662,7 +663,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -684,7 +685,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -707,7 +708,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
@@ -730,7 +731,7 @@
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_MEMORY_MODULE;_HAS_AUTO_INITIALIZE;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
|
||||
@@ -260,6 +260,9 @@
|
||||
<ClInclude Include="ImportTable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Initialize.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\README.md">
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
LIBRARY
|
||||
EXPORTS
|
||||
|
||||
MmInitialize
|
||||
MmCleanup
|
||||
|
||||
LoadLibraryMemory
|
||||
LoadLibraryMemoryExA
|
||||
LoadLibraryMemoryExW
|
||||
|
||||
@@ -443,3 +443,38 @@ BOOL WINAPI MmpInitializeHooksForDotNet() {
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID WINAPI MmpCleanupDotNetHooks() {
|
||||
EnterCriticalSection(NtCurrentPeb()->FastPebLock);
|
||||
|
||||
if (MmpGlobalDataPtr->MmpDotNet->PreHooked) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(NtCurrentThread());
|
||||
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileW, HookCreateFileW);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileInformationByHandle, HookGetFileInformationByHandle);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileAttributesExW, HookGetFileAttributesExW);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSize, HookGetFileSize);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileSizeEx, HookGetFileSizeEx);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCreateFileMappingW, HookCreateFileMappingW);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFileEx, HookMapViewOfFileEx);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginMapViewOfFile, HookMapViewOfFile);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginUnmapViewOfFile, HookUnmapViewOfFile);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginCloseHandle, HookCloseHandle);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion2, HookGetFileVersion);
|
||||
|
||||
DetourTransactionCommit();
|
||||
|
||||
MmpGlobalDataPtr->MmpDotNet->PreHooked = FALSE;
|
||||
}
|
||||
|
||||
if (MmpGlobalDataPtr->MmpDotNet->Initialized) {
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(NtCurrentThread());
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpDotNet->Hooks.OriginGetFileVersion1, HookGetFileVersion);
|
||||
DetourTransactionCommit();
|
||||
MmpGlobalDataPtr->MmpDotNet->Initialized = FALSE;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(NtCurrentPeb()->FastPebLock);
|
||||
}
|
||||
|
||||
@@ -8,4 +8,5 @@ typedef HRESULT(WINAPI* GetFileVersion_T)(
|
||||
);
|
||||
|
||||
BOOL WINAPI MmpPreInitializeHooksForDotNet();
|
||||
BOOL WINAPI MmpInitializeHooksForDotNet();
|
||||
BOOL WINAPI MmpInitializeHooksForDotNet();
|
||||
VOID WINAPI MmpCleanupDotNetHooks();
|
||||
|
||||
@@ -100,7 +100,7 @@ typedef enum class _WINDOWS_VERSION :BYTE {
|
||||
#define MEMORY_MODULE_GET_MINOR_VERSION(MinorVersion) (~0x8000&(MinorVersion))
|
||||
|
||||
#define MEMORY_MODULE_MAJOR_VERSION 2
|
||||
#define MEMORY_MODULE_MINOR_VERSION MEMORY_MODULE_MAKE_PREVIEW(1)
|
||||
#define MEMORY_MODULE_MINOR_VERSION MEMORY_MODULE_MAKE_PREVIEW(2)
|
||||
|
||||
typedef struct _MMP_GLOBAL_DATA {
|
||||
|
||||
@@ -137,6 +137,8 @@ typedef struct _MMP_GLOBAL_DATA {
|
||||
|
||||
PMMP_IAT_DATA MmpIat;
|
||||
|
||||
DWORD ReferenceCount;
|
||||
|
||||
}MMP_GLOBAL_DATA, * PMMP_GLOBAL_DATA;
|
||||
|
||||
#define MMP_GLOBAL_DATA_SIZE (\
|
||||
|
||||
+146
-33
@@ -7,6 +7,7 @@
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <3rdparty/Detours/detours.h>
|
||||
#include <set>
|
||||
|
||||
|
||||
PVOID NTAPI MmpQuerySystemInformation(
|
||||
@@ -402,6 +403,96 @@ BOOL NTAPI PreHookNtSetInformationProcess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
int MmpSyncThreadTlsData() {
|
||||
PSYSTEM_PROCESS_INFORMATION pspi = (PSYSTEM_PROCESS_INFORMATION)MmpQuerySystemInformation(SYSTEM_INFORMATION_CLASS::SystemProcessInformation, nullptr);
|
||||
PSYSTEM_PROCESS_INFORMATION current = pspi;
|
||||
std::set<HANDLE>threads;
|
||||
int count = 0;
|
||||
|
||||
//
|
||||
// Build thread id set.
|
||||
//
|
||||
|
||||
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink;
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) {
|
||||
PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
|
||||
threads.insert(j->UniqueThread);
|
||||
|
||||
entry = entry->Flink;
|
||||
}
|
||||
|
||||
while (pspi) {
|
||||
|
||||
if (current->UniqueProcessId == NtCurrentTeb()->ClientId.UniqueProcess) {
|
||||
|
||||
for (ULONG index = 0; index < current->NumberOfThreads; ++index) {
|
||||
CLIENT_ID cid = current->Threads[index].ClientId;
|
||||
|
||||
if (threads.find(cid.UniqueThread) == threads.end()) {
|
||||
|
||||
HANDLE hThread;
|
||||
OBJECT_ATTRIBUTES oa{};
|
||||
NTSTATUS status = NtOpenThread(&hThread, THREAD_QUERY_INFORMATION, &oa, &cid);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
THREAD_BASIC_INFORMATION tbi{};
|
||||
status = NtQueryInformationThread(hThread, THREADINFOCLASS::ThreadBasicInformation, &tbi, sizeof(tbi), nullptr);
|
||||
if (NT_SUCCESS(status)) {
|
||||
|
||||
PTEB teb = tbi.TebBaseAddress;
|
||||
if (teb->ThreadLocalStoragePointer) {
|
||||
|
||||
//
|
||||
// Allocate TLS record
|
||||
//
|
||||
|
||||
auto record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD)));
|
||||
if (record) {
|
||||
record->TlspLdrBlock = (PVOID*)teb->ThreadLocalStoragePointer;
|
||||
record->TlspMmpBlock = (PVOID*)MmpAllocateTlsp();
|
||||
record->UniqueThread = cid.UniqueThread;
|
||||
if (record->TlspMmpBlock) {
|
||||
record->TlspMmpBlock = ((PTLS_VECTOR)record->TlspMmpBlock)->ModuleTlsData;
|
||||
|
||||
auto size = CONTAINING_RECORD(record->TlspLdrBlock, TLS_VECTOR, ModuleTlsData)->Length;
|
||||
if ((HANDLE)(ULONG_PTR)size != record->UniqueThread) {
|
||||
RtlCopyMemory(
|
||||
record->TlspMmpBlock,
|
||||
record->TlspLdrBlock,
|
||||
size * sizeof(PVOID)
|
||||
);
|
||||
}
|
||||
|
||||
teb->ThreadLocalStoragePointer = record->TlspMmpBlock;
|
||||
InsertTailList(&MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer, &record->InMmpThreadLocalStoragePointer);
|
||||
InterlockedIncrement(&MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount);
|
||||
|
||||
++count;
|
||||
}
|
||||
else {
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, record);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NtClose(hThread);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!current->NextEntryOffset)break;
|
||||
current = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)current + current->NextEntryOffset);
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, pspi);
|
||||
return count;
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
_In_opt_ HANDLE ProcessHandle,
|
||||
_In_ PROCESSINFOCLASS ProcessInformationClass,
|
||||
@@ -423,6 +514,12 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
PPROCESS_TLS_INFORMATION Tls = nullptr;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
||||
//
|
||||
// Sync thread data with ntdll!Ldr.
|
||||
//
|
||||
|
||||
MmpSyncThreadTlsData();
|
||||
|
||||
do {
|
||||
if (ProcessTlsInformation->OperationType >= MaxProcessTlsOperation) {
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
@@ -456,7 +553,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
break;
|
||||
}
|
||||
|
||||
// reserved 0x50 PVOID for ntdll loader
|
||||
// reserved 0x80 PVOID for ntdll loader
|
||||
if (ProcessTlsInformation->TlsVectorLength >= MMP_START_TLS_INDEX) {
|
||||
status = STATUS_NO_MEMORY;
|
||||
break;
|
||||
@@ -496,50 +593,55 @@ NTSTATUS NTAPI HookNtSetInformationProcess(
|
||||
//
|
||||
EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) {
|
||||
BOOL found = FALSE;
|
||||
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink;
|
||||
|
||||
// Find thread-spec tlsp
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) {
|
||||
if (Tls->ThreadData[i].Flags == 2) {
|
||||
|
||||
PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
|
||||
BOOL found = FALSE;
|
||||
PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer.Flink;
|
||||
|
||||
if (ProcessTlsInformation->OperationType == ProcessTlsReplaceVector) {
|
||||
if (j->TlspMmpBlock[ProcessTlsInformation->TlsVectorLength] == ProcessTlsInformation->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]) {
|
||||
found = TRUE;
|
||||
// Find thread-spec tlsp
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls->MmpThreadLocalStoragePointer) {
|
||||
|
||||
// Copy old data to new pointer
|
||||
RtlCopyMemory(
|
||||
ProcessTlsInformation->ThreadData[i].TlsVector,
|
||||
j->TlspMmpBlock,
|
||||
sizeof(PVOID) * ProcessTlsInformation->TlsVectorLength
|
||||
);
|
||||
PMMP_TLSP_RECORD j = CONTAINING_RECORD(entry, MMP_TLSP_RECORD, InMmpThreadLocalStoragePointer);
|
||||
|
||||
// Swap the tlsp
|
||||
std::swap(
|
||||
j->TlspLdrBlock,
|
||||
ProcessTlsInformation->ThreadData[i].TlsVector
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (j->TlspMmpBlock[ProcessTlsInformation->TlsIndex] == ProcessTlsInformation->ThreadData[i].TlsModulePointer) {
|
||||
found = TRUE;
|
||||
if (ProcessTlsInformation->OperationType == ProcessTlsReplaceVector) {
|
||||
if (j->TlspMmpBlock[ProcessTlsInformation->TlsVectorLength] == ProcessTlsInformation->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]) {
|
||||
found = TRUE;
|
||||
|
||||
if (ProcessHandle) {
|
||||
j->TlspLdrBlock[ProcessTlsInformation->TlsIndex] = ProcessTlsInformation->ThreadData[i].TlsModulePointer;
|
||||
// Copy old data to new pointer
|
||||
RtlCopyMemory(
|
||||
ProcessTlsInformation->ThreadData[i].TlsVector,
|
||||
j->TlspMmpBlock,
|
||||
sizeof(PVOID) * ProcessTlsInformation->TlsVectorLength
|
||||
);
|
||||
|
||||
// Swap the tlsp
|
||||
std::swap(
|
||||
j->TlspLdrBlock,
|
||||
ProcessTlsInformation->ThreadData[i].TlsVector
|
||||
);
|
||||
}
|
||||
|
||||
ProcessTlsInformation->ThreadData[i].TlsModulePointer = Tls->ThreadData[i].TlsModulePointer;
|
||||
}
|
||||
else {
|
||||
if (j->TlspMmpBlock[ProcessTlsInformation->TlsIndex] == ProcessTlsInformation->ThreadData[i].TlsModulePointer) {
|
||||
found = TRUE;
|
||||
|
||||
if (ProcessHandle) {
|
||||
j->TlspLdrBlock[ProcessTlsInformation->TlsIndex] = ProcessTlsInformation->ThreadData[i].TlsModulePointer;
|
||||
}
|
||||
|
||||
ProcessTlsInformation->ThreadData[i].TlsModulePointer = Tls->ThreadData[i].TlsModulePointer;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)break;
|
||||
entry = entry->Flink;
|
||||
}
|
||||
|
||||
if (found)break;
|
||||
entry = entry->Flink;
|
||||
ProcessTlsInformation->ThreadData[i].Flags = Tls->ThreadData[i].Flags;
|
||||
ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId;
|
||||
}
|
||||
|
||||
ProcessTlsInformation->ThreadData[i].Flags = Tls->ThreadData[i].Flags;
|
||||
ProcessTlsInformation->ThreadData[i].ThreadId = Tls->ThreadData[i].ThreadId;
|
||||
}
|
||||
LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock);
|
||||
|
||||
@@ -798,4 +900,15 @@ BOOL NTAPI MmpTlsInitialize() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID NTAPI MmpTlsCleanup() {
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(NtCurrentThread());
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginLdrShutdownThread, HookLdrShutdownThread);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginNtSetInformationProcess, HookNtSetInformationProcess);
|
||||
DetourDetach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginRtlUserThreadStart, HookRtlUserThreadStart);
|
||||
DetourTransactionCommit();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
BOOL NTAPI MmpTlsInitialize();
|
||||
|
||||
VOID NTAPI MmpTlsCleanup();
|
||||
|
||||
NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry);
|
||||
|
||||
NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "MmpTlsFiber.h"
|
||||
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
typedef struct _MMP_POSTPONED_TLS {
|
||||
|
||||
@@ -31,8 +32,7 @@ DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) {
|
||||
auto iter = MmpPostponedTlsList->begin();
|
||||
|
||||
while (iter != MmpPostponedTlsList->end()) {
|
||||
const auto& item = *iter;
|
||||
GetExitCodeThread(item.hThread, &code);
|
||||
GetExitCodeThread(iter->hThread, &code);
|
||||
|
||||
if (code == STILL_ACTIVE) {
|
||||
++iter;
|
||||
@@ -41,7 +41,7 @@ DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) {
|
||||
|
||||
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
auto TlspMmpBlock = (PVOID*)item.lpOldTlsVector->ModuleTlsData;
|
||||
auto TlspMmpBlock = (PVOID*)iter->lpOldTlsVector->ModuleTlsData;
|
||||
auto entry = MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink;
|
||||
while (entry != &MmpGlobalDataPtr->MmpTls->MmpTlsList) {
|
||||
|
||||
@@ -51,13 +51,13 @@ DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) {
|
||||
entry = entry->Flink;
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(item.lpTlsRecord->TlspLdrBlock, TLS_VECTOR, TLS_VECTOR::ModuleTlsData));
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, item.lpTlsRecord);
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, item.lpOldTlsVector);
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(iter->lpTlsRecord->TlspLdrBlock, TLS_VECTOR, TLS_VECTOR::ModuleTlsData));
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, iter->lpTlsRecord);
|
||||
RtlFreeHeap(RtlProcessHeap(), 0, iter->lpOldTlsVector);
|
||||
|
||||
RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
||||
|
||||
CloseHandle(item.hThread);
|
||||
CloseHandle(iter->hThread);
|
||||
iter = MmpPostponedTlsList->erase(iter);
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ VOID WINAPI MmpQueuePostponedTls(PMMP_TLSP_RECORD record) {
|
||||
);
|
||||
|
||||
item.lpOldTlsVector = MmpAllocateTlsp();
|
||||
assert(item.lpOldTlsVector);
|
||||
|
||||
item.lpTlsRecord = record;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user