R3枚举进程模块的方法

发布时间 2023-03-24 12:13:45作者: Hanpto

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();


}