我要投稿
  • 您当前的位置:57365.com -> 技术教程 -> 操作系统教程 -> Win2000教程 -> 教程内容
  • [ 收藏本页教程 ]
  • 枚举本地远程NT系统进程

    教程作者:佚名    教程来源:不详   教程栏目:Win2000教程    收藏本页
    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 

    #include 

    #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[i] );

      return;

    }



    <<第二部分:调用ToolHelp API枚举本地系统进程>>

      在第一部分提到的PSAPI函数只能枚举NT系统的进程,在Windows9x环境下我们可以通过调用ToolHelp API函数来达到枚举系统进程的目的。M$的Windows NT开发小组因为不喜欢ToolHelp函数,所以没有将这些函数添加给Windows NT,所以他们开发了自己的Process Status函数,就是第一部分提到的PSAPI了。但是后来M$已经将ToolHelp函数添加给了Windows 2000。ToolHelp共有12个函数,通过调用这些函数可以方面的取得本地系统进程的详细信息,以下这个简单的例子只调用了三个函数,获取我们所需要系统进程名字和进程ID。程序如下:

    /**********************************************************************

    Module:ps.c

    说明:调用ToolHelp函数枚举本地系统进程名和ID,Only for 9x/2000

    **********************************************************************/

    #include 

    #include 

    #include 





    int main()

    {

      HANDLE     hProcessSnap = NULL;

      PROCESSENTRY32 pe32   = {0};

      hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

      if (hProcessSnap == (HANDLE)-1)

      {

        printf("\nCreateToolhelp32Snapshot() failed:%d",GetLastError());

      return 1;

    }

      pe32.dwSize = sizeof(PROCESSENTRY32);

      printf("\nProcessName     ProcessID");

      if (Process32First(hProcessSnap, &pe32))

      {

        do

        {

    printf("\n%-20s%d",pe32.szExeFile,pe32.th32ProcessID);

         }while (Process32Next(hProcessSnap, &pe32));

      }

      else

      {

        printf("\nProcess32Firstt() failed:%d",GetLastError());

      }

      CloseHandle (hProcessSnap);

    return 0;

    }



    <<第三部分:调用NTDLL.DLL中未公开API枚举本地系统进程>>





       第一部分和第二部分说的是调用MS公开的API来枚举系统进程,在NTDLL.DLL中其实有一个未公开API,也可以用来枚举系统进程。此方法是从别处看来的,我可没这本事自己发现哦,出处记不清楚了,好像是pwdump2 中的源代码中的一部分吧。

        OK!那个未公开API就是NtQuerySystemInformation,使用方法如下:

    ////////////////////////////////////////////////////////////////////////////////

    #include 

    #include 

    #include 



    typedef unsigned long NTSTATUS;

    typedef unsigned short USHORT;

    typedef unsigned long ULONG;

    typedef unsigned long DWORD;

    typedef long LONG;

    typedef __int64 LONGLONG;

    typedef struct {

      USHORT Length;

      USHORT MaxLen;

      USHORT *Buffer;

    } UNICODE_STRING;



    struct process_info {

      ULONG NextEntryDelta;

      ULONG ThreadCount;

      ULONG Reserved1[6];

      LARGE_INTEGER CreateTime;

      LARGE_INTEGER UserTime;

      LARGE_INTEGER KernelTime;

      UNICODE_STRING ProcessName;

      ULONG BasePriority;

      ULONG ProcessId;

    };



    typedef NTSTATUS (__stdcall *NtQuerySystemInformation1)(

        IN ULONG SysInfoClass,

    IN OUT PVOID SystemInformation,

        IN ULONG SystemInformationLength,

        OUT PULONG RetLen

            );



    int main()

    {

      HINSTANCE hNtDll;

      NtQuerySystemInformation1 NtQuerySystemInformation;

      NTSTATUS rc;

      ULONG ulNeed = 0;

      void *buf = NULL;

      size_t len = 0;

      struct process_info *p ;

      int done;



      hNtDll = LoadLibrary ("NTDLL");

      if (!hNtDll)

        return 0;

      NtQuerySystemInformation = (NtQuerySystemInformation1)GetProcAddress (hNtDll,

    "NtQuerySystemInformation");

        if (!NtQuerySystemInformation)

          return 0;



      do {

        len += 0x1000;

        buf =&nb
    我要投稿   -   广告合作   -   关于本站   -   友情连接   -   网站地图   -   联系我们   -   版权声明   -   设为首页   -   加入收藏   -   网站留言
    Copyright © 2009 - 20012 www.www.hxswjs.com All Rights Reserved.57365.com 版权所有