R3层枚举进程模块的方法有以下三种:
1.ToolHelp库
2.PsApi库
3.遍历Peb中的Ldr链表
1.ToolHelp库:
点击查看代码
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
{
_tprintf(_T("CreateToolhelp32Snapshot Error\r\n"));
return;
}
MODULEENTRY32 moduleEntry;
moduleEntry.dwSize = sizeof(moduleEntry);
TCHAR lpstrModuleFileName[260];
int count = 0;
if (Module32First(hSnapshot, &moduleEntry))
{
while (Module32Next(hSnapshot, &moduleEntry))
{
count++;
GetModuleFileName(moduleEntry.hModule, lpstrModuleFileName, sizeof(lpstrModuleFileName));
_tprintf(_T("第%d个模块 名称为:%s 基地址:0x%08x 大小:%d\r\n"), count, lpstrModuleFileName, moduleEntry.modBaseAddr, moduleEntry.modBaseSize);
}
}
2.PsApi库:
点击查看代码
HMODULE hmProcess[1000];
DWORD dwNeeded = 0;
TCHAR lpstrModuleFileName[260];
EnumProcessModules(GetCurrentProcess(), hmProcess, sizeof(hmProcess), &dwNeeded);
DWORD dwModuleCount = dwNeeded / sizeof(DWORD);
MODULEINFO moduleInfo;
for (int i = 0; i < dwModuleCount; i++)
{
GetModuleFileName(hmProcess[i], lpstrModuleFileName, sizeof(lpstrModuleFileName));
GetModuleInformation(GetCurrentProcess(), hmProcess[i], &moduleInfo, sizeof(moduleInfo));
_tprintf(_T("第%d个模块 名称为:%s 基地址:0x % 08x 大小 : % d 入口点 : 0x % 08x\r\n"), (i+1), lpstrModuleFileName, moduleInfo.lpBaseOfDll, moduleInfo.SizeOfImage, moduleInfo.EntryPoint);
}
3.遍历Ldr链表:
点击查看代码
#include<iostream>
#include<Windows.h>
#include <Winternl.h>
#include<tchar.h>
typedef NTSTATUS(NTAPI* LPFN_NTQUERYINFORMATIONPROCESS)(IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
void _tmain()
{
HMODULE hModule = NULL;
LPFN_NTQUERYINFORMATIONPROCESS _NtQueryInformationProcess = NULL;
_PROCESS_BASIC_INFORMATION ProcessbBasicInfo = { 0 };
ULONG NeededLen = 0;
NTSTATUS Status = FALSE;
PPEB_LDR_DATA Ldr = NULL;
PLIST_ENTRY InMemoryOrderModuleList = NULL;
PLIST_ENTRY Current = NULL;
PLDR_DATA_TABLE_ENTRY Entry = NULL;
_tsetlocale(LC_ALL, _T("Chinese-simplified"));//使当前程序支持中文
//使用NtQueryInformationProcess获取InMemoryOrderLinks地址
hModule = GetModuleHandle(_T("ntdll.dll"));
if (hModule == NULL)
{
printf("GetModuleHandle fail.\r\n");
return;
}
_NtQueryInformationProcess = (LPFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(hModule, "NtQueryInformationProcess");
if (_NtQueryInformationProcess == NULL)
{
printf("GetProcAddress fail.\r\n");
return;
}
Status = _NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &ProcessbBasicInfo, sizeof(ProcessbBasicInfo), &NeededLen);
if (!NT_SUCCESS(Status))
{
_tprintf(_T("NtQueryInformationProcess fail.\r\n"));
return;
}
Ldr = ProcessbBasicInfo.PebBaseAddress->Ldr;
Current = Ldr->InMemoryOrderModuleList.Flink;
do
{
Entry = (PLDR_DATA_TABLE_ENTRY)Current;
_tprintf(_T("DllName:%s\t DllBase:0x:%x\r\n"), Entry->FullDllName.Buffer,Entry->DllBase);
Current = Current->Flink;
} while (Current!=NULL&&Current->Flink !=&Ldr->InMemoryOrderModuleList);
_tprintf(_T("input anykey to exit\r\n"));
_gettchar();
}