列举Windows所有进程ToolHelp
目录
1 基础知识:. 2
1.1结构框图... 2
1.2 快照函数... 2
2 Heap Walking解析... 3
2.1 Heap Walking定义... 3
2.2 Heap Walking常用函数... 4
2.3 实例... 4
3 Process Walking 解析... 5
3.1 PROCESSENTRY32定义... 5
3.2 Process Walking 常用函数... 6
3.3 Process Walking 实例... 6
4 Thread Walking 解析... 7
4.1 THREADENTRY32定义... 7
4.2 Thread Walking常用的函数... 8
4.3 Thread Walking 使用... 8
5 Module Walking 解析... 9
5.1 MODULEENTRY32结构定义... 9
5.2 Module Walking常用函数... 10
5.3 Module Walking 实例... 10
列举Windows所有进程
1 基础知识:
1.1结构框图
注意:使用时添加#include<tlhelp32.h>
1.2 快照函数
快照(Snapshot):简单的理解就是给当前系统所处的状态记录下来.
快照的函数:CreateToolhelp32Snapshot
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID );
dwFlags:
the32ProcessID:
通过上图的dwFlags类型可以选择快照的类型,当不使用时关闭它.
使用: BOOL CloseHandle( HANDLE hObject);或
BOOL WINAPI CloseToolhelp32Snapshot(HANDLE hSnapshot);
DWORD GetLastError( void );//错误信息.
2 Heap Walking解析
2.1 Heap Walking定义
Heap Walking
定义: 此结构描述了指定的进程使用的堆链表的进入点
原型:
typedef struct tagHEAPLIST32
{
DWORD dwSize;
DWORD th32ProcessID;
DWORD th32HeapID;
DWORD dwFlags;
} HEAPLIST32;
typedef HEAPLIST32 * PHEAPLIST32;
typedef HEAPLIST32 * LPHEAPLIST32;
参数解释:
1. dwSize: HEAPLIST32结构体的大小,参数时必须的.
2. th32ProcessID: 进程ID
3. th32HeapID: 堆标示符
4. dwFlags:
#define HF32_DEFAULT 1 //进程的默认堆
#define HF32_SHARED 2 //共享堆模式
其他字段通过Heap32ListFirst和Heap32Listnext 来填充
HEAPENTRY32定义:
typedef struct tagHEAPENTRY32
{
DWORD dwSize;
HANDLE hHandle;
DWORD dwAddress;
DWORD dwBlockSize;
DWORD dwFlags;
DWORD dwLockCount;
DWORD dwResvd;
DWORD th32ProcessID;
DWORD th32HeapID;
} HEAPENTRY32;
typedef HEAPENTRY32 * PHEAPENTRY32;
typedef HEAPENTRY32 * LPHEAPENTRY32;
参数解释
1. dwSize: HEAPENTRY32结构体的大小,必须的
2. hHandle: 这个参数指向一个堆块
3. dwAddress: 这个参数代表堆的线性起始地址
4. dwBlockSize: 当前这个堆的大小
5. dwFlags:
#define LF32_FREE 0x00000002 //内存块不能用
#define LF32_FIXED 0x00000001 //内存块可以用,不可以移动
#define LF32_MOVEABLE 0x00000004 //内存块可移动
6. dwLockCount: 参数保留
7. dwResvd: 参数保留
8. th32ProcessID: 使用这个堆块的进程ID
9. th32HeapID: 当前堆块的标示符
2.2 Heap Walking使用中常用的API函数
(1) BOOL WINAPI Heap32ListFirst(
HANDLE hSnapshot,
LPHEAPLIST32 lphl);
(2) BOOL WINAPI Heap32ListNext(
HANDLE hSnapshot,
LPHEAPLIST32 lphl);
(3) BOOL WINAPI Heap32First(
HANDLE hSnapshot,
LPHEAPENTRY32 lphe,
DWORD th32ProcessID,
DWORD th32HeapID );
(4) BOOL WINAPI Heap32Next(
HANDLE hSnapshot,
LPHEAPENTRY32 lphe );
(5) BOOL WINAPI Toolhelp32ReadProcessMemory(
DWORD th32ProcessID,
LPCVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD cbRead,
LPDWORD lpNumberOfBytesRead );
2.3 实例
#include<tlhelp32.h>
//获取指定进程下的堆信息
BOOL ListProcessHeaps(DWORD dwOwnerPID)
{
HEAPLIST32 h1;
HANDLE hHeapSnap = INVALID_HANDLE_VALUE;
//创建指定进程下的堆快照
hHeapSnap = CreateToolhelp32SnapShot(TH32CS_SNAPHEAPLIST, dwOwnerPID);
if(hHeapSnap == INVALID_HANDLE_VALUE)
return FALSE;
//填充结构成员
h1.dwSize = sizeof(HEAPLIST32);
if(Heap32ListFirst(hHeapSnap, &h1))
{
do
{
//堆中的一个块
HEAPENTRY32 he;
ZeroMemory(&he, 0, sizeof(HEAPENTRY32));
he.dwSize = sizeof(HEAPENTRY32);
//遍历当前进程,指定堆ID下所有块
if(Heap32First(hHeapSnap, &he,
h1.th32ProcessID, h1.th32HeapID))
{
printf(“\nnHeap ID: %d\n”, h1.th32HeapID);
do
{
printf("Block size: %d\n", he.dwBlockSize);
he.dwSize = sizeof(HEAPENTRY32);
}while(Heap32Next(hHeapSnap, &he));
}
h1.hwSize = sizeof(HEAPLIST32);
}while(Heap32ListNext(hHeapSnap, &h1));
}
CloseHandle(hHeapSnap);
return TRUE;
}
3 Process Walking 解析
3.1 PROCESSENTRY32定义
typedef struct tagPROCESSENTRY32
{
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID; // this process
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID; // associated exe
DWORD cntThreads;
DWORD th32ParentProcessID; // this process's parent process
LONG pcPriClassBase; // Base priority of process's threads
DWORD dwFlags;
CHAR szExeFile[MAX_PATH]; // Path
} PROCESSENTRY32;
typedef PROCESSENTRY32 * PPROCESSENTRY32;
typedef PROCESSENTRY32 * LPPROCESSENTRY32;
下面就来解释 PROCESSENTRY32 中的结构成员
dwSize: PROCESSENTRY32 结构体的大小,在使用 Process32First 之前需要将这个成员设置好。
cntUsage: //这个参数呢,不管它了,也不需要设置,因为这个值的结果必须为 1 。
th32ProcessID: // 这个参数代表一个进程的 ID,即进程标识符。
th32DefaultHeapID: // 这个参数的话代表了进程的默认堆标识符。
th32ModuleID: // 这个参数代表了进程的模块标识符.
cntThreads: //代表进程所启动的线程数目。
th32ParentProcessID: // 代表该进程的父进程 ID。
pcPriClassBase: //该值代表由该进程所创建的线程所拥有的基本优先级。
dwFlags: //保留,暂未使用。
szExeFile: //返回该进程的可执行文件所在的路径。
th32MemoryBase: //该可执行文件所加载的基地址。
th32AccessKey: //访问标识符。
这个结构体只需要填充第一个字段 dwSize 即可,
其他字段都是通过调用函数 Process32First 或者是 Process32Next 来填充的。
3.2 Process Walking 函数
BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
3.3 Process Walking 实例
#include <tlhelp32.h>
//获取到进程列表
BOOL GetProcessList()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
//对系统中当前所有的进程拍下快照
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
//在使用 PROCESSENTRY32 结构之间需要先设置好该结构的大小
pe32.dwSize = sizeof(PROCESSENTRY32);
//获取第一个进程
if(!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return FALSE;
}
//采用 Do - While 遍历所有进程
do
{
printf("\n-----------------------------------------------------");
printf("\n PROCESS NAME: = %s", pe32.szExeFile);
printf("\n parent process ID = 0x%08X", pe32.th32ParentProcessID);
printf("\n process ID = 0x%08X", pe32.th32ProcessID);
printf("\n thread count = %d", pe32.cntThreads);
printf("\n Priority Base = %d", pe32.pcPriClassBase);
//遍历获取下一个进程
} while(Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return TRUE;
}
4 Thread Walking 解析
4.1 THREADENTRY32定义
typedef struct tagTHREADENTRY32
{
DWORD dwSize;
DWORD cntUsage;
DWORD th32ThreadID; // this thread
DWORD th32OwnerProcessID; // Process this thread is associated with
LONG tpBasePri;
LONG tpDeltaPri;
DWORD dwFlags;
} THREADENTRY32;
typedef THREADENTRY32 * PTHREADENTRY32;
typedef THREADENTRY32 * LPTHREADENTRY32;
下面解释 PTHREADENTRY32 中的结构成员的含义了。
dwSize: //PTHREADENTRY32 结构体的大小,在使用 Thread32First 之前需要将这个成员设置好。
cntUsage: //这个参数不需要设置,总是为 0 。
th32ThreadID: //这个参数代表一个线程的 ID,即线程标识符。
th32OwnerProcessID:// 这个参数的话代表了该线程所属的进程的标识符。
tpBasePri : //这个参数代表了分配给这个线程的基本优先级。
tpDeltaPri : //这个参数总是 0 ,不需要理会 。
dwFlags : //这个参数也总是 0 ,不需要理会 。
在使用上面的这个结构体只需要填充第一个字段 dwSize 即可,
其他字段都是通过调用函数 Thread32First 或者是 Thread32Next 来填充的。
4.2 Thread Walking常用的函数
BOOL WINAPI Thread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpte);
BOOL WINAPI Thread32Next(HANDLE hSnapshot, LPTHREADENTRY32 lpte);
4.3 Thread Walking 使用
#include <tlhelp32.h>
using namespace std;
//获取到进程列表
BOOL GetProcessList()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
//对系统中当前所有的进程拍下快照
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
return FALSE;
//在使用 PROCESSENTRY32 结构之间需要先设置好该结构的大小
pe32.dwSize = sizeof(PROCESSENTRY32);
//获取第一个进程
if(!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return FALSE;
}
//采用 Do - While 遍历所有进程
do
{
printf("\n-----------------------------------------------------");
printf("\n PROCESS NAME: = %s", pe32.szExeFile);
printf("\n parent process ID = 0x%08X", pe32.th32ParentProcessID);
printf("\n process ID = 0x%08X", pe32.th32ProcessID);
printf("\n thread count = %d", pe32.cntThreads);
printf("\n Priority Base = %d", pe32.pcPriClassBase);
//列举出指定进程下的所有线程
ListProcessThreads(pe32.th32ProcessID);
//遍历获取下一个进程
} while(Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return TRUE;
}
//获取指定进程下的所有的线程信息
BOOL ListProcessThreads(DWORD dwOwnerPID)
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
//给当前行的下所有的线程进行拍照
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if(hThreadSnap == INVALID_HANDLE_VALUE)
{
return FALSE;
}
te32.dwSize = sizeof(THREADENTRY32 );
//获取指定进程的第一个线程
if(!Thread32First(hThreadSnap, &te32))
{
CloseHandle(hThreadSnap);
return FALSE;
}
do
{
//用来核对当前线程是否属于指定进程
if(te32.th32OwnerProcessID == dwOwnerPID)
{
printf("\n\n THREAD ID = 0x%08X", te32.th32ThreadID);
printf("\n base priority = %d", te32.tpBasePri);
printf("\n delta priority = %d", te32.tpDeltaPri);
}
//遍历指定进程的下一个线程
} while(Thread32Next(hThreadSnap, &te32));
CloseHandle(hThreadSnap);
return TRUE;
}
5 Module Walking 解析
5.1 MODULEENTRY32结构定义
typedef struct tagMODULEENTRY32
{
DWORD dwSize;
DWORD th32ModuleID; // This module
DWORD th32ProcessID; // owning process
DWORD GlblcntUsage; // Global usage count on the module
DWORD ProccntUsage; // Module usage count in th32ProcessID's context
BYTE * modBaseAddr; // Base address of module in th32ProcessID's context
DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr
HMODULE hModule; // The hModule of this module in th32ProcessID's context
char szModule[MAX_MODULE_NAME32 + 1];
char szExePath[MAX_PATH];
} MODULEENTRY32;
typedef MODULEENTRY32 * PMODULEENTRY32;
typedef MODULEENTRY32 * LPMODULEENTRY32;
下面就来解释 PMODULEENTRY32 中的结构成员的含义了。
dwSize: //PMODULEENTRY32 结构体的大小,在使用 Module32First 之前需要将这个成员设置好
th32ModuleID : //这个参数已不再使用,不管它了,也不需要设置 。
th32ProcessID: // 这个参数就很明显了,代表一个进程的 ID,即进程标识符 。
GlblcntUsage: //这个参数代表这个模块在整个系统中加载的数目 , 也不用理会 。
ProccntUsage: //这个参数代表和前面的参数差不多,只不过不再是整个系统,而是指当前进程的上下文中,也不理会 。
modBaseAddr: //代表模块在进程上下文中的基地址 。
modBaseSize: //代表该模块的大小 。
hModule : //该值代表模块句柄 .
szModule : //该参数代表模块名。
szExePath: //回该模块所在的路径。
在使用当中上面的这个结构体只需要填充第一个字段 dwSize 即可,
其他字段都是通过调用函数 Module32First 或者是 Module32Next 来填充的。
5.2 Module Walking常用函数
BOOL WINAPI Module32First(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
BOOL WINAPI Module32Next(HANDLE hSnapshot, LPMODULEENTRY32 lpme);
5.3 Module Walking 实例
#include <tlhelp32.h>
//获取到进程列表
BOOL GetProcessList()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
//对系统中当前所有的进程拍下快照
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
return FALSE;
//在使用 PROCESSENTRY32 结构之间需要先设置好该结构的大小
pe32.dwSize = sizeof(PROCESSENTRY32);
//获取第一个进程
if(!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return FALSE;
}
//采用 Do - While 遍历所有进程
do
{
printf("\n-----------------------------------------------------");
printf("\n PROCESS NAME: = %s", pe32.szExeFile);
printf("\n parent process ID = 0x%08X", pe32.th32ParentProcessID);
printf("\n process ID = 0x%08X", pe32.th32ProcessID);
printf("\n thread count = %d", pe32.cntThreads);
printf("\n Priority Base = %d", pe32.pcPriClassBase);
//列出与该进程相关联的模块信息
ListProcessModules(pe32.th32ProcessID);
//遍历获取下一个进程
} while(Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return TRUE;
}
//获取指定进程引用的所有的模块信息
BOOL ListProcessModules(DWORD dwPID)
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
//给进程所引用的模块信息设定一个快照
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
if(hModuleSnap == INVALID_HANDLE_VALUE)
return FALSE;
me32.dwSize = sizeof(MODULEENTRY32);
if(!Module32First(hModuleSnap, &me32))
{
CloseHandle(hModuleSnap);
return FALSE;
}
do
{
printf("\n\n MODULE NAME: %s", me32.szModule);
printf("\n executable = %s", me32.szExePath);
printf("\n process ID = 0x%08X", me32.th32ProcessID);
printf("\n ref count (g) = 0x%04X", me32.GlblcntUsage);
printf("\n ref count (p) = 0x%04X", me32.ProccntUsage);
printf("\n base address = 0x%08X", (DWORD)me32.modBaseAddr);
printf("\n base size = %d", me32.modBaseSize);
} while(Module32Next(hModuleSnap, &me32));
CloseHandle(hModuleSnap);
return TRUE;
}