首页
社区
课程
招聘
[原创]驱动程序检验器使用参考
发表于: 2012-10-4 20:41 5127

[原创]驱动程序检验器使用参考

2012-10-4 20:41
5127
驱动程序检验器,看到这个名字,有时候甚至找到对应的文件也不知道有啥用,认为与自己相距遥远,直到有一天……
接触了驱动,并且在很多无名的驱动的问题下,一步步逼上了驱动程序检验器。

驱动程序检验器说白了就是检验驱动的问题的,它的后果就是直接让你蓝屏。
这也是许多人不敢找他惹他的原因,但是对于一类特殊的人群却特别喜欢他,那就是到了一定火候的驱动开发人员等。

好了言归正传,驱动程序检验器就是你系统自带的那个verifier.exe,可以在开始->运行的里面直接运行。
这里会打开一个界面,不过它也可以在命令行中运行,这里就不谈了。

--------------------------------------------------------------------------------------------------------------

它可以检验图形驱动程序,不过我没有搞过这,这也就不谈了。用户模式的驱动我也没有试过。

按照上面的运行过之后弹出一个界面(以windows server 2003为例),
我们选择:创建自定义设置(供程序开发人员使用)(C),再点击进入下一步。
这时出现一个界面,这里面有两个大的选项:
1.启动预先定义的设置(P):;
2.从一个完整的列表选项选择单个设置(I)。
其实这两个选项是一样的,只不过第一个选项中的标准设置对应第二个选项的里面的列表中的多个。

具体的对应是:
标准设置包括:特殊池,池跟踪,强制IRQL检查,I/O验证,增强的I/O验证,死锁检查,DMA检查。这7项。
这个可以通过显示现有设置选项来验证。

这一步设置完毕之后,点击下一步,进入另一个页面。
在这个页面中选择:从一个列表选择驱动程序(L),点击下一步,进入另一个页面。
在这个页面中选择自己要测试的驱动,如果没有,就点击:将目前没有加载的驱动程序天剑到列表中(A)...,然后再添加。

至此设置完成,重启后起效。注释:在安全模式下无效。
其他的设置较为简单,这里就不说了。如显示和删除等。相信你会了这一操作,别的都会了。

对于上面的设置,其实是在注册表HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Managemen中修改的。
例如:那些选项是\VerifyDriverLevel的位掩码。
      驱动的名字是在VerifyDrivers中设置的,多个用空格分开,全部请用*,不支持通配符。

关于它的实现原理,好像也是用hook的办法,好像也有一类以vf开头的函数(少的可怜,后面还加fail)。
没有在内核中找到Verifier开头的函数,也许有(在别处),但没有导出。

--------------------------------------------------------------------------------------------------------------

每一个选项之我的理解:不足不正之处,敬请指正。

1.特殊内存池
就是所分配到的内存,在内存的上下各加一个无效的页面,从而能检查出上溢和下溢出,一旦发生就蓝屏,代码是:0xXX.

内存溢出大多是上溢,所以Gflags.exe的verify end选项是开启的。这也是驱动程序检验器的设置。
如果要开启下溢,请修改下面的注册表值为0:
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\MemoryManage-ment\PoolTagOverruns

强制设置所有驱动使用特殊内存池的办法是设置下面的值为0x2a:
HKLM\SYSTEMCurrentControlSet\Control\Session Manager\Memory Manage-ment\PoolTag

提示一个注意的情况是:
ExAllocateWithTagPriority的Priority参数来设置成XxxSpecialPoolOverrun 或XxxSpecialPoolUnderrun。

2.内存池跟踪
就是你申请的内存到你的驱动卸载的时候没有释放,它给你显示蓝屏,蓝屏的代码是:0xc4.
关机的时候我没有测试会不会蓝屏。
有一个命令可以查看有多少分页内存没有释放和多少非分页内存没有释放,这个命令我一时忘了。
不过Bug Check 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION的说明很详细。

补充:
不是本选项的功能,但是驱动卸载的时候驱动程序检验器还会做如下的检查:
  1.未删除的定时器
  2.未定的 DPC
  3.未删除的辅助列表
  4.未删除的工作线程
  5.未删除的队列
  6.其他类似的资源
