11#include " stdafx.h"
22
33#if (MMPP_USE_TLS)
4+ #include " MmpTlsp.h"
5+ #include " MmpTlsFiber.h"
6+
47#include < cassert>
58#include < algorithm>
69#include < 3rdparty/Detours/detours.h>
710
8- //
9- // ThreadLocalStoragePointer Tls indexs
10- // [0, MMP_START_TLS_INDEX) Reserved for ntdll loader
11- // [MMP_START_TLS_INDEX, MMP_MAXIMUM_TLS_INDEX) Reserved for MemoryModule
12- //
13-
14- #define MMP_START_TLS_INDEX 0x80 // 128
15-
16- #define MMP_MAXIMUM_TLS_INDEX 0x100 // 256
17-
18- #define MMP_TLSP_INDEX_BUFFER_SIZE (MMP_MAXIMUM_TLS_INDEX / 8 ) // 32
19-
20- #if (((MMP_START_TLS_INDEX | MMP_MAXIMUM_TLS_INDEX) & 7) || (MMP_START_TLS_INDEX >= MMP_MAXIMUM_TLS_INDEX))
21- #error "MMP_START_TLS_INDEX must be smaller than MMP_MAXIMUM_TLS_INDEX, and both are 8-bit aligned."
22- #endif
23-
24- #define MmpAllocateTlsp () (RtlAllocateHeap(\
25- RtlProcessHeap (),\
26- HEAP_ZERO_MEMORY,\
27- sizeof(PVOID)* MMP_MAXIMUM_TLS_INDEX\
28- ))
29-
30- typedef struct _TLS_VECTOR {
31- union
32- {
33- ULONG Length;
34- HANDLE ThreadId;
35- };
36-
37- struct _TLS_VECTOR * PreviousDeferredTlsVector;
38- PVOID ModuleTlsData[ANYSIZE_ARRAY];
39- } TLS_VECTOR, * PTLS_VECTOR;
40-
41- typedef struct _TLS_ENTRY {
42- LIST_ENTRY TlsEntryLinks;
43- IMAGE_TLS_DIRECTORY TlsDirectory;
44- PLDR_DATA_TABLE_ENTRY ModuleEntry;
45- } TLS_ENTRY, * PTLS_ENTRY;
46-
47- typedef struct _MMP_TLSP_RECORD {
48-
49- LIST_ENTRY InMmpThreadLocalStoragePointer;
50-
51- HANDLE UniqueThread;
52-
53- // PEB->ThreadLocalStoragePointer allocated by ntdll!Ldr
54- PVOID* TlspLdrBlock;
55-
56- // PEB->ThreadLocalStoragePointer allocated by MemoryModulePP
57- PVOID* TlspMmpBlock;
58- }MMP_TLSP_RECORD, * PMMP_TLSP_RECORD;
59-
60- typedef struct _THREAD_CONTEXT {
61- PTHREAD_START_ROUTINE ThreadStartRoutine;
62- LPVOID ThreadParameter;
63- }THREAD_CONTEXT, * PTHREAD_CONTEXT;
6411
6512PVOID NTAPI MmpQuerySystemInformation (
6613 _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
@@ -217,6 +164,8 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) {
217164 record->TlspMmpBlock = (PVOID*)MmpAllocateTlsp ();
218165 record->UniqueThread = NtCurrentThreadId ();
219166 if (record->TlspMmpBlock ) {
167+ record->TlspMmpBlock = ((PTLS_VECTOR)record->TlspMmpBlock )->ModuleTlsData ;
168+
220169 auto size = CONTAINING_RECORD (record->TlspLdrBlock , TLS_VECTOR, ModuleTlsData)->Length ;
221170 if ((HANDLE)(ULONG_PTR)size != NtCurrentThreadId ()) {
222171 RtlCopyMemory (
@@ -327,6 +276,7 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
327276
328277 PLIST_ENTRY entry;
329278 PMMP_TLSP_RECORD record = nullptr ;
279+ BOOL postpone = IsThreadAFiber ();
330280
331281 //
332282 // Find our tlsp record
@@ -335,48 +285,54 @@ VOID NTAPI HookLdrShutdownThread(VOID) {
335285
336286 record = MmpFindTlspRecordLockHeld ();
337287 if (record) {
338-
339- //
340- // Restore tlsp
341- //
342-
343- NtCurrentTeb ()->ThreadLocalStoragePointer = record->TlspLdrBlock ;
344288 RemoveEntryList (&record->InMmpThreadLocalStoragePointer );
345-
346289 --MmpGlobalDataPtr->MmpTls ->MmpActiveThreadCount ;
347290 }
348291
349292 assert (0 < (int )MmpGlobalDataPtr->MmpTls ->MmpActiveThreadCount );
350293
351294 LeaveCriticalSection (&MmpGlobalDataPtr->MmpTls ->MmpTlspLock );
352295
353- //
354- // Free MemoryModule Tls data
355- //
356- RtlAcquireSRWLockExclusive (&MmpGlobalDataPtr->MmpTls ->MmpTlsListLock );
357-
358296 if (record) {
359- auto TlspMmpBlock = (PVOID*)record->TlspMmpBlock ;
360- entry = MmpGlobalDataPtr->MmpTls ->MmpTlsList .Flink ;
361- while (entry != &MmpGlobalDataPtr->MmpTls ->MmpTlsList ) {
297+ if (postpone) {
298+
299+ //
300+ // Free MemoryModule Tls data after terminated
301+ //
302+
303+ MmpQueuePostponedTls (record);
304+ }
305+ else {
362306
363- auto p = CONTAINING_RECORD (entry, TLS_ENTRY, TlsEntryLinks);
364- RtlFreeHeap (RtlProcessHeap (), 0 , TlspMmpBlock[p->TlsDirectory .Characteristics ]);
307+ //
308+ // Free MemoryModule Tls data
309+ //
365310
366- entry = entry->Flink ;
367- }
311+ RtlAcquireSRWLockExclusive (&MmpGlobalDataPtr->MmpTls ->MmpTlsListLock );
312+
313+ auto TlspMmpBlock = (PVOID*)record->TlspMmpBlock ;
314+ entry = MmpGlobalDataPtr->MmpTls ->MmpTlsList .Flink ;
315+ while (entry != &MmpGlobalDataPtr->MmpTls ->MmpTlsList ) {
316+
317+ auto p = CONTAINING_RECORD (entry, TLS_ENTRY, TlsEntryLinks);
318+ RtlFreeHeap (RtlProcessHeap (), 0 , TlspMmpBlock[p->TlsDirectory .Characteristics ]);
319+ TlspMmpBlock[p->TlsDirectory .Characteristics ] = nullptr ;
368320
369- RtlFreeHeap (RtlProcessHeap (), 0 , TlspMmpBlock);
370- RtlFreeHeap (RtlProcessHeap (), 0 , record);
321+ entry = entry->Flink ;
322+ }
323+
324+ RtlFreeHeap (RtlProcessHeap (), 0 , CONTAINING_RECORD (record->TlspLdrBlock , TLS_VECTOR, TLS_VECTOR::ModuleTlsData));
325+ RtlFreeHeap (RtlProcessHeap (), 0 , record);
326+
327+ RtlReleaseSRWLockExclusive (&MmpGlobalDataPtr->MmpTls ->MmpTlsListLock );
328+ }
371329 }
372330 else {
373331 if (MmpGlobalDataPtr->MmpTls ->MmpTlsList .Flink != &MmpGlobalDataPtr->MmpTls ->MmpTlsList ) {
374332 assert (NtCurrentTeb ()->ThreadLocalStoragePointer == nullptr );
375333 }
376334 }
377335
378- RtlReleaseSRWLockExclusive (&MmpGlobalDataPtr->MmpTls ->MmpTlsListLock );
379-
380336 //
381337 // Call the original function
382338 //
@@ -405,9 +361,12 @@ BOOL NTAPI PreHookNtSetInformationProcess() {
405361 for (DWORD i = 0 ; i < CurrentThreadCount; ++i) {
406362 auto & current = ProcessTlsInformation->ThreadData [i];
407363 current.TlsVector = (PVOID*)MmpAllocateTlsp ();
408- if (!current.TlsVector ) {
364+ if (current.TlsVector ) {
365+ current.TlsVector = ((PTLS_VECTOR)current.TlsVector )->ModuleTlsData ;
366+ }
367+ else {
409368 for (DWORD j = 0 ; j < i; ++j) {
410- RtlFreeHeap (RtlProcessHeap (), 0 , ProcessTlsInformation->ThreadData [j].TlsVector );
369+ RtlFreeHeap (RtlProcessHeap (), 0 , CONTAINING_RECORD ( ProcessTlsInformation->ThreadData [j].TlsVector , TLS_VECTOR, TLS_VECTOR::ModuleTlsData) );
411370 }
412371
413372 success = FALSE ;
@@ -848,6 +807,8 @@ BOOL NTAPI MmpTlsInitialize() {
848807 DetourAttach ((PVOID*)&MmpGlobalDataPtr->MmpTls ->Hooks .OriginRtlUserThreadStart , HookRtlUserThreadStart);
849808 DetourTransactionCommit ();
850809
810+ MmpTlsFiberInitialize ();
811+
851812 return TRUE ;
852813}
853814
0 commit comments