From ff8a663acae27c74a28f05ead7dee261b3162af4 Mon Sep 17 00:00:00 2001 From: Boring <1079299053@qq.com> Date: Mon, 3 Oct 2022 17:25:02 +0800 Subject: [PATCH] refactoring --- MemoryModule/BaseAddressIndex.cpp | 6 +- MemoryModule/BaseAddressIndex.h | 7 +- MemoryModule/Initialize.cpp | 149 +++++++++++- MemoryModule/InvertedFunctionTable.cpp | 17 +- MemoryModule/InvertedFunctionTable.h | 8 +- MemoryModule/LdrEntry.cpp | 144 ++++++------ MemoryModule/LdrEntry.h | 50 ++-- MemoryModule/LoadDllMemoryApi.cpp | 24 +- MemoryModule/LoadDllMemoryApi.h | 20 +- MemoryModule/Loader.cpp | 63 ++--- MemoryModule/Loader.h | 41 ++-- MemoryModule/MemoryModule.cpp | 23 +- MemoryModule/MemoryModule.h | 5 +- MemoryModule/MmpGlobalData.h | 23 ++ MemoryModule/MmpTls.cpp | 6 +- MemoryModule/MmpTls.h | 4 +- MemoryModule/Utils.cpp | 309 +++++++++++-------------- MemoryModule/Utils.h | 63 ++--- MemoryModulePP.sln | 8 +- a/load.cpp | 3 +- test/test.cpp | 8 +- 21 files changed, 581 insertions(+), 400 deletions(-) diff --git a/MemoryModule/BaseAddressIndex.cpp b/MemoryModule/BaseAddressIndex.cpp index eacbf89..5b6f180 100644 --- a/MemoryModule/BaseAddressIndex.cpp +++ b/MemoryModule/BaseAddressIndex.cpp @@ -1,6 +1,8 @@ #include "stdafx.h" -NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress) { +NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode( + _In_ PLDR_DATA_TABLE_ENTRY DataTableEntry, + _In_ PVOID BaseAddress) { auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex; if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL; @@ -32,7 +34,7 @@ NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY Data return STATUS_SUCCESS; } -NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry) { +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); diff --git a/MemoryModule/BaseAddressIndex.h b/MemoryModule/BaseAddressIndex.h index c19ff53..f40016f 100644 --- a/MemoryModule/BaseAddressIndex.h +++ b/MemoryModule/BaseAddressIndex.h @@ -1,5 +1,8 @@ #pragma once -NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry, IN PVOID BaseAddress); +NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode( + _In_ PLDR_DATA_TABLE_ENTRY DataTableEntry, + _In_ PVOID BaseAddress +); -NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(IN PLDR_DATA_TABLE_ENTRY DataTableEntry); +NTSTATUS NTAPI RtlRemoveModuleBaseAddressIndexNode(_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry); diff --git a/MemoryModule/Initialize.cpp b/MemoryModule/Initialize.cpp index 579d338..da27d02 100644 --- a/MemoryModule/Initialize.cpp +++ b/MemoryModule/Initialize.cpp @@ -3,16 +3,10 @@ PMMP_GLOBAL_DATA MmpGlobalDataPtr; -#ifdef _WIN64 -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 -#else -#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 -#endif - BOOLEAN MmpBuildSectionName(_Out_ PUNICODE_STRING SectionName) { WCHAR buffer[128]; - swprintf(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP*%08X", NtCurrentPeb()->SessionId, (unsigned int)NtCurrentProcessId()); + swprintf_s(buffer, L"\\Sessions\\%d\\BaseNamedObjects\\MMPP*%08X", NtCurrentPeb()->SessionId, (unsigned int)(ULONG_PTR)NtCurrentProcessId()); return RtlCreateUnicodeString(SectionName, buffer); } @@ -51,6 +45,7 @@ static __forceinline bool IsModuleUnloaded(PLDR_DATA_TABLE_ENTRY entry) { } } +#ifndef _WIN64 PVOID FindLdrpInvertedFunctionTable32() { // _RTL_INVERTED_FUNCTION_TABLE x86 // Count +0x0 ???????? @@ -103,6 +98,8 @@ PVOID FindLdrpInvertedFunctionTable32() { return nullptr; } +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable32 +#else PVOID FindLdrpInvertedFunctionTable64() { // _RTL_INVERTED_FUNCTION_TABLE x64 // Count +0x0 ???????? @@ -165,6 +162,9 @@ PVOID FindLdrpInvertedFunctionTable64() { return nullptr; } +#define FindLdrpInvertedFunctionTable FindLdrpInvertedFunctionTable64 +#endif + PLIST_ENTRY FindLdrpHashTable() { PLIST_ENTRY list = nullptr; PLIST_ENTRY head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = head->Flink; @@ -183,6 +183,94 @@ PLIST_ENTRY FindLdrpHashTable() { return list; } +VOID InitializeWindowsVersion() { + + WINDOWS_VERSION version = WINDOWS_VERSION::invalid; + + switch (MmpGlobalDataPtr->NtVersions.MajorVersion) { + case 5: { + switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { + case 1: + version = MmpGlobalDataPtr->NtVersions.BuildNumber == 2600 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; + break; + + case 2: + version = MmpGlobalDataPtr->NtVersions.BuildNumber == 3790 ? WINDOWS_VERSION::xp : WINDOWS_VERSION::invalid; + break; + } + break; + } + + case 6: { + switch (MmpGlobalDataPtr->NtVersions.MinorVersion) { + case 0: { + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { + case 6000: + case 6001: + case 6002: + version = WINDOWS_VERSION::vista; + break; + } + break; + } + + case 1: { + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { + case 7600: + case 7601: + version = WINDOWS_VERSION::win7; + break; + } + break; + } + + case 2: { + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9200) version = WINDOWS_VERSION::win8; + break; + } + + case 3: { + if (MmpGlobalDataPtr->NtVersions.BuildNumber == 9600) version = WINDOWS_VERSION::win8_1; + break; + } + + } + break; + } + + case 10: { + if (MmpGlobalDataPtr->NtVersions.MinorVersion)break; + switch (MmpGlobalDataPtr->NtVersions.BuildNumber) { + case 10240: + case 10586: + version = WINDOWS_VERSION::win10; + break; + + case 14393: + version = WINDOWS_VERSION::win10_1; + break; + + case 15063: + case 16299: + case 17134: + case 17763: + case 18362: + version = WINDOWS_VERSION::win10_2; + break; + + default: + if (RtlIsWindowsVersionOrGreater(MmpGlobalDataPtr->NtVersions.MajorVersion, MmpGlobalDataPtr->NtVersions.MinorVersion, 15063)) version = WINDOWS_VERSION::win10_2; + break; + } + + break; + } + + } + + MmpGlobalDataPtr->WindowsVersion = version; +} + NTSTATUS InitializeLockHeld() { NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE hSection = nullptr; @@ -255,6 +343,53 @@ NTSTATUS InitializeLockHeld() { GetSystemInfo(&MmpGlobalDataPtr->SystemInfo); + RtlGetNtVersionNumbers( + &MmpGlobalDataPtr->NtVersions.MajorVersion, + &MmpGlobalDataPtr->NtVersions.MinorVersion, + &MmpGlobalDataPtr->NtVersions.BuildNumber + ); + if (MmpGlobalDataPtr->NtVersions.BuildNumber & 0xf0000000)MmpGlobalDataPtr->NtVersions.BuildNumber &= 0xffff; + + InitializeWindowsVersion(); + + switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::xp: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_XP); + break; + + case WINDOWS_VERSION::vista: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_VISTA); + break; + + case WINDOWS_VERSION::win7: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN7); + break; + + case WINDOWS_VERSION::win8: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); + break; + + case WINDOWS_VERSION::win8_1: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN8_1); + break; + + case WINDOWS_VERSION::win10: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10); + break; + + case WINDOWS_VERSION::win10_1: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1); + break; + + case WINDOWS_VERSION::win10_2: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); + break; + + default: + MmpGlobalDataPtr->LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); + break; + } + MmpGlobalDataPtr->MmpBaseAddressIndex.NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll"); MmpGlobalDataPtr->MmpBaseAddressIndex.LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex(); diff --git a/MemoryModule/InvertedFunctionTable.cpp b/MemoryModule/InvertedFunctionTable.cpp index c5f90a9..572a410 100644 --- a/MemoryModule/InvertedFunctionTable.cpp +++ b/MemoryModule/InvertedFunctionTable.cpp @@ -1,6 +1,9 @@ #include "stdafx.h" -static VOID NTAPI RtlpInsertInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABLE InvertedTable, IN PVOID ImageBase, IN ULONG SizeOfImage) { +static VOID RtlpInsertInvertedFunctionTable( + _In_ PRTL_INVERTED_FUNCTION_TABLE InvertedTable, + _In_ PVOID ImageBase, + _In_ ULONG SizeOfImage) { #ifdef _WIN64 ULONG CurrentSize; PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionTable; @@ -86,7 +89,9 @@ static VOID NTAPI RtlpInsertInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL return; } -static VOID NTAPI RtlpRemoveInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABLE InvertedTable, IN PVOID ImageBase) { +static VOID RtlpRemoveInvertedFunctionTable( + _In_ PRTL_INVERTED_FUNCTION_TABLE InvertedTable, + _In_ PVOID ImageBase) { ULONG CurrentSize; ULONG Index; //bool need = RtlIsWindowsVersionOrGreater(6, 2, 0); @@ -136,7 +141,7 @@ static VOID NTAPI RtlpRemoveInvertedFunctionTable(IN PRTL_INVERTED_FUNCTION_TABL return; } -static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { +static NTSTATUS RtlProtectMrdata(_In_ ULONG Protect) { static PVOID MrdataBase = nullptr; static SIZE_T size = 0; NTSTATUS status; @@ -157,7 +162,9 @@ static NTSTATUS NTAPI RtlProtectMrdata(IN SIZE_T Protect) { return NtProtectVirtualMemory(GetCurrentProcess(), &tmp, &tmp_len, Protect, &old); } -NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize) { +NTSTATUS NTAPI RtlInsertInvertedFunctionTable( + _In_ PVOID BaseAddress, + _In_ ULONG ImageSize) { auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable); if (!table)return STATUS_NOT_SUPPORTED; bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); @@ -176,7 +183,7 @@ NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t Im STATUS_NO_MEMORY : STATUS_SUCCESS; } -NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase) { +NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(_In_ PVOID ImageBase) { auto table = PRTL_INVERTED_FUNCTION_TABLE(MmpGlobalDataPtr->MmpInvertedFunctionTable.LdrpInvertedFunctionTable); bool need_virtual_protect = RtlIsWindowsVersionOrGreater(6, 3, 0); NTSTATUS status; diff --git a/MemoryModule/InvertedFunctionTable.h b/MemoryModule/InvertedFunctionTable.h index 979a3e6..6f8e229 100644 --- a/MemoryModule/InvertedFunctionTable.h +++ b/MemoryModule/InvertedFunctionTable.h @@ -52,5 +52,9 @@ typedef RTL_INVERTED_FUNCTION_TABLE_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE, RTL_IN typedef _RTL_INVERTED_FUNCTION_TABLE_ENTRY_WIN7_32 _RTL_INVERTED_FUNCTION_TABLE_ENTRY, RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; #endif -NTSTATUS NTAPI RtlInsertInvertedFunctionTable(IN PVOID BaseAddress, IN size_t ImageSize); -NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(IN PVOID ImageBase); +NTSTATUS NTAPI RtlInsertInvertedFunctionTable( + _In_ PVOID BaseAddress, + _In_ ULONG ImageSize +); + +NTSTATUS NTAPI RtlRemoveInvertedFunctionTable(_In_ PVOID ImageBase); diff --git a/MemoryModule/LdrEntry.cpp b/MemoryModule/LdrEntry.cpp index 867cd22..d35db8a 100644 --- a/MemoryModule/LdrEntry.cpp +++ b/MemoryModule/LdrEntry.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include -static NTSTATUS NTAPI RtlFreeDependencies(IN PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntry) { +static NTSTATUS RtlFreeDependencies(_In_ PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntry) { _LDR_DDAG_NODE* DependentDdgeNode = nullptr; PLDR_DATA_TABLE_ENTRY_WIN10 ModuleEntry = nullptr; _LDRP_CSLIST* head = (decltype(head))LdrEntry->DdagNode->Dependencies, * entry = head; @@ -81,7 +81,7 @@ static NTSTATUS NTAPI RtlFreeDependencies(IN PLDR_DATA_TABLE_ENTRY_WIN10 LdrEntr return STATUS_SUCCESS; } -PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(IN PVOID BaseAddress) { +PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(_In_ PVOID BaseAddress) { PLDR_DATA_TABLE_ENTRY LdrEntry = nullptr; PIMAGE_NT_HEADERS NtHeader; HANDLE heap = NtCurrentPeb()->ProcessHeap; @@ -89,22 +89,22 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(IN PVOID BaseAddress) { /* Make sure the header is valid */ if (NtHeader = RtlImageNtHeader(BaseAddress)) { /* Allocate an entry */ - LdrEntry = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, LdrpDataTableEntrySize()); + LdrEntry = (PLDR_DATA_TABLE_ENTRY)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, MmpGlobalDataPtr->LdrDataTableEntrySize); } /* Return the entry */ return LdrEntry; } -bool NTAPI RtlInitializeLdrDataTableEntry( - OUT PLDR_DATA_TABLE_ENTRY LdrEntry, - IN DWORD dwFlags, - IN PVOID BaseAddress, - IN UNICODE_STRING& DllBaseName, - IN UNICODE_STRING& DllFullName) { - RtlZeroMemory(LdrEntry, LdrpDataTableEntrySize()); +BOOL NTAPI RtlInitializeLdrDataTableEntry( + _Out_ PLDR_DATA_TABLE_ENTRY LdrEntry, + _In_ DWORD dwFlags, + _In_ PVOID BaseAddress, + _In_ UNICODE_STRING& DllBaseName, + _In_ UNICODE_STRING& DllFullName) { + RtlZeroMemory(LdrEntry, MmpGlobalDataPtr->LdrDataTableEntrySize); PIMAGE_NT_HEADERS headers = RtlImageNtHeader(BaseAddress); - if (!headers)return false; + if (!headers)return FALSE; HANDLE heap = NtCurrentPeb()->ProcessHeap; bool FlagsProcessed = false; @@ -119,24 +119,24 @@ bool NTAPI RtlInitializeLdrDataTableEntry( } } - switch (NtWindowsVersion()) { - case win10: - case win10_1: - case win10_2: { + switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::win10: + case WINDOWS_VERSION::win10_1: + case WINDOWS_VERSION::win10_2: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry; entry->ReferenceCount = 1; } - case win8: - case win8_1: { + case WINDOWS_VERSION::win8: + case WINDOWS_VERSION::win8_1: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN8)LdrEntry; const static bool IsWin8 = RtlIsWindowsVersionInScope(6, 2, 0, 6, 3, -1); NtQuerySystemTime(&entry->LoadTime); entry->OriginalBase = headers->OptionalHeader.ImageBase; entry->BaseNameHashValue = LdrHashEntry(DllBaseName, false); entry->LoadReason = LoadReasonDynamicLoad; - if (!NT_SUCCESS(RtlInsertModuleBaseAddressIndexNode(LdrEntry, BaseAddress)))return false; + if (!NT_SUCCESS(RtlInsertModuleBaseAddressIndexNode(LdrEntry, BaseAddress)))return FALSE; if (!(entry->DdagNode = (decltype(entry->DdagNode)) - RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, IsWin8 ? sizeof(_LDR_DDAG_NODE_WIN8) : sizeof(_LDR_DDAG_NODE))))return false; + RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, IsWin8 ? sizeof(_LDR_DDAG_NODE_WIN8) : sizeof(_LDR_DDAG_NODE))))return FALSE; //RtlInitializeListEntry(&entry->NodeModuleLink); //RtlInitializeListEntry(&entry->DdagNode->Modules); //RtlInitializeSingleEntry(&entry->DdagNode->CondenseLink); @@ -156,23 +156,23 @@ bool NTAPI RtlInitializeLdrDataTableEntry( FlagsProcessed = true; } - case win7: { - if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { + case WINDOWS_VERSION::win7: { + if (MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN7)LdrEntry; entry->OriginalBase = headers->OptionalHeader.ImageBase; NtQuerySystemTime(&entry->LoadTime); } } - case vista: { - if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || - LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { + case WINDOWS_VERSION::vista: { + if (MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || + MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { auto entry = (PLDR_DATA_TABLE_ENTRY_VISTA)LdrEntry; - RtlInitializeListEntry(&entry->ForwarderLinks); - RtlInitializeListEntry(&entry->StaticLinks); - RtlInitializeListEntry(&entry->ServiceTagLinks); + InitializeListHead(&entry->ForwarderLinks); + InitializeListHead(&entry->StaticLinks); + InitializeListHead(&entry->ServiceTagLinks); } } - case xp: { + case WINDOWS_VERSION::xp: { LdrEntry->DllBase = BaseAddress; LdrEntry->SizeOfImage = headers->OptionalHeader.SizeOfImage; LdrEntry->TimeDateStamp = headers->FileHeader.TimeDateStamp; @@ -184,30 +184,30 @@ bool NTAPI RtlInitializeLdrDataTableEntry( LdrEntry->Flags = LDRP_IMAGE_DLL | LDRP_ENTRY_INSERTED | LDRP_ENTRY_PROCESSED | LDRP_PROCESS_ATTACH_CALLED; if (CorImage)LdrEntry->Flags |= LDRP_COR_IMAGE; } - RtlInitializeListEntry(&LdrEntry->HashLinks); - return true; + InitializeListHead(&LdrEntry->HashLinks); + return TRUE; } - default:return false; + default:return FALSE; } } -bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { +BOOL NTAPI RtlFreeLdrDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry) { HANDLE heap = NtCurrentPeb()->ProcessHeap; - switch (NtWindowsVersion()) { - case win10: - case win10_1: - case win10_2: - case win8: - case win8_1: { + switch (MmpGlobalDataPtr->WindowsVersion) { + case WINDOWS_VERSION::win10: + case WINDOWS_VERSION::win10_1: + case WINDOWS_VERSION::win10_2: + case WINDOWS_VERSION::win8: + case WINDOWS_VERSION::win8_1: { auto entry = (PLDR_DATA_TABLE_ENTRY_WIN10)LdrEntry; RtlFreeDependencies(entry); RtlFreeHeap(heap, 0, entry->DdagNode); RtlRemoveModuleBaseAddressIndexNode(LdrEntry); } - case win7: - case vista: { - if (LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || - LdrpDataTableEntrySize() == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { + case WINDOWS_VERSION::win7: + case WINDOWS_VERSION::vista: { + if (MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_VISTA) || + MmpGlobalDataPtr->LdrDataTableEntrySize == sizeof(LDR_DATA_TABLE_ENTRY_WIN7)) { PLDR_DATA_TABLE_ENTRY_VISTA entry = (decltype(entry))LdrEntry; PLIST_ENTRY head = &entry->ForwarderLinks, next = head->Flink; while (head != next) { @@ -218,7 +218,7 @@ bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { } } } - case xp: { + case WINDOWS_VERSION::xp: { RtlFreeHeap(heap, 0, LdrEntry->BaseDllName.Buffer); RtlFreeHeap(heap, 0, LdrEntry->FullDllName.Buffer); RemoveEntryList(&LdrEntry->InLoadOrderLinks); @@ -226,13 +226,15 @@ bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { RemoveEntryList(&LdrEntry->InInitializationOrderLinks); RemoveEntryList(&LdrEntry->HashLinks); RtlFreeHeap(heap, 0, LdrEntry); - return true; + return TRUE; } - default:return false; + default:return FALSE; } } -NTSTATUS NTAPI RtlUpdateReferenceCount(IN OUT PMEMORYMODULE pModule, IN DWORD Flags) { +NTSTATUS NTAPI RtlUpdateReferenceCount( + _Inout_ PMEMORYMODULE pModule, + _In_ DWORD Flags) { if (Flags != FLAG_REFERENCE && Flags != FLAG_DEREFERENCE)return STATUS_INVALID_PARAMETER_2; if (Flags == FLAG_REFERENCE && pModule->dwReferenceCount != 0xffffffff) @@ -243,14 +245,16 @@ NTSTATUS NTAPI RtlUpdateReferenceCount(IN OUT PMEMORYMODULE pModule, IN DWORD Fl return STATUS_SUCCESS; } -NTSTATUS NTAPI RtlGetReferenceCount(IN PMEMORYMODULE pModule, OUT PULONG Count) { +NTSTATUS NTAPI RtlGetReferenceCount( + _In_ PMEMORYMODULE pModule, + _Out_ PULONG Count) { *Count = pModule->dwReferenceCount; return STATUS_SUCCESS; } -VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { +VOID NTAPI RtlInsertMemoryTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry) { PPEB_LDR_DATA PebData = NtCurrentPeb()->Ldr; PLIST_ENTRY LdrpHashTable = MmpGlobalDataPtr->MmpLdrEntry.LdrpHashTable; ULONG i; @@ -265,19 +269,28 @@ VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry) { InsertTailList(&PebData->InInitializationOrderModuleList, &LdrEntry->InInitializationOrderLinks); } -VOID NTAPI RtlRbInsertNodeEx(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Parent, IN BOOLEAN Right, OUT PRTL_BALANCED_NODE Node) { - decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx = decltype(_RtlRbInsertNodeEx)(RtlGetNtProcAddress("RtlRbInsertNodeEx")); +VOID NTAPI RtlRbInsertNodeEx( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Parent, + _In_ BOOLEAN Right, + _Out_ PRTL_BALANCED_NODE Node) { + static decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx = decltype(_RtlRbInsertNodeEx)(RtlGetNtProcAddress("RtlRbInsertNodeEx")); + + RtlZeroMemory(Node, sizeof(*Node)); + if (!_RtlRbInsertNodeEx)return; return _RtlRbInsertNodeEx(Tree, Parent, Right, Node); } -VOID NTAPI RtlRbRemoveNode(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Node) { - decltype(&RtlRbRemoveNode)_RtlRbRemoveNode = decltype(_RtlRbRemoveNode)(RtlGetNtProcAddress("RtlRbRemoveNode")); +VOID NTAPI RtlRbRemoveNode( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Node) { + static decltype(&RtlRbRemoveNode)_RtlRbRemoveNode = decltype(_RtlRbRemoveNode)(RtlGetNtProcAddress("RtlRbRemoveNode")); if (!_RtlRbRemoveNode)return; return _RtlRbRemoveNode(Tree, Node); } -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress) { +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(_In_ PVOID BaseAddress) { PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink; PLDR_DATA_TABLE_ENTRY CurEntry; while (ListEntry != ListHead) { @@ -290,21 +303,21 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress) { return nullptr; } -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName) { +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(_In_z_ PCWSTR BaseName) { PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink; PLDR_DATA_TABLE_ENTRY CurEntry; while (ListEntry != ListHead) { CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); ListEntry = ListEntry->Flink; - if (!wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || - !wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { + if (!_wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || + !_wcsnicmp(BaseName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { return CurEntry; } } return nullptr; } -ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor) { +ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& str, _In_ BOOL _xor) { ULONG result = 0; if (RtlIsWindowsVersionOrGreater(6, 2, 0)) { RtlHashUnicodeString(&str, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &result); @@ -316,20 +329,3 @@ ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor) { if (_xor)result &= (LDR_HASH_TABLE_ENTRIES - 1); return result; } - -size_t NTAPI LdrpDataTableEntrySize() { - static size_t size = 0; - if (size)return size; - - switch (NtWindowsVersion()) { - case xp:return size = sizeof(LDR_DATA_TABLE_ENTRY_XP); - case vista:return size = sizeof(LDR_DATA_TABLE_ENTRY_VISTA); - case win7:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN7); - case win8:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); - case win8_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8_1); - case win10:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10); - case win10_1:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1); - case win10_2:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); - default:return size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_2); - } -} diff --git a/MemoryModule/LdrEntry.h b/MemoryModule/LdrEntry.h index fb6ec01..bd760fa 100644 --- a/MemoryModule/LdrEntry.h +++ b/MemoryModule/LdrEntry.h @@ -3,21 +3,33 @@ #define FLAG_REFERENCE 0 #define FLAG_DEREFERENCE 1 -PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(IN PVOID BaseAddress); +PLDR_DATA_TABLE_ENTRY NTAPI RtlAllocateDataTableEntry(_In_ PVOID BaseAddress); -bool NTAPI RtlInitializeLdrDataTableEntry(OUT PLDR_DATA_TABLE_ENTRY LdrEntry, IN DWORD dwFlags, IN PVOID BaseAddress, IN UNICODE_STRING& DllBaseName, IN UNICODE_STRING& DllFullName); +BOOL NTAPI RtlInitializeLdrDataTableEntry( + _Out_ PLDR_DATA_TABLE_ENTRY LdrEntry, + _In_ DWORD dwFlags, + _In_ PVOID BaseAddress, + _In_ UNICODE_STRING& DllBaseName, + _In_ UNICODE_STRING& DllFullName +); -bool NTAPI RtlFreeLdrDataTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry); +BOOL NTAPI RtlFreeLdrDataTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry); -NTSTATUS NTAPI RtlUpdateReferenceCount(IN OUT PMEMORYMODULE pModule, IN DWORD Flags); +NTSTATUS NTAPI RtlUpdateReferenceCount( + _Inout_ PMEMORYMODULE pModule, + _In_ DWORD Flags +); -NTSTATUS NTAPI RtlGetReferenceCount(IN PMEMORYMODULE pModule, OUT PULONG Count); +NTSTATUS NTAPI RtlGetReferenceCount( + _In_ PMEMORYMODULE pModule, + _Out_ PULONG Count +); -VOID NTAPI RtlInsertMemoryTableEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry); +VOID NTAPI RtlInsertMemoryTableEntry(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry); -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress); +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(_In_ PVOID BaseAddress); -PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName); +PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(_In_z_ PCWSTR BaseName); // // Loader Data Table Entry Flags @@ -50,10 +62,17 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(PCWSTR BaseName); #define LDR_GET_HASH_ENTRY(x) (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1)) #define LDR_HASH_TABLE_ENTRIES 32 -// RtlRbInsertNodeEx -VOID NTAPI RtlRbInsertNodeEx(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Parent, IN BOOLEAN Right, OUT PRTL_BALANCED_NODE Node); -// RtlRbRemoveNode -VOID NTAPI RtlRbRemoveNode(IN PRTL_RB_TREE Tree, IN PRTL_BALANCED_NODE Node); +VOID NTAPI RtlRbInsertNodeEx( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Parent, + _In_ BOOLEAN Right, + _Out_ PRTL_BALANCED_NODE Node +); + +VOID NTAPI RtlRbRemoveNode( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Node +); struct _LDR_DDAG_NODE_WIN8 { _LIST_ENTRY Modules; //0x0 @@ -326,9 +345,4 @@ typedef struct _LDR_DATA_TABLE_ENTRY_WIN10_2 { UCHAR SigningLevel; //0x11c }LDR_DATA_TABLE_ENTRY_WIN10_2, * PLDR_DATA_TABLE_ENTRY_WIN10_2; -ULONG NTAPI LdrHashEntry(IN UNICODE_STRING& str, IN bool _xor = true); - -#define RtlInitializeListEntry(entry) ((entry)->Blink = (entry)->Flink = (entry)) -#define RtlInitializeSingleEntry(entry) ((entry->Next = (entry))) - -size_t NTAPI LdrpDataTableEntrySize(); +ULONG NTAPI LdrHashEntry(_In_ UNICODE_STRING& str, _In_ BOOL _xor = TRUE); diff --git a/MemoryModule/LoadDllMemoryApi.cpp b/MemoryModule/LoadDllMemoryApi.cpp index 321d2fd..1d06a95 100644 --- a/MemoryModule/LoadDllMemoryApi.cpp +++ b/MemoryModule/LoadDllMemoryApi.cpp @@ -1,33 +1,43 @@ #include "stdafx.h" -HMEMORYMODULE WINAPI LoadLibraryMemory(PVOID BufferAddress) { +HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress) { HMEMORYMODULE hMemoryModule = nullptr; NTSTATUS status = LdrLoadDllMemory(&hMemoryModule, BufferAddress, 0); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { SetLastError(RtlNtStatusToDosError(status)); } return hMemoryModule; } -HMEMORYMODULE WINAPI LoadLibraryMemoryExA(PVOID BufferAddress, size_t Reserved, LPCSTR DllBaseName, LPCSTR DllFullName, DWORD Flags) { +HMEMORYMODULE WINAPI LoadLibraryMemoryExA( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCSTR DllBaseName, + _In_opt_ LPCSTR DllFullName, + _In_ DWORD Flags) { HMEMORYMODULE hMemoryModule = nullptr; NTSTATUS status = LdrLoadDllMemoryExA(&hMemoryModule, nullptr, Flags, BufferAddress, Reserved, DllBaseName, DllFullName); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { SetLastError(RtlNtStatusToDosError(status)); } return hMemoryModule; } -HMEMORYMODULE WINAPI LoadLibraryMemoryExW(PVOID BufferAddress, size_t Reserved, LPCWSTR DllBaseName, LPCWSTR DllFullName, DWORD Flags) { +HMEMORYMODULE WINAPI LoadLibraryMemoryExW( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCWSTR DllBaseName, + _In_opt_ LPCWSTR DllFullName, + _In_ DWORD Flags) { HMEMORYMODULE hMemoryModule = nullptr; NTSTATUS status = LdrLoadDllMemoryExW(&hMemoryModule, nullptr, Flags, BufferAddress, Reserved, DllBaseName, DllFullName); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { SetLastError(RtlNtStatusToDosError(status)); } return hMemoryModule; } -BOOL WINAPI FreeLibraryMemory(HMEMORYMODULE hMemoryModule) { +BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule) { NTSTATUS status = LdrUnloadDllMemory(hMemoryModule); if (!NT_SUCCESS(status)) { SetLastError(RtlNtStatusToDosError(status)); diff --git a/MemoryModule/LoadDllMemoryApi.h b/MemoryModule/LoadDllMemoryApi.h index 2c96247..54d8368 100644 --- a/MemoryModule/LoadDllMemoryApi.h +++ b/MemoryModule/LoadDllMemoryApi.h @@ -10,13 +10,25 @@ typedef HMODULE HMEMORYMODULE; #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) #endif -HMEMORYMODULE WINAPI LoadLibraryMemory(PVOID BufferAddress); +HMEMORYMODULE WINAPI LoadLibraryMemory(_In_ PVOID BufferAddress); -HMEMORYMODULE WINAPI LoadLibraryMemoryExA(PVOID BufferAddress, size_t Reserved, LPCSTR DllBaseName, LPCSTR DllFullName, DWORD Flags); +HMEMORYMODULE WINAPI LoadLibraryMemoryExA( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCSTR DllBaseName, + _In_opt_ LPCSTR DllFullName, + _In_ DWORD Flags +); -HMEMORYMODULE WINAPI LoadLibraryMemoryExW(PVOID BufferAddress, size_t Reserved, LPCWSTR DllBaseName, LPCWSTR DllFullName, DWORD Flags); +HMEMORYMODULE WINAPI LoadLibraryMemoryExW( + _In_ PVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCWSTR DllBaseName, + _In_opt_ LPCWSTR DllFullName, + _In_ DWORD Flags +); -BOOL WINAPI FreeLibraryMemory(HMEMORYMODULE hMemoryModule); +BOOL WINAPI FreeLibraryMemory(_In_ HMEMORYMODULE hMemoryModule); #define NtLoadDllMemory LdrLoadDllMemory #define NtLoadDllMemoryExA LdrLoadDllMemoryExA diff --git a/MemoryModule/Loader.cpp b/MemoryModule/Loader.cpp index 5dbf836..eb95b89 100644 --- a/MemoryModule/Loader.cpp +++ b/MemoryModule/Loader.cpp @@ -1,8 +1,12 @@ #include "stdafx.h" #include -static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlags, IN PCWSTR DllName OPTIONAL, - IN PCWSTR lpFullDllName OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY* DataTableEntry OPTIONAL) { +static NTSTATUS NTAPI LdrMapDllMemory( + _In_ HMEMORYMODULE ViewBase, + _In_ DWORD dwFlags, + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR lpFullDllName, + _Out_opt_ PLDR_DATA_TABLE_ENTRY* DataTableEntry) { UNICODE_STRING FullDllName, BaseDllName; PIMAGE_NT_HEADERS NtHeaders; @@ -13,7 +17,7 @@ static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlag if (!(LdrEntry = RtlAllocateDataTableEntry(ViewBase))) return STATUS_NO_MEMORY; - if (!RtlResolveDllNameUnicodeString(DllName, lpFullDllName, &BaseDllName, &FullDllName)) { + if (!NT_SUCCESS(RtlResolveDllNameUnicodeString(DllName, lpFullDllName, &BaseDllName, &FullDllName))) { RtlFreeHeap(heap, 0, LdrEntry); return STATUS_NO_MEMORY; } @@ -30,18 +34,21 @@ static NTSTATUS NTAPI LdrMapDllMemory(IN HMEMORYMODULE ViewBase, IN DWORD dwFlag return STATUS_SUCCESS; } -NTSTATUS NTAPI LdrLoadDllMemory(OUT HMEMORYMODULE* BaseAddress, IN LPVOID BufferAddress, IN size_t BufferSize) { - return LdrLoadDllMemoryExW(BaseAddress, nullptr, LOAD_FLAGS_NOT_FAIL_IF_HANDLE_TLS, BufferAddress, BufferSize, nullptr, nullptr); +NTSTATUS NTAPI LdrLoadDllMemory( + _Out_ HMEMORYMODULE* BaseAddress, + _In_ LPVOID BufferAddress, + _In_ size_t Reserved) { + return LdrLoadDllMemoryExW(BaseAddress, nullptr, 0, BufferAddress, Reserved, nullptr, nullptr); } NTSTATUS NTAPI LdrLoadDllMemoryExW( - OUT HMEMORYMODULE* BaseAddress, - OUT PVOID* LdrEntry OPTIONAL, - IN DWORD dwFlags, - IN LPVOID BufferAddress, - IN size_t BufferSize, - IN LPCWSTR DllName OPTIONAL, - IN LPCWSTR DllFullName OPTIONAL) { + _Out_ HMEMORYMODULE* BaseAddress, + _Out_opt_ PVOID* LdrEntry, + _In_ DWORD dwFlags, + _In_ LPVOID BufferAddress, + _In_ size_t BufferSize, + _In_opt_ LPCWSTR DllName, + _In_opt_ LPCWSTR DllFullName) { PMEMORYMODULE module = nullptr; NTSTATUS status = STATUS_SUCCESS; PLDR_DATA_TABLE_ENTRY ModuleEntry = nullptr; @@ -76,8 +83,8 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( /* Check if it's being unloaded */ if (!CurEntry->InMemoryOrderLinks.Flink) continue; /* Check if name matches */ - if (!wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || - !wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { + if (!_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, (CurEntry->BaseDllName.Length / sizeof(wchar_t)) - 4) || + !_wcsnicmp(DllName, CurEntry->BaseDllName.Buffer, CurEntry->BaseDllName.Length / sizeof(wchar_t))) { /* Let's compare their headers */ if (!(h2 = RtlImageNtHeader(CurEntry->DllBase)))continue; if (!(module = MapMemoryModuleHandle((HMEMORYMODULE)CurEntry->DllBase)))continue; @@ -94,7 +101,7 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( } } - status = MemoryLoadLibrary(BaseAddress, BufferAddress, BufferSize); + status = MemoryLoadLibrary(BaseAddress, BufferAddress, (DWORD)BufferSize); if (!NT_SUCCESS(status) || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)return status; if (!(module = MapMemoryModuleHandle(*BaseAddress))) { @@ -191,33 +198,33 @@ NTSTATUS NTAPI LdrLoadDllMemoryExW( } NTSTATUS NTAPI LdrLoadDllMemoryExA( - OUT HMEMORYMODULE* BaseAddress, - OUT PVOID* LdrEntry OPTIONAL, - IN DWORD dwFlags, - IN LPVOID BufferAddress, - IN size_t BufferSize, - IN LPCSTR DllName OPTIONAL, - IN LPCSTR DllFullName OPTIONAL){ + _Out_ HMEMORYMODULE* BaseAddress, + _Out_opt_ PVOID* LdrEntry, + _In_ DWORD dwFlags, + _In_ LPVOID BufferAddress, + _In_ size_t BufferSize, + _In_opt_ LPCSTR DllName, + _In_opt_ LPCSTR DllFullName) { LPWSTR _DllName = nullptr, _DllFullName = nullptr; size_t size; NTSTATUS status; if (DllName) { size = strlen(DllName) + 1; _DllName = new wchar_t[size]; - mbstowcs(_DllName, DllName, size); + mbstowcs_s(nullptr, _DllName, size, DllName, size); } if (DllFullName) { size = strlen(DllFullName) + 1; _DllFullName = new wchar_t[size]; - mbstowcs(_DllFullName, DllFullName, size); + mbstowcs_s(nullptr, _DllFullName, size, DllFullName, size); } status = LdrLoadDllMemoryExW(BaseAddress, LdrEntry, dwFlags, BufferAddress, BufferSize, _DllName, _DllFullName); - if (_DllName)delete[]_DllName; - if (_DllFullName)delete[]_DllFullName; + delete[]_DllName; + delete[]_DllFullName; return status; } -NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress) { +NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress) { __try { ProbeForRead(BaseAddress, sizeof(size_t)); } @@ -280,7 +287,7 @@ NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress) { } __declspec(noreturn) -VOID NTAPI LdrUnloadDllMemoryAndExitThread(IN HMEMORYMODULE BaseAddress, IN DWORD dwExitCode) { +VOID NTAPI LdrUnloadDllMemoryAndExitThread(_In_ HMEMORYMODULE BaseAddress, _In_ DWORD dwExitCode) { LdrUnloadDllMemory(BaseAddress); RtlExitUserThread(dwExitCode); } diff --git a/MemoryModule/Loader.h b/MemoryModule/Loader.h index 9217b12..2819b3e 100644 --- a/MemoryModule/Loader.h +++ b/MemoryModule/Loader.h @@ -2,9 +2,9 @@ //Load dll from the provided buffer. NTSTATUS NTAPI LdrLoadDllMemory( - OUT HMEMORYMODULE* BaseAddress, // Output module base address - IN LPVOID BufferAddress, // Pointer to the dll file data buffer - IN size_t Reserved // Reserved parameter, must be 0 + _Out_ HMEMORYMODULE* BaseAddress, // Output module base address + _In_ LPVOID BufferAddress, // Pointer to the dll file data buffer + _In_ size_t Reserved // Reserved parameter, must be 0 ); #define MEMORY_FEATURE_SUPPORT_VERSION 0x00000001 @@ -56,27 +56,27 @@ NTSTATUS NTAPI LdrQuerySystemMemoryModuleFeatures(_Out_ PDWORD pFeatures); NTSTATUS NTAPI LdrLoadDllMemoryExW( - OUT HMEMORYMODULE* BaseAddress, // Output module base address - OUT PVOID* LdrEntry OPTIONAL, // Receive a pointer to the LDR node of the module - IN DWORD dwFlags, // Flags - IN LPVOID BufferAddress, // Pointer to the dll file data buffer - IN size_t Reserved, // Reserved parameter, must be 0 - IN LPCWSTR DllName OPTIONAL, // Module file name - IN LPCWSTR DllFullName OPTIONAL // Module file full path + _Out_ HMEMORYMODULE* BaseAddress, // Output module base address + _Out_opt_ PVOID* LdrEntry, // Receive a pointer to the LDR node of the module + _In_ DWORD dwFlags, // Flags + _In_ LPVOID BufferAddress, // Pointer to the dll file data buffer + _In_ size_t Reserved, // Reserved parameter, must be 0 + _In_opt_ LPCWSTR DllName, // Module file name + _In_opt_ LPCWSTR DllFullName // Module file full path ); NTSTATUS NTAPI LdrLoadDllMemoryExA( - OUT HMEMORYMODULE* BaseAddress, - OUT PVOID* LdrEntry OPTIONAL, - IN DWORD dwFlags, - IN LPVOID BufferAddress, - IN size_t Reserved, - IN LPCSTR DllName OPTIONAL, - IN LPCSTR DllFullName OPTIONAL + _Out_ HMEMORYMODULE* BaseAddress, + _Out_opt_ PVOID* LdrEntry, + _In_ DWORD dwFlags, + _In_ LPVOID BufferAddress, + _In_ size_t Reserved, + _In_opt_ LPCSTR DllName, + _In_opt_ LPCSTR DllFullName ); //Unload modules previously loaded from memory -NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress); +NTSTATUS NTAPI LdrUnloadDllMemory(_In_ HMEMORYMODULE BaseAddress); #ifndef _USRDLL #ifdef _WIN64 @@ -89,5 +89,8 @@ NTSTATUS NTAPI LdrUnloadDllMemory(IN HMEMORYMODULE BaseAddress); #endif extern "C" { - __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread(IN HMEMORYMODULE BaseAddress, IN DWORD dwExitCode); + __declspec(noreturn) VOID NTAPI LdrUnloadDllMemoryAndExitThread( + _In_ HMEMORYMODULE BaseAddress, + _In_ DWORD dwExitCode + ); } diff --git a/MemoryModule/MemoryModule.cpp b/MemoryModule/MemoryModule.cpp index 6c1731f..5474069 100644 --- a/MemoryModule/MemoryModule.cpp +++ b/MemoryModule/MemoryModule.cpp @@ -51,7 +51,7 @@ PMEMORYMODULE WINAPI MapMemoryModuleHandle(HMEMORYMODULE hModule) { return pModule; } -bool WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule) { +BOOL WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule) { return MapMemoryModuleHandle(hModule) != nullptr; } @@ -81,16 +81,12 @@ NTSTATUS MemoryResolveImportTable( } if (importDesc && count) { - if (!(hMemoryModule->hModulesList = new HMODULE[count])) { + hMemoryModule->hModulesList = (HMODULE*)RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof(HMODULE) * count); + if (!hMemoryModule->hModulesList) { status = STATUS_NO_MEMORY; break; } - RtlZeroMemory( - hMemoryModule->hModulesList, - sizeof(HMODULE) * count - ); - for (DWORD i = 0; i < count; ++i, ++importDesc) { uintptr_t* thunkRef; FARPROC* funcRef; @@ -131,7 +127,7 @@ NTSTATUS MemoryResolveImportTable( for (DWORD i = 0; i < hMemoryModule->dwModulesCount; ++i) FreeLibrary(hMemoryModule->hModulesList[i]); - delete[]hMemoryModule->hModulesList; + RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, hMemoryModule->hModulesList); hMemoryModule->hModulesList = nullptr; hMemoryModule->dwModulesCount = 0; } @@ -406,21 +402,22 @@ NTSTATUS MemoryLoadLibrary( return status; } -bool MemoryFreeLibrary(HMEMORYMODULE mod) { +BOOL MemoryFreeLibrary(HMEMORYMODULE mod) { PMEMORYMODULE module = MapMemoryModuleHandle(mod); PIMAGE_NT_HEADERS headers = RtlImageNtHeader(mod); - if (!module) return false; - if (module->loadFromNtLoadDllMemory && !module->underUnload)return false; + if (!module) return FALSE; + if (module->loadFromNtLoadDllMemory && !module->underUnload)return FALSE; if (module->hModulesList) { for (DWORD i = 0; i < module->dwModulesCount; ++i) { if (module->hModulesList[i]) { FreeLibrary(module->hModulesList[i]); } } - delete[] module->hModulesList; + + RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, module->hModulesList); } if (module->codeBase) VirtualFree(mod, 0, MEM_RELEASE); - return true; + return TRUE; } diff --git a/MemoryModule/MemoryModule.h b/MemoryModule/MemoryModule.h index b0b14ec..db1bf2e 100644 --- a/MemoryModule/MemoryModule.h +++ b/MemoryModule/MemoryModule.h @@ -1,5 +1,4 @@ #pragma once -#pragma warning(disable:4996) #ifndef __MEMORY_MODULE_HEADER #define __MEMORY_MODULE_HEADER @@ -81,9 +80,9 @@ extern "C" { _In_ PIMAGE_NT_HEADERS lpNtHeaders ); - bool MemoryFreeLibrary(HMEMORYMODULE); + BOOL MemoryFreeLibrary(HMEMORYMODULE); - bool WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule); + BOOL WINAPI IsValidMemoryModuleHandle(HMEMORYMODULE hModule); PMEMORYMODULE WINAPI MapMemoryModuleHandle(HMEMORYMODULE hModule); diff --git a/MemoryModule/MmpGlobalData.h b/MemoryModule/MmpGlobalData.h index d672a7f..42d8b08 100644 --- a/MemoryModule/MmpGlobalData.h +++ b/MemoryModule/MmpGlobalData.h @@ -59,6 +59,19 @@ typedef struct _MMP_DOT_NET_DATA { }Hooks; }MMP_DOT_NET_DATA, * PMMP_DOT_NET_DATA; +typedef enum class _WINDOWS_VERSION :BYTE { + null, + xp, + vista, + win7, + win8, + win8_1, + win10, + win10_1, + win10_2, + invalid +}WINDOWS_VERSION; + typedef struct _MMP_GLOBAL_DATA { WORD MajorVersion; @@ -66,6 +79,16 @@ typedef struct _MMP_GLOBAL_DATA { DWORD MmpFeatures; + struct { + DWORD MajorVersion; + DWORD MinorVersion; + DWORD BuildNumber; + }NtVersions; + + WINDOWS_VERSION WindowsVersion; + + WORD LdrDataTableEntrySize; + SYSTEM_INFO SystemInfo; MMP_BASE_ADDRESS_INDEX_DATA MmpBaseAddressIndex; diff --git a/MemoryModule/MmpTls.cpp b/MemoryModule/MmpTls.cpp index 7887635..61842d0 100644 --- a/MemoryModule/MmpTls.cpp +++ b/MemoryModule/MmpTls.cpp @@ -513,7 +513,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( } Tls->OperationType = ProcessTlsReplaceIndex; - for (auto i = 0; i < Tls->ThreadDataCount; ++i) { + for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) { Tls->ThreadData[i].TlsModulePointer = Tls->ThreadData[i].TlsVector[ProcessTlsInformation->TlsVectorLength]; } } @@ -543,7 +543,7 @@ NTSTATUS NTAPI HookNtSetInformationProcess( // Modify our mapping // EnterCriticalSection(&MmpGlobalDataPtr->MmpTls.MmpTlspLock); - for (auto i = 0; i < Tls->ThreadDataCount; ++i) { + for (ULONG i = 0; i < Tls->ThreadDataCount; ++i) { bool found = false; PLIST_ENTRY entry = MmpGlobalDataPtr->MmpTls.MmpThreadLocalStoragePointer.Flink; @@ -769,7 +769,7 @@ NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry) { nullptr, // hack PROCESSINFOCLASS::ProcessTlsInformation, ProcessTlsInformation, - Length + (ULONG)Length ); for (DWORD i = 0; i < ProcessTlsInformation->ThreadDataCount; ++i) { diff --git a/MemoryModule/MmpTls.h b/MemoryModule/MmpTls.h index ebcc64a..33de5c9 100644 --- a/MemoryModule/MmpTls.h +++ b/MemoryModule/MmpTls.h @@ -2,6 +2,6 @@ BOOL NTAPI MmpTlsInitialize(); -NTSTATUS NTAPI MmpReleaseTlsEntry(PLDR_DATA_TABLE_ENTRY lpModuleEntry); +NTSTATUS NTAPI MmpReleaseTlsEntry(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); -NTSTATUS NTAPI MmpHandleTlsData(PLDR_DATA_TABLE_ENTRY lpModuleEntry); +NTSTATUS NTAPI MmpHandleTlsData(_In_ PLDR_DATA_TABLE_ENTRY lpModuleEntry); diff --git a/MemoryModule/Utils.cpp b/MemoryModule/Utils.cpp index 3fe4e27..aa58470 100644 --- a/MemoryModule/Utils.cpp +++ b/MemoryModule/Utils.cpp @@ -2,68 +2,115 @@ #include #pragma comment(lib,"ntdll.lib") -bool NTAPI RtlResolveDllNameUnicodeString( - IN PCWSTR DllName OPTIONAL, IN PCWSTR DllFullName OPTIONAL, - OUT PUNICODE_STRING BaseDllName, OUT PUNICODE_STRING FullDllName) { +NTSTATUS NTAPI RtlResolveDllNameUnicodeString( + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR DllFullName, + _Out_ PUNICODE_STRING BaseDllName, + _Out_ PUNICODE_STRING FullDllName) { std::random_device random; - size_t Length = 0; - size_t FullLength = 0; - PWSTR _DllName = nullptr, _DllFullName = _DllName; HANDLE heap = NtCurrentPeb()->ProcessHeap; - bool result = false; - if (DllName) { - bool add = false; - if ((Length = wcslen(DllName)) <= 4 || wcsnicmp(DllName + Length - 4, L".dll", 4)) { - add = true; - Length += 4; - } - _DllName = new wchar_t[++Length]; - wcscpy(_DllName, DllName); - if (add)wcscat(_DllName, L".DLL"); - } - else { - Length = 16 + 4 + 1; //hex(ULONG64) + ".dll" + '\0' - _DllName = new wchar_t[Length]; - swprintf(_DllName, L"%016llX.DLL", ((ULONG64)random() << 32) | random()); - } - if (DllFullName) { - bool add = false; - FullLength = wcslen(DllFullName); - if (DllName && !wcsstr(DllFullName, DllName) && wcsnicmp(DllFullName + FullLength - 4, L".dll", 4)) { - add = true; - FullLength += Length; - } - wcscpy(_DllFullName = new wchar_t[++FullLength], DllFullName); - if (add) swprintf(_DllFullName, L"%s\\%s", _DllFullName, _DllName); - } - else { - FullLength = 16 + 1 + Length; //hex(ULONG64) + '\\' + _DllName - swprintf(_DllFullName = new wchar_t[FullLength], L"%016llX\\%s", ((ULONG64)random() << 32) | random(), _DllName); - } - FullLength *= sizeof(wchar_t); - Length *= sizeof(wchar_t); + NTSTATUS status = STATUS_SUCCESS; + size_t length; - /* Allocate space for full DLL name */ - if (!(FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, FullLength))) goto end; - FullDllName->Length = FullLength - sizeof(wchar_t); - FullDllName->MaximumLength = FullLength; - wcscpy(FullDllName->Buffer, _DllFullName); + RtlZeroMemory(BaseDllName, sizeof(*BaseDllName)); + RtlZeroMemory(FullDllName, sizeof(*FullDllName)); - /* Construct base DLL name */ - BaseDllName->Length = Length - sizeof(wchar_t); - BaseDllName->MaximumLength = Length; - BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, Length); - if (!BaseDllName->Buffer) { + do { + + if (DllName && *DllName) { + bool extend = false; + + length = wcslen(DllName); + if (length <= 4 || _wcsnicmp(DllName + length - 4, L".dll", 4)) { + length += 4; + extend = true; + } + + if (++length >= 0xffff) { + status = STATUS_OBJECT_NAME_INVALID; + break; + } + + BaseDllName->MaximumLength = (USHORT)(length * sizeof(WCHAR)); + BaseDllName->Length = BaseDllName->MaximumLength - sizeof(WCHAR); + BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, BaseDllName->MaximumLength); + if (!BaseDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(BaseDllName->Buffer, length, extend ? L"%s.dll" : L"%s", DllName); + } + else { + DllName = nullptr; + + BaseDllName->MaximumLength = (16 + 4 + 1) * sizeof(WCHAR); //hex(ULONG64) + ".dll" + '\0' + BaseDllName->Length = BaseDllName->MaximumLength - sizeof(WCHAR); + BaseDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, BaseDllName->MaximumLength); + if (!BaseDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(BaseDllName->Buffer, BaseDllName->MaximumLength / sizeof(WCHAR), L"%016llX.DLL", ((ULONG64)random() << 32) | random()); + } + + if (DllFullName && *DllFullName) { + bool extend = false, backslash = false; + + unsigned int wc = BaseDllName->Length / sizeof(WCHAR); + length = wcslen(DllFullName); + if (length <= wc + 1 || _wcsicmp(DllFullName + length - wc, BaseDllName->Buffer) || *(DllFullName + length - wc - 1) != '\\') { + extend = true; + + if (DllFullName[length - 1] != '\\') { + backslash = true; + + ++length; + } + + length += BaseDllName->Length / sizeof(WCHAR); + } + + if (++length >= 0xffff) { + status = STATUS_OBJECT_NAME_INVALID; + break; + } + + FullDllName->MaximumLength = (USHORT)(length * sizeof(WCHAR)); + FullDllName->Length = FullDllName->MaximumLength - sizeof(WCHAR); + FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, FullDllName->MaximumLength); + if (!FullDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(FullDllName->Buffer, length, extend ? backslash ? L"%s\\%s" : L"%s%s" : L"%s", DllFullName, BaseDllName->Buffer); + } + else { + FullDllName->MaximumLength = (16 + 1 + 1) * sizeof(WCHAR) + BaseDllName->Length; //hex(ULONG64) + '\\' + BaseDllName + '\0' + FullDllName->Length = FullDllName->MaximumLength - sizeof(WCHAR); + FullDllName->Buffer = (PWSTR)RtlAllocateHeap(heap, 0, FullDllName->MaximumLength); + if (!FullDllName->Buffer) { + status = STATUS_NO_MEMORY; + break; + } + + swprintf_s(FullDllName->Buffer, FullDllName->MaximumLength / sizeof(WCHAR), L"%016llX\\%s", ((ULONG64)random() << 32) | random(), BaseDllName->Buffer); + } + + } while (false); + + if (!NT_SUCCESS(status)) { RtlFreeHeap(heap, 0, BaseDllName->Buffer); - goto end; + RtlFreeHeap(heap, 0, FullDllName->Buffer); + + RtlZeroMemory(BaseDllName, sizeof(*BaseDllName)); + RtlZeroMemory(FullDllName, sizeof(*FullDllName)); } - wcscpy(BaseDllName->Buffer, _DllName); - result = true; -end: - delete[]_DllName; - delete[]_DllFullName; - return result; + + return status; } BOOL NTAPI LdrpExecuteTLS(PMEMORYMODULE module) { @@ -118,9 +165,9 @@ SIZE_T NTAPI _RtlCompareMemory( #endif NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( - IN HMODULE hModule OPTIONAL, - IN LPCSTR lpSectionName OPTIONAL, - IN OUT PSEARCH_CONTEXT SearchContext) { + _In_ HMODULE hModule, + _In_ LPCSTR lpSectionName, + _Inout_ PSEARCH_CONTEXT SearchContext) { NTSTATUS status = STATUS_SUCCESS; size_t begin = 0, buffer = 0; @@ -142,7 +189,7 @@ NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( if (!headers)return STATUS_INVALID_PARAMETER_1; section = IMAGE_FIRST_SECTION(headers); for (WORD i = 0; i < headers->FileHeader.NumberOfSections; ++i) { - if (!_stricmp(lpSectionName, (LPCSTR)section->Name)) { + if (!_strnicmp(lpSectionName, (LPCSTR)section->Name, 8)) { begin = SearchContext->OutBufferPtr = (size_t)hModule + section->VirtualAddress; Length = SearchContext->RemainingLength = section->Misc.VirtualSize; break; @@ -256,7 +303,7 @@ BOOLEAN NTAPI RtlIsValidImageBuffer( IMAGE_FIRST_SECTION(headers.nt32); ProbeForRead(Buffer, SizeofImage); if (Size)*Size = SizeofImage; - result = CheckSumBufferedFile(Buffer, SizeofImage); + result = CheckSumBufferedFile(Buffer, (DWORD)SizeofImage); } __except (EXCEPTION_EXECUTE_HANDLER) { SetLastError(RtlNtStatusToDosError(GetExceptionCode())); @@ -268,20 +315,6 @@ FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name) { return GetProcAddress(GetModuleHandleA("ntdll.dll"), func_name); } -VOID NTAPI RtlGetNtVersionNumbersEx(OUT DWORD* MajorVersion, OUT DWORD* MinorVersion, OUT DWORD* BuildNumber) { - static DWORD Versions[3]{ 0 }; - - if (Versions[0]) goto ret; - RtlGetNtVersionNumbers(Versions, Versions + 1, Versions + 2); - if (Versions[2] & 0xf0000000)Versions[2] &= 0xffff; - -ret: - if (MajorVersion)*MajorVersion = Versions[0]; - if (MinorVersion)*MinorVersion = Versions[1]; - if (BuildNumber)*BuildNumber = Versions[2]; - return; -} - BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect) { if (size) { MEMORY_BASIC_INFORMATION mbi{}; @@ -302,113 +335,44 @@ BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK prote return TRUE; } -bool NTAPI RtlVerifyVersion(IN DWORD MajorVersion, IN DWORD MinorVersion OPTIONAL, IN DWORD BuildNumber OPTIONAL, IN BYTE Flags) { - DWORD Versions[3]; - RtlGetNtVersionNumbersEx(Versions, Versions + 1, Versions + 2); - if (Versions[0] == MajorVersion && - ((Flags & RTL_VERIFY_FLAGS_MINOR_VERSION) ? Versions[1] == MinorVersion : true) && - ((Flags & RTL_VERIFY_FLAGS_BUILD_NUMBERS) ? Versions[2] == BuildNumber : true))return true; - return false; +BOOL NTAPI RtlVerifyVersion( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber, + _In_ BYTE Flags +) { + if (MmpGlobalDataPtr->NtVersions.MajorVersion == MajorVersion && + ((Flags & RTL_VERIFY_FLAGS_MINOR_VERSION) ? MmpGlobalDataPtr->NtVersions.MinorVersion == MinorVersion : true) && + ((Flags & RTL_VERIFY_FLAGS_BUILD_NUMBERS) ? MmpGlobalDataPtr->NtVersions.BuildNumber == BuildNumber : true))return TRUE; + return FALSE; } -bool NTAPI RtlIsWindowsVersionOrGreater(IN DWORD MajorVersion, IN DWORD MinorVersion, IN DWORD BuildNumber) { - static DWORD Versions[3]{}; - if (!Versions[0])RtlGetNtVersionNumbersEx(Versions, Versions + 1, Versions + 2); - - if (Versions[0] == MajorVersion) { - if (Versions[1] == MinorVersion) return Versions[2] >= BuildNumber; - else return (Versions[1] > MinorVersion); +BOOL NTAPI RtlIsWindowsVersionOrGreater( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber +) { + if (MmpGlobalDataPtr->NtVersions.MajorVersion == MajorVersion) { + if (MmpGlobalDataPtr->NtVersions.MinorVersion == MinorVersion) return MmpGlobalDataPtr->NtVersions.BuildNumber >= BuildNumber; + else return (MmpGlobalDataPtr->NtVersions.MinorVersion > MinorVersion); } - else return Versions[0] > MajorVersion; + else return MmpGlobalDataPtr->NtVersions.MajorVersion > MajorVersion; } -bool NTAPI RtlIsWindowsVersionInScope( - IN DWORD MinMajorVersion, IN DWORD MinMinorVersion, IN DWORD MinBuildNumber, - IN DWORD MaxMajorVersion, IN DWORD MaxMinorVersion, IN DWORD MaxBuildNumber) { +BOOL NTAPI RtlIsWindowsVersionInScope( + _In_ DWORD MinMajorVersion, + _In_ DWORD MinMinorVersion, + _In_ DWORD MinBuildNumber, + + _In_ DWORD MaxMajorVersion, + _In_ DWORD MaxMinorVersion, + _In_ DWORD MaxBuildNumber +) { return RtlIsWindowsVersionOrGreater(MinMajorVersion, MinMinorVersion, MinBuildNumber) && !RtlIsWindowsVersionOrGreater(MaxMajorVersion, MaxMinorVersion, MaxBuildNumber); } -WINDOWS_VERSION NTAPI NtWindowsVersion() { - static WINDOWS_VERSION version = null; - DWORD versions[3]{}; - if (version)return version; - RtlGetNtVersionNumbersEx(versions, versions + 1, versions + 2); - - switch (versions[0]) { - case 5: { - switch (versions[1]) { - case 1:return version = versions[2] == 2600 ? xp : invalid; - case 2:return version = versions[2] == 3790 ? xp : invalid; - default:break; - } - break; - } - break; - case 6: { - switch (versions[1]) { - case 0: { - switch (versions[2]) { - case 6000: - case 6001: - case 6002: - return version = vista; - default: - break; - } - break; - } - break; - case 1: { - switch (versions[2]) { - case 7600: - case 7601: - return version = win7; - default: - break; - } - break; - } - break; - case 2: { - if (versions[2] == 9200)return version = win8; - break; - } - break; - case 3: { - if (versions[2] == 9600)return version = win8_1; - break; - } - break; - default: - break; - } - break; - } - break; - case 10: { - if (versions[1])break; - switch (versions[2]) { - case 10240: - case 10586: return version = win10; - case 14393: return version = win10_1; - case 15063: - case 16299: - case 17134: - case 17763: - case 18362:return version = win10_2; - default:if (RtlIsWindowsVersionOrGreater(versions[0], versions[1], 15063))return version = win10_2; - break; - } - break; - } - break; - default: - break; - } - return version = invalid; -} - +#ifndef _WIN64 int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount) { PIMAGE_LOAD_CONFIG_DIRECTORY pLoadConfigDirectory; PIMAGE_COR20_HEADER pCor20; @@ -436,3 +400,4 @@ int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTabl *SEHandlerTable = *SEHandlerCount = ((pCor20 && pCor20->Flags & 1) ? -1 : 0); return 0; } +#endif diff --git a/MemoryModule/Utils.h b/MemoryModule/Utils.h index afe375d..8d945fd 100644 --- a/MemoryModule/Utils.h +++ b/MemoryModule/Utils.h @@ -21,28 +21,31 @@ typedef struct _SEARCH_CONTEXT { }SEARCH_CONTEXT, * PSEARCH_CONTEXT; NTSTATUS NTAPI RtlFindMemoryBlockFromModuleSection( - IN HMODULE hModule OPTIONAL, - IN LPCSTR lpSectionName OPTIONAL, - IN OUT PSEARCH_CONTEXT SearchContext + _In_ HMODULE hModule, + _In_ LPCSTR lpSectionName, + _Inout_ PSEARCH_CONTEXT SearchContext ); typedef BOOL(WINAPI* PDLL_STARTUP_ROUTINE)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); -bool NTAPI RtlResolveDllNameUnicodeString(IN PCWSTR DllName OPTIONAL, IN PCWSTR DllFullName OPTIONAL, OUT PUNICODE_STRING BaseDllName, OUT PUNICODE_STRING FullDllName); +NTSTATUS NTAPI RtlResolveDllNameUnicodeString( + _In_opt_ PCWSTR DllName, + _In_opt_ PCWSTR DllFullName, + _Out_ PUNICODE_STRING BaseDllName, + _Out_ PUNICODE_STRING FullDllName +); BOOL NTAPI LdrpExecuteTLS(PMEMORYMODULE module); BOOL NTAPI LdrpCallInitializers(PMEMORYMODULE module, DWORD dwReason); -BOOLEAN NTAPI RtlIsValidImageBuffer(PVOID Buffer, size_t* Size); +BOOLEAN NTAPI RtlIsValidImageBuffer( + _In_ PVOID Buffer, + _Out_opt_ size_t* Size +); FARPROC NTAPI RtlGetNtProcAddress(LPCSTR func_name); -VOID NTAPI RtlGetNtVersionNumbersEx( - OUT DWORD* MajorVersion, - OUT DWORD* MinorVersion, - OUT DWORD* BuildNumber); - BOOLEAN NTAPI VirtualAccessCheck(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS_MASK protect); #define ProbeForRead(pBuffer, size) VirtualAccessCheck(pBuffer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE) @@ -62,29 +65,29 @@ BOOLEAN NTAPI VirtualAccessCheckNoException(LPCVOID pBuffer, size_t size, ACCESS #define RTL_VERIFY_FLAGS_BUILD_NUMBERS 2 #define RTL_VERIFY_FLAGS_DEFAULT RTL_VERIFY_FLAGS_MAJOR_VERSION|RTL_VERIFY_FLAGS_MINOR_VERSION|RTL_VERIFY_FLAGS_BUILD_NUMBERS -bool NTAPI RtlVerifyVersion(IN DWORD MajorVersion, IN DWORD MinorVersion OPTIONAL, IN DWORD BuildNumber OPTIONAL, IN BYTE Flags); - -bool NTAPI RtlIsWindowsVersionOrGreater(IN DWORD MajorVersion, IN DWORD MinorVersion, IN DWORD BuildNumber); - -bool NTAPI RtlIsWindowsVersionInScope( - IN DWORD MinMajorVersion, IN DWORD MinMinorVersion, IN DWORD MinBuildNumber, - IN DWORD MaxMajorVersion, IN DWORD MaxMinorVersion, IN DWORD MaxBuildNumber +BOOL NTAPI RtlVerifyVersion( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber, + _In_ BYTE Flags ); +BOOL NTAPI RtlIsWindowsVersionOrGreater( + _In_ DWORD MajorVersion, + _In_ DWORD MinorVersion, + _In_ DWORD BuildNumber +); -typedef enum _WINDOWS_VERSION { - null, - xp, - vista, - win7, - win8, - win8_1, - win10, - win10_1, - win10_2, - invalid -}WINDOWS_VERSION; +BOOL NTAPI RtlIsWindowsVersionInScope( + _In_ DWORD MinMajorVersion, + _In_ DWORD MinMinorVersion, + _In_ DWORD MinBuildNumber, -WINDOWS_VERSION NTAPI NtWindowsVersion(); + _In_ DWORD MaxMajorVersion, + _In_ DWORD MaxMinorVersion, + _In_ DWORD MaxBuildNumber +); +#ifndef _WIN64 int NTAPI RtlCaptureImageExceptionValues(PVOID BaseAddress, PDWORD SEHandlerTable, PDWORD SEHandlerCount); +#endif diff --git a/MemoryModulePP.sln b/MemoryModulePP.sln index 21ce55a..0b985a5 100644 --- a/MemoryModulePP.sln +++ b/MemoryModulePP.sln @@ -19,12 +19,12 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.ActiveCfg = Debug|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x64.Build.0 = Debug|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = DebugDll|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = DebugDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.ActiveCfg = Debug|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Debug|x86.Build.0 = Debug|Win32 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.ActiveCfg = Release|x64 {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x64.Build.0 = Release|x64 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = ReleaseDll|Win32 - {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = ReleaseDll|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.ActiveCfg = Release|Win32 + {5B1F46DB-036E-4A50-AF5F-F5D6584D42C6}.Release|x86.Build.0 = Release|Win32 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.ActiveCfg = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Build.0 = Debug|x64 {5B3131BA-178A-4A28-BD54-315A45C97ED1}.Debug|x64.Deploy.0 = Debug|x64 diff --git a/a/load.cpp b/a/load.cpp index 5262540..72babcb 100644 --- a/a/load.cpp +++ b/a/load.cpp @@ -4,7 +4,8 @@ static PVOID ReadDllFile(LPCSTR FileName) { LPVOID buffer; size_t size; - FILE* f = fopen(FileName, "rb"); + FILE* f; + fopen_s(&f, FileName, "rb"); if (!f)return 0; _fseeki64(f, 0, SEEK_END); if (!(size = _ftelli64(f))) { diff --git a/test/test.cpp b/test/test.cpp index f5a7ac2..701ac74 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,11 +1,11 @@ #include "../MemoryModule/stdafx.h" #include -#pragma warning(disable:4996) static PVOID ReadDllFile(LPCSTR FileName) { LPVOID buffer; size_t size; - FILE* f = fopen(FileName, "rb"); + FILE* f; + fopen_s(&f, FileName, "rb"); if (!f)return 0; _fseeki64(f, 0, SEEK_END); if (!(size = _ftelli64(f))) { @@ -30,8 +30,8 @@ int test() { 0, // Flags buffer, // Buffer 0, // Reserved - L"a.dll", // DllBaseName - L"C:\\Windows\\System32\\a.dll" // DllFullName + nullptr, // DllBaseName + nullptr // DllFullName ); if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) {