NDIS Filter Study

首先看相关概念:

驱动对象是操作系统首次装载一个驱动程序时创建的记录这个驱动程序的数据结构(实际上就是一个windows定义的结构体)。设备对象是操作系统针对硬件设备建立的描述记录其相关信息的数据结构。正因为如此,一个驱动对象可以对应多个设备对象(同一个驱动对象的设备对象挂接在一个链表中)。irp即i/o请求包,用于驱动程序与操作系统之间的通信,用于完成实体的操作,也是一个数据结构。驱动程序,设备,i/o请求包在操作系统中都是以栈的形式组织的。几者之间的关系大致是这样的: 驱动对象由操作系统创建,作为driverentry的第一个参数传给你的驱动程序。你的驱动程序需要对该对象的一些字段进行初始化,包括 driverstartio(指向Startio入口函数的指针),driverunload(指向driverunload入口函数的指 针),majorfunction(一个数组, 数组中每个元素又是一个指向不同入口函数的指针。接受不同的irp时,操作系统会自动调用不同的入口函数),deviceobject(指向链表的指针, 链表即之前提到的驱动程序上挂接的设备对象),driverextension(指向另一个结构体,该结构体中唯一有用的字段为adddevice,该字 段指向一个入口函数,当操作系统发现一个新的设备实例时自动调用adddevice函数,该函数中应该写一些与设备实例初始化工作的代码)。 设备对象可以利用内核API函数iocreatedevice创建。操作系统负责部分字段初始化和分配内存空间,驱动程序中接收到irp-mn- remove-device消息将删除设备对象,亦可以调用内核api函数iodeletedevice 删除设备对象。设备对象中的字段较多,恕我既不清了,可以找本书参考一下。 irp对象中也有很多字段,也记不清了。操作系统创建完irp后,调用iogetnextirpstacklocation函数获得该irp下一个栈单元 的指针。然后初始化这个栈单元。初始化完成后可以调用iocalldriver函数把irp发送到设备驱动程序的派遣例程。驱动程序的派遣例程接收到irp后一般有三种处理方式:立即完成该irp,传递到同一个堆栈的下层驱动程序,排队该irp以便由该驱动程序中的其他例程处理。irp请求的操作做完后,程序员要 做:用恰当的状态码填充irp受不得iostatus结构的status成员,以通知发送发完成的状态;填充irp首部的iostatus结构的 information成员,传递其他完成信息;以该irp为参数调用iocompleterequest例程。iocompleterequest主要 完成工作如下:依次调用挂接在irp上的完成例程;将mdladdress域对应的物理内存解锁;触发一个同步事件,激活发送方,发送方将做最后的清除工作(咱们可以简单的理解为通知的作用)

过滤驱动:过滤是在不影响上层和下层接口的情况下,在Windows系统内核中加入新的层,从而不需要修改上层的软件或者下层的真实驱动程序,就加入了新的功能。 过滤驱动就是挂载在其他驱动上,对某设备的irp进行拦截过滤作用,可以对设备进行功能扩展,或是数据加密等的驱动程序。

驱动irp:驱动中的IRP的全名是I/O Request Package,即输入输出请求包,它是Windows内核中的一种非常重要的数据结构。上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求,操作系统将相应的I/O请求转换成相应的IRP,不同的IRP会根据类型被分派到不同的派遣例程中进行处理。

例程:作用类似于函数,但含义更为丰富一些。例程是某个系统对外提供的功能接口或服务的集合。比如操作系统的API、服务等就是例程;如果把这些函数编写为DLL动态库的输出函数的话,此时虽然对于编写这个DLL的程序员来讲,仍然可以用函数的概念来理解这些DLL提供的功能,但对于以后调用这个DLL的程序来说,DLL里面提供的输出函数(或者说服务)就是例程了。因此“例程”的基本概念就包含了“例行事务性子程序”的含义,既然是例行的事务子程序,则必然通用性和相对独立性都比较强,所以很适合通过DLL、静态库(各种编程语言里面的库函数)、API、操作系统服务等方式来实现了。

设备栈:物理设备对象(Physical Device Object,PDO)和功能设备对象(Function Device Object,FDO)的关系是“附加”与“被附加”的关系。
当PC插入某个设备时,PDO会自动创建。确切的说,是由总线驱动创建的。PDO不能单独操作设备,需要配合FDO一起使用。系统会提示检测到新设备,要求安装驱动程序。需要安装的驱动程序就是WDM程序,此驱动程序负责创建FDO,并且附加到PDO上。

