|
1 | 1 | #include "stdafx.h" |
2 | 2 |
|
3 | 3 | #if (MMPP_USE_TLS) |
| 4 | +#include "MmpTlsp.h" |
| 5 | +#include "MmpTlsFiber.h" |
| 6 | + |
4 | 7 | #include <cassert> |
5 | 8 | #include <algorithm> |
6 | 9 | #include <3rdparty/Detours/detours.h> |
7 | 10 |
|
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; |
64 | 11 |
|
65 | 12 | PVOID NTAPI MmpQuerySystemInformation( |
66 | 13 | _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, |
@@ -217,6 +164,8 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { |
217 | 164 | record->TlspMmpBlock = (PVOID*)MmpAllocateTlsp(); |
218 | 165 | record->UniqueThread = NtCurrentThreadId(); |
219 | 166 | if (record->TlspMmpBlock) { |
| 167 | + record->TlspMmpBlock = ((PTLS_VECTOR)record->TlspMmpBlock)->ModuleTlsData; |
| 168 | + |
220 | 169 | auto size = CONTAINING_RECORD(record->TlspLdrBlock, TLS_VECTOR, ModuleTlsData)->Length; |
221 | 170 | if ((HANDLE)(ULONG_PTR)size != NtCurrentThreadId()) { |
222 | 171 | RtlCopyMemory( |
@@ -335,48 +284,27 @@ VOID NTAPI HookLdrShutdownThread(VOID) { |
335 | 284 |
|
336 | 285 | record = MmpFindTlspRecordLockHeld(); |
337 | 286 | if (record) { |
338 | | - |
339 | | - // |
340 | | - // Restore tlsp |
341 | | - // |
342 | | - |
343 | | - NtCurrentTeb()->ThreadLocalStoragePointer = record->TlspLdrBlock; |
344 | 287 | RemoveEntryList(&record->InMmpThreadLocalStoragePointer); |
345 | | - |
346 | 288 | --MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount; |
347 | 289 | } |
348 | 290 |
|
349 | 291 | assert(0 < (int)MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount); |
350 | 292 |
|
351 | 293 | LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); |
352 | 294 |
|
353 | | - // |
354 | | - // Free MemoryModule Tls data |
355 | | - // |
356 | | - RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); |
357 | | - |
358 | 295 | if (record) { |
359 | | - auto TlspMmpBlock = (PVOID*)record->TlspMmpBlock; |
360 | | - entry = MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink; |
361 | | - while (entry != &MmpGlobalDataPtr->MmpTls->MmpTlsList) { |
362 | | - |
363 | | - auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks); |
364 | | - RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock[p->TlsDirectory.Characteristics]); |
365 | | - |
366 | | - entry = entry->Flink; |
367 | | - } |
| 296 | + // |
| 297 | + // Free MemoryModule Tls data after terminated |
| 298 | + // |
368 | 299 |
|
369 | | - RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock); |
370 | | - RtlFreeHeap(RtlProcessHeap(), 0, record); |
| 300 | + MmpQueuePostponedTls(record); |
371 | 301 | } |
372 | 302 | else { |
373 | 303 | if (MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTls->MmpTlsList) { |
374 | 304 | assert(NtCurrentTeb()->ThreadLocalStoragePointer == nullptr); |
375 | 305 | } |
376 | 306 | } |
377 | 307 |
|
378 | | - RtlReleaseSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock); |
379 | | - |
380 | 308 | // |
381 | 309 | // Call the original function |
382 | 310 | // |
@@ -405,9 +333,12 @@ BOOL NTAPI PreHookNtSetInformationProcess() { |
405 | 333 | for (DWORD i = 0; i < CurrentThreadCount; ++i) { |
406 | 334 | auto& current = ProcessTlsInformation->ThreadData[i]; |
407 | 335 | current.TlsVector = (PVOID*)MmpAllocateTlsp(); |
408 | | - if (!current.TlsVector) { |
| 336 | + if (current.TlsVector) { |
| 337 | + current.TlsVector = ((PTLS_VECTOR)current.TlsVector)->ModuleTlsData; |
| 338 | + } |
| 339 | + else { |
409 | 340 | for (DWORD j = 0; j < i; ++j) { |
410 | | - RtlFreeHeap(RtlProcessHeap(), 0, ProcessTlsInformation->ThreadData[j].TlsVector); |
| 341 | + RtlFreeHeap(RtlProcessHeap(), 0, CONTAINING_RECORD(ProcessTlsInformation->ThreadData[j].TlsVector, TLS_VECTOR, TLS_VECTOR::ModuleTlsData)); |
411 | 342 | } |
412 | 343 |
|
413 | 344 | success = FALSE; |
@@ -848,6 +779,8 @@ BOOL NTAPI MmpTlsInitialize() { |
848 | 779 | DetourAttach((PVOID*)&MmpGlobalDataPtr->MmpTls->Hooks.OriginRtlUserThreadStart, HookRtlUserThreadStart); |
849 | 780 | DetourTransactionCommit(); |
850 | 781 |
|
| 782 | + MmpTlsFiberInitialize(); |
| 783 | + |
851 | 784 | return TRUE; |
852 | 785 | } |
853 | 786 |
|
|
0 commit comments