mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
142 lines
3.4 KiB
C++
142 lines
3.4 KiB
C++
#include "stdafx.h"
|
|
#include "MmpTlsp.h"
|
|
#include "MmpTlsFiber.h"
|
|
|
|
#include <vector>
|
|
#include <cassert>
|
|
|
|
typedef struct _MMP_POSTPONED_TLS {
|
|
|
|
HANDLE hThread;
|
|
PMMP_TLSP_RECORD lpTlsRecord;
|
|
PTLS_VECTOR lpOldTlsVector;
|
|
|
|
}MMP_POSTPONED_TLS, * PMMP_POSTPONED_TLS;
|
|
|
|
std::vector<MMP_POSTPONED_TLS>* MmpPostponedTlsList;
|
|
|
|
HANDLE MmpPostponedTlsEvent;
|
|
CRITICAL_SECTION MmpPostponedTlsLock;
|
|
|
|
DWORD WINAPI MmpReleasePostponedTlsWorker(PVOID) {
|
|
|
|
DWORD code;
|
|
DWORD waitTime = INFINITE;
|
|
|
|
while (true) {
|
|
WaitForSingleObject(MmpPostponedTlsEvent, waitTime);
|
|
|
|
EnterCriticalSection(&MmpPostponedTlsLock);
|
|
|
|
if (MmpPostponedTlsList) {
|
|
auto iter = MmpPostponedTlsList->begin();
|
|
|
|
while (iter != MmpPostponedTlsList->end()) {
|
|
GetExitCodeThread(iter->hThread, &code);
|
|
|
|
if (code == STILL_ACTIVE) {
|
|
++iter;
|
|
}
|
|
else {
|
|
|
|
RtlAcquireSRWLockExclusive(&MmpGlobalDataPtr->MmpTls->MmpTlsListLock);
|
|
|
|
auto TlspMmpBlock = (PVOID*)iter->lpOldTlsVector->ModuleTlsData;
|
|
auto entry = MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink;
|
|
while (entry != &MmpGlobalDataPtr->MmpTls->MmpTlsList) {
|
|
|
|
auto p = CONTAINING_RECORD(entry, TLS_ENTRY, TlsEntryLinks);
|
|
RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock[p->TlsDirectory.Characteristics]);
|
|
|
|
entry = entry->Flink;
|
|
}
|
|
|
|
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(iter->hThread);
|
|
iter = MmpPostponedTlsList->erase(iter);
|
|
}
|
|
|
|
}
|
|
|
|
waitTime = MmpPostponedTlsList->empty() ? INFINITE : 1000;
|
|
}
|
|
else {
|
|
LeaveCriticalSection(&MmpPostponedTlsLock);
|
|
break;
|
|
}
|
|
|
|
LeaveCriticalSection(&MmpPostponedTlsLock);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
DWORD WINAPI MmpReleasePostponedTlsWorker_Wrap(PVOID) {
|
|
__try {
|
|
return MmpReleasePostponedTlsWorker(nullptr);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
VOID WINAPI MmpQueuePostponedTls(PMMP_TLSP_RECORD record) {
|
|
MMP_POSTPONED_TLS item;
|
|
|
|
item.hThread = OpenThread(
|
|
THREAD_QUERY_INFORMATION,
|
|
FALSE,
|
|
(DWORD)(ULONG_PTR)NtCurrentThreadId()
|
|
);
|
|
|
|
item.lpOldTlsVector = MmpAllocateTlsp();
|
|
assert(item.lpOldTlsVector);
|
|
|
|
item.lpTlsRecord = record;
|
|
|
|
RtlCopyMemory(
|
|
item.lpOldTlsVector->ModuleTlsData,
|
|
record->TlspMmpBlock,
|
|
sizeof(PVOID) * MMP_MAXIMUM_TLS_INDEX
|
|
);
|
|
|
|
EnterCriticalSection(&MmpPostponedTlsLock);
|
|
|
|
if (MmpPostponedTlsList) {
|
|
MmpPostponedTlsList->push_back(item);
|
|
SetEvent(MmpPostponedTlsEvent);
|
|
}
|
|
else {
|
|
RtlFreeHeap(RtlProcessHeap(), 0, item.lpOldTlsVector);
|
|
}
|
|
|
|
LeaveCriticalSection(&MmpPostponedTlsLock);
|
|
}
|
|
|
|
VOID OnExit() {
|
|
EnterCriticalSection(&MmpPostponedTlsLock);
|
|
|
|
MmpPostponedTlsList->~vector();
|
|
HeapFree(RtlProcessHeap(), 0, MmpPostponedTlsList);
|
|
MmpPostponedTlsList = nullptr;
|
|
|
|
CloseHandle(MmpPostponedTlsEvent);
|
|
|
|
LeaveCriticalSection(&MmpPostponedTlsLock);
|
|
}
|
|
|
|
VOID MmpTlsFiberInitialize() {
|
|
InitializeCriticalSection(&MmpPostponedTlsLock);
|
|
MmpPostponedTlsEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
|
MmpPostponedTlsList = new(HeapAlloc(GetProcessHeap(), 0, sizeof(std::vector<MMP_POSTPONED_TLS>))) std::vector<MMP_POSTPONED_TLS>();
|
|
|
|
atexit(OnExit);
|
|
|
|
CreateThread(nullptr, 0, MmpReleasePostponedTlsWorker_Wrap, nullptr, 0, nullptr);
|
|
}
|