如何在C中获取进程句柄而不是其名称?

时间:2011-12-12 19:46:35

标签: c windows winapi

我正在Windows XP上编写一个程序,试图获取calc.exe的proccess句柄。我可以假设用户确实运行了calc.exe,但他可能已经更改了文件名。

是否有名称来获取calc.exe进程的句柄,即使名称已被更改?

我找到了这个答案,但它没有处理顽皮用户更改名称的情况(例如calc_new.exe):

How can I get a process handle by its name in C++?

我是否可以使用Win32进程的其他属性来查找句柄?

2 个答案:

答案 0 :(得分:1)

您可以使用以下Win32 API调用序列执行此操作:

  1. 使用Spy ++或类似内容查找您要定位的顶级窗口的类名。
  2. 致电FindWindowEnumWindows,找到具有该班级名称的顶级窗口。
  3. 致电GetWindowThreadProcessId以查找每个感兴趣的窗口的进程ID。
  4. 调用OpenProcess传递进程ID以获取进程句柄。

答案 1 :(得分:1)

如果用户可以更改calc.exe的名称,他们还可以更改哪些内容以避免检测?可执行文件中的任意字节?如果是这种情况,那么您将遇到病毒扫描程序供应商面临的同类问题。

无论如何,这是我的疯狂想法(未经测试!不可行,真的):

  1. 使用CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0)快照所有流程的模块信息。
  2. 浏览快照中的进程列表。
  3. 对于每个流程,请浏览模块列表。
  4. 对于每个模块,请查看MODULEENTRY32::szExePath以查找加载模块的路径。这假设模块仍在该位置,未被覆盖,磁盘未被删除等。
  5. 您可能希望将文件大小与已知calc.exe文件大小列表进行比较,但这无济于事。用户可能已填充可执行文件或对其进行压缩(例如,使用UPX)以避免检测。
  6. 使用WinVerifyTrust()检查模块的数字签名。如果它是由Microsoft以外的其他人签名,未签名或签名未签出,那么它可能是calc.exe的副本,用户已修改(并可能重新签名)以避免被检测到,并且您必须将流程标记为calc.exe
  7. 如果模块的数字签名表明该文件是由Microsoft签名且未经修改,则使用GetFileVersionInfo()和好友获取OriginalFilename字符串。如果字符串等于CALC.EXE,则将该进程标记为calc.exe