OpenProcess打开进程返回错误的问题

问题描述

      项目中需要做一个小功能:能够查看系统中当前正在运行的进程的内存信息,如内存块类型、分配状态、访问权限等。如下图所示:

      需要的信息和上图相差无几。说起来也不算太难,毕竟现成的API已经提供了。我们要做的就是遍历获取每个进程的句柄,然后逐个打开就可以提取信息了。

排查结论

      但是,当我逐步编写完代码并运行时,发现什么结果也没得到。于是乎,打开调试器下了几个断点跟了进去发现:GetLastError()的返回值在遇到System Process时,会返回错误代码87。回头一查MSDN,人家已然说明:当OpenProcess()给定的进程ID为0时,该函数会失败并且GetLastError()返回的错误代码是ERROR_INVALID_PARAMETER。这个错误代码值就是87。另外还说明了,当给定的进程是空闲进程(Idle Process)或CSRSS进程之一时,GetLastError()返回的错误代码是ERROR_ACCESS_DENIED,其值为5. 出于系统安全性考虑,操作系统禁止用户层代码打开这些进程。

      显然,错误很明显了。我并没有过滤这些特殊进程,而是一股脑的全部调用OpenProcess()打开进程。而刚好,我的系统上第一个遍历的进程就是System Process(进程ID为0)。于是程序直接跳出了而得不到任何结果。另外,我的系统是Windows 7 64位系统,网上有人说在Windows XP系统上不会出现这种错误,不知道真假。

      遍历进程并打开:

HANDLE proc = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (proc == INVALID_HANDLE_VALUE)
{
	assert(proc != INVALID_HANDLE_VALUE);
	return ;
}
ProcessMemory item;
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
PROCESSENTRY32 procEntry = { 0 };
procEntry.dwSize = sizeof(PROCESSENTRY32);
BOOL bRet = Process32First(proc,&procEntry);
while (bRet)
{
	hProcess = OpenProcess( PROCESS_QUERY_INFORMATION| PROCESS_VM_READ, FALSE, procEntry.th32ProcessID );
	if (NULL == hProcess) 
	{
		int ret = GetLastError();
		// skip the system process and Idle process or one of CSRSS process
		if (ret != ERROR_INVALID_PARAMETER && ret != ERROR_ACCESS_DENIED)  
			return;  // function failed for other errors
	}
	else 
	{
		if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
		{
			item.pname = procEntry.szExeFile;
			item.pid = procEntry.th32ProcessID;
			item.PageFaultCount = pmc.PageFaultCount;
			item.PagefileUsage = pmc.PagefileUsage;
			item.PeakPagefileUsage = pmc.PeakPagefileUsage;
			item.PeakWorkingSetSize = pmc.PeakWorkingSetSize;
			item.QuotaNonPagedPoolUsage = pmc.QuotaNonPagedPoolUsage;
			item.QuotaPagedPoolUsage = pmc.QuotaPagedPoolUsage;
			item.QuotaPeakNonPagedPoolUsage = pmc.QuotaPeakNonPagedPoolUsage;
			item.QuotaPeakPagedPoolUsage = pmc.QuotaPeakPagedPoolUsage;

			m_procsmem.push_back(item);
		}
	}

	bRet = Process32Next(proc, &procEntry);
}
CloseHandle(hProcess);
CloseHandle(proc);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ml

unbuntu系统( PC机 )中安装360wifi步骤

少说废话,每一步都经过验证:   1.  首先查看一下当前使用的linux版本: gxjun@gxjun:~$ uname -r 4.8.0-59-generi...

3453
来自专栏影子

springboot添加多数据源连接池并配置Mybatis

4433
来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第二十一天 Web商城实战一【悟空教程】

public class BaseServlet extends HttpServlet {

1874
来自专栏一只程序汪的自我修养

手把手教你用.NET Core写爬虫

自从上一个项目58HouseSearch从.NET迁移到.NET core之后,磕磕碰碰磨蹭了一个月才正式上线到新版本。

32512
来自专栏FreeBuf

远程RPC溢出EXP编写实战之MS06-040

0x01 前言 MS06-040算是个比较老的洞了,在当年影响十分之广,基本上Microsoft大部分操作系统都受到了影响,威力不亚于17年爆出的”永恒之蓝”漏...

28310
来自专栏高性能服务器开发

windows完成端口(六)

系列目录 windows完成端口(一) windows完成端口(二) windows完成端口(三) windows完成端口(四) windows完成端口(五) ...

3364
来自专栏转载gongluck的CSDN博客

VC(win32)通过进程名杀死进程

#include "TlHelp32.h" void CKillProcessDlg::OnBnClickedOk() { // TODO: 在此添加...

3854
来自专栏Android源码框架分析

Android6.0权限适配及兼容库的实现

从6.0 MarshMallow开始,Android支持动态权限管理,即有些权限需要在使用到的时候动态申请,根据用户的选择需要有不同的处理,具体表现可以看下图:

1532
来自专栏比原链

Derek解读Bytom源码-P2P网络 地址簿

Gitee地址:https://gitee.com/BytomBlockchain/bytom

1123
来自专栏大内老A

Windows安全认证是如何进行的?[Kerberos篇]

最近一段时间都在折腾安全(Security)方面的东西,比如Windows认证、非对称加密、数字证书、数字签名、TLS/SSL、WS-Security等。如果时...

2257

扫码关注云+社区

领取腾讯云代金券