记一次蓝屏问题解决

时间:2024-04-06 19:14:19

  最近看了张银奎的《软件调试》第30章,有种醍醐灌顶、如沐春风的感觉,想找找机会去用windbg去实战下。

  最好的方式是看看部门有没有现有的问题让我去跟,于是找到领导,问最近有没有什么蓝屏问题之类的需要跟踪的,领导喜笑颜开,你真我的好员工啊,有个问题我正愁没人跟呢,我们小组的***不是要离职了吗,他最近在跟踪一个蓝屏问题,跟了几天,我看他也没什么心思在上面,你把这个问题接过来吧。

  好嘞!说跟就跟,向同事要了dump文件,windbg挂上:

记一次蓝屏问题解决

 

   查看堆栈信息:

记一次蓝屏问题解决

  从dump文件可以看到蓝屏的原因就是在高IRQL下访问分页内存导致的,具体函数发生在netkvm.sys模块的NdisAllocateMemoryWithTag函数,由于这份代码不是我们维护的,所以用IDA反编译了下,通过地址找到了对应的代码段:

记一次蓝屏问题解决

  代码上下文没问题,通过msdn查询NdisAllocateMemoryWithTag函数,其也不可能分配分页内存,所以这样一看代码没问题,为什么就蓝了呢,真是匪夷所思。

  还是好好研究下DRIVER_CORRUPTED_EXPOOL这个错误吧,通过windbg描述,错误的原因是高IRQL访问分页内存导致,但是以前这种报错不是这样的啊,是IRQL_NOT_LESS_OR_EQUAL的报错,这两种报错有什么区别呢,通过查找资料找到了DRIVER_CORRUPTED_EXPOOL的错误其实是:其他驱动或者内存越界导致的内核POOL被破坏,导致引用的一些字段被改成了不存在的地址或者分页内存

继续用命令调试

打印帧栈信息:

记一次蓝屏问题解决

可以看到是eax地址的问题,查看汇编代码:

记一次蓝屏问题解决

 

从汇编代码来看eax的地址最初来源于ebp-20h,查看该地址

记一次蓝屏问题解决

查看80566168这个地址

记一次蓝屏问题解决

  第一个地址正好是eax地址,可以看到其他行的第一列和第二列都是相同的,只有第一行不同,可以确定这个地址被污染但是内存并没有特别的标志之类的,无法进行内存搜索,无法确定是哪个模块导致的问题。

  好在windows提供了一个driver verifier工具可以对我们内部开发的一些驱动进行检测,开启special pool开关,该开关主要针对驱动内存溢出、内存泄露的检测,于是单独对各个驱动进行检测,发现ChannelSerial在升级的时候蓝屏概率非常高,dump文件也是显示该驱动导致,关掉driver verify不会蓝屏,其他驱动未出现过蓝屏情况,所以踩内存可能由该驱动导致。最终通过排查ChannelSerial驱动文件,解决几处可能导致的内存溢出问题,再进行测试,之前的蓝屏问题不复存在。