Toolhelp API 简介
Toolhelp APIs是Windows中一组能够方便得到系统中win32应用程序的当前运行状况的函数,这些函数设计目的是实现一些基于Win32子系统的工具,特别是调试器。通过使用Toolhelp API,我们可以实现象Windows附带的系统工具Dr watson一样的功能(当然真正实现它的所有功能不是光靠Toolhelp API一个函数库就可以的)。而且这些函数适用于win9x,winnt,win2k,所以不需要为在不同的windows版本中移植代码操心。
下面将介绍ToolHelp APIs中一些主要的函数和结构。主要有CreateToolhelp32Snapshot和Xxx32First,Xxx32Next系列函数,还有Toolhelp32ReadProcessMemory。所用语言为Object Pascal,对于使用C++的程序员可以参考SDK index中的tool help library [Win32].
以下是它们的定义和说明:
1. 创建快照函数CreateToolhelp32Snapshot
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags, // 要得到进程的信息,赋为TH32CS_SNAPPROCESS
// 要得到线程的信息,赋为TH32CS_SNAPTHREAD
// 要得到指定进程的堆列表,赋为TH32CS_SNAPHEAPLIST
// 要得到指定进程的模块列表,赋为TH32CS_SNAPMODULE
DWORD th32ProcessID // 当我们把dwFlags赋为TH32CS_SNAPMODULE 或者
// TH32CS_SNAPHEAPLIST时,需要指定具体的进程ID,否则
// 将忽略此参数。把它赋为0表示当前进程(也就是自己)
);// 返回值THandle将在以后要枚举进程、线程等对象时使用
当我们得到快照的句柄后可以分别使用Xxx32First,Xxx32Next这些函数进行对象枚举。
它们的定义如下所示:
2. Xxx32First,Xxx32Next枚举函数与有关结构
l 进程有关的函数与结构
typedef struct tagPROCESSENTRY32 {
DWORD dwSize; // 指定结构的大小,
// 在调用Process32First前需要设置,否则将会失败
DWORD cntUsage; // 引用计数
DWORD th32ProcessID; // 进程号
DWORD th32DefaultHeapID; // 进程的堆号,只对Toolhelp函数有意义,并不是一个有效句柄
DWORD th32ModuleID; // 进程的模块号,只对Toolhelp函数有意义,并不是一个有效句柄
DWORD cntThreads; // 进程中包括的线程数
DWORD th32ParentProcessID; // 进程的母进程
LONG pcPriClassBase; // 进程的线程的基优先级,所有此进程创建的线程将基于此优先级
DWORD dwFlags; // 保留,没有使用
char szExeFile[MAX_PATH]; // 进程所对应的文件及路径
} PROCESSENTRY32;
typedef PROCESSENTRY32 * PPROCESSENTRY32;
typedef PROCESSENTRY32 * LPPROCESSENTRY32;
BOOL WINAPI Process32First(
hSnapshot: THandle; // 前面由CreateToolhelp32Snapshot创建的快照句柄
var lppe: TProcessEntry32 //函数输出进程信息
): BOOL; //调用成功将为True,否则为False
BOOL WINAPI Process32Next(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL;
l 模块有关的函数和结构
typedef struct tagMODULEENTRY32 {
DWORD dwSize; // 指定结构的大小,
// 在调用Module32First前需要设置,否则将会失败
DWORD th32ModuleID; // 模块号
DWORD th32ProcessID; // 包含本模块的进程号
DWORD GlblcntUsage; // 本模块的全局引用计数
DWORD ProccntUsage; // 包含模块的进程上下文中的模块引用计数
BYTE * modBaseAddr; // 模块基地址
DWORD modBaseSize; // 模块大小(字节数)
HMODULE hModule; // 包含模块的进程上下文中的hModule句柄.注意:modBaseAddr 与 hModule 只在th32ProcessID的上下文才有效
char szModule[MAX_MODULE_NAME32 + 1]; //模块名
char szExePath[MAX_PATH]; //模块对应的文件名和路径
} MODULEENTRY32;
typedef MODULEENTRY32 * PMODULEENTRY32;
typedef MODULEENTRY32 * LPMODULEENTRY32;
BOOL WINAPI Module32First(hSnapshot: THandle; var lpme: TModuleEntry32): BOOL; //同进程说明
BOOL WINAPI Module32Next(hSnapshot: THandle; var lpme: TModuleEntry32): BOOL;
l 线程有关的函数和结构
typedef struct tagTHREADENTRY32{
DWORD dwSize; // 指定结构的大小,
// 在调用Thread32First前需要设置,否则将会失败
DWORD cntUsage; // 线程引用计数
DWORD th32ThreadID; // 线程号
DWORD th32OwnerProcessID; // 拥有线程的进程号
LONG tpBasePri; // 在线程创建时的初始优先级
LONG tpDeltaPri; // 现在线程的优先级的相对于初始值的改变量
DWORD dwFlags; // 保留,没有使用
} THREADENTRY32;
typedef THREADENTRY32 * PTHREADENTRY32;
typedef THREADENTRY32 * LPTHREADENTRY32;
BOOL WINAPI Thread32First(hSnapshot: THandle; var lpte: TThreadEntry32): BOOL; stdcall;
BOOL WINAPI Thread32Next(hSnapshot: THandle; var lpte: TThreadENtry32): BOOL; stdcall;
l 堆有关的函数和结构
typedef struct tagHEAPENTRY32
{
DWORD dwSize; // 指定结构的大小,在调用Heap32First前需要设置,否则将会失败
HANDLE hHandle; // 堆的句柄
DWORD dwAddress; // 堆起始位置的线性地址
DWORD dwBlockSize; // 堆的大小(字节数)
DWORD dwFlags; // 标志,为以下值:LF32_FIXED 堆内存块的位置是固定的;LF32_FREE 堆内存块没有使用;LF32_MOVEABLE
//堆内存块的位置是可移动的
DWORD dwLockCount; // 堆的锁定计数,每次对堆的执行GlobalLock. 或者LocalLock都将使它增1
DWORD dwResvd; // 保留,没有使用
DWORD th32ProcessID; // 拥有本堆的进程号,这个ID是可以被其他WIN32 API使用的。
DWORD th32HeapID; // 堆号,只能在ToolHelp API中内部使用,
} HEAPENTRY32;
typedef HEAPENTRY32 * PHEAPENTRY32;
typedef HEAPENTRY32 * LPHEAPENTRY32;
BOOL WINAPI Heap32First(
LPHEAPENTRY32 lphe,
DWORD th32ProcessID,
DWORD th32HeapID
);
BOOL WINAPI Heap32Next(
LPHEAPENTRY32 lphe
);
3. 更为有用的Toolhelp API函数有Toolhelp32ReadProcessMemory,它可以读其他进程内存空间的内容。
BOOL WINAPI Toolhelp32ReadProcessMemory(
DWORD th32ProcessID, // 指定进程
LPCVOID lpBaseAddress, // 要读的进程内存空间的起始地址
LPVOID lpBuffer, // 将要读的内容的保存缓冲区
DWORD cbRead, // 要读的字节数
LPDWORD lpNumberOfBytesRead // 成功读取的字节数
); // 函数成功返回True,否则返回False
利用上面的函数,我们得出以下的程序端:
首先我们应该调用CreateToolhelp32Snapshot创建快照;然后调用Process32First,把创建的快照的句柄传递给hSnapshot参数,函数成功返回后我们将在lppe参数中得到第一个进程的信息;继续调用Process32Next,我们将得到后续的进程信息,直到Process32Next返回False为止。记住最后我们应该调用CloseHandle把快照的句柄安全的释放。 根据进程名找到进程ID,然后使用EnumWindows进行获取句柄。
EnumWindows函数功能:该函数枚举所有屏幕上的顶层窗口,办法是先将句柄传给每一个窗口,然后再传送给应用程序定义的回调函数。EnumThreadWindows函数继续到所有顶层窗口枚举完为止或回调函数返回FALSE为止函数原型:
BOOL EnumWindows(WNDENUMPROC lpEnumFunc,LPARAM lParam);
参数:
lpEnumFunc:指向一个应用程序定义的回调数指针,请参看EnumWindowsProc。
lPararm:指定一个传递给回调函数的应用程序定义值。
返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。若想获得更多错误信息,请调用GetLastError函数。
// 列出所有进程
void CProcess::SysListProcess()
{
// 初始化
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
// 获得句柄
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == (HANDLE)-1)
{
printf("\nCreateToolhelp32Snapshot()failed:%d",GetLastError());
return;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
// 列举所有进程名称
if (Process32First(hProcessSnap, &pe32))
{
for (int i = 0; Process32Next(hProcessSnap, &pe32); i++)
{
// 将进程名加到列表中
m_list.InsertItem(i, pe32.szExeFile); // CListCtrl m_list;
}
}
else
{
printf("\nProcess32Firstt() failed:%d",GetLastError());
}
// 关闭句柄
CloseHandle (hProcessSnap);
}
分享到:
相关推荐
4. **ToolHelp API**:这个名字可能暗示了该工具利用了Windows CE或Windows Mobile等PDA操作系统中的ToolHelp API。ToolHelp API是一组函数,允许开发者枚举、查询和监视系统中的进程和线程信息,这对于创建类似...
在VB(Visual Basic)编程中,有时我们需要访问操作系统底层的功能,这时就需要调用系统API(Application Programming Interface)函数。在给定的文件中,重点介绍了如何使用VB来调用`CreateToolhelp32Snapshot`函数...
其中的"ToolHelp"可能是指易语言中的一个模块或工具集,用于帮助开发者获取系统中运行的进程、线程等信息,类似于Windows API中的ToolHelp函数库。 在Windows编程中,ToolHelp API提供了一种遍历和查询系统中进程、...
"ToolHelp"是Windows API中的一个工具,用于在程序中获取系统中运行的进程、线程等信息。在易语言中,开发者可以使用ToolHelp相关的API函数来实现对系统状态的查询和管理。 易语言ToolHelp源码通常涉及到以下几个...
本文将详细介绍如何使用ToolHelp API来枚举系统中的进程,并将进程ID(PID)与进程名输出到屏幕和文件。 首先,我们要理解什么是ToolHelp API。ToolHelp API是Windows API的一部分,它提供了一种简单的方式来遍历和...
本教程将深入探讨如何利用VC++和MFC库,通过ToolHelp API来实现这一功能。ToolHelp API是Windows提供的一种轻量级的方法,可以用来枚举系统中的进程和线程。 首先,我们需要了解ToolHelp API中的关键函数。`...
23. 工具帮助(ToolHelp) 提供了获取进程、线程和内存区域信息的API。 24. 窗口、桌面与工作站 这部分介绍了窗口句柄、桌面对象和工作站对象的管理API。 25. WinTrust API 这些API涉及代码和内容的认证,确保文件...
其中`dwProcessId`为待跟踪进程的ID,可通过使用ToolHelp库或Psapi库获取进程ID。 2. **创建带有跟踪标志的进程**:使用`CreateProcess`函数创建新进程时,可以通过设置`dwCreationFlags`参数中的`DEBUG_PROCESS`...
VC 写的APIHook实例源代码,VC 写的APIHook实例源代码,大致翻了一下,只挂引入表的函数,注入有SetWindowHookEx和CreateRemoteThread两种方式,进程枚举也区分了不同系统下使用的psai和toolhelp,另外为了获得...
Win32 API提供了丰富的功能来实现这一目标。本文主要介绍了如何使用Win32 API来枚举应用程序的顶层窗口以及系统中的进程。 首先,枚举桌面顶层窗口通常通过`EnumWindows()`函数来实现。这个函数接收两个参数,一个...
ToolHelp服务提供了一系列API,如`CreateToolhelp32Snapshot()`、`Process32First()`和`Process32Next()`等,这些API可以用来获取当前系统的进程快照并遍历这些进程。 1. **创建快照**: ```c++ HANDLE hSnapshot...
在Windows API中,`CreateToolhelp32Snapshot`、`Process32First`和`Process32Next`是一组重要的函数,它们用于枚举和获取系统中的进程信息。这些函数通常被开发者用来进行系统监控、调试或者性能分析等任务。 `...
printf("ShowProcessPath with [ToolHelp API]\n\n"); report=Process32First(hProcess,pinfo); while(report) { hModule=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pinfo->th32ProcessID); Module...
这里提到了`coredll.dll`和`toolhelp.dll`两个动态链接库,它们提供了与进程相关的API函数。 1. **coredll.dll**: 这是WinCE系统的核心库,包含了许多基本的系统函数,如内存管理、线程和进程操作等。 2. **...
内容索引:VC/C++源码,系统相关,HOOK,钩子 VC++写的APIHook实例源代码,大致翻了一下,只挂引入表的函数,注入有SetWindowHookEx和CreateRemoteThread两种方式,进程枚举也区分了不同系统下使用的psai和toolhelp,...
ToolHelp库是Windows API提供的一组函数,它允许程序员以简单的方式遍历和获取系统中的进程和线程信息。 在Windows操作系统中,进程是执行中的程序实例,每个进程都有一个独立的内存空间。通过进程察看工具,用户或...
这四种方法分别利用了Windows API中的ToolHelp服务、Psapi库以及Win32 API的底层机制。 **方法一:使用ToolHelp服务** ToolHelp服务提供了几个关键的API函数,如`CreateToolhelp32Snapshot()`、`Process32First()`...
- `ToolHelp.h`:包含关于ToolHelp函数的声明,用于创建和操作进程快照。 - `Resource.h`:定义了应用程序的资源,如菜单、对话框和图标等。 - `ProcessInfo.cpp`:是程序的主要实现文件,包含了实际的代码逻辑。...
本文将详细讲解如何利用Windows API中的`ReadProcessMemory`和`WriteProcessMemory`函数来实现这一目标,同时也会探讨相关概念和技术。 `ReadProcessMemory`和`WriteProcessMemory`是Windows API提供的系统级函数,...
针对进程信息的控制,Windows操作系统提供了PSAPI和ToolHelp32两套API获取进程信息。恶意代码通常会HOOK `EnumProcesses()`、`Process32First()`和`Process32Next()`等函数,从进程列表中隐藏自身。关键在于`...