文章目录
进程遍历-EnumProcesses枚举
1. 相关函数及结构体
1.1 enumProcesses
检索系统中每个进程对象的进程标识符
BOOL EnumProcesses(
[out] DWORD *lpidProcess,
[in] DWORD cb,
[out] LPDWORD lpcbNeeded
);
lpidProcess 指向接收进程标识符列表的数组的指针
cb 进程标识符列表数组的大小(以字节为单位) 一般使用sizeof(lpidProcess [])作为默认空间值
lpcbNeeded 进程标识符列表数组中返回的字节数
1.2 OpenProcess
打开现有的本地进程对象
HANDLE OpenProcess(
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwProcessId
);
dwDesiredAccess 对进程对象的访问,针对进程的安全描述符检查此访问权限,在这里我们主要关注以下几个权限:
PROCESS_QUERY_INFORMATION (0x0400) 检索有关进程的某些信息(例如其令牌、退出代码和优先级类)
PROCESS_VM_READ (0x0010) 使用 ReadProcessMemory 读取进程中的内存
bInheritHandle 此进程创建的进程是否继承句柄
dwProcessId 打开的本地进程的标识符
1.3 enumProcessModules
检索指定进程中每个模块的句柄
BOOL EnumProcessModules(
[in] HANDLE hProcess,
[out] HMODULE *lphModule,
[in] DWORD cb,
[out] LPDWORD lpcbNeeded
);
hProcess 进程的句柄
lphModule 接收模块句柄列表的数组
cb lphModule 数组的大小(以字节为单位)
lpcbNeeded 在 lphModule 数组中存储所有模块句柄所需的字节数
1.4 getModuleFileNameExW
检索包含指定模块的文件的完全限定路径
DWORD GetModuleFileNameExW(
[in] HANDLE hProcess,
[in, optional] HMODULE hModule,
[out] LPWSTR lpFilename,
[in] DWORD nSize
);
hProcess 包含模块的进程句柄,句柄必须具有 PROCESS_QUERY_INFORMATION 和 PROCESS_VM_READ 访问权限
hModule 模块的句柄, 如果此参数为 NULL, 则 GetModuleFileNameEx 返回 hProcess 中指定的进程的可执行文件的路径。
lpFilename 指向接收模块的完全限定路径的缓冲区的指针。 如果文件名的大小大于 nSize 参数的值,则函数会成功,但文件名将被截断并用 null 结尾。
nSize lpFilename 缓冲区的大小(以字符为单位)
2. 遍历进程
2.1 遍历进程思路分析
- 通过EnumProcesses 遍历进程pid号
- 通过OpenProcess 尝试打开对应pid进程内存空间
- 通过EnumProcessModules 遍历当前进程调用的所有模块
- 通过GetModuleFileNameEx 检索指定模块的路径
- 处理进程信息结构体
2.2 遍历进程具体实现
#include <Windows.h>
#include <psapi.h>
#include <stdio.h>
#include <tchar.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, "zh_CN.UTF-8");
DWORD pProcess[1024];
DWORD cbNeeded;
DWORD cProcesses;
if (!EnumProcesses(pProcess, sizeof(pProcess), &cbNeeded)) {
return 0;
}
cProcesses = cbNeeded / sizeof(DWORD);
for (int index = 0; index < cProcesses; index++) {
HANDLE hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
pProcess[index]
);
if (hProcess == NULL) {
continue;
}
HMODULE hHmoudle[1024];
DWORD cbProcessNeeded;
if (EnumProcessModules(hProcess, hHmoudle, sizeof(hHmoudle), &cbProcessNeeded)) {
for (int pIndex = 0; pIndex < cbProcessNeeded / sizeof(DWORD); pIndex++) {
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(hProcess, hHmoudle[pIndex], szModName, sizeof(szModName) / sizeof(TCHAR) )) {
_tprintf(TEXT("\t%ws (0x%08X)\n"), szModName, hHmoudle[pIndex]);
}
}
}
CloseHandle(hProcess);
}
return 1;
}
参考文献
[1] https://learn.microsoft.com/zh-cn/windows/win32/api/psapi/nf-psapi-enumprocesses?redirectedfrom=MSDN
[2] https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess
[3] https://learn.microsoft.com/zh-cn/windows/win32/procthread/process-security-and-access-rights
[4] https://learn.microsoft.com/zh-cn/windows/win32/psapi/enumerating-all-modules-for-a-process
[5] https://learn.microsoft.com/zh-cn/windows/win32/api/psapi/nf-psapi-enumprocessmodules
[6] https://learn.microsoft.com/zh-cn/windows/win32/api/psapi/nf-psapi-getmodulefilenameexw
关注我们,咱们在安全的路上,扬帆起航