64位操作系统下R3枚举进程及模块的两种方式

应用层枚举进程及模块的两种方式

1.快照方式枚举进程

BOOL EnumProcesses(HWND hProcessList)
{
	ListView_DeleteAllItems(hProcessList);
	PROCESSENTRY32 pe = { 0 };
	pe.dwSize = sizeof(pe);
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	int i = 0;
	TCHAR buff[256] = { 0 };
	while (Process32Next(hSnap, &pe))
	{
		ListInsertItem(hProcessList, i, 0, pe.szExeFile);
		wsprintf(buff, L"%d", (int)pe.th32ParentProcessID);
		ListSetItemText(hProcessList, i, 1, buff);
		wsprintf(buff, L"%d", (int)pe.th32ProcessID);
		ListSetItemText(hProcessList, i, 2, buff);
		i++;
	}
	CloseHandle(hSnap);
	return TRUE;
}

快照方式枚举进程测试图片

2.快照方式枚举进程模块

BOOL EnumModule(HWND hProcessList, DWORD pid)
{
	ListView_DeleteAllItems(hProcessList);
	MODULEENTRY32 me = { 0 };
	me.dwSize = sizeof(me);
	int i = 0;
	TCHAR buff[256] = { 0 };
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
	while (Module32Next(hSnap, &me))
	{
		ListInsertItem(hProcessList, i, 0, me.szModule);
		wsprintf(buff, L"%p",me.modBaseAddr);
		ListSetItemText(hProcessList, i, 1, buff);
		wsprintf(buff, L"%08X", me.modBaseSize);
		ListSetItemText(hProcessList, i, 2, buff);
	}
	CloseHandle(hSnap);
	return TRUE;
}

快照方式枚举进程模块测试图片

3.通过NtQuerySystemInformation函数枚举进程

BOOL EnumProcesses(HWND hProcessList)
{
	ListView_DeleteAllItems(hProcessList);
	ULONG len = 0;
	ULONG m_bsize = 1024;
	BYTE* m_buff = new BYTE[1024];
	HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
	if (!hNtdll)
	{
		return FALSE;
	}
	pfNtQuerySystemInformation NtQuerySystemInformation = (pfNtQuerySystemInformation)GetProcAddress(hNtdll, "NtQuerySystemInformation");
	NtQuerySystemInformation(SystemProcessInformation, m_buff, m_bsize, &len);
	while (m_bsize < len)
	{
		delete[] m_buff;
		m_bsize = len;
		m_buff = new BYTE[m_bsize];
		NtQuerySystemInformation(SystemProcessInformation, m_buff, m_bsize, &len);
	}
	SYSTEM_PROCESS_INFORMATION* ps = (SYSTEM_PROCESS_INFORMATION*)m_buff;
	ps = (SYSTEM_PROCESS_INFORMATION*)((ULONG64)ps + ps->NextEntryOffset);
	int i = 0;
	WCHAR buff[256] = { 0 };
	while (ps->NextEntryOffset)
	{
		ListInsertItem(hProcessList, i, 0, (LPCTSTR)(ps->ImageName.Buffer));
		wsprintf(buff, L"%d", (int)ps->InheritedFromUniqueProcessId);
		ListSetItemText(hProcessList, i, 1, buff);
		wsprintf(buff, L"%d", (int)ps->UniqueProcessId);
		ListSetItemText(hProcessList, i, 2, buff);
		wsprintf(buff, L"%d", CriticalLevel((int)ps->UniqueProcessId));
		ListSetItemText(hProcessList, i, 3, buff);
		i++;
		ps = (SYSTEM_PROCESS_INFORMATION*)((ULONG64)ps + ps->NextEntryOffset);
	}
	ListInsertItem(hProcessList, i, 0, (LPCTSTR)(ps->ImageName.Buffer));
	wsprintf(buff, L"%d", (int)ps->InheritedFromUniqueProcessId);
	ListSetItemText(hProcessList, i, 1, buff);
	wsprintf(buff, L"%d", (int)ps->UniqueProcessId);
	ListSetItemText(hProcessList, i, 2, buff);
	wsprintf(buff, L"%d", CriticalLevel((int)ps->UniqueProcessId));
	ListSetItemText(hProcessList, i, 3, buff);
	return TRUE;
}

NtQuerySystemInformation函数枚举进程

4.通过NtQueryInformationProcess函数枚举进程模块

