• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 枚舉本地遠程NT系統進程

    發表于:2007-05-25來源:作者:點擊數: 標簽:
    Windows2000中有個工具taskmgr.exe就可以比較詳細的查看當前系統進程信息,但是那是WindowsGUI程序,有時候是不是覺得命令行下的東西更方便呢?其實已經有不少命令行下的枚舉系統進程的工具了,M$的ResourceKit中好象也有,但去了解他們是怎么實現的,自己動

    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 longULONG;

    typedef unsigned longDWORD;

    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 = realloc (buf, len);

    if (!buf)

     return 0;

    rc = NtQuerySystemInformation (5, buf, len, &ulNeed);

    } while (rc == 0xc0000004);// STATUS_INFO_LEN_MISMATCH



    if (rc <0) {

    free (buf);

    return 0;

    }



     printf("\nProcessName ProcessID");

    p = (struct process_info *)buf;

    done = 0;



    while (!done) {

    if ((p->ProcessName.Buffer != 0))

    {

     printf("\n%-20S%d",p->ProcessName.Buffer,p->ProcessId);



    }

    done = p->NextEntryDelta == 0;

    p = (struct process_info *)(((char *)p) + p->NextEntryDelta);

    }

    free (buf);

    FreeLibrary (hNtDll);

    return 0;

    }





    <<第四部分:從PDH中取得本地/遠程系統進程信息>>



     前面說的三種方法都只能枚舉本地的系統進程,如何枚舉遠程系統的進程呢?目前我只知道從PDH中取得進程信息。

     OK!我先簡單的說說PDH是什么東西,hoho~難的偶也不會。PDH是英文Performance Data Helper的縮寫,Windows NT一直在更新這個稱為Performance Data的數據庫,這個數據庫包含了大量的信息,例如CPU使用率,內存使用率,系統進程信息等等一大堆有用的信息,可以通過注冊表函數來訪問。注意哦,Windows 9x中并沒有配置這個數據庫。但是,這個數據庫中的信息布局很復雜,很多人并不愿意使用它,包括我。而且剛開始的時候,它也沒有自己特定的函數,只能通過現有的注冊表函數來操作。后來,為了使該數據庫的使用變得容易,MS開發了一組Performance Data Helper函數,包含在PDH.DLL文件中。

    Windows 2000默認是允許遠程注冊表操作的,所以我們就可以通過連接遠程系統的注冊表,從它的PDH中取得我們所需要的系統進程信息了,當然這需要遠程系統的Admin權限。

    OK!我們下面所舉的例子是直接利用注冊表函數來從本地/遠程系統的PDH數據庫中取得我們所需要的數據的,我們并沒有利用PDH API。



     程序代碼如下:

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

    Module:ps.c

    Author:mikeblas@nwlink.com

    Modify:ey4s

    Http://www.ey4s.org

    Date:2001/6/23

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

    #include 

    #include 

    #include 



    #define INITIAL_SIZE 51200

    #define EXTEND_SIZE  12800

    #define REGKEY_PERF "software\\microsoft\\windows nt\\currentversion\\perflib"

    #define REGSUBKEY_COUNTERS"Counters"

    #define PROCESS_COUNTER "process"

    #define PROCESSID_COUNTER "id process"

    #define UNKNOWN_TASK "unknown" 

    #define MaxProcessNum 52//最大進程數量



    #pragma comment(lib,"mpr.lib")



    typedef struct ProcessInfo

    {

    char ProcessName[128];

    DWORD dwProcessID;

    }pi;



    void banner();

    int ConnIPC(char *,char *,char *);

    DWORD GetProcessInfo(pi *,char *,char *,char *);



    int main(int argc,char **argv)

    {

    int i,iRet;

    pi TaskList[MaxProcessNum];

    banner();

    if(argc==1)

    {

    iRet=GetProcessInfo(TaskList,NULL,NULL,NULL);

    printf("\nProcess Info for [LOCAL]:");

    }

    else if(argc==4)

    {

    iRet=GetProcessInfo(TaskList,argv[1],argv[2],argv[3]);

    printf("\nProcess Info for [%s]:",argv[1]);

    }

    else

    {

    printf("\nUsage:%s ",argv[0]);

    return 1;

    }

    if(iRet>0)

    for(i=0,printf("\nProcessName ProcessID");


    printf("\n%-20s %d",TaskList[i].ProcessName,TaskList[i].dwProcessID),i++); 

    return 0;

    }



    DWORD GetProcessInfo(pi *ProList,char *ip,char *user,char *pass)

    {

    DWORD rc,dwType,dwSize,i,dwProcessIdTitle,dwProcessIdCounter,dwRet=-1;

     HKEY hKeyNames;

     LPSTR buf = NULL,p,p2;

     CHAR szSubKey[1024],szProcessName[MAX_PATH];

     PPERF_DATA_BLOCK pPerf;

     PPERF_OBJECT_TYPE pObj;

    PPERF_INSTANCE_DEFINITION pInst;

     PPERF_COUNTER_BLOCK pCounter;

     PPERF_COUNTER_DEFINITION pCounterDef;

    HKEY ghPerfKey =NULL,// get perf data from this key

    ghMachineKey = NULL;// get title index from this key

    BOOL bRemote=FALSE;



    // Look for the list of counters. Always use the neutral

    // English version, regardless of the local language.We

    // are looking for some particular keys, and we are always

    // going to do our looking in English. We are not going

    // to show the user the counter names, so there is no need

    // to go find the corresponding name in the local language.



     __try

     {

     if((ip)&&(user)&&(pass))

     {

      if(ConnIPC(ip,user,pass)!=0)

     {

     printf("\nConnect to %s failed.",ip);

     __leave;

     }

      else

     bRemote=TRUE;

     }

     //連接本地or遠程注冊表

     if(RegConnectRegistry(ip,HKEY_PERFORMANCE_DATA,

      &ghPerfKey)!=ERROR_SUCCESS)

     {

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

      __leave;

     }

    ` if(RegConnectRegistry(ip,HKEY_LOCAL_MACHINE,&ghMachineKey)!=ERROR_SUCCESS)

     {

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

      __leave;

     }



    sprintf( szSubKey, "%s\\%03x", REGKEY_PERF,MAKELANGID( LANG_ENGLISH, SUBLANG_NEUTRAL));



    if(RegOpenKeyEx(ghMachineKey,szSubKey,0,KEY_READ,&hKeyNames)!=ERROR_SUCCESS)

      __leave;



     // 從counter names取得需要的緩沖區大小

    if(RegQueryValueEx(hKeyNames,REGSUBKEY_COUNTERS,NULL,&dwType,NULL,&dwSize)!= ERROR_SUCCESS)

    __leave;

     //分配內存

     buf = (LPSTR) malloc( dwSize );

     if (buf == NULL)

      __leave;

     memset( buf, 0, dwSize );

     // read the counter names from the registry

    if(RegQueryValueEx(ghPerfKey,REGSUBKEY_COUNTERS,NULL,&dwType,(LPBYTE) buf,&dwSize)!= ERROR_SUCCESS)

      __leave;

     // now loop thru the counter names looking for the following counters:

     //1. "Process"process name

     //2."ID Process"process id



     // the buffer contains multiple null terminated strings and then

     // finally null terminated at the end.the strings are in pairs of

     // counter number and counter name.



     p = buf;

     while (*p)

     {

     if (p>buf)

    for( p2=p-2; isdigit(*p2); p2--) ;

     if (stricmp(p, PROCESS_COUNTER) == 0)

     {

     // look backwards for the counter number

    for( p2=p-2; isdigit(*p2); p2--) ;

     strcpy( szSubKey, p2+1 );

     }

      else if (stricmp(p, PROCESSID_COUNTER) == 0)

     {

     // look backwards for the counter number

    for( p2=p-2; isdigit(*p2); p2--) ;

     dwProcessIdTitle = atol( p2+1 );

     }

     // next string

     p += (strlen(p) + 1);

     }

     // free the counter names buffer

     free( buf );

     // allocate the initial buffer for the performance data

     dwSize = INITIAL_SIZE;

     buf = (LPSTR) malloc( dwSize );



     while (TRUE)

     {

     if (buf == NULL)

     __leave;

      memset( buf, 0, dwSize );

      rc=RegQueryValueEx(ghPerfKey,szSubKey,NULL,&dwType,(LPBYTE) buf,&dwSize);

      pPerf = (PPERF_DATA_BLOCK) buf;

     // check for suclearcase/" target="_blank" >ccess and valid perf data block signature

     if ((rc == ERROR_SUCCESS) &&

      (dwSize > 0) &&

     (pPerf)->Signature[0] == (WCHAR)'P' &&

     (pPerf)->Signature[1] == (WCHAR)'E' &&

     (pPerf)->Signature[2] == (WCHAR)'R' &&

     (pPerf)->Signature[3] == (WCHAR)'F' )

     break;

     // if buffer is not big enough, reallocate and try again

     if (rc == ERROR_MORE_DATA)

     {

     dwSize += EXTEND_SIZE;

     buf = (LPSTR) realloc( buf, dwSize );

     }

      else __leave;

     }

     // set the perf_object_type pointer

     pObj = (PPERF_OBJECT_TYPE) ((DWORD)pPerf + pPerf->HeaderLength);

     //loop thru the performance counter definition records looking

     //for the process id counter and then save its offset



     pCounterDef = (PPERF_COUNTER_DEFINITION) ((DWORD)pObj + pObj->HeaderLength);



     for (i=0; i<(DWORD)pObj->NumCounters; i++)

     {

     if (pCounterDef->CounterNameTitleIndex == dwProcessIdTitle)

     {

     dwProcessIdCounter = pCounterDef->CounterOffset;

     break;

     }

      pCounterDef++;

     }



     pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pObj + pObj->DefinitionLength);



     // loop thru the performance instance data extracting each process name

     // and process id



     for (i=0; i < (DWORD)pObj->NumInstances-1 && i 
     {

     // pointer to the process name

     p = (LPSTR) ((DWORD)pInst + pInst->NameOffset);

     // convert it to ascii

     rc = WideCharToMultiByte( CP_ACP,0,(LPCWSTR)p,-1,szProcessName,sizeof(szProcessName),NULL,NULL);



     // if we cant convert the string then use a default value

     if (!rc) strcpy( ProList[i].ProcessName, UNKNOWN_TASK );

      else strncpy(ProList[i].ProcessName, szProcessName,sizeof(ProList[i].ProcessName)-1);



     // get the process id

     pCounter = (PPERF_COUNTER_BLOCK) ((DWORD)pInst + pInst->ByteLength);

    ProList[i].dwProcessID = *((LPDWORD) ((DWORD)pCounter + dwProcessIdCounter));



     // next process

    pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pCounter + pCounter->ByteLength); 

     }

     dwRet=i;

     }//end of try

     __finally

     {

     if (buf) free( buf );

     RegCloseKey( hKeyNames );

     RegCloseKey( HKEY_PERFORMANCE_DATA );

     if(bRemote)

     {

      char tmp[52],tmp2[96];

      strncpy(tmp,ip,sizeof(tmp)-1);

      wsprintf(tmp2,"\\\\%s\\ipc$",tmp);

      WNetCancelConnection2(tmp2,CONNECT_UPDATE_PROFILE,TRUE);

     }

     }

     return dwRet;

    }



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



    int ConnIPC(char *RemoteName,char *User,char *Pass)

    {

     NETRESOURCE nr;

     char RN[50]="\\\\";



     strncat(RN,RemoteName,sizeof(RN)-11);

     strcat(RN,"\\ipc$");



     nr.dwType=RESOURCETYPE_ANY;

     nr.lpLocalName=NULL;

     nr.lpRemoteName=RN;

     nr.lpProvider=NULL;



     if(WNetAddConnection2(&nr,Pass,User,FALSE)==NO_ERROR)

     return 0;

     else

     return 1;

    }



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

    void banner()

    {

     printf("\nPsList ==>Local and Remote process list"

      "\nPower by ey4s"

      "\nhttp://www.ey4s.org"

      "\n2001/6/22\n");

    }



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



    程序在Windows2000、VC++6.0環境下編譯,運行良好。注意哦,遠程機器要允許IPC連接和遠程操作注冊表才可以哦,并且需要Admin權限.

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>