如果出现上面的情况,驱动程序检验器,会给你蓝屏.
如果没有驱动程序检验器,如果非法的不正当的访问这些资源,也会蓝屏.

3.强制IRQL检查
就是你在各种IRQL上的内存(分页和非分页)操作是否合乎规范要求,不符合就蓝屏,蓝屏代码为:0xA。
关于这规则我就不说了。当然也和一些锁有关联。

4.低资源模拟
就是随机的让你申请内存的函数失败,这发生在系统启动之后的7分钟以后。
不过,申请内存时用必须成功的标志不受这个限制。

5.i/o检查
就是irp是从一个特殊的内存池中申请的,这个irp的使用受到监控,如果非法使用就蓝屏,蓝屏代码为:0xc9.
这里的irp是通过IoAllocateIrp获得的,这是常用的,好多是封装了这个函数。
这里的i/o检查是1级的,2级的仅仅使用于windows 2000,已经过时不再使用。
这种情况对于监控一个驱动最为有效。

非法的i/o调用包括:
  1.尝试释放一个非 IO_TYPE_IRP类型的 IRP
  2.传递非法设备对象给 IoCallDriver  
  3.传递一 IRP  给含有非法的状态或仍保留一已取消的例程集的 IoCompleteRequest
  4.通过驱动程序调度例程的调用来改变 IRQL
  5.尝试释放保留关联的一个线程的 IRP
  6.传递一个设备对象给已经有初始化过的定时器的 IoInitializeTimer
  7.传递一个非法的缓冲区给  IoBuildAsynchronousFsdRequest 或  IoBuildDeviceIoControlRequest  
  8.当一个 I/O 状态块分配给一极松散的堆栈时,传递一个 I/O 状态块给一个 IRP
  9.当一个事件对象分配给一极松散的堆栈时,传递一个事件对象给一个 IRP
  10.等等其他。

6.增强的i/o检查
检查一下内容:
  1.异步的IRP操作
  2.驱动程序删除设备对象多次
  3.模拟操作,给驱动程序发送一些假的电源管理的wmi查询的IRP。
  4.改变设备被列举的顺序。
  5.调整irp的状态(pnp和电源IRP完成时)。

7.DMA检查
就是检查调用DMA函数的参数和缓冲区的地址检查。

8.磁盘完整性检查
就是检查你的磁盘有没有损坏掉.利用校验和的办法.

9.scsi检查
这是一个隐含项,只要你开启了驱动程序检查器,并进行了相关的操作,就会起作用的.

10.被默认隐含检查的功能还有:
  1.通过调用 KeLowerIrql提高IRQL
  2.通过调用 KeRaiseIrql 降低IRQL
  3.零内存分配请求
  4.在APC_LEVER 之上的 IRQL 分配和释放分页池
  5.在DIPATCH_LEVER 之上的 IRQL 分配和释放非分页池
  6.尝试释放一个没有从前面的分配里返回的地址。
  7.尝试释放一个已被释放的地址。
  8.在APC_LEVER 之上的在 IRQL 获取和释放一个快速的互斥体
  9.在IRQL 而非在DIPATCH_LEVER 之上获取和释放一个自旋锁
  10.双倍释放一个自旋锁
  11.指定一非法或随机(未初始化的)参数给任一 API
  12.等等.

--------------------------------------------------------------------------------------------------------------
  
关于dump文件的分析这里就不多言了,一定要结合自己的代码加上内核的规则。

驱动程序检验器不但能定位问题,发现隐含的问题,还能解决部分死机(挂起)等问题。用法同上(一般不要加上低资源模拟)。

还有一个应用程序检验器和WdfVerifier.exe,性质与此类似,但是用法有所不同。

如的你的驱动编译的时候没有警告,并且oacr没有变红,最后通过Verifier.exe的长时间压力测试,祝贺你,你的驱动可以参
加微软的WHQL认证了。

参考资料:
《深入解析windows操作系统》第四版
《win2000驱动程序设计指南》第二章

made by correy
QQ:112426112
made at 2012.10.03
Email:kouleguan at hotmail dot com
Homepage:http://correy.webs.com
此文献给献给所有爱好驱动的国人和我年迈的父亲。

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//