diff --git a/MemoryModule/BaseAddressIndex.cpp b/MemoryModule/BaseAddressIndex.cpp index 4806fd9..daf7f0f 100644 --- a/MemoryModule/BaseAddressIndex.cpp +++ b/MemoryModule/BaseAddressIndex.cpp @@ -53,8 +53,6 @@ NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode( } NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry) { - static auto tree{ MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex }; - if (!tree->Root)return STATUS_UNSUCCESSFUL; - RtlRbRemoveNode(tree, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode); + RtlRbRemoveNode(MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex, &PLDR_DATA_TABLE_ENTRY_WIN8(DataTableEntry)->BaseAddressIndexNode); return STATUS_SUCCESS; } diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index 27b7a93..494106c 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -6,7 +6,7 @@ static NTSTATUS RtlFreeDependencies(_In_ PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntry) { PLDR_DATA_TABLE_ENTRY_WIN10 ModuleEntry = nullptr; _LDRP_CSLIST* head = (decltype(head))LdrEntry->DdagNode->Dependencies, * entry = head; HANDLE heap = NtCurrentPeb()->ProcessHeap; - const static bool IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); + BOOL IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); if (!LdrEntry->DdagNode->Dependencies)return STATUS_SUCCESS; //find all dependencies and free @@ -134,7 +134,7 @@ BOOL NTAPI RtlInitializeLdrDataTableEntry( case WINDOWS_VERSION::win8: case WINDOWS_VERSION::winBlue: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN8)LdrEntry; - const static bool IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); + BOOL IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); NtQuerySystemTime(&entry->LoadTime); entry->OriginalBase = headers->OptionalHeader.ImageBase; entry->BaseNameHashValue = LdrHashEntry(DllBaseName, false); diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 98f6fb7..42dd825 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -197,20 +197,20 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { goto __skip_tls; } - // - // Check if we have already initialized - // - EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); - record = MmpFindTlspRecordLockHeld(); - LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); - - if (!!record)goto __skip_tls; - // // Allocate and replace ThreadLocalStoragePointer for new thread // EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); + // + // Check if we have already initialized + // + record = MmpFindTlspRecordLockHeld(); + if (!!record) { + LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); + goto __skip_tls; + } + record = PMMP_TLSP_RECORD(RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(MMP_TLSP_RECORD))); if (record) { record->TlspLdrBlock = (PVOID*)NtCurrentTeb()->ThreadLocalStoragePointer; @@ -276,9 +276,7 @@ DWORD NTAPI MmpUserThreadStart(LPVOID lpThreadParameter) { return ERROR_NOT_ENOUGH_MEMORY; } - EnterCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); - ++MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount; - LeaveCriticalSection(&MmpGlobalDataPtr->MmpTls->MmpTlspLock); + InterlockedIncrement(&MmpGlobalDataPtr->MmpTls->MmpActiveThreadCount); __skip_tls: return Context.ThreadStartRoutine(Context.ThreadParameter); @@ -369,6 +367,9 @@ VOID NTAPI HookLdrShutdownThread(VOID) { } RtlFreeHeap(RtlProcessHeap(), 0, TlspMmpBlock); + RtlFreeHeap(RtlProcessHeap(), 0, record); + RtlFreeHeap(RtlProcessHeap(), 0, record); + RtlFreeHeap(RtlProcessHeap(), 0, record); } else { if (MmpGlobalDataPtr->MmpTls->MmpTlsList.Flink != &MmpGlobalDataPtr->MmpTls->MmpTlsList) { diff --git a/MemoryModule/stdafx.h b/MemoryModule/stdafx.h index 3e8708e..a15eb40 100644 --- a/MemoryModule/stdafx.h +++ b/MemoryModule/stdafx.h @@ -11,7 +11,9 @@ // // Determine whether to use MmpTls(1) or LdrpTls(0) // +#ifndef MMPP_USE_TLS #define MMPP_USE_TLS 1 +#endif // offsetof() #include diff --git a/test/test.cpp b/test/test.cpp index 606369e..02a46fc 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,6 +1,7 @@ #include "../MemoryModule/stdafx.h" #include "../MemoryModule/LoadDllMemoryApi.h" #include +#pragma comment(lib,"ntdll.lib") //PMMP_GLOBAL_DATA MmpGlobalDataPtr = *(PMMP_GLOBAL_DATA*)GetProcAddress(GetModuleHandleA("MemoryModule.dll"), "MmpGlobalDataPtr"); @@ -36,16 +37,101 @@ static void DisplayStatus() { ); } -int test() { - LPVOID buffer = ReadDllFile("a.dll"); +PVOID ReadDllFile2(LPCSTR FileName) { + CHAR path[MAX_PATH + 4]; + DWORD len = GetModuleFileNameA(nullptr, path, sizeof(path)); - HMODULE hm = LoadLibraryMemory(buffer); - FARPROC fp = GetProcAddress(hm, "GdiplusTest"); - bool c = true; - while (c) { - fp(); + if (len) { + while (len && path[len] != '\\') --len; + + if (len) { + strcpy_s(&path[len + 1], sizeof(path) - len - 1, FileName); + return ReadDllFile(path); + } } - + + return nullptr; +} + +int test() { + LPVOID buffer = ReadDllFile2("a.dll"); + + HMEMORYMODULE m1 = nullptr, m2 = m1; + HMODULE hModule = nullptr; + FARPROC pfn = nullptr; + DWORD MemoryModuleFeatures = 0; + + typedef int(*_exception)(int code); + _exception exception = nullptr; + HRSRC hRsrc; + DWORD SizeofRes; + HGLOBAL gRes; + char str[10]; + + LdrQuerySystemMemoryModuleFeatures(&MemoryModuleFeatures); + if (MemoryModuleFeatures != MEMORY_FEATURE_ALL) { + printf("not support all features on this version of windows.\n"); + } + + if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m1, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end; + LoadLibraryW(L"wininet.dll"); + if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m2, nullptr, 0, buffer, 0, L"kernel128", nullptr))) goto end; + + //forward export + hModule = (HMODULE)m1; + pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW + pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); //wintrust.WinVerifyTrust + hModule = (HMODULE)m2; + pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); + pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); + + //exception + hModule = (HMODULE)m1; + exception = (_exception)GetProcAddress(hModule, "exception"); + if (exception) { + for (int i = 0; i < 5; ++i)exception(i); + } + + //tls + pfn = GetProcAddress(hModule, "thread"); + if (pfn && pfn()) { + printf("thread test failed.\n"); + } + + //resource + if (!LoadStringA(hModule, 101, str, 10)) { + printf("load string failed.\n"); + } + else { + printf("%s\n", str); + } + if (!(hRsrc = FindResourceA(hModule, MAKEINTRESOURCEA(102), "BINARY"))) { + printf("find binary resource failed.\n"); + } + else { + if ((SizeofRes = SizeofResource(hModule, hRsrc)) != 0x10) { + printf("invalid res size.\n"); + } + else { + if (!(gRes = LoadResource(hModule, hRsrc))) { + printf("load res failed.\n"); + } + else { + if (!LockResource(gRes))printf("lock res failed.\n"); + else { + printf("resource test success.\n"); + } + } + } + } + +end: + delete[]buffer; + if (m1)LdrUnloadDllMemory(m1); + FreeLibrary(LoadLibraryW(L"wininet.dll")); + FreeLibrary(GetModuleHandleW(L"wininet.dll")); + if (m2)LdrUnloadDllMemory(m2); + return 0; } @@ -53,7 +139,5 @@ int main() { DisplayStatus(); test(); - WaitForSingleObject(NtCurrentProcess(), INFINITE); - return 0; }