全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1090
推到 Plurk!
推到 Facebook!

Win2K下關聯進程/埠之代碼初步分析

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-07-24 17:01:24 IP:61.64.xxx.xxx 未訂閱
 Win2K下關聯進程/埠之代碼初步分析    關鍵字 進程/埠
原作者姓名 Shotgun[Shotgun@xici.net]
文章原始出處 http://shotgun.patching.net/bbs.htm 
讀者評分 3 評分次數 1 
正文
在西祠或者中綠的BBS中,經常見到網友問:如何才能關聯我的進程和埠呀?
沒錯,關聯進程和埠是一個非常有用的功能,你可以清楚地知道哪些程式在使用
哪些埠,對於查殺木馬很有幫助。可是我們雖然可以使用任務管理器流覽進程列
表,使用Netstat查看埠的使用狀況,卻沒有一個命令可以直接關聯進程和埠
(WinXP上增加了新的NetStat功能,支援直接查看埠進程狀況),今年年初的時
候,國外出了一個有名的軟體Fport,它可以顯示當前所有的埠及他們所屬的進
程,可是,這個軟體並沒有公開源代碼,(太不符合自由軟體精神了吧?),
我根據對這個軟體的逆向工程,做了一個類似的工具,在這裏和大家探討一下它的原理。    一拿到Fport的時候,我就對它進行了API分析,發現除了一些基本的API以外,
它還調用了NTDLL.dll的幾個未公開API,如NtQuerySystemInfomation,
NtQueryInfomationProcess,直覺告訴我,關鍵應該在這兩個函數中,特別是前者。    為了能夠理解Fport的運行機理,我們首先要來復習一下SOCKET。
SOCKET究竟是什麼?它的中文名稱叫做套介面,但是,實際上我們所謂的
SOCKET資料結構只是一個32位元的無符號整數(在UNIX中是16位的),
它對於Windows作業系統來說其實是一個檔控制碼(SOCKET是檔?奇怪麼?
作業系統在底層實現的時候,常常使用檔的概念來完成一些基本的功能),
這樣的話問題就明朗了,如果我們能夠枚舉系統所有的控制碼,從中獲得屬性為
SOCKET的,不就可以完成Fport的功能?現在你應該想到了,為什麼Fport
要調用NtQuerySystemInfomation這個API,實際上,NtQuerySystemInfomation
這個函數提供了一個簡單的途徑以獲得系統所有的HANDLE,
我們先來看看這個函數的原型:    DWORD NtQuerySystemInformation( DWORD dwRecordType,
                PDWORD pdwHandleList,
                DWORD dwNumBytes,
                PDWORD pdwNumBytesRet ); 