FDO是附在PDO上面的,当然FDO上面还可以有其他的FDO。这样就构成了一个栈,就是设备栈。

一个物理设备的驱动(不限于物理设备),通常由几个驱动程序分层的共同完成。每层一个设备对象,他们联系在一起,组成一个设备栈。当然,每层的设备对应一个驱动程序,也组成一个驱动程序栈。二者是平行联系的关系。一个设备栈上的设备对象,从上自下,联系在一起。从下自上,也联系在一起。


这个图里面画的是不同的驱动创建的不同设备对象构成的设备栈。其实同一个驱动也可以创建多个设备构成设备栈(需不需要这么做是另外一回事情)。
那么设备栈会起什么作用呢?比如用户模式的caller打开了DeviceA,并且向这个设备发生一个IRP,那么这个IRP会先经过DeviceC,然后到达DeviceA。IRP的过程是:
DeviceC -> DeviceB -> DeviceA -> PDO

DriverUnload:一般负责删除在DriverEntry中创建的设备对象并且将设备对象所关联的符号链接删除另外,DriverUnload还负责对一些资源进行回收

DriverEntry:在驱动被加载后DriverEntry是第一个被驱动程序调用的函数,它负责初始化驱动程序。

NTSTATUS DriverEntry(
  _In_  PDRIVER_OBJECT DriverObject,
  _In_  PUNICODE_STRING RegistryPath
);
参数
DriverObject [in]
指向一个 DRIVER_OBJECT 结构体,它是WDM驱动的对象
RegistryPath [in]

指向一个 UNICODE_STRING 结构体,他指定了驱动关键参数在注册表中的路径

OID:对象标识符(Object identifier, OID)是由ISO/IEC、ITU国际标准组织共同提出的标识机制,用于对任何类型的对象、概念或者“事物”进行全球无歧义、唯一命名。一旦命名,该名称终生有效。由于OID具有分层灵活、可扩展性强等特点,适合作为现有各种编码方案之间进行交换的元标识机制

驱动程序上下文:

驱动程序上下文是指驱动程序的当前运行环境。上下文会限制驱动程序可执行的操作。驱动程序上下文取决于调用的执行代码。驱动程序代码在以下四种上下文中执行:
用户上下文。用户线程以同步方式调用驱动程序入口点时,此入口点具有用户上下文。即,用户线程会等待系统从调用的入口点返回。例如,通过 read(2) 系统调用来调用驱动程序的 read(9E) 入口点时,此入口点具有用户上下文。在这种情况下,驱动程序可访问用户区域,以在用户线程中复制数据。
内核上下文。通过某部分内核调用驱动程序函数时,此函数具有内核上下文。在块设备驱动程序中,可以通过 pageout 守护进程来调用 strategy(9E) 入口点,以向设备中写入页面。由于页面守护进程与当前用户线程无关,因此在这种情况下 strategy(9E) 具有内核上下文。
中断上下文 中断上下文是一种限制性更强的内核上下文形式。中断上下文是在提供中断服务的情况下调用。驱动程序中断例程在中断上下文中以关联的中断级别运行。回调例程也在中断上下文中运行。
高级中断上下文高级中断上下文是一种限制性更强的中断上下文形式。如果 ddi_intr_hilevel(9F) 指示某中断为高级中断,则驱动程序中断处理程序将在高级中断上下文中运行。

中断:处理器速度远快于外设速度,因此不希望一直等待外设,而是希望能有一种机制,在外设需要处理器关注(处理)外设的时候,能通知处理器。这种机制就是中断,一个中断是一个硬件在它需要处理器的注意时发出的信号。

即当某进程要启动某个I/O设备工作时,便由CPU向相应的设备控制器发出一条I/O命令,然后立即返回继续执行原来的任务,设备控制器则按照该命令的要求去控制指定I/O设备。此时,CPU与I/O设备并行操作。

例如,在输入时,当设备控制器收到CPU发来的读命令后,便去控制相应的输入设备读数据。一旦数据进入数据寄存器,控制器便通过控制线向CPU发送一个中断信号,由CPU检查输入过程中是否出错,若无错,便向控制器发送取走数据的信号,然后再通过控制器及数据线,将数据写入内存指定单元中。