BOOL EnumModule(HWND hProcessList,DWORD pid)
{
	ListView_DeleteAllItems(hProcessList);
	HMODULE hNtdll = GetModuleHandle(L"ntdll.dll");
	if (!hNtdll)
	{
		return FALSE;
	}
	int i = 0;
	pfNtOpenProcess NtOpenProcess = (pfNtOpenProcess)GetProcAddress(hNtdll, "NtOpenProcess");
	pfNtQueryInformationProcess NtQueryInformationProcess = (pfNtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");
	pfNtReadVirtualMemory NtReadVirtualMemory = (pfNtReadVirtualMemory)GetProcAddress(hNtdll, "NtReadVirtualMemory");
	BOOL source = FALSE;
	BOOL target = FALSE;
	IsWow64Process(GetCurrentProcess(), &source);
	HANDLE hProcess = 0;
	CLIENT_ID client = { 0 };
	OBJECT_ATTRIBUTES oa = { 0 };
	client.UniqueProcess = pid;
	oa.Length = sizeof(OBJECT_ATTRIBUTES);
	NtOpenProcess(&hProcess, GENERIC_ALL, &oa, &client);
	if (NULL == hProcess)
	{
		return FALSE;
	}
	IsWow64Process(hProcess, &target);
	if (source == FALSE && target == FALSE)
	{
		PROCESS_BASIC_INFORMATION64 pbi64 = { 0 };
		NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL);
		DWORD64 Ldr64 = 0;
		LIST_ENTRY64 ListEntry64 = { 0 };
		LDR_DATA_TABLE_ENTRY64 LDTE64 = { 0 };
		wchar_t buff[256] = { 0 };
		NtReadVirtualMemory(hProcess, (PVOID64)(pbi64.PebBaseAddress + offsetof(PEB64, Ldr)), &Ldr64, sizeof(Ldr64), NULL);
		NtReadVirtualMemory(hProcess, (PVOID64)(Ldr64 + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList)), &ListEntry64, sizeof(LIST_ENTRY64), NULL);
		NtReadVirtualMemory(hProcess, (PVOID64)(ListEntry64.Flink), &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		while (LDTE64.InLoadOrderLinks.Flink != ListEntry64.Flink)
		{
			NtReadVirtualMemory(hProcess, (PVOID64)LDTE64.BaseDllName.Buffer, buff, sizeof(buff), NULL);
			ListInsertItem(hProcessList, i, 0, buff);
			wsprintf(buff, L"%p", (PVOID64)LDTE64.DllBase);
			ListSetItemText(hProcessList, i, 1, buff);
			wsprintf(buff, L"%08X", LDTE64.SizeOfImage);
			ListSetItemText(hProcessList, i, 2, buff);
			i++;
			//printf("模块基址:0x%llX\t模块大小:0x%-10X\t模块路径:%ls\n", LDTE64.DllBase, LDTE64.SizeOfImage, ProPath64);
			NtReadVirtualMemory(hProcess, (PVOID64)LDTE64.InLoadOrderLinks.Flink, &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		}
	}
#ifndef _WIN64
	else if (source == TRUE && target == FALSE)
	{

		PROCESS_BASIC_INFORMATION64 pbi64 = { 0 };
		pfNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfNtWow64QueryInformationProcess64)GetProcAddress(hNtdll, "NtWow64QueryInformationProcess64");
		NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL);
		DWORD64 Ldr64 = 0;
		LIST_ENTRY64 ListEntry64 = { 0 };
		LDR_DATA_TABLE_ENTRY64 LDTE64 = { 0 };
		wchar_t buff[256] = { 0 };
		pfNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfNtWow64ReadVirtualMemory64)GetProcAddress(hNtdll, "NtWow64ReadVirtualMemory64");
		NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(pbi64.PebBaseAddress + offsetof(PEB64, Ldr)), &Ldr64, sizeof(Ldr64), NULL);
		NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(Ldr64 + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList)), &ListEntry64, sizeof(LIST_ENTRY64), NULL);
		NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(ListEntry64.Flink), &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		while (LDTE64.InLoadOrderLinks.Flink != ListEntry64.Flink)
		{
			NtWow64ReadVirtualMemory64(hProcess, (PVOID64)LDTE64.BaseDllName.Buffer, buff, sizeof(buff), NULL);
			ListInsertItem(hProcessList, i, 0, buff);
			wsprintf(buff, L"%08X%08X", *((ULONG*)&LDTE64.DllBase+1) ,*(ULONG*)&LDTE64.DllBase);
			ListSetItemText(hProcessList, i, 1, buff);
			wsprintf(buff, L"%08X", LDTE64.SizeOfImage);
			ListSetItemText(hProcessList, i, 2, buff);
			i++;
			//printf("模块基址:0x%llX\t模块大小:0x%-10X\t模块路径:%ls\n", LDTE64.DllBase, LDTE64.SizeOfImage, ProPath64);
			NtWow64ReadVirtualMemory64(hProcess, (PVOID64)LDTE64.InLoadOrderLinks.Flink, &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		}
	}
	else if (source == TRUE && target == TRUE)
	{
		PROCESS_BASIC_INFORMATION64 pbi64 = { 0 };
		pfNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfNtWow64QueryInformationProcess64)GetProcAddress(hNtdll, "NtWow64QueryInformationProcess64");
		NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL);
		DWORD64 Ldr64 = 0;
		LIST_ENTRY64 ListEntry64 = { 0 };
		LDR_DATA_TABLE_ENTRY64 LDTE64 = { 0 };
		wchar_t buff[256] = { 0 };
		pfNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfNtWow64ReadVirtualMemory64)GetProcAddress(hNtdll, "NtWow64ReadVirtualMemory64");
		NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(pbi64.PebBaseAddress + offsetof(PEB64, Ldr)), &Ldr64, sizeof(Ldr64), NULL);
		NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(Ldr64 + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList)), &ListEntry64, sizeof(LIST_ENTRY64), NULL);
		NtWow64ReadVirtualMemory64(hProcess, (PVOID64)(ListEntry64.Flink), &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		while (LDTE64.InLoadOrderLinks.Flink != ListEntry64.Flink)
		{
			NtWow64ReadVirtualMemory64(hProcess, (PVOID64)LDTE64.BaseDllName.Buffer, buff, sizeof(buff), NULL);
			ListInsertItem(hProcessList, i, 0, buff);
			wsprintf(buff, L"%08X%08X", *((ULONG*)&LDTE64.DllBase + 1), *(ULONG*)&LDTE64.DllBase);
			ListSetItemText(hProcessList, i, 1, buff);
			wsprintf(buff, L"%08X", LDTE64.SizeOfImage);
			ListSetItemText(hProcessList, i, 2, buff);
			i++;
			//printf("模块基址:0x%llX\t模块大小:0x%-10X\t模块路径:%ls\n", LDTE64.DllBase, LDTE64.SizeOfImage, ProPath64);
			NtWow64ReadVirtualMemory64(hProcess, (PVOID64)LDTE64.InLoadOrderLinks.Flink, &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		}

		PROCESS_BASIC_INFORMATION32 pbi32 = { 0 };
		NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi32, sizeof(pbi32), NULL);
		DWORD Ldr32 = 0;
		LIST_ENTRY32 ListEntry32 = { 0 };
		LDR_DATA_TABLE_ENTRY32 LDTE32 = { 0 };
		//wchar_t buff[256] = { 0 };
		NtReadVirtualMemory(hProcess, (PVOID)(pbi32.PebBaseAddress + offsetof(PEB32, Ldr)), &Ldr32, sizeof(Ldr32), NULL);
		NtReadVirtualMemory(hProcess, (PVOID)(Ldr32 + offsetof(PEB_LDR_DATA32, InLoadOrderModuleList)), &ListEntry32, sizeof(LIST_ENTRY32), NULL);
		NtReadVirtualMemory(hProcess, (PVOID)(ListEntry32.Flink), &LDTE32, sizeof(LDR_DATA_TABLE_ENTRY32), NULL);
		while (LDTE32.InLoadOrderLinks.Flink != ListEntry32.Flink)
		{
			NtReadVirtualMemory(hProcess, (PVOID)LDTE32.BaseDllName.Buffer, buff, sizeof(buff), NULL);
			ListInsertItem(hProcessList, i, 0, buff);
			wsprintf(buff, L"%08X", LDTE32.DllBase);
			ListSetItemText(hProcessList, i, 1, buff);
			wsprintf(buff, L"%08X", LDTE32.SizeOfImage);
			ListSetItemText(hProcessList, i, 2, buff);
			i++;
			//NtReadVirtualMemory(hProcess, (PVOID)LDTE32.FullDllName.Buffer, ProPath32, sizeof(ProPath32), NULL);
			//printf("模块基址:0x%08X\t模块大小:0x%-08X\t模块路径:%ws\n", LDTE32.DllBase, LDTE32.SizeOfImage, ProPath32);
			NtReadVirtualMemory(hProcess, (PVOID)LDTE32.InLoadOrderLinks.Flink, &LDTE32, sizeof(LDR_DATA_TABLE_ENTRY32), NULL);
		}
	}
