R3下枚举进程DLL的几种方法

mac2024-01-31  54

一、Module32First、Module32Next

void Enum1() { HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); if (hSnapshot == INVALID_HANDLE_VALUE) return; MODULEENTRY32W module{ 0 }; module.dwSize = sizeof(module); BOOL bFound = Module32FirstW(hSnapshot, &module); while (bFound) { std::wcout << module.szExePath << std::endl; bFound = Module32Next(hSnapshot, &module); } CloseHandle(hSnapshot); }

函数底层是通过搜索PEB.Ldr.InLoadOrderModuleList链来找到模块信息的。

二、EnumProcessModules

void Enum2() { HANDLE hProcess = GetCurrentProcess(); HMODULE hModules[1024]; DWORD cbNeeded = 0; if (EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded)) { for (auto i = 0u; i < (cbNeeded / sizeof(HMODULE)); i++) { WCHAR szFileName[MAX_PATH]; if (GetModuleFileNameExW(hProcess, hModules[i], szFileName, _countof(szFileName))) { std::wcout << szFileName << std::endl; } } } }

函数底层是通过搜索PEB.Ldr.InMemoryOrderModuleList链来找到模块信息的。

三、VirtualQuery

void Enum3() { SYSTEM_INFO SystemInfo; GetSystemInfo(&SystemInfo); ULONG_PTR ulStart = (ULONG_PTR)SystemInfo.lpMinimumApplicationAddress; ULONG_PTR ulEnd = (ULONG_PTR)SystemInfo.lpMaximumApplicationAddress; ULONG_PTR ulBaseAddress = ulStart; MEMORY_BASIC_INFORMATION info{ 0 }; while (ulBaseAddress <= ulEnd) { if (VirtualQuery((PVOID)ulBaseAddress, &info, sizeof(info)) == sizeof(info)) { if ((info.Type == MEM_IMAGE) && (info.AllocationBase == info.BaseAddress)) { WCHAR szFileName[MAX_PATH]; if (GetModuleFileNameW((HMODULE)info.BaseAddress, szFileName, _countof(szFileName)) > 0) { std::wcout << szFileName << std::endl; } } } ulBaseAddress += 0x10000; } }

这个就是使用暴力搜索内存页的方法来定位模块信息,不依赖LDR链,VirtualQuery内部又会调用NtQueryVirtualMemory来取得内存页信息。这个方法效率低下,特别是在64位进程中,由于内存地址范围太大,需要很长时间去遍历完整个内存,所以一般情况下不使用这个方法。

最新回复(0)