Windows下如何枚举所有进程

要编写一个类似于 Windows 任务管理器的软件,首先遇到的问题是如何实现枚举所有进程。暂且不考虑进入核心态去查隐藏进程一类的,下面提供几种方法。请注意每种方法的使用局限,比如使用这些 API 所需要的操作系统是什么(尤其是是否能在 Windows Mobile 下使用)。

本文参考用户态枚举进程的几种方法,原文对于每一种方法都给出了完整的代码,被我照抄下来。还有一篇:如何用 Win32 APIs 枚举应用程序窗口和进程。基于我现学现卖的本质,对我演绎的部分请抱着批判的眼光来看,另外代码也没有充分验证。

使用 ToolHelp API

ToolHelp API 的功能就是为了获取当前运行程序的信息,从而编写适合自己需要的工具(@MSDN)。它支持的平台比较广泛,可以在 Windows CE 下使用。在 Windows Mobile SDK 的 Samples 里面有一个 PViewCE 的样例程序,就是用这个来查看进程和线程信息的。

使用方法就是先用 CreateToolhelp32Snapshot 将当前系统的进程、线程、DLL、堆的信息保存到一个缓冲区,这就是一个系统快照。如果你只是对进程信息感兴趣,那么只要包含 TH32CS_SNAPPROCESS 标志即可。

然后调用一次 Process32First 函数,从快照中获取第一个进程,然后重复调用 Process32Next,直到函数返回 FALSE 为止。这样将遍历快照中进程列表。这两个函数都带两个参数,它们分别是快照句柄和一个 PROCESSENTRY32 结构。调用完 Process32First 或 Process32Next 之后,PROCESSENTRY32 中将包含系统中某个进程的关键信息。其中进程 ID 就存储在此结构的 th32ProcessID。此 ID 传给 OpenProcess API 可以获得该进程的句柄。对应的可执行文件名及其存放路径存放在 szExeFile 结构成员中。在该结构中还可以找到其它一些有用的信息。

需要注意的是:在调用 Process32First() 之前,要将 PROCESSENTRY32 结构的 dwSize 成员设置成 sizeof(PROCESSENTRY32)。 然后再用 Process32First、Process32Next 来枚举进程。使用结束后要调用 CloseHandle 来释放保存的系统快照。

以下为参考代码:

使用 Processing Status API

在 Windows SDK 中可以找到 PSAPI,通过 PSAPI 可以获取进程列表和设备驱动列表。通过 EnumProcesses、EnumProcessModules、GetModuleFileNameEx 和 GetModuleBaseName 来实现。

首先使用 EnumProcesses 来枚举所有进程,它有三个参数:DWORD 类型的数组指针 lpidProcess;该数组的大小尺寸 cb;以及一个指向 DWORD 的指针 cbNeeded,它接收返回数据的长度。DWORD 数组用于保存当前运行的进程IDs。cbNeeded 返回数组所用的内存大小。下面算式可以得出返回了多少进程:nReturned = cbNeeded / sizeof(DWORD)。

注意:虽然文档将返回的 DWORD 命名为”cbNeeded”,实际上是没有办法知道到底要传多大的数组的。EnumProcesses 根本不会在 cbNeeded 中返回一个大于 cb 参数传递的数组值。所以,唯一确保 EnumProcesses 函数成功的方法是分配一个 DWORD 数组,并且,如果返回的 cbNeeded 等于 cb,分配一个较大的数组,并不停地尝试直到 cbNeeded 小于 cb 。

下面是参考代码:

使用 Native API

在 使用Native API 探测本机系统信息 中我介绍了 Native API 中的 NtQuerySystemInformation(ZwQuerySystemInformation)。当设置查询的信息类型为 SystemProcessesAndThreadsInformation 时(第5号功能),可以用来枚举所有进程和线程。

提醒:这个函数属于 Undocumented API,并且不建议使用,因为不同系统的结构和常量有所不同。下面列出 Windows XP 下可以用的相关结构和常量:

然后动态加载 ntdll.dll,获得函数的地址。便可以进行进程的枚举相关代码如下:

对这个方法有问题的,可以参考我之前的那篇介绍 Native API 的文章。

同样使用 ZwQuerySystemInformation 函数,查询类型如果设置为 SystemHandleInformation(第16号功能)也可以达到目的。它能获取系统中所有句柄,再加上进程 ID 的判断就可以枚举所有进程了。

原文中提到,在进行进程”隐藏”工作的时候,此处的句柄是一件容易被忽略的地方,因此需要注意隐藏由程序打开的相关句柄。由于系统中句柄数量经常变换,所以没有什么必要修改其中的 NumberOfHandles 域,因为如果修改此处的值,则需要不停对句柄的变化进行维护,开销比较大。在用户态下的进程枚举已经变得不可靠,因为一个内核级的 Rootkit 很容易就能够更改这些函数的返回结果。所以进程的可靠枚举应在内核态中实现,可以通过编写驱动来实现。

有关16位程序

根据参考的第二篇文章:在 Windows 95,Windows 98 和 Windows ME 中,ToolHelp32 对待16位程序一视同仁,它们与 Win32 程序一样有自己的进程 IDs。但是在 Windows NT,Windows 2000 或 Windows XP 中情况并不是这样。在这些操作系统中,16位程序运行在所谓的 VDM 当中(也就是DOS机)。

