refactoring

This commit is contained in:
Boring
2022-10-03 17:25:02 +08:00
parent 1af4e81913
commit ff8a663aca
21 changed files with 581 additions and 400 deletions
+4 -2
View File
@@ -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);
+5 -2
View File
@@ -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
View File
@@ -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();
+12 -5
View File
@@ -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;
+6 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+17 -7
View File
@@ -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));
+16 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
);
}
+10 -13
View File
@@ -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;
}
+2 -3
View File
@@ -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);
+23
View File
@@ -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;
+3 -3
View File
@@ -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 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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