mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
refactoring
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+142
-7
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
+70
-74
@@ -1,7 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include <cstddef>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
+32
-18
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
+35
-28
@@ -1,8 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include <cstdlib>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
+22
-19
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
+137
-172
@@ -2,68 +2,115 @@
|
||||
#include <random>
|
||||
#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
|
||||
|
||||
+33
-30
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user