forked from bb107/MemoryModulePP
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrtlldr.cpp
More file actions
124 lines (106 loc) · 4.43 KB
/
rtlldr.cpp
File metadata and controls
124 lines (106 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "rtlldr.h"
#pragma warning(disable:4996)
PLDR_DATA_TABLE_ENTRY const LdrpNtdllBase = RtlFindLdrTableEntryByBaseName(L"ntdll.dll");
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"));
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"));
if (!_RtlRbRemoveNode)return;
return _RtlRbRemoveNode(Tree, Node);
}
PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(PVOID BaseAddress) {
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 (CurEntry->DllBase == BaseAddress) {
return CurEntry;
}
}
return nullptr;
}
PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(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))) {
return CurEntry;
}
}
return nullptr;
}
ULONG NTAPI LdrHashEntry(IN const UNICODE_STRING& str, IN bool _xor) {
ULONG result = 0;
if (RtlIsWindowsVersionOrGreater(6, 2, 0)) {
RtlHashUnicodeString(&str, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &result);
}
else {
for (USHORT i = 0; i < (str.Length / sizeof(wchar_t)); ++i)
result += 0x1003F * RtlUpcaseUnicodeChar(str.Buffer[i]);
}
if (_xor)result &= (LDR_HASH_TABLE_ENTRIES - 1);
return result;
}
HANDLE NTAPI RtlFindLdrpHeap() {
PLIST_ENTRY ListHead, ListEntry;
PLDR_DATA_TABLE_ENTRY CurEntry;
MEMORY_BASIC_INFORMATION mbi{};
static HANDLE result = nullptr;
if (result)return result;
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
ListEntry = ListHead->Flink;
if (ListHead == ListEntry)return result;
CurEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
NtQueryVirtualMemory(NtCurrentProcess(), CurEntry, MemoryBasicInformation, &mbi, sizeof(mbi), (PSIZE_T)&ListHead);
return result = mbi.AllocationBase;
}
PLIST_ENTRY NTAPI RtlFindLdrpHashTable() {
static PLIST_ENTRY list = nullptr;
if (list) return list;
PLIST_ENTRY head = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList, entry = head->Flink;
PLDR_DATA_TABLE_ENTRY CurEntry = nullptr;
while (head != entry) {
CurEntry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, LDR_DATA_TABLE_ENTRY::InInitializationOrderLinks);
entry = entry->Flink;
if (CurEntry->HashLinks.Flink == &CurEntry->HashLinks)continue;
list = CurEntry->HashLinks.Flink;
if (list->Flink == &CurEntry->HashLinks) {
list = (decltype(list))((size_t)CurEntry->HashLinks.Flink - LdrHashEntry(CurEntry->BaseDllName) * sizeof(_LIST_ENTRY));
break;
}
list = nullptr;
}
return list;
}
PVOID NTAPI RtlAllocateLdrpHeap(IN size_t size) {
HANDLE heap = RtlFindLdrpHeap();
if (!heap)return nullptr;
return RtlAllocateHeap(heap, HEAP_ZERO_MEMORY, size);
}
BOOL NTAPI RtlFreeLdrpHeap(IN PVOID buffer) {
HANDLE LdrpHeap = RtlFindLdrpHeap();
if (!LdrpHeap)return FALSE;
return RtlFreeHeap(LdrpHeap, 0, buffer);
}
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);
}
}