为了在 Windows NT,Windows 2000 和 Windows XP 中枚举16位程序,必须使用一个名为 VDMEnumTaskWOWEx 的函数。它的声明包含在 Windows SDK 中的 VDMDBG.h 中,并且需要在项目中链接 VDMDBG.lib 文件。

微软的网上帮助里面有一篇介绍的文章:如何在 Windows NT、 Windows 2000 和 Windows XP 上使用 VDMDBG 函数。

Original: https://www.cnblogs.com/MaxWoods/p/4136205.html
Author: Max Woods
Title: Windows下如何枚举所有进程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/552634/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • JAVA8-Lambda-List转Map

    List转Map需要注意点是在收集map时Collectors.toMap()建议选三个入参的方法。 示例如下:(注意list中的”张三”有两个我们将其作为…

    技术杂谈 2023年7月24日
    060
  • 策略模式、策略模式与Spring的碰撞

    策略模式是GoF23种设计模式中比较简单的了,也是常用的设计模式之一,今天我们就来看看策略模式。 实际案例 我工作第三年的时候,重构旅游路线的机票查询模块,旅游路线分为四种情况: …

    技术杂谈 2023年7月25日
    053
  • c#处理空白字符

    空白字符是指在屏幕不会显示出来的字符(如空格,制表符tab,回车换行等)。空格、制表符、换行符、回车、换页垂直制表符和换行符称为 “空白字符”,因为它们为与…

    技术杂谈 2023年5月30日
    077
  • Takeown–夺取文件or文件夹所有权

    强制将当前目录下的所有文件及文件夹、子文件夹下的所有者更改为管理员组(administrators)命令:takeown /f * /a /r /d y 将所有d:\documen…

    技术杂谈 2023年6月1日
    079
  • Qt学习笔记

    联系方式 QQ: 2653728884 ,加Q请注明添加原因! Original: https://www.cnblogs.com/arminker/p/5121596.htmlA…

    技术杂谈 2023年7月11日
    067
  • SQL库函数

    一、 字符串函数1. 删除字符 、 添加字符trim ( str ) : 去掉两侧空格ltrim( str ) : 去掉左侧空格rtrim ( str ) : 去掉右侧空格 tri…

    技术杂谈 2023年7月25日
    0112
  • InnoDB中不同SQL语句设置的锁

    锁定读、UPDATE 或 DELETE 通常会给在SQL语句处理过程扫描到的每个索引记录上设置记录锁。语句中是否存在排除该行的WHERE条件并不重要。InnoDB不记得确切的WHE…

    技术杂谈 2023年7月24日
    059
  • js替换字符串中的空格,换行符rn或n替换成<br>

    为了让回车换行符正确显示,需要将 \n 或 \r\n 替换成。同样地,将空格替换存 。这里我们通过正则表达式来替换。 一、替换所有的空格、回车换行符 javascript;gutt…

    技术杂谈 2023年5月31日
    082
  • UML

    posted on2022-06-13 17:28 莫水千流 阅读(18 ) 评论() 编辑 Original: https://www.cnblogs.com/zhoug2020…

    技术杂谈 2023年6月1日
    098
  • vim配置修改教程

    一、动态修改vim配置 反操作基本在原操作前加上no即可。 显示行号 set nu #关闭行号 set nonu 开启粘贴模式 set paste 关闭粘贴模式 set nopas…

    技术杂谈 2023年5月31日
    0114
  • 安装cuda和cudnn

    原来机器上有安装一个cuda 10.0,想要再安装一个cuda 10.1 安装CUDA 1.首先下载.run文件 https://developer.nvidia.com/cuda…

    技术杂谈 2023年6月1日
    064
  • Locust压测结果准确性验证

    最近闲着没事做,就重新研究了一下基于python语言的Locust性能测试框架 发现在压测的过程中,虽然设置了100并发,但是通过实际监控,完全看不到100并发压测的效果 通过代码…

    技术杂谈 2023年5月31日
    080
  • 寿司店问题 PV操作 pthread表示

    寿司店问题。假设一个寿司店有 5 个座位,如果你到达的时候有一个空座位,你可以立刻就坐。但是如果你到达的时候 5 个座位都是满的有人已经就坐,这就意味着这些人都是一起来吃饭的,那么…

    技术杂谈 2023年7月25日
    065
  • 如何在 30 分钟完成表格增删改查的前后端框架搭建

    30分钟,你可以做什么?可以风卷残云的饱餐一顿;可以简单地打扫一下房间;或者可以跳10十遍刘畊宏《本草纲目》毽子操。而今天,本葡萄要带你在30分钟内完成一套拥有增删改查表格系统的前…

    技术杂谈 2023年5月31日
    092
  • Vue中预览HIKVSION海康威视摄像头时ip不通浏览器卡死问题解决

    场景 SpringBoot+Vue+HIKVSION实现摄像头多选并多窗口预览(插件版): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/ar…

    技术杂谈 2023年5月31日
    0134
  • python学习

    ; ; 目录: 1、课程推荐以及书籍推荐 2、学习记录 2.1:无 1. 实践过程 廖雪峰的官方网站 2. 学习记录 2.1 无: posted @2022-02-12 19:44…

    技术杂谈 2023年6月21日
    0108
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球