遍历进程+遍历模块
遍歷進程有多種方法,我是用的是 CreateToolhelp32Snapshot 進程快照的方式;遍歷模塊我用的是 Process Status Helper 的函數,VC6需要下載 psapi.h 和相應的靜態庫文件,我已經上傳好了。
https://pan.baidu.com/s/1AY-6J1rZ0nM4QGIy4uSVkQ
提取碼:ord2
我下面的代碼可以用32位的VC6或者visual studio編譯,可以遍歷32/64位進程,但是只能遍歷32位進程的模塊,因為32位編譯的 EnumProcessModules 函數只能枚舉32位進程的模塊。如果程序是64位的,則可以枚舉64位進程的模塊,如果需要使程序能枚舉64位進程模塊,可以自行修改(要改的地方應該蠻多的,涉及指針強轉的都要改)。
程序運行結果是這樣的:
打印了程序和子模塊的 ImageBase 和 SizeOfImage
代碼
// EnumProcessAndModules.cpp : Defines the entry point for the console application. //#include "StdAfx.h" #include <stdio.h> #include <MALLOC.H> #include <windows.h> #include <LOCALE.h> #include <TLHELP32.H> #include <psapi.h> #pragma comment(lib,"psapi.lib")#include <vector>#ifdef _UNICODE #define _tprintf wprintf #else #define _tprintf printf #endifstruct ModuleInfo {TCHAR szExeFile[MAX_PATH]; // 模塊文件名DWORD ImageBase;DWORD SizeOfImage; };struct ProcessInfo {ModuleInfo MainModuleInfo; // 主模塊信息DWORD dwPID; // 進程IDModuleInfo *modules; // 子模塊數組DWORD dwModules; // 子模塊數量// ~ProcessInfo() // { // free(modules); // } };DWORD TakeProcessSnapshot(std::vector<ProcessInfo> &processInfos); DWORD EnumModulesHandle(HANDLE hProcess, HMODULE **lpModule);int main(int argc, char* argv[]) {setlocale(LC_ALL, "");std::vector<ProcessInfo> processInfos;TakeProcessSnapshot(processInfos);for (int i = 0; i < processInfos.size(); i++){_tprintf(TEXT("PID: %6d\t%s\n"), processInfos[i].dwPID, processInfos[i].MainModuleInfo.szExeFile);for (int j = 0; j < processInfos[i].dwModules; j++){_tprintf(TEXT("\t\t%x\t%x\t%s\n"), processInfos[i].modules[j].ImageBase, processInfos[i].modules[j].SizeOfImage, processInfos[i].modules[j].szExeFile);}}printf("Bye\n");getchar();return 0; }// 枚舉進程地址空間內的模塊句柄,返回數組長度 DWORD EnumModulesHandle(HANDLE hProcess, HMODULE **lpModule) {DWORD cbBytesNeeded = 0;// 備注:EnumProcessModules 函數無法枚舉64位進程的模塊,除非程序以64位編譯EnumProcessModules(hProcess, NULL, 0, &cbBytesNeeded); // 計算數組大小*lpModule = (HMODULE *)malloc(cbBytesNeeded + 0x1000);EnumProcessModules(hProcess, *lpModule, cbBytesNeeded + 0x1000, &cbBytesNeeded); // 枚舉模塊句柄return cbBytesNeeded / sizeof(HMODULE); }// 獲取當前所有進程的信息 DWORD TakeProcessSnapshot(std::vector<ProcessInfo> &processInfos) {processInfos.clear();// 獲取進程快照,得到當前所有進程的PIDPROCESSENTRY32 pe32;pe32.dwSize = sizeof(PROCESSENTRY32);HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProcessSnapshot == INVALID_HANDLE_VALUE){MessageBox(NULL, TEXT("獲取進程快照失敗"), TEXT("Error"), MB_OK);return -1;} // 遍歷進程BOOL bNext = Process32First(hProcessSnapshot, &pe32);while (bNext){ProcessInfo psi;memset(&psi, 0, sizeof(ProcessInfo));lstrcpy(psi.MainModuleInfo.szExeFile, pe32.szExeFile);psi.dwPID = pe32.th32ProcessID; HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, psi.dwPID);if (hProcess != NULL){HMODULE *lpModuleHandle = NULL;psi.dwModules = EnumModulesHandle(hProcess, &lpModuleHandle);psi.modules = (ModuleInfo*)malloc(psi.dwModules * sizeof(ModuleInfo));MODULEINFO moduleInfo;for (size_t i = 0; i < psi.dwModules; i++){GetModuleInformation(hProcess, lpModuleHandle[i], &moduleInfo, sizeof(MODULEINFO));//printf("\t%x\t%x\n", lpModuleHandle[i], moduleInfo.SizeOfImage);GetModuleFileNameEx(hProcess, lpModuleHandle[i], (psi.modules)[i].szExeFile, MAX_PATH);(psi.modules)[i].ImageBase = (DWORD)(lpModuleHandle[i]);(psi.modules)[i].SizeOfImage = moduleInfo.SizeOfImage;}free(lpModuleHandle);}processInfos.push_back(psi);bNext = Process32Next(hProcessSnapshot, &pe32);}return 0; }總結
- 上一篇: 使用 _tprintf 宏兼容多字节字符
- 下一篇: LPCTSTR 与 int 的互相转换