Skip to content

Commit 79f258b

Browse files
authored
Merge pull request #56 from bb107/MmpTlsFixup
Mmp tls fixup
2 parents f35b311 + 0391e3c commit 79f258b

File tree

17 files changed

+352
-153
lines changed

17 files changed

+352
-153
lines changed

3rdparty/phnt/include/ntioapi.h

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -774,22 +774,6 @@ typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION
774774
WCHAR FileName[1];
775775
} FILE_ID_EXTD_BOTH_DIR_INFORMATION, *PFILE_ID_EXTD_BOTH_DIR_INFORMATION;
776776

777-
// private
778-
typedef struct _FILE_STAT_INFORMATION
779-
{
780-
LARGE_INTEGER FileId;
781-
LARGE_INTEGER CreationTime;
782-
LARGE_INTEGER LastAccessTime;
783-
LARGE_INTEGER LastWriteTime;
784-
LARGE_INTEGER ChangeTime;
785-
LARGE_INTEGER AllocationSize;
786-
LARGE_INTEGER EndOfFile;
787-
ULONG FileAttributes;
788-
ULONG ReparseTag;
789-
ULONG NumberOfLinks;
790-
ACCESS_MASK EffectiveAccess;
791-
} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION;
792-
793777
// private
794778
typedef struct _FILE_MEMORY_PARTITION_INFORMATION
795779
{
@@ -805,43 +789,6 @@ typedef struct _FILE_MEMORY_PARTITION_INFORMATION
805789
} Flags;
806790
} FILE_MEMORY_PARTITION_INFORMATION, *PFILE_MEMORY_PARTITION_INFORMATION;
807791

808-
// LxFlags
809-
#define LX_FILE_METADATA_HAS_UID 0x1
810-
#define LX_FILE_METADATA_HAS_GID 0x2
811-
#define LX_FILE_METADATA_HAS_MODE 0x4
812-
#define LX_FILE_METADATA_HAS_DEVICE_ID 0x8
813-
#define LX_FILE_CASE_SENSITIVE_DIR 0x10
814-
815-
// private
816-
typedef struct _FILE_STAT_LX_INFORMATION
817-
{
818-
LARGE_INTEGER FileId;
819-
LARGE_INTEGER CreationTime;
820-
LARGE_INTEGER LastAccessTime;
821-
LARGE_INTEGER LastWriteTime;
822-
LARGE_INTEGER ChangeTime;
823-
LARGE_INTEGER AllocationSize;
824-
LARGE_INTEGER EndOfFile;
825-
ULONG FileAttributes;
826-
ULONG ReparseTag;
827-
ULONG NumberOfLinks;
828-
ACCESS_MASK EffectiveAccess;
829-
ULONG LxFlags;
830-
ULONG LxUid;
831-
ULONG LxGid;
832-
ULONG LxMode;
833-
ULONG LxDeviceIdMajor;
834-
ULONG LxDeviceIdMinor;
835-
} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION;
836-
837-
#define FILE_CS_FLAG_CASE_SENSITIVE_DIR 0x00000001
838-
839-
// private
840-
typedef struct _FILE_CASE_SENSITIVE_INFORMATION
841-
{
842-
ULONG Flags;
843-
} FILE_CASE_SENSITIVE_INFORMATION, *PFILE_CASE_SENSITIVE_INFORMATION;
844-
845792
// private
846793
typedef enum _FILE_KNOWN_FOLDER_TYPE
847794
{

MemoryModule/Initialize.cpp

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ NTSTATUS InitializeLockHeld() {
438438
status = STATUS_NOT_SUPPORTED;
439439
}
440440
else {
441+
++MmpGlobalDataPtr->ReferenceCount;
441442
status = STATUS_SUCCESS;
442443
}
443444
}
@@ -448,6 +449,7 @@ NTSTATUS InitializeLockHeld() {
448449
MmpGlobalDataPtr->MajorVersion = MEMORY_MODULE_MAJOR_VERSION;
449450
MmpGlobalDataPtr->MinorVersion = MEMORY_MODULE_MINOR_VERSION;
450451
MmpGlobalDataPtr->BaseAddress = MmpGlobalDataPtr;
452+
MmpGlobalDataPtr->ReferenceCount = 1;
451453

452454
GetSystemInfo(&MmpGlobalDataPtr->SystemInfo);
453455

@@ -504,16 +506,74 @@ NTSTATUS InitializeLockHeld() {
504506
return status;
505507
}
506508

507-
NTSTATUS NTAPI Initialize() {
509+
NTSTATUS NTAPI MmInitialize() {
508510
NTSTATUS status;
509511

510-
RtlAcquirePebLock();
511-
status = InitializeLockHeld();
512-
RtlReleasePebLock();
512+
PVOID cookie;
513+
LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie);
514+
515+
__try {
516+
status = InitializeLockHeld();
517+
}
518+
__finally {
519+
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie);
520+
}
513521

514522
return status;
515523
}
516524

