圍觀網路之三 淺探索NDIS5 1 1

2021-06-06 23:48:51 字數 3948 閱讀 4698

前言

本文討論w2k&xp適用的ndis5.x 網路架構。

ndis4.0原始碼太老,ros又yy了太多,所以這次的參考**基本都是自己f5的…具體結構都有了,我f5的毫無壓力=。=

除錯的時候利用imd(中間層驅動)下斷點,更無壓力了...

ndis5.x網路的堆疊結構大概是:

winsock  api → afd → 協議驅動tcpip(其上層是tdi介面 ) →可能存在的中間層驅動→ndiswan 系統提供中間層驅動(用於簡化規程對於miniport的繫結) →miniport介面卡網絡卡驅動 

ndis管理的部分,就是抽象成 "規程端(protocol edge) → 小埠端(miniport edge) → 規程端→ 小埠端" 這一流程的管理,tcpip是最靠前的規程驅動,只有規程端,真實網絡卡驅動只有小埠端,中間層驅動都同時具備小埠和規程的特徵屬性

winsock**用程式呼叫協議驅動主要處理網路連線的邏輯,afd將這些請求轉化為協議層明白的引數(tdi規範)發給tcpip

如上圖所示,實際上要更複雜一點,ndiswan是系統提供的乙個中間層驅動,提供了許多服務

一、驅動程式初始化 —— 向ndis註冊

ndis內部維護了若干全域性鍊錶 用來儲存協議驅動,小埠驅動,介面卡驅動的相關結構

這裡主要看看passthru,同時包含了協議驅動和微埠驅動的部分特性

a.在driverentry中 初始化包裝控制代碼

這個api不過是填充了如下結構

+0x000 driverobject     : 0x81447030 _driver_object

+0x004 serviceregpath   : _unicode_string "\registry\machine\system\controlset001\services\passthrump"

b.回到driverentry,緊接著,要填充乙個ndis_miniport_characteristics 

然後呼叫ndisimregisterlayeredminiport註冊我們的微埠驅動,但這個是中間層驅動呼叫的,真正的微埠驅動呼叫的是ndismregisterminiport,但這兩個都是呼叫內部函式ndisregisterminiportdriver,中間層只是多加了乙個標誌位

&mchars,

sizeof(mchars),

&driverhandle);

ndisregisterminiportdriver的邏輯:

1.一大堆判斷版本、判斷引數有效性,如果一些引數是空的,將返回ndis_status_bad_characteristics  

2.填充driverobject的派遣函式

3. 呼叫ioallocatedriverobjectextension分配乙個_ndis_m_driver_block作為驅動擴充套件,並返回在driverhandle中

4.初始化結構 除錯資訊如下

kd>  dt _ndis_m_driver_block 814880b0

ndis!_ndis_m_driver_block,在driverext中,driverhanle

+0x000 nextdriver       : 0x817cf010 _ndis_m_driver_block  ;全域性鍊錶ndisminidriverlist

+0x004 miniportqueue    : 0x81342ad0 _ndis_miniport_block ;所有的miniport block鍊錶

+0x00c associatedprotocol : 0x817be4c8 _ndis_protocol_block ;關聯的protblock

+0x010 devicelist       : _list_entry [ 0x81484898 - 0x81484898 ]

+0x018 pendingdevicelist : (null) 

+0x01c unloadhandler    : 0xf763e540     void  passthru!ptunload+0

+0x020 miniportcharacteristics : _ndis51_miniport_characteristics

+0x09c miniportsremovedevent : _kevent

+0x0ac ref              : _reference

+0x0b4 flags            : 1

+0x0b8 imstartremovemutex : _kmutant

+0x0d8 driverversion    : 0

c. 回到driverentry,接下來該初始化協議驅動了,呼叫

ndisregisterprotocol(&status,

&prothandle,

&pchars,

sizeof(ndis_protocol_characteristics));

ndisregisterprotocol的邏輯比較簡單:

1、引數判斷 竟然還有dbgprint

2、初始化結構_ndis_protocol_block 存放在prothandle中返回

ndis!_ndis_protocol_block

+0x000 openqueue        : 0x81593008 _ndis_open_block ;openblock佇列

+0x004 ref              : _reference

+0x00c deregevent       : (null) 

+0x010 nextprotocol     : 0x8145c588 _ndis_protocol_block ;下乙個prot繫結

+0x014 protocolcharacteristics : _ndis50_protocol_characteristics

+0x080 workitem         : _work_queue_item

+0x090 mutex            : _kmutant

+0x0b0 mutexowner       : 0x10b46

+0x0b4 binddevicename   : (null) 

+0x0b8 rootdevicename   : 0x816d53ec _unicode_string "\device\ndiswanip"

+0x0bc associatedminidriver : 0x81484888 _ndis_m_driver_block  關聯的miniblock

+0x0c0 bindingadapter   : 0x816e1130 _ndis_miniport_block 繫結的adapter

d.初始化的最後一步,將小埠驅動和協議驅動聯絡起來,這個就更簡單了

ndisimassociateminiport(driverhandle, prothandle);

_ndis_protocol_block *__stdcall ndisimassociateminiport(_ndis_m_driver_block *minidriverhandle, _ndis_protocol_block *prothandle)

小結:

至此初始化部分就完成了,ndis_handle是乙個討厭的東西,ndis隱藏了真實結構的真相,這裡總結一下各個handle都是什麼

prothandle 協議控制代碼,是_ndis_protocol_block,儲存了_ndis_open_block(這個很重要),協議全域性鍊錶節點,協議特徵表,連線的微埠驅動

探索設計模式之三 抽象工廠模式

前面介紹的 簡單工廠模式 和 工廠方法模式 立足點都是避免顯式的建立具體物件,封裝建立物件時可能出現的變化點,這已經能比較好的解決單個物件建立的問題,但實際業務中,還經常出現需要一系列物件互相關聯使用來完成任務的情況。對於存在關聯 以來的產品來說,使用簡單工廠或者工廠方法乙個乙個的建立其中的具體產品...

網路協議系列之三 IP

前言 這篇部落格主要對ip協議中一些基礎知識點加以總結,並將書中一些晦澀難懂的部分去除了。ip位址協議是網路層中最重要的協議,ip位址協議可以對網際網路上的所有裝置進行唯一標識,也正因為有了ip協議,我們的計算機才能實現與全球任意一台裝置進行通訊。同時這也是網路層存在的意義,我將對部分的內容分為兩個...

iphone開發記憶體管理之三 深拷貝和淺拷貝

在iphone程式中,屬性合成中的retain copy assign有什麼區別?1 assign就不用說了,因為基本上是為簡單資料型別準備的,原子類型別,例如cgpoint cgfloat等,而不是ns物件們 2 retain vs copy copy其實是建立了乙個相同的物件,而retain不是...