Mini Filter Driver触发Bugcheck D1问题分析
来源:互联网 发布:pc蛋蛋幸运28算法公式 编辑:程序博客网 时间:2024/05/16 14:40
前段时间帮朋友改进他做的文件加密Mini Filter Driver,好不容易把期待的功能完善好了,测试时开始频繁触发蓝屏,Bugcheck号是D1。WinDbg对这个错误号的简单解释如下:
DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an interrupt request level (IRQL) that is too high. This is usually caused by drivers using improper addresses.
也就是在高IRQL试图访问可换页内存。看到这种错误的第一反应是头皮发麻。冷静下来后,我回想起以前自己总结出的经验,那就是碰到错误不要慌,首先把错误的所有信息解读清楚。
从栈回溯来看,发生错误的位置如下:
STACK_TEXT:
8078ab6c 99298fff badb0d00 868992b8 89d28620 nt!KiTrap0E+0x1b3
8078ac30 84c587d1 868992b8 8078ac84 9db0cff8 S_Crypt!PostRead+0x27
8078ac60 84c33324 868992b8 0278ac84 9db0cff8 fltmgr!FltvPostOperation+0x71
8078acc8 84c36512 00899258 86899258 10000000 fltmgr!FltpPerformPostCallbacks+0x24a
8078acdc 84c36b46 86899258 8078ad90 8078ad1c fltmgr!FltpProcessIoCompletion+0x10
8078acec 82b50cd4 8a288728 9db08e28 86899258 fltmgr!FltpPassThroughCompletion+0x98
8078ad1c 82896dd3 8a288728 9db08e28 8078ad90 nt!IovpLocalCompletionRoutine+0x14b
8078ad60 82b50b64 00000001 89c09e98 8a234008 nt!IopfCompleteRequest+0x128
8078adc8 85248498 8078adfc 85248abd 8a2336a8 nt!IovCompleteRequest+0x133
这个函数里并没有提升IRQL的相关动作。那为什么会出这个错呢?
因为我之前也没有做Mini Filter Driver的经验,本着认真学习的态度,开始认真阅读WDK的帮助中有关PFLT_POST_OPERATION_CALLBACK的内容。
Post-operation callback routines are called in an arbitrary thread context, at IRQL <= DISPATCH_LEVEL. Because this callback routine can be called at IRQL DISPATCH_LEVEL, it is subject to the following constraints ... ...
大意是说Post-operation回调函数可能在任何线程上下文中被调用,IRQL <= DISPATCH_LEVEL。因为有可能IRQL是DISPATCH_LEVEL,所以会有一些限制。基于当时对WinDbg对D1 bugcheck的解释,我很容易的找到了其中的一个限制,于是认为自己大致明白了这个错误的原因:PostRead函数可能会在DISPATCH_LEVEL被调用,所以在它里面不可以访问paged pool.
Any data structures used in this routine must be allocated from nonpaged pool.
此时,再来看Bugcheck信息里包含的几个参数。
Arguments:
Arg1: 99299000, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000008, value 0 = read operation, 1 = write operation
Arg4: 99298fff, address which referenced memory
惊奇地发现,发出访问请求的地址和被访问的地址都是PostRead函数里的代码地址。这是为什么呢?再冷静下来细看,每次发生蓝屏时,被访问地址的后三位都是000,也就是被访问地址刚好都是一个页的起始地址。猜测是在要执行下一条地址时,下一条地址刚好在另一个内存页上,而这个内存页此时是无效的,所以需要触发Page Fault,而在DISPATCH_LEVEL,这又是不允许的。
再回过头来看WDK的帮助,发现其中还有一条限制如下。之前没有注意到它,可能是因为它太简短,一时没有看明白它的含义。现在明白,它说的是Post-operation回调函数本身不可以是可换页的。
It cannot be made pageable.
经过一番查找,在一个头文件里找到了如下的内容。
<pre name="code" class="cpp">#pragma alloc_text(PAGE, S_PostRead)
修改过后,重新测试,问题消失。
#pragma alloc_text(NONPAGED, S_PostRead)再后来,我又追究起为什么刚开始时测试时,没有这样的蓝屏出现,查找之下。原来是在发现功能基本稳定后,打开了Driver Verifier,这大大提高了解发该BSOD的概率。
- Mini Filter Driver触发Bugcheck D1问题分析
- Visual Studio 2013开发 mini-filter driver step by step (1) - 创建 mini filter driver 工程
- File System Mini Filter Driver Step by Step
- Mini Filter 操作消息的分析
- Visual Studio 2013开发 mini-filter driver step by step (11) driver 签名
- Visual Studio 2013开发 mini-filter driver step by step (2) - 编译,部署,运行
- Visual Studio 2013开发 mini-filter driver step by step (3) - 查看运行结果
- Visual Studio 2013开发 mini-filter driver step by step (4) - 获取文件名
- Visual Studio 2013开发 mini-filter driver step by step (5) - 读写文件
- Visual Studio 2013开发 mini-filter driver step by step 获取文件读写内容(6)
- Visual Studio 2013开发 mini-filter driver step by step 内核中使用线程(7)
- Visual Studio 2013开发 mini-filter driver step by step 应用层与内核通讯(8)
- Visual Studio 2013开发 mini-filter driver step by step 内核代码段分页alloc_text的使用(9)
- Visual Studio 2013开发 mini-filter driver step by step 获取可执行文件名称 - 实现process monitor的一个功能 (10)
- 关于迷你驱动(Mini driver)
- Mini Filter加解密开始
- Careless BugCheck
- DFS_FILE_SYSTEM bugcheck
- 游戏服务器端编程书籍
- Java中ASC码与字符互相转换
- DedeCMS添加字段提示Invalid utf8 character string错误的解决办法
- angularjs 数据初始化
- textAlign和textBaseline属性集合
- Mini Filter Driver触发Bugcheck D1问题分析
- Angularjs使用指令做表单校验
- 在Windows7上搭建Cocos2d-x win32开发环境-v3.x
- 2014年总结:究竟是什么才能让我飞得更高?
- 2014工作总结
- Android电视机(机顶盒)初次开发的一些经验分享
- 使用fastjson解析json抓取新浪新闻文章
- 斯晨斯夕
- angularjs单页面多Controller示例