围观网络之三 -- 浅探索NDIS5.1(1)

来源:互联网 发布:现实中网络女主播好丑 编辑:程序博客网 时间:2024/06/11 18:57

前言

本文讨论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.sys除了像win32k一样作为内核的API补充支持,另外的作用就是隐藏整个网络框架的真像- -!(这是NDIS wrapper得名的原因?)  网络设备驱动与WDM框架不同,大概是 由于网络IO的特殊性以及出于对效率的考虑

 

一、驱动程序初始化 —— 向NDIS注册

 

NDIS内部维护了若干全局链表 用来保存协议驱动,小端口驱动,适配器驱动的相关结构

 

这里主要看看passthru,同时包含了协议驱动和微端口驱动的部分特性

 

A.在DriverEntry中 初始化包装句柄

NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);

这个API不过是填充了如下结构

 

kd> dt _NDIS_WRAPPER_HANDLE 8138f1f8

NDIS!_NDIS_WRAPPER_HANDLE

   +0x000 DriverObject     : 0x81447030 _DRIVER_OBJECT

   +0x004 ServiceRegPath   : _UNICODE_STRING "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\PassthruMP"

 

B.回到DriverEntry,紧接着,要填充一个NDIS_MINIPORT_CHARACTERISTICS 

 

然后调用NdisIMRegisterLayeredMiniport注册我们的微端口驱动,但这个是中间层驱动调用的,真正的微端口驱动调用的是NdisMRegisterMiniport,但这两个都是调用内部函数ndisRegisterMiniportDriver,中间层只是多加了一个标志位

        Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle,

                                                  &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链表

   +0x008 NdisDriverInfo   : 0x814e3380 _NDIS_WRAPPER_HANDLE 

   +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_PROTOCOL_BLOCK *result; // eax@1

  result = protHandle;

  miniDriverHandle->AssociatedProtocol = protHandle; //两个指针一互指 完事儿

  protHandle->AssociatedMiniDriver = miniDriverHandle;

  return result;

}

小结:

至此初始化部分就完成了,NDIS_HANDLE是一个讨厌的东西,NDIS隐藏了真实结构的真相,这里总结一下各个handle都是什么

 

WrapperHandle 所谓的包装句柄,是_NDIS_WRAPPER_HANDLE 存储了DriverObj 和注册表路径,代表了驱动本身

DriverHandle 微端口句柄 是_NDIS_M_DRIVER_BLOCK,存储了所属的驱动(NdisDriverInfo,也就是WrapperHandle),连接的协议驱动(AssociatedProtocol),微端口全局链表节点,以及自己的微端口特征表

ProtHandle 协议句柄,是_NDIS_PROTOCOL_BLOCK,存储了_NDIS_OPEN_BLOCK(这个很重要),协议全局链表节点,协议特征表,连接的微端口驱动

 

参考资料:

1. NDIS 5.1学习笔记

2. MSDN

3. IDA,Windbg,ROS src,NT4 src



原创粉丝点击