1. 程式人生 > >NDIS WIN7 WINXP hook網路發包收包(轉)

NDIS WIN7 WINXP hook網路發包收包(轉)

多年前做過xp-win10的 ndishook。由於時間太久,都忘得差不多了。由於公司程式碼有bug,特意網上找了一下介紹,不過沒有找到圖。湊合看下

轉:
   網上有很多討論關於NDIS HOOK的文章,但大多隻講了WIN7之前的HOOK NDIS_OPEN_BLOCK下的例程,至於WIN7下怎麼
HOOK以及如何做MINIPORT-HOOK,網路上則鮮有提及.根據前陣子的相關分析,我把NDIS HOOK總結一下,網上有一些討論
NDIS HOOK的文章,請讀者先閱讀那些文章對NDIS HOOK有個基本瞭解.

[0x01] 

    首先是獲取物理網絡卡的裝置GUID,如果只是做普通的NDIS HOOK則可以忽略此步.為什麼要獲取物理網絡卡的GUID呢,
因為系統內可能有多個MINIPORT,每個MINIPORT對應一個網絡卡裝置,無論這個網絡卡是虛擬的還是物理的.
    
    所以我們要做MINIPORT HOOK的話就必須找到物理網絡卡對應的miniport.下面是兩種獲得物理網絡卡GUID的方法。

   方法1:通過登錄檔項\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards
獲得網絡卡的裝置名,比如{F0AFC092-E841-48DF-909F- 78146070F5D3},不過在有些系統下沒有這個登錄檔項,所以這種
方法不通用.

   方法2:還是通過登錄檔,首先遍歷HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\PCI下的子鍵,當遍歷到第
二級的時候,比如
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\PCI\VEN_10DE&DEV_0BE4&SUBSYS_00000000&REV_A1\4&2f49a5f6&0&0108.
   
   則獲取當前裝置的ClassGUID,如果ClassGUID為{4d36e972-e325-11ce-bfc1-08002be10318},則說明當前裝置為網路
介面卡裝置,那麼我們再繼續讀名為Driver的鍵值,其資料一般為類似{4d36e972-e325-11ce-bfc1-08002be10318}\0007
這樣的值.

   然後我們把這個值拼接到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class這個路徑後面組成
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0007,
這個子鍵下的鍵值NetCfgInstanceId即為物理網絡卡的裝置GUID.
 
[0x02]

    XP NDIS HOOK:通過註冊假協議,遍歷所有NDIS_OPEN_BLOCK,掛接TCPIP協議下所有的NDIS_OPEN_BLOCK裡的相關例程
即可(ReceiveHandler,ReceivePacketHandler,WanSendHandler,SendHandler,SendPacketsHandler等),這在其他講述
NDIS HOOK的文章裡均有描述,這裡不再贅述.

    XP NDIS MINIPORT HOOK:仍然先要註冊假協議,找到DeviceName是物理網絡卡裝置GUID的NDIS_OPEN_BLOCK,掛接其
WSendHandler或者WSendPacketsHandler即可.只有這個NDIS_OPEN_BLOCK才是繫結到物理網絡卡的.從而避免掛接到繫結
到其他虛擬網絡卡的NDIS_OPEN_BLOCK或者中間層過濾驅動同上層協議之間的繫結關係(還記得嗎,中間層過濾驅動的
upperlayer向上對協議驅動表現為MINIPORT).

[0x03]

    WIN7 NDIS HOOK:仍然是遍歷所有NDIS_OPEN_BLOCK:攔截Send操作需要Inline Hook ndis!NdisSendNetBufferLists,
或者HOOK TCPIP.SYS的IAT裡的ndis!NdisSendNetBufferLists,攔截Receive操作需要Hook NDIS_OPEN_BLOCK裡的
ReceiveNetBufferListsHandler.

    WIN7 MINIPORT HOOK:遍歷NDIS_OPEN_BLOCK,找到DeviceName是物理網絡卡裝置GUID的NDIS_OPEN_BLOCK,根據NDIS_OPEN_BLOCK
定位到對應的NDIS_MINIPORT_BLOCK,然後定位到M_DRIVER_BLOCK結構體(offset:0xE04),然後M_DRIVER_BLOCK的偏移0x60
處就是MINIPORT的傳送函式SendNetBufferListsHandler,直接掛接這裡即可.
 
[0x04]

其他說明:
NDIS_PRPTOCOL_BLOCK:這個結構表示協議相關的資訊,每個協議對應一個

NDIS_OPEN_BLOCK:這個結構是表示協議(PROTOCOL)和網絡卡(MINIPORT)的繫結關係的

NDIS_MINIPORT_BLOCK:這個結構是表示小埠資訊的,除了物理網絡卡和虛擬網絡卡存在這個結構外,IMD(中間層過濾驅動)由
於是向上表現為MINIPORT,所以IMD也存在一個本結構

IMD:向上表現為MINIORT,向下表現為PROTCOL,所以IMD和PROTOCOL之間也存在NDIS_OPEN_BLOCK,而IMD和下層的MINIOPORT
也存在NDIS_OPEN_BLOCK

出處