枚举本地-远程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;
}
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;
}