mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
554 lines
16 KiB
C
554 lines
16 KiB
C
//#include <Windows.h>
|
|
//#include "../MemoryModule/NativeFunctionsInternal.h"
|
|
//
|
|
//typedef struct _THREAD_TLS_INFORMATION {
|
|
// ULONG Flags;
|
|
// union {
|
|
// PVOID* TlsVector;
|
|
// PVOID TlsModulePointer;
|
|
// };
|
|
// HANDLE ThreadId;
|
|
//} THREAD_TLS_INFORMATION, * PTHREAD_TLS_INFORMATION;
|
|
//
|
|
//typedef enum _PROCESS_TLS_INFORMATION_TYPE {
|
|
// ProcessTlsReplaceIndex,
|
|
// ProcessTlsReplaceVector,
|
|
// MaxProcessTlsOperation
|
|
//} PROCESS_TLS_INFORMATION_TYPE, * PPROCESS_TLS_INFORMATION_TYPE;
|
|
//
|
|
//typedef struct _PROCESS_TLS_INFORMATION {
|
|
// ULONG Reserved; // Reserved bitmask
|
|
// ULONG OperationType;
|
|
// ULONG ThreadDataCount;
|
|
// union {
|
|
// ULONG TlsIndex;
|
|
// ULONG TlsVectorLength;
|
|
// };
|
|
// THREAD_TLS_INFORMATION ThreadData[ANYSIZE_ARRAY];
|
|
//} PROCESS_TLS_INFORMATION, * PPROCESS_TLS_INFORMATION;
|
|
//
|
|
//// Need struct name
|
|
//typedef struct _TLS_VECTOR {
|
|
// union {
|
|
// ULONG Length;
|
|
// HANDLE ThreadId;
|
|
// };
|
|
//
|
|
// struct _TLS_VECTOR* PreviousDeferredTlsVector;
|
|
// PVOID ModuleTlsData[ANYSIZE_ARRAY];
|
|
//} TLS_VECTOR, * PTLS_VECTOR;
|
|
//
|
|
//// Need struct name
|
|
//typedef struct _TLS_RECLAIM_TABLE_ENTRY {
|
|
// PTLS_VECTOR TlsVector;
|
|
// RTL_SRWLOCK Lock;
|
|
//} TLS_RECLAIM_TABLE_ENTRY, * PTLS_RECLAIM_TABLE_ENTRY;
|
|
//
|
|
//// Need struct name
|
|
//typedef struct _TLS_ENTRY {
|
|
// LIST_ENTRY TlsEntryLinks;
|
|
// IMAGE_TLS_DIRECTORY TlsDirectory;
|
|
// PLDR_DATA_TABLE_ENTRY ModuleEntry;
|
|
//} TLS_ENTRY, * PTLS_ENTRY;
|
|
//
|
|
////0x10 bytes (sizeof)
|
|
//typedef struct _RTL_BITMAP {
|
|
// ULONG SizeOfBitMap; //0x0
|
|
// ULONG* Buffer; //0x8
|
|
//}RTL_BITMAP, * PRTL_BITMAP;
|
|
//
|
|
//VOID RtlClearBit(
|
|
// PRTL_BITMAP BitMapHeader,
|
|
// ULONG BitNumber
|
|
//);
|
|
//
|
|
//VOID RtlInitializeBitMap(
|
|
// PRTL_BITMAP BitMapHeader,
|
|
// PULONG BitMapBuffer,
|
|
// ULONG SizeOfBitMap
|
|
//);
|
|
//
|
|
//ULONG RtlFindClearBitsAndSet(
|
|
// PRTL_BITMAP BitMapHeader,
|
|
// ULONG NumberToFind,
|
|
// ULONG HintIndex
|
|
//);
|
|
//
|
|
//VOID RtlClearBits(
|
|
// PRTL_BITMAP BitMapHeader,
|
|
// ULONG StartingIndex,
|
|
// ULONG NumberToClear
|
|
//);
|
|
//
|
|
//VOID RtlSetBit(
|
|
// PRTL_BITMAP BitMapHeader,
|
|
// ULONG BitNumber
|
|
//);
|
|
//
|
|
//BOOLEAN RemoveEntryList(
|
|
// PLIST_ENTRY Entry
|
|
//);
|
|
//
|
|
//VOID NTAPI RtlAcquireSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock);
|
|
//VOID NTAPI RtlReleaseSRWLockExclusive(IN OUT PRTL_SRWLOCK SRWLock);
|
|
//
|
|
//NTSTATUS NTAPI NtSetInformationProcess(
|
|
// IN HANDLE ProcessHandle,
|
|
// IN ULONG ProcessInformationClass,
|
|
// IN PVOID ProcessInformation,
|
|
// IN ULONG ProcessInformationLength);
|
|
//
|
|
//#define ProcessTlsInformation ProcessResourceManagement
|
|
//
|
|
//PUCHAR NtdllBaseTag = 0;
|
|
//ULONG LdrpActiveThreadCount = 0;
|
|
//ULONG LdrpPotentialTlsLeaks = 0;
|
|
//RTL_BITMAP LdrpTlsBitmap;
|
|
//LIST_ENTRY LdrpTlsList;
|
|
//
|
|
//TLS_RECLAIM_TABLE_ENTRY LdrpDelayedTlsReclaimTable[16];
|
|
//
|
|
//ULONG LdrpStaticTlsBitmapVector[4];
|
|
//ULONG LdrpActualBitmapSize = 0;
|
|
//
|
|
//
|
|
//VOID LdrpInit() {
|
|
// RtlCopyMemory(&LdrpTlsBitmap, NtCurrentPeb()->TlsBitmap, sizeof(RTL_BITMAP));
|
|
// PROCESS_TLS_INFORMATION pti;
|
|
//
|
|
//}
|
|
//
|
|
//VOID LdrpReleaseTlsIndex(ULONG TlsIndex) {
|
|
// RtlClearBit(&LdrpTlsBitmap, TlsIndex);
|
|
//}
|
|
//
|
|
//#define LDRP_BITMAP_INCREMENT (0x27 - sizeof( PVOID ))
|
|
//
|
|
//NTSTATUS LdrpAcquireTlsIndex(PULONG TlsIndex, PBOOLEAN AllocatedBitmap) {
|
|
// ULONG Length;
|
|
// ULONG Index;
|
|
// PULONG NewBitmapBuffer;
|
|
//
|
|
// Length = LdrpTlsBitmap.SizeOfBitMap;
|
|
//
|
|
// if (Length == 0) {
|
|
// //
|
|
// // If we're the first caller, then we shall need to be initializing the
|
|
// // bitmap.
|
|
// //
|
|
// // This implies that we don't need to expand as by definition, there
|
|
// // shall exist space for ourselves at the start of the bitmap now.
|
|
// //
|
|
// RtlInitializeBitMap(&LdrpTlsBitmap, LdrpStaticTlsBitmapVector, 4);
|
|
// LdrpActualBitmapSize = 1;
|
|
// }
|
|
// else {
|
|
// Index = RtlFindClearBitsAndSet(&LdrpTlsBitmap, 1, 0);
|
|
//
|
|
// //
|
|
// // If we found space in the existing bitmap then there is no reason to
|
|
// // expand buffers, so we'll just return with the existing data.
|
|
// //
|
|
// if (Index != 0xFFFFFFFF) {
|
|
// *TlsIndex = Index;
|
|
// *AllocatedBitmap = FALSE;
|
|
// return STATUS_SUCCESS;
|
|
// }
|
|
//
|
|
// //
|
|
// // Check if we need to grow the bitmap itself or if the bitmap still
|
|
// // has space.
|
|
// //
|
|
// if (((LdrpTlsBitmap.SizeOfBitMap + LDRP_BITMAP_INCREMENT) >> 5) > LdrpActualBitmapSize) {
|
|
// //
|
|
// // We'll need to grow it. Let's go do so now.
|
|
// //
|
|
//
|
|
// //
|
|
// // BUG: We set the new size before checking the allocation. If we
|
|
// // fail, then we leave the TLS variables in an inconsistant state.
|
|
// //
|
|
// LdrpActualBitmapSize = (Length + LDRP_BITMAP_INCREMENT) >> 5;
|
|
// NewBitmapBuffer = (PULONG)RtlAllocateHeap(GetProcessHeap(), (ULONG_PTR)((PUCHAR)NtdllBaseTag + 0x000C0000), LdrpActualBitmapSize);
|
|
// if (!NewBitmapBuffer) return STATUS_NO_MEMORY;
|
|
//
|
|
// //
|
|
// // Copy the contents of the previous buffer into the new one.
|
|
// //
|
|
// RtlCopyMemory(NewBitmapBuffer, LdrpTlsBitmap.Buffer, Length + 7);
|
|
//
|
|
// //
|
|
// // Free the old buffer if it wasn't the initial static buffer.
|
|
// //
|
|
// if (LdrpTlsBitmap.Buffer != LdrpStaticTlsBitmapVector) {
|
|
// RtlFreeHeap(GetProcessHeap(), 0, LdrpTlsBitmap.Buffer);
|
|
// }
|
|
//
|
|
// //
|
|
// // Reinitialize the bitmap as we've changed the buffer pointer.
|
|
// //
|
|
// RtlInitializeBitMap(&LdrpTlsBitmap, NewBitmapBuffer, Length + 4);
|
|
// }
|
|
// else {
|
|
// LdrpTlsBitmap.SizeOfBitMap += 4;
|
|
// }
|
|
// }
|
|
//
|
|
// RtlClearBits(&LdrpTlsBitmap, Length + 1, 3);
|
|
// RtlSetBit(&LdrpTlsBitmap, Length);
|
|
//
|
|
// *TlsIndex = Index;
|
|
// *AllocatedBitmap = TRUE;
|
|
//
|
|
// return STATUS_SUCCESS;
|
|
//}
|
|
//
|
|
//NTSTATUS LdrpAllocateTlsEntry(PIMAGE_TLS_DIRECTORY TlsDirectory, PLDR_DATA_TABLE_ENTRY ModuleEntry, PULONG TlsIndex, PBOOLEAN AllocatedBitmap, PTLS_ENTRY* TlsEntry) {
|
|
//
|
|
// PTLS_ENTRY Entry = nullptr;
|
|
// NTSTATUS Status;
|
|
//
|
|
// __try {
|
|
// Entry = (PTLS_ENTRY)RtlAllocateHeap(GetProcessHeap(), (ULONG_PTR)((PUCHAR)NtdllBaseTag + 0x000C0000), sizeof(TLS_ENTRY));
|
|
// if (!Entry) return STATUS_NO_MEMORY;
|
|
// Status = STATUS_SUCCESS;
|
|
// RtlCopyMemory(&Entry->TlsDirectory, TlsDirectory, sizeof(IMAGE_TLS_DIRECTORY));
|
|
// }
|
|
// __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
// //
|
|
// // Also print string and complain.
|
|
// //
|
|
// Status = GetExceptionCode();
|
|
// }
|
|
//
|
|
// if (!NT_SUCCESS(Status)) {
|
|
// RtlFreeHeap(GetProcessHeap(), 0, Entry);
|
|
// return Status;
|
|
// }
|
|
//
|
|
// //
|
|
// // Validate that the TLS directory entry is sane.
|
|
// //
|
|
// if (Entry->TlsDirectory.StartAddressOfRawData < Entry->TlsDirectory.EndAddressOfRawData) {
|
|
// RtlFreeHeap(GetProcessHeap(), 0, Entry);
|
|
// return STATUS_INVALID_IMAGE_FORMAT;
|
|
// }
|
|
// Entry->ModuleEntry = ModuleEntry;
|
|
//
|
|
// //
|
|
// // Insert the entry into our list.
|
|
// //
|
|
//
|
|
// InsertTailList(&LdrpTlsList, &Entry->TlsEntryLinks);
|
|
// if (AllocatedBitmap) {
|
|
// Status = LdrpAcquireTlsIndex(TlsIndex, AllocatedBitmap);
|
|
// if (!NT_SUCCESS(Status)) {
|
|
// //
|
|
// // BUG: We don't remove the entry from LdrpTlsList
|
|
// //
|
|
// RtlFreeHeap(GetProcessHeap(), 0, Entry);
|
|
// return Status;
|
|
// }
|
|
// }
|
|
// else {
|
|
// *TlsIndex += 1;
|
|
// }
|
|
//
|
|
// //
|
|
// // We reuse the 'Characteristics' field for the real TLS index.
|
|
// //
|
|
// Entry->TlsDirectory.Characteristics = *TlsIndex;
|
|
// __try {
|
|
// *(PULONG)Entry->TlsDirectory.AddressOfIndex = *TlsIndex;
|
|
// }
|
|
// __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
// Status = GetExceptionCode();
|
|
// }
|
|
// if (!NT_SUCCESS(Status)) {
|
|
// if (AllocatedBitmap) {
|
|
// LdrpReleaseTlsIndex(*TlsIndex);
|
|
// if (*AllocatedBitmap) LdrpTlsBitmap.SizeOfBitMap -= 4;
|
|
// }
|
|
//
|
|
// //
|
|
// // BUG: We don't remove the entry from LdrpTlsList
|
|
// //
|
|
// RtlFreeHeap(GetProcessHeap(), 0, Entry);
|
|
// return Status;
|
|
// }
|
|
//
|
|
// if (TlsEntry) *TlsEntry = Entry;
|
|
// return STATUS_SUCCESS;
|
|
//}
|
|
//
|
|
//PTLS_ENTRY __fastcall LdrpFindTlsEntry(PLDR_DATA_TABLE_ENTRY ModuleEntry) {
|
|
// PTLS_ENTRY TlsEntry;
|
|
// PLIST_ENTRY ListHead;
|
|
//
|
|
// ListHead = &LdrpTlsList;
|
|
//
|
|
// for (TlsEntry = CONTAINING_RECORD(LdrpTlsList.Flink, TLS_ENTRY, TlsEntryLinks);
|
|
// &TlsEntry->TlsEntryLinks != ListHead;
|
|
// TlsEntry = CONTAINING_RECORD(TlsEntry->TlsEntryLinks.Flink, TLS_ENTRY, TlsEntryLinks)) {
|
|
//
|
|
// if (TlsEntry->ModuleEntry == ModuleEntry) return TlsEntry;
|
|
// }
|
|
//
|
|
// return 0;
|
|
//}
|
|
//
|
|
//NTSTATUS LdrpReleaseTlsEntry(PLDR_DATA_TABLE_ENTRY ModuleEntry) {
|
|
// PTLS_ENTRY TlsEntry;
|
|
//
|
|
// //
|
|
// // Find the corresponding TLS_ENTRY for this module entry.
|
|
// //
|
|
// TlsEntry = LdrpFindTlsEntry(ModuleEntry);
|
|
// if (!TlsEntry) return STATUS_NOT_FOUND;
|
|
//
|
|
// //
|
|
// // Remove it from the global list of outstanding TLS entries.
|
|
// //
|
|
// RemoveEntryList(&TlsEntry->TlsEntryLinks);
|
|
//
|
|
// //
|
|
// // Deallocate the TLS index.
|
|
// //
|
|
// LdrpReleaseTlsIndex(TlsEntry->TlsDirectory.Characteristics);
|
|
//
|
|
// //
|
|
// // Deallocate the TLS_ENTRY object itself.
|
|
// //
|
|
// RtlFreeHeap(GetProcessHeap(), 0, TlsEntry);
|
|
//
|
|
// //
|
|
// // We're done.
|
|
// //
|
|
// return STATUS_SUCCESS;
|
|
//}
|
|
//
|
|
//PVOID* __fastcall LdrpGetNewTlsVector(ULONG TlsBitmapLength) {
|
|
// PTLS_VECTOR TlsVector;
|
|
//
|
|
// TlsVector = (PTLS_VECTOR)RtlAllocateHeap(GetProcessHeap(), (ULONG_PTR)((PUCHAR)NtdllBaseTag + 0x000C0000),
|
|
// sizeof(TLS_VECTOR) + (sizeof(PVOID) * TlsBitmapLength) - sizeof(PVOID));
|
|
// if (!TlsVector) return 0;
|
|
// TlsVector->Length = TlsBitmapLength;
|
|
// RtlZeroMemory(TlsVector->ModuleTlsData, TlsBitmapLength * sizeof(PVOID));
|
|
// return TlsVector->ModuleTlsData;
|
|
//}
|
|
//
|
|
//VOID LdrpQueueDeferredTlsData(PVOID TlsVector, PVOID ThreadId) {
|
|
// PTLS_VECTOR RealTlsVector;
|
|
// PTLS_RECLAIM_TABLE_ENTRY ReclaimEntry;
|
|
//
|
|
// RealTlsVector = CONTAINING_RECORD(TlsVector, TLS_VECTOR, ModuleTlsData);
|
|
//
|
|
// RealTlsVector->ThreadId = ThreadId;
|
|
//
|
|
// ReclaimEntry = &LdrpDelayedTlsReclaimTable[((ULONG_PTR)(ThreadId) >> 2) & 0xF];
|
|
//
|
|
// RtlAcquireSRWLockExclusive(&ReclaimEntry->Lock);
|
|
//
|
|
// RealTlsVector->PreviousDeferredTlsVector = ReclaimEntry->TlsVector;
|
|
// ReclaimEntry->TlsVector = RealTlsVector;
|
|
//
|
|
// RtlReleaseSRWLockExclusive(&ReclaimEntry->Lock);
|
|
//}
|
|
//
|
|
//#define SIZEOF_TLS_INFO(_ThreadCount_) (_ThreadCount_==0)?sizeof(PROCESS_TLS_INFORMATION)-sizeof(THREAD_TLS_INFORMATION):(_ThreadCount_-1)*sizeof(THREAD_TLS_INFORMATION)+sizeof(PROCESS_TLS_INFORMATION)
|
|
//NTSTATUS LdrpHandleTlsData(PLDR_DATA_TABLE_ENTRY ModuleEntry) {
|
|
// PIMAGE_TLS_DIRECTORY TlsDirectory;
|
|
// ULONG DirectorySize;
|
|
// ULONG TlsIndex;
|
|
// HANDLE Heap;
|
|
// PPROCESS_TLS_INFORMATION TlsInfo;
|
|
// PROCESS_TLS_INFORMATION OneThreadTlsInfo;
|
|
// NTSTATUS Status;
|
|
// BOOLEAN AllocatedBitmap;
|
|
// PTLS_ENTRY TlsEntry;
|
|
// ULONG TlsBitmapLength;
|
|
// SIZE_T TlsRawDataLength;
|
|
// ULONG ThreadIndex;
|
|
// PVOID TlsData = nullptr;
|
|
// PVOID* TlsVector;
|
|
// PTHREAD_TLS_INFORMATION ThreadTlsData;
|
|
// ULONG ThreadsCleanedUp;
|
|
//
|
|
// if (LdrpActiveThreadCount == 0) return STATUS_SUCCESS;
|
|
// TlsDirectory = (PIMAGE_TLS_DIRECTORY)RtlImageDirectoryEntryToData(ModuleEntry->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_TLS, &DirectorySize);
|
|
// if (!TlsDirectory) return STATUS_SUCCESS;
|
|
// Heap = NtCurrentPeb()->ProcessHeap;
|
|
//
|
|
// TlsInfo = LdrpActiveThreadCount == 1 ? &OneThreadTlsInfo :
|
|
// (decltype(TlsInfo))RtlAllocateHeap(Heap, (ULONG)NtdllBaseTag + 0x000C0000, SIZEOF_TLS_INFO(LdrpActiveThreadCount));
|
|
// if (!TlsInfo) return STATUS_NO_MEMORY;
|
|
//
|
|
// do {
|
|
// TlsBitmapLength = LdrpTlsBitmap.SizeOfBitMap;
|
|
// Status = LdrpAllocateTlsEntry(TlsDirectory, ModuleEntry, &TlsIndex, &AllocatedBitmap, &TlsEntry);
|
|
// if (!NT_SUCCESS(Status)) break;
|
|
// TlsInfo->ThreadDataCount = LdrpActiveThreadCount;
|
|
// if (AllocatedBitmap) {
|
|
// TlsInfo->OperationType = ProcessTlsReplaceVector;
|
|
// TlsInfo->TlsVectorLength = TlsBitmapLength;
|
|
// TlsBitmapLength = LdrpTlsBitmap.SizeOfBitMap;
|
|
// }
|
|
// else {
|
|
// TlsInfo->OperationType = ProcessTlsReplaceIndex;
|
|
// TlsInfo->TlsIndex = TlsIndex;
|
|
// }
|
|
// Status = STATUS_SUCCESS;
|
|
// ThreadsCleanedUp = 0;
|
|
//
|
|
// //
|
|
// // Calculate the size of the raw TLS data for this module.
|
|
// //
|
|
// TlsRawDataLength = TlsEntry->TlsDirectory.EndAddressOfRawData - TlsEntry->TlsDirectory.StartAddressOfRawData;
|
|
//
|
|
// //
|
|
// // Prepare data for each running thread.
|
|
// //
|
|
// for (ThreadIndex = 0; ThreadIndex < TlsInfo->ThreadDataCount; ++ThreadIndex) {
|
|
// TlsData = RtlAllocateHeap(Heap, (ULONG_PTR)((PUCHAR)NtdllBaseTag + 0x000C0000), TlsRawDataLength);
|
|
// if (!TlsData) {
|
|
// Status = STATUS_NO_MEMORY;
|
|
// break;
|
|
// }
|
|
// __try {
|
|
// RtlCopyMemory(TlsData, (PVOID)TlsEntry->TlsDirectory.StartAddressOfRawData, TlsRawDataLength);
|
|
// }
|
|
// __except (EXCEPTION_EXECUTE_HANDLER) {
|
|
// Status = GetExceptionCode();
|
|
// }
|
|
// if (!NT_SUCCESS(Status)) {
|
|
// RtlFreeHeap(Heap, 0, TlsData);
|
|
// break;
|
|
// }
|
|
//
|
|
// if (AllocatedBitmap) {
|
|
// TlsVector = LdrpGetNewTlsVector(TlsBitmapLength);
|
|
// if (!TlsVector) {
|
|
// RtlFreeHeap(Heap, 0, TlsData);
|
|
// break;
|
|
// }
|
|
// TlsVector[TlsIndex] = TlsData;
|
|
// TlsInfo->ThreadData[ThreadIndex].TlsVector = TlsVector;
|
|
// }
|
|
// else {
|
|
// TlsInfo->ThreadData[ThreadIndex].TlsModulePointer = TlsData;
|
|
// }
|
|
//
|
|
// TlsInfo->ThreadData[ThreadIndex].Flags = 0;
|
|
// }
|
|
//
|
|
// //
|
|
// // This is awkward; all the 'break' above really are either goto or
|
|
// // __leave, but we aren't using those. This is really supposed to
|
|
// // just happen on normal for loop exit.
|
|
// //
|
|
// if (ThreadIndex == TlsInfo->ThreadDataCount) {
|
|
// TlsInfo->Reserved = 0;
|
|
// Status = NtSetInformationProcess(GetCurrentProcess(), ProcessTlsInformation, TlsInfo,
|
|
// TlsInfo->ThreadDataCount * sizeof(THREAD_TLS_INFORMATION) + sizeof(PROCESS_TLS_INFORMATION) - sizeof(THREAD_TLS_INFORMATION));
|
|
// }
|
|
//
|
|
// //
|
|
// // Let's handle each thread that we replaced, as the
|
|
// // ProcessTlsInformation call fills our buffer with the old data
|
|
// // after performing a swap.
|
|
// //
|
|
// for (ThreadTlsData = &TlsInfo->ThreadData[ThreadIndex]; ThreadIndex > 0;) {
|
|
// ThreadIndex -= 1;
|
|
// ThreadTlsData -= 1;
|
|
//
|
|
// if (ThreadTlsData->Flags & 0x2) {
|
|
// if (!ThreadTlsData->TlsVector) continue;
|
|
//
|
|
// if (!AllocatedBitmap) {
|
|
// RtlFreeHeap(Heap, 0, ThreadTlsData->TlsVector);
|
|
// continue;
|
|
// }
|
|
// else {
|
|
// LdrpQueueDeferredTlsData(ThreadTlsData->TlsVector, ThreadTlsData->ThreadId);
|
|
// continue;
|
|
// }
|
|
// }
|
|
// else {
|
|
// if (ThreadTlsData->Flags & 0x1) {
|
|
// ++LdrpPotentialTlsLeaks;
|
|
// continue;
|
|
// }
|
|
// else {
|
|
// ++ThreadsCleanedUp;
|
|
// if (AllocatedBitmap) {
|
|
// TlsData = ThreadTlsData->TlsVector[TlsIndex];
|
|
// RtlFreeHeap(Heap, 0, CONTAINING_RECORD(ThreadTlsData->TlsVector, TLS_VECTOR, ModuleTlsData));
|
|
// }
|
|
// RtlFreeHeap(Heap, 0, TlsData);
|
|
// continue;
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
// if (!NT_SUCCESS(Status)) {
|
|
// LdrpReleaseTlsEntry(ModuleEntry);
|
|
// if (AllocatedBitmap) LdrpTlsBitmap.SizeOfBitMap -= 4;
|
|
// }
|
|
// else if (ThreadsCleanedUp > 0) {
|
|
// LdrpActiveThreadCount -= ThreadsCleanedUp;
|
|
// }
|
|
// } while (0);
|
|
//
|
|
// if (TlsInfo != &OneThreadTlsInfo) RtlFreeHeap(Heap, 0, TlsInfo);
|
|
// if (!NT_SUCCESS(Status)) return Status;
|
|
// ModuleEntry->TlsIndex = 0xFFFF;
|
|
// return STATUS_SUCCESS;
|
|
//}
|
|
//
|
|
////struct UNKNOWN {
|
|
//// PVOID unknown1; //+0x0
|
|
//// PVOID unknown2; //+0x8
|
|
//// PVOID unknown3; //+0x10
|
|
//// struct {
|
|
//// DWORD dwFlags; //+0x14
|
|
//// DWORD unknown4; //+0x18
|
|
//// };
|
|
//// PWSTR DllName; //+0x20
|
|
//// PVOID unknown[11];
|
|
////};
|
|
////
|
|
//////#include "../MemoryModule/Native.h"
|
|
////
|
|
//////size = 0xC0 + DllName->Length + sizeof(wchar_t)
|
|
////typedef struct _ALLOCATE_ENTRY_PARAMETER {
|
|
//// UNICODE_STRING DllName; //+0x0
|
|
//// UNKNOWN* unknown_structure; //+0x10
|
|
//// PVOID reserved1; //+0x18
|
|
//// struct {
|
|
//// DWORD ProcessStatus; //+0x20
|
|
//// DWORD reserved2; //+0x24
|
|
//// };
|
|
//// PVOID reserved3; //+0x28
|
|
//// PVOID reserved4; //+0x30
|
|
//// PVOID LdrEntry; //+0x38
|
|
//// PVOID reserved[16]; //+0x40
|
|
//// BYTE UnicodeStringBuffer[1]; //+0xC0
|
|
////}ALLOCATE_ENTRY_PARAMETER, * PALLOCATE_ENTRY_PARAMETER;
|
|
//
|
|
|
|
|
|
typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 {
|
|
PVOID ImageBase;
|
|
ULONG ImageSize;
|
|
ULONG SEHandlerCount;
|
|
PVOID NextEntrySEHandlerTableEncoded;
|
|
} RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32;
|
|
typedef struct _RTL_INVERTED_FUNCTION_TABLE {
|
|
ULONG Count;
|
|
ULONG MaxCount;
|
|
ULONG Overflow;
|
|
ULONG NextEntrySEHandlerTableEncoded;
|
|
RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 Entries[0x200];
|
|
} RTL_INVERTED_FUNCTION_TABLE, * PRTL_INVERTED_FUNCTION_TABLE;
|