天天看點

一些技巧(2)

枚舉本地-遠端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;

繼續閱讀