枚舉本地-遠端NT系統程序
Windows2000中有個工具taskmgr.exe就可以比較詳細的檢視目前系統程序資訊,但是那是Windows GUI程式,有時候是不是覺得指令行下的東西更友善呢?其實已經有不少指令行下的枚舉系統程序的工具了,M$的Resource Kit中好象也有,但去了解他們是怎麼實作的,自己動手做出來,是不是更有意思呢:)
程序通常被定義為一個正在運作的程式的執行個體,它由兩部分組成:
<1>作業系統用來管理程序的核心對象。核心對象也是系統用來存放關于程序的統計資訊的地方。
<2>位址空間。它包含所有可執行子產品或DLL子產品的代碼和資料。它還包含動态記憶體配置設定的空間,如線程的堆棧和堆配置設定空間。
枚舉系統程序的實作方法大概有四種,其中有一種可以用來枚舉遠端NT系統的程序,前提是有遠端系統的管理者權限。
<<第一部分:調用PSAPI函數枚舉系統程序>>
M$的Windows NT開發小組開發了自己Process Status函數,包含在PSAPI.DLL檔案中,這些函數隻能在高于NT4.0以後的版本中使用。PSAPI一共有14個函數[實際PSAPI.DLL輸出函數有19個,但其中有5個函數有兩個版本,分别是ANSI和Unicode版本],通過調用這些函數,我們可以很友善的取得系統程序的所有資訊,例如程序名、程序ID、父程序ID、程序優先級、映射到程序空間的子產品清單等等。為了友善起見,以下的例子程式隻擷取程序的名字和ID。
簡單的程式如下:
Module:ps.c
說明:調用PSAPI函數枚舉系統程序名和ID,Only for NT/2000
********************************************************
#include "psapi.h"
#pragma comment(lib,"psapi.lib")
void PrintProcessNameAndID(DWORD processID)
{
char szProcessName[MAX_PATH] = "unknown";
//取得程序的句柄
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
//取得程序名稱
if (hProcess)
{
HMODULE hMod;
DWORD cbNeeded;
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
GetModuleBaseName(hProcess, hMod, szProcessName,
sizeof(szProcessName));
}
//回顯程序名稱和ID
printf("/n%-20s%-20d", szProcessName, processID);
CloseHandle(hProcess);
}
void main()
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
//枚舉系統程序ID清單
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return;
// Calculate how many process identifiers were returned.
//計算程序數量
cProcesses = cbNeeded / sizeof(DWORD);
// 輸出每個程序的名稱和ID
for (i = 0; i < cProcesses; i++)
PrintProcessNameAndID(aProcesses);
return;