525+
NTSTATUS CleanupLockHeld() {
526+
527+
PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink;
528+
PLDR_DATA_TABLE_ENTRY CurEntry;
529+
530+
while (ListEntry != ListHead) {
531+
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
532+
ListEntry = ListEntry->Flink;
533+
534+
if (IsValidMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase)) {
535+
536+
//
537+
// Make sure all memory module is unloaded.
538+
//
539+
540+
return STATUS_NOT_SUPPORTED;
541+
}
542+
}
543+
544+
if (--MmpGlobalDataPtr->ReferenceCount > 0) {
545+
return STATUS_SUCCESS;
546+
}
547+
548+
MmpTlsCleanup();
549+
MmpCleanupDotNetHooks();
550+
551+
NtUnmapViewOfSection(NtCurrentProcess(), MmpGlobalDataPtr->BaseAddress);
552+
MmpGlobalDataPtr = nullptr;
553+
return STATUS_SUCCESS;
554+
}
555+
556+
NTSTATUS NTAPI MmCleanup() {
557+
NTSTATUS status;
558+
PVOID cookie;
559+
LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, nullptr, &cookie);
560+
561+
__try {
562+
563+
if (MmpGlobalDataPtr == nullptr) {
564+
status = STATUS_ACCESS_VIOLATION;
565+
__leave;
566+
}
567+
568+
status = CleanupLockHeld();
569+
}
570+
__finally {
571+
LdrUnlockLoaderLock(LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, cookie);
572+
}
573+
574+
return status;
575+
}
576+
517577
#ifdef _USRDLL
518578
extern "C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll(HMODULE hModule) {
519579
PIMAGE_NT_HEADERS headers = RtlImageNtHeader(hModule);
@@ -542,7 +602,8 @@ extern "C" __declspec(dllexport) BOOL WINAPI ReflectiveMapDll(HMODULE hModule) {
542602

543603
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
544604
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
545-
if (NT_SUCCESS(Initialize())) {
605+
#ifdef _HAS_AUTO_INITIALIZE
606+
if (NT_SUCCESS(MmInitialize())) {
546607
if (lpReserved == (PVOID)-1) {
547608
if (!ReflectiveMapDll(hModule)) {
548609
RtlRaiseStatus(STATUS_NOT_SUPPORTED);
@@ -553,10 +614,13 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
553614
}
554615

555616
return FALSE;
617+
#endif
556618
}
557619

558620
return TRUE;
559621
}
560622
#else
561-
const NTSTATUS Initializer = Initialize();
623+
#ifdef _HAS_AUTO_INITIALIZE
624+
const NTSTATUS Initializer = MmInitialize();
625+
#endif
562626
#endif

MemoryModule/Initialize.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
NTSTATUS NTAPI MmInitialize();
4+
NTSTATUS NTAPI MmCleanup();
5+
6+
//
7+
// This function is available only if the MMPP is compiled as a DLL.
8+
//
9+
BOOL WINAPI ReflectiveMapDll(HMODULE hModule);

MemoryModule/LoadDllMemoryApi.h

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,37 @@
33

44
typedef HMODULE HMEMORYMODULE;
55
#include "Loader.h"
6+
#include "Initialize.h"
67

78
#define MemoryModuleToModule(_hMemoryModule_) (_hMemoryModule_)
89

910
#ifndef NT_SUCCESS
1011
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
1112
#endif
1213

13-
HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress);
14-
15-
HMEMORYMODULE WINAPI LoadLibraryMemoryExA(
16-
_In_ PVOID BufferAddress,
17-
_In_ size_t Reserved,
18-
_In_opt_ LPCSTR DllBaseName,
19-
_In_opt_ LPCSTR DllFullName,
20-
_In_ DWORD Flags
21-
);
22-
23-
HMEMORYMODULE WINAPI LoadLibraryMemoryExW(
24-
_In_ PVOID BufferAddress,
25-
_In_ size_t Reserved,
26-
_In_opt_ LPCWSTR DllBaseName,
27-
_In_opt_ LPCWSTR DllFullName,
28-
_In_ DWORD Flags
29-
);
30-
31-
BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule);
14+
extern "C" {
15+
16+
HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress);
17+
18+
HMEMORYMODULE WINAPI LoadLibraryMemoryExA(
19+
_In_ PVOID BufferAddress,
20+
_In_ size_t Reserved,
21+
_In_opt_ LPCSTR DllBaseName,
22+
_In_opt_ LPCSTR DllFullName,
23+
_In_ DWORD Flags
24+
);
25+
26+
HMEMORYMODULE WINAPI LoadLibraryMemoryExW(
27+
_In_ PVOID BufferAddress,
28+
_In_ size_t Reserved,
29+
_In_opt_ LPCWSTR DllBaseName,
30+
_In_opt_ LPCWSTR DllFullName,
31+
_In_ DWORD Flags
32+
);
33+
34+
BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule);
35+
36+
}
3237

3338
#define NtLoadDllMemory LdrLoadDllMemory
3439
#define NtLoadDllMemoryExA LdrLoadDllMemoryExA

MemoryModule/Loader.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,14 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW(
6161
__try {
6262
*BaseAddress = nullptr;
6363
if (LdrEntry)*LdrEntry = nullptr;
64-
if (!RtlIsValidImageBuffer(BufferAddress, &BufferSize) && !(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK))status = STATUS_INVALID_IMAGE_FORMAT;
64+
65+
if (!RtlIsValidImageBuffer(BufferAddress, &BufferSize) && !(dwFlags & LOAD_FLAGS_PASS_IMAGE_CHECK)) {
66+
status = STATUS_INVALID_IMAGE_FORMAT;
67+
}
68+
69+
if (MmpGlobalDataPtr == nullptr) {
70+
status = STATUS_INVALID_PARAMETER;
71+
}
6572
}
6673
__except (EXCEPTION_EXECUTE_HANDLER) {
6774
status = GetExceptionCode();
@@ -229,6 +236,11 @@ NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) {
229236
break;
230237
}
231238

239+
if (MmpGlobalDataPtr == nullptr) {
240+
status = STATUS_INVALID_PARAMETER;
241+
break;
242+
}
243+
232244
//Mapping dll failed
233245
if (!module->MappedDll) {
234246
module->underUnload = true;

MemoryModule/Loader.h

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
#define MEMORY_FEATURE_LDRP_RELEASE_TLS_ENTRY 0x00000040
1010
#define MEMORY_FEATURE_ALL 0x0000007f
1111

12-
//Get the implementation of the currently running operating system.
13-
NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures);
14-
1512

1613
/*
1714
LdrLoadDllMemoryEx dwFlags
@@ -47,21 +44,24 @@ NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures);
4744
//Hook for dotnet dlls
4845
#define LOAD_FLAGS_HOOK_DOT_NET 0x00000010
4946

47+
extern "C" {
5048

51-
NTSTATUS NTAPI LdrLoadDllMemoryExW(
52-
_Out_ HMEMORYMODULE* BaseAddress, // Output module base address
53-
_Out_opt_ PVOID* LdrEntry, // Receive a pointer to the LDR node of the module
54-
_In_ DWORD dwFlags, // Flags
55-
_In_ LPVOID BufferAddress, // Pointer to the dll file data buffer
56-
_In_ size_t Reserved, // Reserved parameter, must be 0
57-
_In_opt_ LPCWSTR DllName, // Module file name
58-
_In_opt_ LPCWSTR DllFullName // Module file full path
59-
);
49+
//Get the implementation of the currently running operating system.
50+
NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures);
51+
52+
NTSTATUS NTAPI LdrLoadDllMemoryExW(
53+
_Out_ HMEMORYMODULE* BaseAddress, // Output module base address
54+
_Out_opt_ PVOID* LdrEntry, // Receive a pointer to the LDR node of the module
55+
_In_ DWORD dwFlags, // Flags
56+
_In_ LPVOID BufferAddress, // Pointer to the dll file data buffer
57+
_In_ size_t Reserved, // Reserved parameter, must be 0
58+
_In_opt_ LPCWSTR DllName, // Module file name
59+
_In_opt_ LPCWSTR DllFullName // Module file full path
60+
);
6061

61-
//Unload modules previously loaded from memory
62-
NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress);
62+
//Unload modules previously loaded from memory
63+
NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress);
6364

64-
extern "C" {
6565
__declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread(
6666
_In_ HMEMORYMODULE BaseAddress,
6767
_In_ DWORD dwExitCode

0 commit comments

Comments
 (0)