我來解釋一下,NtQuerySystemInformation這個函數有四個參數,第一個參數是
dwRecordType,這個參數指定了我們所查詢的系統資訊類型,為了查詢系統
HANDLE列表,我們定義一個常量#defineNT_HANDLE_LIST    
16(這個數值我是查資料得到的,如果誰有更詳細的資料,也請讓我共用一下);
第二個參數是一個指標,這個指標用來返回系統控制碼列表,
在調用NtQuerySystemInformation函數之前,必須為這個指標分配足夠的記憶體
空間,否則函數調用會出錯;第三個參數是指定你為HandleList所分配的記憶體
空間大小,單位是byte;
第四個參數是NtQuerySystemInformation返回的HandleList的大小;
如果NtQuerySystemInformation函數調用成功,返回值將是0,
否則可以使用GetLastError()獲得詳細的錯誤代碼。    一旦NtQuerySystemInformation函數調用成功,系統中所有的控制碼將被存放在
pdwHandleList所指向記憶體空間中,其中,pdwHandleList所指向的第一個32
位數,是這個buf所包含的控制碼數量,之後是順序排列的控制碼指標
pHandleInfo,指向的是HANDLEINFO結構:    typedef struct _HandleInfo
{
    USHORTdwPid;               
    USHORTCreatorBackTraceIndex; 
    BYTE  ObjType;
    BYTE  HandleAttributes;
    USHORT HndlOffset;
    DWORD dwKeObject;
    ULONG GrantedAccess;
}HANDLEINFO, *PHANDLEINFO;    看到這個結構,我們心中就有底了,控制碼資訊中包括了控制碼所屬進程的
PID,這樣我們就可以關聯進程和SOCKET了,可是,在NT中有各種各樣的控
制碼:進程控制碼、權杖控制碼、檔控制碼、視窗控制碼……我們怎樣才能判斷
一個控制碼究竟是不是SOCKET呢?
這就要靠HANDLEINFO結構中的ObjType屬性了,經過分析,我們發現,
SOCKET控制碼的類型值為0x1A,所以,我們將所有類型為0x1A的控制碼取
出,進行getsockname操作就可以得到當前的進程/埠對應列表,實際上並不然,
要知道,我們得到的控制碼都屬於其他的進程,在NT中根據進程保護的原則,
一個進程沒有辦法直接得到其他進程的各種資訊,特別是控制碼,不同進程中的
同一控制碼(控制碼的數值相同)根本就不是同樣的東西,因此,我們還必須進行
一次轉換,將其他進程的控制碼轉換為本進程的控制碼,這個轉換工作只要簡單地調用DuplicateHandle函數就可以完成了:    DuplicateHandle(hSourceProc,
        (HANDLE)pHandleInfo->HndlOffset,
        hCurrentProc,
          &hMyHandle,
          STANDARD_RIGHTS_REQUIRED,
          true,
          0 );    之後我們就可以通過getsockname、getsockopt等函數來獲得SOCKET的各種屬
性了(使我困惑的是,Fport並沒有調用getsockname,這說明,應該有更簡單的
方法來得到SOCKET控制碼的各種屬性,看來我對SOCKET控制碼的瞭解程度
還是很膚淺呀)    sockaddr_in name = {0};    name.sin_family = AF_INET;    int namelen = sizeof(sockaddr_in);    SOCKET s = (SOCKET)hMyHandle;    char szSockType[6][6] = { "NUL", "TCP", "UDP", "RAW", "RDM","SEQ" };    iRet = getsockname( s, (sockaddr*)&name, &namelen );    if ( iRet != SOCKET_ERROR )    {      int sockType = 0;      int optlen = 4;      iRet = getsockopt(  s,SOL_SOCKET, SO_TYPE, (char*)&sockType, &optlen );      printf("PID=M PORT=] %s\n",pHandleInfo->dwPid,          ntohs( name.sin_port ), szSockType[sockType] );    }    至此,進程和埠關聯的工作已經基本完成,可是,還有一些不足的地方,首先,
這個軟體不像Fport一樣能夠查看system進程(就是那個著名的8#進程)的
SOCKET,錯誤代碼是5(accessdenied),一個簡單的解決方法是將自己做成
service,這樣就有了對LocalSystem進程的訪問許可權,不過似乎Fport並不是
這麼做的,此為疑點一;其次,由於我對HANDLE屬性的膚淺認識,有的時候
會出現誤報或漏報的現象,即使沒有誤報,將所有屬性為0x1A的控制碼都進行
getsockname效率也略微低了一點,這裏應該有更好的解決方案,此為疑點二;
最後,Fport並沒有調用socket函數來獲得socket屬性,這說明有一個更簡單直
接的方法可以從SOCKET控制碼中得到埠、協定等資訊,可惜我不知道,此為
疑點三。不過令人欣慰的是,我寫出來的Gport可以在Win2K的非管理員用戶
下運行,此時,僅能獲得本用戶所有進程的埠,這大概是Fport所沒有具備的功
能。    寫本文的目的,一方面是為了解答某些網友對Fport原理的疑問,另一方面也是
為了抛磚引玉,希望能解答我心中的這些疑點,望各位高手能不吝賜教。    最後附上Gport的代碼,Gport的測試版和代碼檔可以在我的主頁上下載,位址為: http://shotgun.patching.net/Gport.zip     正文完
附件:
•  Gport的測試版和代碼檔 Gport.zip
發表人 - conundrum 於 2004/07/24 17:12:13
系統時間:2024-05-18 15:52:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!