CreateToolhelp32Snapshot函数
- CreateToolhelp32Snapshot可以通过获取进程信息为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程建立一个快照。说到底,可以获取系统中正在运行的进程信息,线程信息,等。
原型:
HANDLE WINAPI CreateToolhelp32Snapshot(
_In_ DWORD dwFlags, //用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等
_In_ DWORD th32ProcessID //一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取 当前进程快照时可以设为0
);
0x01.参数
dwFlags [in]
要包括在快照中的系统部分。此参数可以是以下一个或多个值。
值 | 含义 |
---|---|
TH32CS_INHERIT 0x80000000 | 表示快照句柄是可继承的。 |
TH32CS_SNAPALL | 包括系统中的所有进程和线程,以及th32ProcessID中指定的进程的堆和模块。等效于使用OR运算指定组合的TH32CS_SNAPHEAPLIST,TH32CS_SNAPMODULE,TH32CS_SNAPPROCESS和TH32CS_SNAPTHREAD值。 |
TH32CS_SNAPHEAPLIST 0x00000001 | 包括快照中th32ProcessID中指定的进程的所有堆。要枚举堆,请参阅Heap32ListFirst。 |
TH32CS_SNAPMODULE 0x00000008 | 包括快照中th32ProcessID中指定的进程的所有模块。要枚举模块,请参阅Module32First。如果函数失败并返回ERROR_BAD_LENGTH,请重试该函数直到成功。64位Windows:在32位进程中使用此标志包括th32ProcessID中指定的进程的32位模块,而在64位进程中使用该进程包括64位模块。要包括来自64位进程的th32ProcessID中指定的进程的32位模块,请使用TH32CS_SNAPMODULE32标志。 |
TH32CS_SNAPMODULE32 0x00000010 | 包括从64位进程调用时快照中的th32ProcessID中指定的进程的所有32位模块。该标志可以与TH32CS_SNAPMODULE或TH32CS_SNAPALL组合使用。如果函数失败并返回ERROR_BAD_LENGTH,请重试该函数直到成功。 |
TH32CS_SNAPPROCESS 0x00000002 | 包括快照中系统中的所有进程。要枚举进程,请参阅Process32First。 |
TH32CS_SNAPTHREAD 0x00000004 | 包括快照中系统中的所有线程。要枚举线程,请参阅Thread32First。要标识属于特定进程的线程,在枚举线程时将其进程标识符与THREADENTRY32结构的th32OwnerProcessID成员进行比较。 |
参数2
th32ProcessID [in]
要包括在快照中的进程的进程标识符。此参数可以为零以指示当前进程。当指定TH32CS_SNAPHEAPLIST,TH32CS_SNAPMODULE,TH32CS_SNAPMODULE32或TH32CS_SNAPALL
值时,使用此参数。否则,它将被忽略,并且所有进程都包括在快照中。
如果指定的进程是空闲进程或其中一个CSRSS
进程,则此函数将失败,并且最后一个错误代码为ERROR_ACCESS_DENIED
,因为它们的访问限制会阻止用户级代码打开它们。
如果指定的进程是64位进程,并且调用程序是32位进程,则此函数失败,最后一个错误代码为ERROR_PARTIAL_COPY(299)
。
返回值
如果函数成功,它将返回一个打开的句柄到指定的快照。
如果函数失败,则返回INVALID_HANDLE_VALUE
。要获取扩展错误信息,请调用GetLastError
。可能的错误代码包括ERROR_BAD_LENGTH
。
0x02.备注
- 此功能拍摄的快照由其他工具帮助功能检查,以提供其结果。对快照的访问是只读的。快照句柄充当对象句柄,并且遵守与其在其中有效的进程和线程相同的规则。
- 要枚举所有进程的堆或模块状态,请指定
TH32CS_SNAPALL
并将th32ProcessID
设置为零。然后,对于快照中的每个附加进程,再次调用CreateToolhelp32Snapshot
,指定其进程标识符和TH32CS_SNAPHEAPLIST
或TH32_SNAPMODULE
值。 - 当为包含当前进程以外的进程的堆和模块创建快照时,由于各种原因,
CreateToolhelp32Snapshot
函数可能会失败或返回不正确的信息。例如,如果目标进程中的加载器数据表已损坏或未初始化,或者在作为DLL被加载或卸载的结果的函数调用期间模块列表发生更改,则函数可能会失败,并显示ERROR_BAD_LENGTH
或其他错误代码。确保目标进程未在暂挂状态下启动,并尝试再次调用该函数。如果在使用TH32CS_SNAPMODULE
或TH32CS_SNAPMODULE32
调用时,函数失败,ERROR_BAD_LENGTH
,则再次调用该函数,直到成功。 TH32CS_SNAPMODULE
和TH32CS_SNAPMODULE32
标志不会检索使用LOAD_LIBRARY_AS_DATAFILE
或类似标志加载的模块的句柄。有关详细信息,请参阅LoadLibraryEx
。
要销毁快照,请使用CloseHandle
函数。
请注意,您可以使用QueryFullProcessImageName
函数从32位进程检索32位和64位进程的可执行映像的全名。
0x03.包含库
Minimum supported client | Windows XP [desktop apps only] |
---|---|
Minimum supported server | Windows Server 2003 [desktop apps only] |
Header | TlHelp32.h |
Library | Kernel32.lib |
DLL | Kernel32.dll |
0x04.Example
#include "StdAfx.h"
#include "windows.h"
#include "tlhelp32.h"
#include "stdio.h"
int main(int argc, char* argv[])
{
PROCESSENTRY32 pe32;
//在使用这个结构前,先设置它的大小
pe32.dwSize = sizeof(pe32);
//给系统内所有的进程拍个快照
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot 调用失败.\n");
return -1;
}
//遍历进程快照,轮流显示每个进程的信息
BOOL bMore = ::Process32First(hProcessSnap,&pe32);
while (bMore)
{
printf("进程名称:%s\n",pe32.szExeFile);
printf("进程ID:%u\n\n",pe32.th32ProcessID);
bMore = ::Process32Next(hProcessSnap,&pe32);
}
//不要忘记清除掉snapshot对象
::CloseHandle(hProcessSnap);
return 0;
}