#endif
	else if (source == FALSE && target == TRUE)
	{
		PROCESS_BASIC_INFORMATION64 pbi64 = { 0 };
		NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL);
		DWORD64 Ldr64 = 0;
		LIST_ENTRY64 ListEntry64 = { 0 };
		LDR_DATA_TABLE_ENTRY64 LDTE64 = { 0 };
		wchar_t buff[256] = { 0 };
		NtReadVirtualMemory(hProcess, (PVOID64)(pbi64.PebBaseAddress + offsetof(PEB64, Ldr)), &Ldr64, sizeof(Ldr64), NULL);
		NtReadVirtualMemory(hProcess, (PVOID64)(Ldr64 + offsetof(PEB_LDR_DATA64, InLoadOrderModuleList)), &ListEntry64, sizeof(LIST_ENTRY64), NULL);
		NtReadVirtualMemory(hProcess, (PVOID64)(ListEntry64.Flink), &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		while (LDTE64.InLoadOrderLinks.Flink != ListEntry64.Flink)
		{
			NtReadVirtualMemory(hProcess, (PVOID64)LDTE64.BaseDllName.Buffer, buff, sizeof(buff), NULL);
			ListInsertItem(hProcessList, i, 0, buff);
			wsprintf(buff, L"%p", (PVOID64)LDTE64.DllBase);
			ListSetItemText(hProcessList, i, 1, buff);
			wsprintf(buff, L"%08X", LDTE64.SizeOfImage);
			ListSetItemText(hProcessList, i, 2, buff);
			i++;
			//printf("模块基址:0x%llX\t模块大小:0x%-10X\t模块路径:%ls\n", LDTE64.DllBase, LDTE64.SizeOfImage, ProPath64);
			NtReadVirtualMemory(hProcess, (PVOID64)LDTE64.InLoadOrderLinks.Flink, &LDTE64, sizeof(LDR_DATA_TABLE_ENTRY64), NULL);
		}

		ULONG_PTR peb32 = { 0 };//用来存储32位PEB地址
		NtQueryInformationProcess(hProcess, ProcessWow64Information, &peb32, sizeof(peb32), NULL);
		DWORD32 Ldr32 = 0;
		LIST_ENTRY32 ListEntry32 = { 0 };
		LDR_DATA_TABLE_ENTRY32 LDTE32 = { 0 };
		//wchar_t buff[256] = { 0 };
		NtReadVirtualMemory(hProcess, (PVOID)(peb32 + offsetof(PEB32, Ldr)), &Ldr32, sizeof(Ldr32), NULL);
		NtReadVirtualMemory(hProcess, (PVOID)(Ldr32 + offsetof(PEB_LDR_DATA32, InLoadOrderModuleList)), &ListEntry32, sizeof(LIST_ENTRY32), NULL);
		NtReadVirtualMemory(hProcess, (PVOID)(ListEntry32.Flink), &LDTE32, sizeof(LDR_DATA_TABLE_ENTRY32), NULL);
		while (LDTE32.InLoadOrderLinks.Flink != ListEntry32.Flink)
		{
			NtReadVirtualMemory(hProcess, (PVOID)LDTE32.BaseDllName.Buffer, buff, sizeof(buff), NULL);
			ListInsertItem(hProcessList, i, 0, buff);
			wsprintf(buff, L"%08X", LDTE32.DllBase);
			ListSetItemText(hProcessList, i, 1, buff);
			wsprintf(buff, L"%08X", LDTE32.SizeOfImage);
			ListSetItemText(hProcessList, i, 2, buff);
			i++;
			//NtReadVirtualMemory(hProcess, (PVOID)LDTE32.FullDllName.Buffer, ProPath32, sizeof(ProPath32), NULL);
			//printf("模块基址:0x%lX\t模块大小:0x%-10X\t模块路径:%ls\n", LDTE32.DllBase, LDTE32.SizeOfImage, ProPath32);
			NtReadVirtualMemory(hProcess, (PVOID)LDTE32.InLoadOrderLinks.Flink, &LDTE32, sizeof(LDR_DATA_TABLE_ENTRY32), NULL);
		}
	}
	return TRUE;
}

NtQueryInformationProcess函数枚举进程模块

5.总结

综上,第一种方法使用快照枚举进程和模块,优点是代码量少,缺点是32位进程无法枚举64位进程模块。第二种方法使用Nt函数枚举进程和模块,优点是32位进程可以枚举64位进程模块,缺点是代码量多且要使用未文档化的数据结构。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值