网络适配器:其实网络适配器说白了就是我们常说的网卡,硬件方面当然是在主板上插着有小灯泡的那个.不过现在一般都是主板集成了.就是插网线口的地方。适配器就是一个接口转换器。

一. 介绍NDIS Filter Drivers

Filter Drivers提供了针对微端口驱动(Miniport Drivers)的过滤服务(filtering service),NDIS驱动栈上 必须包含微端口驱动(Miniport Drivers)和协议驱动(Protocol Drivers),可选的包含 Filter Drivers更多关于 NDIS驱动栈的信息可查看 DDK的 MSDN中的 Driver Stack Management。下面列举基本的栈配置图示:

下面的应用可能就需要一个 Filter Drivers 来完成:
1) 基于安全或其它目录的数据过滤应用

2) 对网络数据进行监视,收集及统计的应用
1.1 Filter Drivers 特性

1) 一个 Filter Drivers 实例叫 Filter Module。Filter Module 附加在一个适配器的微端口驱动上,来自相同或不同 Filter Drivers 的多个 Filter Module 都可以被堆叠在一个网络适配器上 。
2)在 Filter Module 被安装到驱动栈时,之上的协议驱动和之下的微端口驱动都不需要提供额外的支持功能。
3)因为 Filter Module 不像中间层驱动(intermediate driver)那样提供一个虚拟的微口,也不与某个设备对象联结,所以在微端口适配器(miniport adapter)之上的 Filter Module 功能相当于一个修过过版本的微端口适配器(miniport adapter)。 原文:Because filter drivers do not implement virtual miniports like an intermediate driver, filter drivers are not associated with a device object. A miniport adapter with overlying filter modules functions as a modified version of the miniport adapter.)
4)NDIS 使用配置信息来到决定一个 Filter Module 附加到一个网络适配器栈上的顺序。
5)在不用拆除整驱动栈的情况下,NDIS 可以动态的插入、删除 Filter Module 或进行重新配置。
6)当 NDIS 重起驱动栈的时候协议驱动可以获得在栈上的 Filter Module 列表。
7)Filter Drivers 可以过滤下层网络适配器上绝大部分的通信。Filter Module 不联结某特定的绑定(Filter modules are not associated with any particular binding between overlying protocol drivers and the miniport adapter.)
8)Filter Drivers 可以选择为过滤服务也可以选择为分流的不过滤服务,选择为哪一种是可以动态配置的(Filter drivers can select the services that are filtered and can be bypassed for the services that are not filtered. The selection of the services that are bypassed and the services that are filtered can be reconfigured dynamically.)
9)NDIS 保证有效的上下文空间,也不就是说 Filter Drivers 不要需要通代码 COPY 缓冲区来获得上下文空间。

1.2 Filter Drivers 服务

Filter Drivers 提供发下服务:
1) 发起一个发送请求和接收指示
2) 改变数据缓冲区的顺序或对发送和接收数据进行调速
3) 在一个驱动栈的接收或发送路径上更改、删除、添加数据
4) 发起查询或设置 OID 的请求给下层驱动
5) 过滤对下层驱动的 OID 查询或设置请求
6) 过滤从下层驱动传来的 OID 查询和设置请求的应答
7) 发起一个状态指示给上层的设备
8) 过滤从下层传来的状态指示
9) 管理注册表中每一个微端口适配器和其接口的参数
1.3 Filter Drivers 类型
1) Monitoring
这种类型可以在驱动栈上做监视行为,但是它不能在驱动栈上进行数据修改行为。Monitoring Filter Drivers 不在修改或发起数据。
2) Modifying
这种类型可以在驱动栈上做更改行为,该类修改类型是特定于驱动的( The type of modification is driver‐specific)。 在驱动的安装 INF 文件中 FilterType 的值是 0x00000001 就是一个 monitoring filter,如果是 0x00000002 就是一个 modifying filter。
你可以指定一个过滤驱动是 mandatory(强制)的(也是在配置 INF 文件中指定个特征),它通常用在 modifying filter 驱动上,如果一个 mandatory 的 Filter 驱动不能被加载,那么它联结的驱动栈将被拆除。

1.4 Mandatory Filter Drivers

Mandatory Filter Drivers 必须存在于驱动栈上,驱动栈才能正常工作。如果一个Mandatory Filter Module 不附加,那么驱动栈也将会被拆除。Modifying 或 Monitoring 类型的
Filter Drivers 可以被指定为 Mandatory(强制)的。 所有中间层过滤驱动(filter intermediate drivers)都是可选的(与 Mandatory 相对,就是说如果不存在驱动栈也不被拆除) 要附加一个 Mandatory Filter Drivers 在一个驱动栈上,NDIS 先解绑定所有协议驱动,附加 Filter Module 后再重新绑定协议驱动。如果不能成功附加 Filter Drivers 那么拆除驱动栈的下边界。 要分离一个 Mandatory Filter Drivers 在一个驱动栈上,NDIS 先解绑定所有协议驱动,分离 Filter Module 后重新绑定协议驱动。要分离一个 optional Filter Drivers(可选 Filter Drivers,与 Mandatory(强制) Filter Drivers 相对)时,NDIS 只暂停驱动栈,分离后重起驱动栈这时并不解绑定协议驱动。 如果计算机重起,如果一个 Mandatory Filter Drivers 还没有附加到微端口适配器(miniport adapter)这时 NDIS 是不会绑定协议驱动的。 在安装时用的 INF 文件中指是驱动是 Mandatory 还是 Optional。在 INF 文件在指定FilterRunType 为 0x00000001 代表驱动是 Mandatory,指定 0x00000002 代表是 Optional。
下面列出 DDK 所有例子 filter 中的 INF 文件的一个相关节,内容如下:

;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Ndi installation support 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
[Inst_Ndi] 
HKR, Ndi,Service,,"NdisMon" 
HKR, Ndi,CoServices,0x00010000,"NdisMon" 
HKR, Ndi,HelpText,,%NdisMon_HelpText% 
HKR, Ndi,FilterClass,, compression 
<span style="color:#3333FF;">HKR, Ndi,FilterType,0x00010001,0x00000001 </span>
HKR, Ndi\Interfaces,UpperRange,,"noupper" 
HKR, Ndi\Interfaces,LowerRange,,"nolower" 
HKR, Ndi\Interfaces, FilterMediaTypes,,"ethernet" 
<span style="color:#FF0000;">HKR, Ndi,FilterRunType, 0x00010001, 1  </span>
标蓝的行是指定它是一个 Modifying 类型的 filter 驱动,标红的行就是指定它是一个Mandatory Filter Drivers。关于 INF 的语法可以参看 DDK 帮助文档中的相关节。




转自:http://bbs.pediy.com/showthread.php?t=183801

Filter Drivers主要包括以下特性:   1) 一个Filter Drivers实例叫Filter Module。Filter Module附加在一个适配器的微端口驱动上, 来自相同或不同Filter Drivers的多个Filter Module都可以被堆叠在一个网络适配器上   2) 在Filter Module被安装到驱动栈时,之上的协议驱动和之下的微端口驱动都不需要提供额外的支持功能   3) 因为Filter Module不像中间层驱动(intermediate driver)那样提供一个虚拟的微口,也不与某个设备对象联结,所以在微端口适配器(miniport adapter)之上的Filter Module 功能相当于一个修过过版本的微端口适配器(miniport adapter)。(原文:Because filter drivers do not implement virtual miniports like an intermediate driver, filter drivers are not associated with a device object. A miniport adapter with overlying filter modules functions as a modified version of the miniport adapter.)   4) NDIS使用配置信息来到决定一个Filter Module附加到一个网络适配器栈上的顺序   5) 在不用拆除整驱动栈的情况下,NDIS可以动态的插入、删除Filter Module或进行重新配置   6) 当NDIS重起驱动栈的时候协议驱动可以获得在栈上的Filter Module列表   7) Filter Drivers可以过滤下层网络适配器上绝大部分的通信。Filter Module不联结某特定的绑定(Filter modules are not associated with any particular binding between overlying protocol drivers and the miniport adapter.)   8) Filter Drivers 可以选择为过滤服务也可以选择为分流的不过滤服务,选择为哪一种是可以动态配置的(Filter drivers can select the services that are filtered and can be bypassed for the services that are not filtered. The selection of the services that are bypassed and the services that are filtered can be reconfigured dynamically.)   9) NDIS 保证有效的上下文空间,也不就是说Filter Drivers不要需要通代码COPY缓冲区来获得上下文空间  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值