windows C++ 遍历进程线程以及进程加载的模块

本文是基于Win32 API函数实现遍历进程、遍历线程和遍历进程加载模块等获取系统信息的操作。

需要用到的函数

CreateToolhelp32Snapshot 函数

此函数可以通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照。
函数声明

HANDLE WINAPI CreateToolhelp32Snapshot(
    DWORD dwFlags, 
    DWORD th32ProcessID 
);

参数

VALUE含义
TH32CS_INHERIT指示快照句柄是可继承的
TH32CS_SNAPALL在快照中包含系统中所有的进程和线程
TH32CS_SNAPHEAPLIST在快照中包含在th32ProcessID中指定的进程的所有的堆
TH32CS_SNAPMODULE在快照中包含在th32ProcessID中指定的进程的所有的模块
TH32CS_SNAPPROCESS在快照中包含系统中所有的进程
TH32CS_SNAPTHREAD在快照中包含系统中所有的线程

th32ProcessID 指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了TH32CS_SNAPHEAPLIST或者TH32CS_SNAPMODULE后才有效,在其他情况下该参数被忽略,所有的进程都会被快照。

返回值
调用成功,返回快照的句柄;调用失败,返回INVALID_HANDLE_VALUE 。

Process32First 和 Process32Next 函数

当我们利用函数CreateToolhelp32Snapshot()获得当前运行所有进程的快照后,我们可以利用Process32First函数来获得第一个进程的句柄,Process32Next函数来获得下一个进程的句柄。

Thread32First 和 Thread32Next 函数

当我们利用函数CreateToolhelp32Snapshot()获得当前运行所有线程的快照后,我们可以利用Thread32First函数来获得第一个线程的句柄,Thread32Next函数来获得下一个线程的句柄。

Module32First 和 Module32Next 函数

当我们利用函数CreateToolhelp32Snapshot()获得指定进程的快照后,我们可以利用Module32First函数来获得进程第一个模块的句柄,Module32Next函数来获得进程下一个模块的句柄。

实现方式

大家可以从上面的函数介绍可以看出,重点理解CreateToolhelp32Snapshot这个函数的操作。我们遍历进程、遍历线程以及遍历进程加载模块等3个操作,都是基于CreateToolhelp32Snapshot函数进行下一步实现的。

对于遍历进程的实现原理是:

首先,使用CreateToolhelp32Snapshot 函数获取所有进程的快照
然后,根据进程快照,使用Process32First 和 Process32Next 函数进行遍历快照,并获取快照信息
最后,关闭上面获取的快照的句柄

对于遍历线程的实现原理是:

首先,使用CreateToolhelp32Snapshot 函数获取所有线程的快照
然后,根据线程快照,使用Thread32First 和 Thread32Next 函数进行遍历快照,并获取快照信息
最后,关闭上面获取的快照的句柄

对于遍历进程模块的实现原理是:

首先,使用CreateToolhelp32Snapshot 函数获取指定进程的所有模块快照。
然后,根据模块快照,使用Module32First 和 Module32Next 函数进行遍历快照,并获取快照信息
最后,关闭上面获取的快照的句柄。

实现代码

遍历进程

BOOL EnumProcess()
{
	PROCESSENTRY32 pe32 = { 0 };
	pe32.dwSize = sizeof(PROCESSENTRY32);
	// 获取全部进程快照
	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hProcessSnap)
	{
		ShowError("CreateToolhelp32Snapshot");
		return FALSE;
	}

	// 获取快照中第一条信息
	BOOL bRet = ::Process32First(hProcessSnap, &pe32);
	while (bRet)
	{
		// 显示 Process ID
		printf("[%d]\t", pe32.th32ProcessID);

		// 显示 进程名称
		printf("[%s]\n", pe32.szExeFile);

		// 获取快照中下一条信息
		bRet = ::Process32Next(hProcessSnap, &pe32);
	}

	// 关闭句柄
	::CloseHandle(hProcessSnap);

	return TRUE;
}

遍历线程

BOOL EnumThread()
{
	THREADENTRY32 te32 = { 0 };
	te32.dwSize = sizeof(THREADENTRY32);
	// 获取全部线程快照
	HANDLE hThreadSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	if (INVALID_HANDLE_VALUE == hThreadSnap)
	{
		ShowError("CreateToolhelp32Snapshot");
		return FALSE;
	}

	// 获取快照中第一条信息
	BOOL bRet = ::Thread32First(hThreadSnap, &te32); 
	while (bRet)
	{
		// 显示 Owner Process ID
		printf("[%d]\t", te32.th32OwnerProcessID);

		// 显示 Thread ID
		printf("[%d]\n", te32.th32ThreadID);

		// 获取快照中下一条信息
		bRet = ::Thread32Next(hThreadSnap, &te32);
	}

	// 关闭句柄
	::CloseHandle(hThreadSnap);

	return TRUE;
}

遍历指定进程模块

BOOL EnumProcessModule(DWORD dwProcessId)
{
	MODULEENTRY32 me32 = { 0 };
	me32.dwSize = sizeof(MODULEENTRY32);
	// 获取指定进程全部模块的快照
	HANDLE hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
	if (INVALID_HANDLE_VALUE == hModuleSnap)
	{
		ShowError("CreateToolhelp32Snapshot");
		return FALSE;
	}

	// 获取快照中第一条信息
	BOOL bRet = ::Module32First(hModuleSnap, &me32);
	while (bRet)
	{
		// 显示 Process ID
		printf("[%d]\t", me32.th32ProcessID);

		// 显示 模块加载基址
		printf("[0x%p]\t", me32.modBaseAddr);

		// 显示 模块名称
		printf("[%s]\n", me32.szModule);

		// 获取快照中下一条信息
		bRet = ::Module32Next(hModuleSnap, &me32);
	}

	// 关闭句柄
	::CloseHandle(hModuleSnap);

	return TRUE;
}

主程序

int _tmain(int argc, _TCHAR* argv[])
{
	// 遍历进程
	if (FALSE == EnumProcess())
	{
		printf("Enum Process Error!\n");
	}

	system("pause");
	system("cls");

	// 遍历线程
	if (FALSE == EnumThread())
	{
		printf("Enum Thread Error!\n");
	}

	system("pause");
	system("cls");

	// 遍历指定进程模块
	if (FALSE == EnumProcessModule(6876))
	{
		printf("Enum Process Module Error!\n");
	}

	system("pause");
	return 0;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值