首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

Windows 系統進程枚舉四大技術方案:從本地到遠程

     編輯:VC++

引言

進程由內核對象(管理統計信息)與地址空間(代碼、數據、堆棧)組成。枚舉系統進程主要有四種技術路線,適用場景各異。

方案一:PSAPI (Process Status API) —— NT 專屬

適用:Windows NT 4.0 及以上。
核心函數:EnumProcesses、OpenProcess、EnumProcessModules、GetModuleBaseName。
流程:

  1. EnumProcesses 獲取所有進程 ID 陣列。
  2. 遍歷 ID,OpenProcess 獲取句柄 (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ)。
  3. EnumProcessModules 取模塊句柄,GetModuleBaseName 取進程名。
  4. CloseHandle 釋放句柄。
DWORD aProcesses[1024], cbNeeded, cProcesses;
if (EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
    cProcesses = cbNeeded / sizeof(DWORD);
    for (unsigned int i = 0; i < cProcesses; i++)
        PrintProcessNameAndID(aProcesses[i]);
}

優點:官方 API,穩定可靠。缺點:僅限 NT 內核,不支援 9x。

方案二:ToolHelp API —— 9x/2000 通用

適用:Windows 9x、2000 及以上(NT 早期無)。
核心函數:CreateToolhelp32Snapshot、Process32First、Process32Next。
流程:快照系統進程,遍歷 PROCESSENTRY32 結構獲取 szExeFile 與 th32ProcessID。

HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe32 = {0}; pe32.dwSize = sizeof(pe32);
if (Process32First(hSnap, &pe32)) {
    do { printf("%-20s %d\n", pe32.szExeFile, pe32.th32ProcessID); }
    while (Process32Next(hSnap, &pe32));
}
CloseHandle(hSnap);

優點:跨平台 (9x/NT)、信息豐富 (線程、模塊、堆棧等)。

方案三:NTDLL 未公開 API —— NtQuerySystemInformation

適用:所有 NT 內核系統。
原理:動態加載 ntdll.dll,獲取 NtQuerySystemInformation 函數指針,傳入 SystemInformationClass = 5 (SystemProcessInformation) 獲取進程鏈表。
關鍵結構:

struct process_info {
    ULONG NextEntryDelta;
    ULONG ThreadCount;
    ULONG Reserved1[6];
    LARGE_INTEGER CreateTime, UserTime, KernelTime;
    UNICODE_STRING ProcessName;
    ULONG BasePriority;
    ULONG ProcessId;
};

流程:循環遞增緩衝區調用直到非 STATUS_INFO_LENGTH_MISMATCH,遍歷鏈表輸出名稱與 PID。風險:非文檔化 API,版本兼容性無保障。

方案四:PDH (Performance Data Helper) —— 本地/遠程通吃

適用:NT 內核本地與遠程 (需遠程註冊表權限、Admin 權限、IPC$ 連通)。
原理:讀取 HKEY_PERFORMANCE_DATA 註冊表鍵值,解析 PERF_DATA_BLOCK、PERF_OBJECT_TYPE、PERF_INSTANCE_DEFINITION、PERF_COUNTER_BLOCK 結構體鏈。
關鍵步驟:

  1. 可選:WNetAddConnection2 建立 IPC$ 連接遠程主機。
  2. RegConnectRegistry 連接本地/遠程 HKEY_PERFORMANCE_DATA 與 HKEY_LOCAL_MACHINE。
  3. 讀取 Counters 找到 Process 對象索引與 ID Process 計數器索引。
  4. 循環讀取性能數據塊,動態擴展緩衝區直到成功。
  5. 解析對象 -> 實例 -> 計數器塊,提取進程名 (Unicode 轉 ANSI) 與 PID。
  6. 遠程場景結束時 WNetCancelConnection2 斷開 IPC$。

優點:唯一支援遠程進程枚舉的標準方式。缺點:解析複雜,需深入理解性能計數器數據結構。

總結對比

方案平台遠程複雜度推薦場景
PSAPINT+否低本地簡易枚舉
ToolHelp9x/2000+否低跨平台本地枚舉
NtQuerySystemInformationNT+否中底層研究、無依賴枚舉
PDHNT+是高遠程管理、性能監控
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved