当前位置:   article > 正文

Windows驱动编程基础(下)之过滤驱动的安装和框架概述_一种usb设备过滤驱动程序的自动安装方法

一种usb设备过滤驱动程序的自动安装方法

第六章 过滤驱动的安装和框架概述

过滤驱动的概念和安装

怎么找设备栈中的功能设备对象呢?

这就牵扯到注册表了,我们在第一部分讲过和驱动相关的注册表,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上图所选即为虚拟机中网卡的实例ID,PCI就是BusDevice,PCI下面那一堆VEN_15AD&DEV_0770&SUBXXX或者VEN_8086&DEV_100F&SUBXXX是DeviceId,设备的硬件ID下可能会挂一堆设备实例;
上图右边栏是实例ID里面的一堆键值,里面有一个关键键是我们这个网卡设备所对应的驱动Driver,大家注意,这个Driver键的值就是我们功能设备驱动,我们记下这个值,然后在Control下面的Class里面找这个值所对应的Class:
在这里插入图片描述

这就是我们网卡的驱动信息,这个就是说在一个类里面建立了跟驱动相关的一些注册表的键值。

在这里插入图片描述

然后我们在Enum\PCI下该网卡驱动相关的注册表键值里记下Service的值,再到CurrentControlSet\Services下面找这个名字所对应的我们的网卡服务:
在这里插入图片描述
在这里插入图片描述
我们每一个驱动都对应一个服务,不管你是什么样的驱动,都会有一个服务跟它对应的,我们的驱动装到操作系统里面,是装成一个服务了,我们服务分为应用层服务,还有内核里面的服务,就是驱动;
我们网卡驱动对应的服务就是E1G60,我们看上图这个服务里面有一个ImagePath,就有我们的驱动文件,这个驱动所创建的设备就是功能设备,这个驱动文件就是我们功能驱动所对应的.sys文件。

我们再找一个功能设备看看:
在这里插入图片描述
ACPI是一个高级电源总线,在设备编号为PNP0501的下面找到一个设备实例1以后,在右侧栏同样有一个Service键,同样的通过这个键值,在CurrentControlSet\Services\Serial就能找到这个设备的功能驱动了,在设备实例1里面我们还可以看到UpperFilters或者LowerFilters,如上图所示UpperFilters键的值serenum也是一个服务的名字,然后我们在CurrentControlSet\Services里面找serenum这个服务:
在这里插入图片描述
这个就是过滤驱动文件。

在这里插入图片描述

在这里插入图片描述

这些信息(区分功能设备、过滤设备和总线驱动)就是从注册表里面找的;
一般书上会说,功能驱动是对设备进行操作的,一般设备操作都放在功能驱动里面;过滤驱动是对这个功能进行补充的,修复BUG的;总线驱动是控制这个设备的总线的;但是真正让你区分这3种驱动的话,你不好区分,没有一个具体的区分方法;
我们刚才手工找的方法就是具体的方法,你按照这种方法就能区分哪个驱动是功能驱动,哪个驱动是过滤驱动;
我们以前讲过,拿IRP_MN_QUERY_RELATION这个子IRP你就能得到物理设备对象PDO了。

我们给某一个功能驱动写一个过滤驱动的时候怎么写呢?
写过滤驱动的原则和写功能驱动的原则是一模一样的。

如何安装过滤驱动

我们要把我们写的过滤驱动,作为我们U盘的过滤驱动装上去。
拿一个U盘插到USB接口上,vmware会弹出如下窗口:
在这里插入图片描述
我们点连接到虚拟机,选择虚拟机上打开的操作系统,点确定,因为我们这是一个usb设备,所以在我的电脑里就能看到该盘符:
在这里插入图片描述
我们在注册表中怎么找这个U盘设备呢?
在这里插入图片描述
上图就是我们U盘设备ID下的设备实例,可以从右侧栏的Service看到它的驱动是disk,为了看找的对不对,还可以查看设备管理器:
在这里插入图片描述

在这里插入图片描述
我们可以看到右侧栏现在没有UpperFilters,我们可以手动新建一个UpperFilters,但是在新建之前,先到我们所写过滤驱动的生成目录里面,打开安装过滤驱动的.inf文件:
在这里插入图片描述
其中的[DefaultInstall]节,这个就是装我们NT式驱动的inf,我们这里只是把驱动安装成一个服务,这个驱动并不动,我们说NT式驱动的安装过程,其实就是在我们操作系统里面安装一个内核类型的服务;
在这个节里,安装服务的时候只要把我们驱动文件拷贝到我们想要的地方,然后再添加注册表。

在[DestinationDirs]节,把我们的驱动文件FilterDriver.sys拷贝到System32\drivers这个目录下。

在这里插入图片描述
这个就是说,如果找不到FilterDriver.sys这个文件,就显示上图1所代表的那一串字符串(…Desktop\新建文件夹)。

在这里插入图片描述

这个就是安装我们服务的节,我们服务的名字是FilterDriver,安装服务的节的节名是FilterService;
[FilterService]就是安装服务的节,安装一个服务其实就是在注册表里面写一堆值。

在这里插入图片描述
大家注意,上图就是修改注册表的节,我们在这个设备实例里面新建了一个键UpperFilters,值是FilterDriver字符串,通过这个节就可以把UpperFilters这个键增加到注册表中我们这个U盘设备实例里面了。

在这里插入图片描述
这就把我们这个WDM驱动安装成一个服务了,然后我们在F5刷新一下注册表:
在这里插入图片描述
如上图所示,我们的U盘驱动有一个上层驱动,就是FilterDriver,这样就把过滤驱动安装上了;
但是过滤驱动安装上以后,它不会立即起作用,我们可以打开U盘里面一个txt文件,写入一些内容并保存,可以看到DebugView里面没有内容输出,这个过滤驱动没有任何作用;
过滤驱动安装好以后必须重新启动电脑,操作系统就会自动把我们这个过滤驱动安装上,这是一种办法;当然还有一种办法一会再说。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
这就表明我们安装上的过滤驱动已经起作用了,这是装过滤驱动的一个办法呢。

怎么卸载这个过滤驱动呢?

在这里插入图片描述
我们直接删掉UpperFilters这个键,当然你要想真正让这个卸载起作用的话你还得重启电脑一次;
当然你还可以不重启,删掉这个键之后,你把U盘拔掉,然后打开DebugView:
在这里插入图片描述
这个时候你再把U盘插上:
在这里插入图片描述
这个时候你在U盘里面删除文件夹,或者修改txt文件,DebugView不打印那些IRP了,说明过滤驱动没有了。

另一种安装过滤驱动的方法

鼠标右击inf文件安装之后,刷新注册表可以看到UpperFilters键值了,现在你在U盘里面创建文件夹,DebugView还是不打印东西,过滤驱动还是不起作用,此时你把U盘拔掉,然后你再把U盘插入以后,DebugView就显示IRP都来了,说明过滤驱动又装进去了。

这两种安装过滤驱动方法的区别:

第一种:我们重启计算机,计算机要挨个加载我们系统里面的驱动,在加载我们U盘这个驱动的时候,它就会到注册表中找UpperFilters键值所在的地方看有没有这个键,如果有这个键的话它就会根据该键值找到一个服务,根据这个服务就能找到一个.sys驱动文件,它就知道这是一个上册驱动,它装入这个.sys文件,这个时候我们这个过滤驱动就装入了。

另外一种,我们把U盘拔掉了,当我们设备remove掉了,我们设备所对应的驱动就应该卸载,卸载掉以后这个驱动就没有了,当我们重新插入这个U盘的时候,操作系统根据我们U盘的电子标识来找我们U盘的驱动,它就又找到注册表中UpperFilters键值所在的地方,它就把Service键所对应的值这个驱动先装上,然后它再看UpperFilters,找到UpperFilters键的值所对应的驱动安装上。

在这里插入图片描述
大家注意,这种驱动是安装在我们这个设备上,但是这种安装在设备上的过滤驱动有什么缺点呢?
我们是对应某一个设备实例来安装的过滤驱动,如果我们再插入同样的一个U盘,那么这个新插入的U盘会不会加载我们的过滤驱动呢,我告诉你,不会的,因为你再插入一个U盘的时候,会生成另外一个设备实例了,这个设备实例里面没有UpperFilters键,自然就会在这个设备实例里面安装;
所以说,我们现在的安装方式,是针对某一个固定的设备来安装一个过滤驱动的;

那我想让所有的U盘都安装我们这个过滤驱动,那么怎么装呢?
大家注意,我们说过我们安装设备的时候每一个设备都属于某一个设备类,只要我们在设备对应的设备类里面安装上我们的那个过滤驱动的话,那么属于我们这个设备类的所有设备都会被安装我们的过滤驱动。
在这里插入图片描述
在这里插入图片描述
也就是把这个过滤驱动装到这个设备类里面,我们在注册表中找这个设备类所在的位置:
在这里插入图片描述
可以看到在这个设备类里面(上图右侧栏)原来已经有UpperFilters和LowerFilters了,也就是说我们这个U盘它装了好多过滤驱动,我们说这是一个多字符串类型的键,人家原来有的我们不能删掉,只能把我们自己的过滤驱动加到人家原来过滤驱动上面,怎么加呢?
在这里插入图片描述
上图所选中的0x10008,比上一行的0x10000多了一个8,这个8的意思就是把我们FilterDriver字符串添加到人家原来字符串的后面,不要把人家原有的字符串给冲掉了,我们把上图inf文件0x10000那一行给注释掉,让0x10008那一行生效,然后拷贝修改好的inf文件到虚拟机中,并右击鼠标安装,按F5键刷新注册表:
在这里插入图片描述
可以看到把我们FilterDriver装进去了,这个时候再插我们U盘的时候,不管把我们U盘插到哪个位置,或者插入多个这种类型的U盘的时候,我们的过滤驱动都会装上的。

这就是安装过滤驱动的两种方法,一种是装到设备实例上,还有一种是装到安装的设备类上,属于这个类的所有的这种设备都会安装这个过滤驱动的,你就可以监视电脑上哪些U盘插入了,哪些U盘可以读、哪些U盘不能读,可以做很多工作了。

过滤驱动框架

在这里插入图片描述

我们通过IoGetAttachedDeviceReference这个函数拿到pdo所在的设备栈最顶上的那个设备,这个函数是通过设备栈里面一个设备对象,拿到设备栈最顶上的设备,最顶上的这个设备有可能是一个FiDO,也有可能是一个FDO,也有可能是一个PDO(整个设备栈中只有一个物理设备对象)。
过滤驱动的设备对象的类型,和我们整个设备栈里面的设备类型都应该一样。
一般我们过滤设备对象不要起名字。

在这里插入图片描述
在这里插入图片描述

假如CurrentLocation是location_2,当调用IoCallDriver这个函数之后,CurrentLocation会指向location_3,会往下跳一层;
但是,当我们使用IoSkipCurrrentIrpStackLocation这个函数以后呢,相当于让当前的CurrentLocation往上跳一层,就指向上面的location_1了,这样的话,后面在执行IoCallDriver往下转发IRP的时候,CurrentLocation又会指回location_2了,这样我们当前IO_STACK_LOCATION(也就是location_2)的内容就可以被下一个设备来使用了(因为每个IO_STACK_LOCATION都对应一个设备对象DO):
在这里插入图片描述

以前讲过,当我们创建IRP的时候,我们要设置MajorFunction和MinorFunctjon,还要设置我们IO_STACK_LOCATION的内容(我们只设置第一个IO_STACK_LOCATION的内容,即上图所示的location_1),当调用IoCallDriver向下转发IRP的时候,转发前你必须要设置下一层IO_STACK_LOCATION里面的内容(location_2)(因为IRP创建好以后,它只会设置最顶上的IO_STACK_LOCATION的内容,它不会把下面每一个IO_STACK_LOCATION都设置的);
设备栈里面每一个设备要把这个IRP转发给底下这一层location_2的时候,由转发的这个设备DO_1来设置底下这一层的IO_STACK_LOCATION的内容,但是现在呢我们写的这个函数只是把IRP转发下去,它不会做任何改变,它啥事不干,只是转发一个IRP,这个时候它就没有必要拷贝了,因为它不改变内容,所以不需要把location_1这一层拷贝到下一层location_2,这个时候它就非常轻松了,它把记录当前location位置的指针往上调一层(指向上图location_1的上一层,是虚假的一层),这个时候再调用IoCallDriver的时候又会指向location_1这一层上了),相当于location_1这一层又会被location_2所对应的设备DO_2来使用;

但是当我们要安装完成例程的时候就不能用IoSkipCurrentIrpStackLocation这个函数往上调一层,让底下的设备DO_2来复用上一层的location_1了;
我们完成例程要安装在IO_STACK_LOCATION里面,设备DO_1对应的location_1和设备DO_2对应的location_2就会不一样,因为location_2里面有一个完成例程,而location_1里面没有完成例程,这两个不一样的话你就不能复用location_1了,这个时候你就只能老老实实把location_1里面的内容拷贝到location_2里面,然后你再调用IoSetCompleteRoutine这个函数把location_2这一层里面的内容给它改变一下,改变成我们的完成例程,也就是location_1这一层所对应的设备对象DO_1要安装完成例程的话,它其实是安装在第2个设备DO_2所对应的location_2这一层里面,当IRP由最底下的PDO完成之后开始往上返回的时候,会往上找每一层的完成例程来执行,当第2个设备DO_2所对应的驱动要完成我们这个IRP的时候,它会在location_2里面能找到location_1这一层设备DO_1的完成例程然后被调用,调用的时候当前的CurrentLocation又指向location_1了,它会把CurrentLocation指针自动往上调的。

在这里插入图片描述
这个子IRP需要特殊处理,不能直接转发,因为这个子IRP可能会改变我们设备对象的Flags:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/905898
推荐阅读
相关标签
  

闽ICP备14008679号