mirror of
https://github.com/bb107/MemoryModulePP
synced 2026-06-08 13:15:33 +00:00
refactoring
This commit is contained in:
@@ -1,25 +1,43 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
VOID RtlRbInsertNodeEx(
|
||||
_In_ PRTL_RB_TREE Tree,
|
||||
_In_ PRTL_BALANCED_NODE Parent,
|
||||
_In_ BOOLEAN Right,
|
||||
_Out_ PRTL_BALANCED_NODE Node) {
|
||||
RtlZeroMemory(Node, sizeof(*Node));
|
||||
|
||||
if (!MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx)return;
|
||||
return decltype(&RtlRbInsertNodeEx)(MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx)(Tree, Parent, Right, Node);
|
||||
}
|
||||
|
||||
VOID RtlRbRemoveNode(
|
||||
_In_ PRTL_RB_TREE Tree,
|
||||
_In_ PRTL_BALANCED_NODE Node) {
|
||||
if (!MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode)return;
|
||||
return decltype(&RtlRbRemoveNode)(MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode)(Tree, Node);
|
||||
}
|
||||
|
||||
NTSTATUS NTAPI RtlInsertModuleBaseAddressIndexNode(
|
||||
_In_ PLDR_DATA_TABLE_ENTRY DataTableEntry,
|
||||
_In_ PVOID BaseAddress) {
|
||||
auto LdrpModuleBaseAddressIndex = MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex;
|
||||
if (!LdrpModuleBaseAddressIndex)return STATUS_UNSUCCESSFUL;
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY_WIN8 LdrNode = decltype(LdrNode)((size_t)LdrpModuleBaseAddressIndex - offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode));
|
||||
PLDR_DATA_TABLE_ENTRY_WIN8 LdrNode = CONTAINING_RECORD(LdrpModuleBaseAddressIndex, LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode);
|
||||
bool bRight = false;
|
||||
const auto i = offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode);
|
||||
|
||||
while (true) {
|
||||
if (BaseAddress < LdrNode->DllBase) {
|
||||
if (!LdrNode->BaseAddressIndexNode.Left)break;
|
||||
LdrNode = decltype(LdrNode)((size_t)LdrNode->BaseAddressIndexNode.Left - offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode));
|
||||
LdrNode = CONTAINING_RECORD(LdrNode->BaseAddressIndexNode.Left, LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode);
|
||||
}
|
||||
else if (BaseAddress > LdrNode->DllBase) {
|
||||
if (!LdrNode->BaseAddressIndexNode.Right) {
|
||||
bRight = true;
|
||||
break;
|
||||
}
|
||||
LdrNode = decltype(LdrNode)((size_t)LdrNode->BaseAddressIndexNode.Right - offsetof(LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode));
|
||||
LdrNode = CONTAINING_RECORD(LdrNode->BaseAddressIndexNode.Right, LDR_DATA_TABLE_ENTRY_WIN8, BaseAddressIndexNode);
|
||||
}
|
||||
else {
|
||||
LdrNode->DdagNode->LoadCount++;
|
||||
|
||||
@@ -269,7 +269,7 @@ VOID InitializeWindowsVersion() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// [13494, 15063)
|
||||
// [14393, 15063)
|
||||
version = WINDOWS_VERSION::win10_1;
|
||||
LdrDataTableEntrySize = sizeof(LDR_DATA_TABLE_ENTRY_WIN10_1);
|
||||
}
|
||||
@@ -415,12 +415,11 @@ NTSTATUS InitializeLockHeld() {
|
||||
MmpGlobalDataPtr->MmpTls = (PMMP_TLS_DATA)((LPBYTE)MmpGlobalDataPtr->MmpLdrEntry + sizeof(MMP_LDR_ENTRY_DATA));
|
||||
MmpGlobalDataPtr->MmpDotNet = (PMMP_DOT_NET_DATA)((LPBYTE)MmpGlobalDataPtr->MmpTls + sizeof(MMP_TLS_DATA));
|
||||
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll");
|
||||
PLDR_DATA_TABLE_ENTRY pNtdllEntry = RtlFindLdrTableEntryByBaseName(L"ntdll.dll");
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry = pNtdllEntry;
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex->LdrpModuleBaseAddressIndex = FindLdrpModuleBaseAddressIndex();
|
||||
|
||||
HMODULE hNtdll = (HMODULE)MmpGlobalDataPtr->MmpBaseAddressIndex->NtdllLdrEntry->DllBase;
|
||||
MmpGlobalDataPtr->MmpLdrEntry->_RtlRbInsertNodeEx = decltype(&RtlRbInsertNodeEx)(GetProcAddress(hNtdll, "RtlRbInsertNodeEx"));
|
||||
MmpGlobalDataPtr->MmpLdrEntry->_RtlRbRemoveNode = decltype(&RtlRbRemoveNode)(GetProcAddress(hNtdll, "RtlRbRemoveNode"));
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbInsertNodeEx = GetProcAddress((HMODULE)pNtdllEntry->DllBase, "RtlRbInsertNodeEx");
|
||||
MmpGlobalDataPtr->MmpBaseAddressIndex->_RtlRbRemoveNode = GetProcAddress((HMODULE)pNtdllEntry->DllBase, "RtlRbRemoveNode");
|
||||
|
||||
MmpGlobalDataPtr->MmpLdrEntry->LdrpHashTable = FindLdrpHashTable();
|
||||
|
||||
|
||||
@@ -281,24 +281,6 @@ 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) {
|
||||
RtlZeroMemory(Node, sizeof(*Node));
|
||||
|
||||
if (!MmpGlobalDataPtr->MmpLdrEntry->_RtlRbInsertNodeEx)return;
|
||||
return MmpGlobalDataPtr->MmpLdrEntry->_RtlRbInsertNodeEx(Tree, Parent, Right, Node);
|
||||
}
|
||||
|
||||
VOID NTAPI RtlRbRemoveNode(
|
||||
_In_ PRTL_RB_TREE Tree,
|
||||
_In_ PRTL_BALANCED_NODE Node) {
|
||||
if (!MmpGlobalDataPtr->MmpLdrEntry->_RtlRbRemoveNode)return;
|
||||
return MmpGlobalDataPtr->MmpLdrEntry->_RtlRbRemoveNode(Tree, Node);
|
||||
}
|
||||
|
||||
PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByHandle(_In_ PVOID BaseAddress) {
|
||||
PLIST_ENTRY ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList, ListEntry = ListHead->Flink;
|
||||
PLDR_DATA_TABLE_ENTRY CurEntry;
|
||||
|
||||
@@ -62,18 +62,6 @@ PLDR_DATA_TABLE_ENTRY NTAPI RtlFindLdrTableEntryByBaseName(_In_z_ PCWSTR BaseNam
|
||||
#define LDR_GET_HASH_ENTRY(x) (RtlUpcaseUnicodeChar((x)) & (LDR_HASH_TABLE_ENTRIES - 1))
|
||||
#define LDR_HASH_TABLE_ENTRIES 32
|
||||
|
||||
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
|
||||
_LDR_SERVICE_TAG_RECORD* ServiceTagList; //0x10
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
typedef struct _MMP_BASE_ADDRESS_INDEX_DATA {
|
||||
PRTL_RB_TREE LdrpModuleBaseAddressIndex;
|
||||
PLDR_DATA_TABLE_ENTRY NtdllLdrEntry;
|
||||
|
||||
PVOID _RtlRbInsertNodeEx;
|
||||
PVOID _RtlRbRemoveNode;
|
||||
}MMP_BASE_ADDRESS_INDEX_DATA, * PMMP_BASE_ADDRESS_INDEX_DATA;
|
||||
|
||||
//InvertedFunctionTable.cpp
|
||||
@@ -14,9 +17,6 @@ typedef struct _MMP_INVERTED_FUNCTION_TABLE_DATA {
|
||||
//LdrEntry.cpp
|
||||
typedef struct _MMP_LDR_ENTRY_DATA {
|
||||
PLIST_ENTRY LdrpHashTable;
|
||||
|
||||
decltype(&RtlRbInsertNodeEx)_RtlRbInsertNodeEx;
|
||||
decltype(&RtlRbRemoveNode)_RtlRbRemoveNode;
|
||||
}MMP_LDR_ENTRY_DATA, * PMMP_LDR_ENTRY_DATA;
|
||||
|
||||
//MmpTls.cpp
|
||||
|
||||
+74
-37
@@ -19,52 +19,89 @@ static PVOID ReadDllFile(LPCSTR FileName) {
|
||||
}
|
||||
|
||||
int test() {
|
||||
HMODULE hModule;
|
||||
NTSTATUS status;
|
||||
PVOID buffer = ReadDllFile("a.dll");
|
||||
if (!buffer) return 0;
|
||||
LPVOID buffer = ReadDllFile("a.dll");
|
||||
|
||||
status = LdrLoadDllMemoryExW(
|
||||
&hModule, // ModuleHandle
|
||||
nullptr, // LdrEntry
|
||||
0, // Flags
|
||||
buffer, // Buffer
|
||||
0, // Reserved
|
||||
nullptr, // DllBaseName
|
||||
nullptr // DllFullName
|
||||
);
|
||||
if (NT_SUCCESS(status) && status != STATUS_IMAGE_MACHINE_TYPE_MISMATCH) {
|
||||
HMEMORYMODULE m1 = nullptr, m2 = m1;
|
||||
HMODULE hModule = nullptr;
|
||||
FARPROC pfn = nullptr;
|
||||
DWORD MemoryModuleFeatures = 0;
|
||||
|
||||
typedef int(__stdcall* func)();
|
||||
func test_user32 = (func)GetProcAddress(hModule, "test_user32");
|
||||
test_user32();
|
||||
typedef int(*_exception)(int code);
|
||||
_exception exception = nullptr;
|
||||
HRSRC hRsrc;
|
||||
DWORD SizeofRes;
|
||||
HGLOBAL gRes;
|
||||
char str[10];
|
||||
|
||||
//
|
||||
// After calling MessageBox, we can't free it.
|
||||
//
|
||||
//LdrUnloadDllMemory(hModule);
|
||||
LdrQuerySystemMemoryModuleFeatures(&MemoryModuleFeatures);
|
||||
if (MemoryModuleFeatures != MEMORY_FEATURE_ALL) {
|
||||
printf("not support all features on this version of windows.\n");
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m1, nullptr, 0, buffer, 0, L"kernel64", nullptr))) goto end;
|
||||
LoadLibraryW(L"wininet.dll");
|
||||
if (!NT_SUCCESS(LdrLoadDllMemoryExW(&m2, nullptr, 0, buffer, 0, L"kernel128", nullptr))) goto end;
|
||||
|
||||
//forward export
|
||||
hModule = (HMODULE)m1;
|
||||
pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket")); //ws2_32.WSASocketW
|
||||
pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse")); //wintrust.WinVerifyTrust
|
||||
hModule = (HMODULE)m2;
|
||||
pfn = (decltype(pfn))(GetProcAddress(hModule, "Socket"));
|
||||
pfn = (decltype(pfn))(GetProcAddress(hModule, "VerifyTruse"));
|
||||
|
||||
//exception
|
||||
hModule = (HMODULE)m1;
|
||||
exception = (_exception)GetProcAddress(hModule, "exception");
|
||||
if (exception) {
|
||||
for (int i = 0; i < 5; ++i)exception(i);
|
||||
}
|
||||
|
||||
//tls
|
||||
pfn = GetProcAddress(hModule, "thread");
|
||||
if (pfn && pfn()) {
|
||||
printf("thread test failed.\n");
|
||||
}
|
||||
|
||||
//resource
|
||||
if (!LoadStringA(hModule, 101, str, 10)) {
|
||||
printf("load string failed.\n");
|
||||
}
|
||||
else {
|
||||
printf("%s\n", str);
|
||||
}
|
||||
if (!(hRsrc = FindResourceA(hModule, MAKEINTRESOURCEA(102), "BINARY"))) {
|
||||
printf("find binary resource failed.\n");
|
||||
}
|
||||
else {
|
||||
if ((SizeofRes = SizeofResource(hModule, hRsrc)) != 0x10) {
|
||||
printf("invalid res size.\n");
|
||||
}
|
||||
else {
|
||||
if (!(gRes = LoadResource(hModule, hRsrc))) {
|
||||
printf("load res failed.\n");
|
||||
}
|
||||
else {
|
||||
if (!LockResource(gRes))printf("lock res failed.\n");
|
||||
else {
|
||||
printf("resource test success.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
delete[]buffer;
|
||||
if (m1)LdrUnloadDllMemory(m1);
|
||||
FreeLibrary(LoadLibraryW(L"wininet.dll"));
|
||||
FreeLibrary(GetModuleHandleW(L"wininet.dll"));
|
||||
if (m2)LdrUnloadDllMemory(m2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
if (MmpGlobalDataPtr->WindowsVersion == WINDOWS_VERSION::win11) {
|
||||
auto head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
|
||||
auto entry = head->Flink;
|
||||
while (entry != head) {
|
||||
PLDR_DATA_TABLE_ENTRY_WIN11 __entry = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY_WIN11, InLoadOrderLinks);
|
||||
wprintf(L"%s\t0x%08X, 0x%08X, 0x%p, %d\n",
|
||||
__entry->BaseDllName.Buffer,
|
||||
__entry->CheckSum,
|
||||
RtlImageNtHeader(__entry->DllBase)->OptionalHeader.CheckSum,
|
||||
__entry->ActivePatchImageBase,
|
||||
__entry->HotPatchState
|
||||
);
|
||||
|
||||
entry = entry->Flink;
|
||||
}
|
||||
}
|
||||
test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user