Windbg和IDA配合解决已卸载的驱动DPC定时器引起的蓝屏DRIVER_IRQL_NOT_LESS_OR_EQUAL
2023-05-31
128
0
最近搞了一个虚拟的设备驱动,自己测试都没有问题,不过拿给同事正式用的时候,会出现蓝屏问题。按他来说,好像成了必现问题。
今天一大早,斜风细雨,天气凉爽,正是揪出这个BUG的好时机,说干就干。
自己先是在调试机中模拟同事的试验方法,可惜的是,试了多次均没有复现。还真是奇怪了,没办法,自己只能不起寻常路了。
先介绍一下,这是一个复合的设备,包括麦克风,摄像头和一个HID设备,通过应用层下发数据给驱动设备数据,实现虚拟设备的功能。
自己通过监听麦克风,打开摄像头再次发送销毁设备后再卸载驱动,终于出现了蓝屏问题。
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.
If kernel debugger is available get stack backtrace.
Arguments:
Arg1: fffff8059c2d2fe0, memory referenced
Arg2: 0000000000000002, IRQL
Arg3: 0000000000000008, value 0 = read operation, 1 = write operation
Arg4: fffff8059c2d2fe0, address which referenced memory
首先我们来看一下堆栈。
2: kd> k
# Child-SP RetAddr Call Site
00 ffff8b81`f13ef298 fffff801`907de5ca nt!DbgBreakPointWithStatus
01 ffff8b81`f13ef2a0 fffff801`907ddfad nt!KeEnterKernelDebugger+0x216
02 ffff8b81`f13ef300 fffff801`90768c64 nt!KeInitializeEnumerationContextFromAffinity+0x8b5
03 ffff8b81`f13efa10 fffff801`90778c29 nt!KeBugCheckEx+0x104
04 ffff8b81`f13efa50 fffff801`90775d6c nt!setjmpex+0x6e79
05 ffff8b81`f13efb90 fffff805`9c2d2fe0 nt!setjmpex+0x3fbc
06 ffff8b81`f13efd28 fffff801`90680df1 <Unloaded_v9323.sys>+0x2fe0
07 ffff8b81`f13efd30 fffff801`9076fa15 nt!KeSetEvent+0x26e1
08 ffff8b81`f13effb0 fffff801`9076f820 nt!KeSynchronizeExecution+0x5e95
09 ffff8b81`f17be6c0 fffff801`9076f155 nt!KeSynchronizeExecution+0x5ca0
0a ffff8b81`f17be6f0 fffff801`9076a8c1 nt!KeSynchronizeExecution+0x55d5
0b ffff8b81`f17be700 fffff801`90742f45 nt!KeSynchronizeExecution+0xd41
0c ffff8b81`f17be890 fffff801`90631005 nt!RtlInitAnsiStringEx+0x439
0d ffff8b81`f17beb90 fffff801`9076fe66 nt!PsGetProcessSessionIdEx+0x2d5
0e ffff8b81`f17bebe0 00000000`00000000 nt!KeSynchronizeExecution+0x62e6
可以看到,由于驱动已经卸载,但是内核又调用了我们的驱动代码,而引起的蓝屏。
我们可以通过db这一块内存地址确定,都是?
2: kd> db fffff8059c2d2fe0
fffff805`9c2d2fe0 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
fffff805`9c2d2ff0 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
fffff805`9c2d3000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
fffff805`9c2d3010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
fffff805`9c2d3020 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
fffff805`9c2d3030 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
fffff805`9c2d3040 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
fffff805`9c2d3050 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
不过由于这里驱动已经卸载,驱动内存已经销毁,Windbg也无法定们到这是那一段代码。
那该怎么办呢?
我们已经知道了地址,这里可以通过IDA来确定。
打开IDA分析驱动,其基地址是0000000140000000,那我们通过
<Unloaded_v9323.sys>+0x2fe0
直接跳转到地址0000000140002FE0
.text:0000000140002FE0
.text:0000000140002FE0 ; =============== S U B R O U T I N E =======================================
.text:0000000140002FE0
.text:0000000140002FE0
.text:0000000140002FE0 ; void __fastcall ProcessIrpTimerDpc(_KDPC *pDpc, void *pContext, void *SysArg1, void *SysArg2)
.text:0000000140002FE0 ProcessIrpTimerDpc proc near ; DATA XREF: BulkUsb_AddDevice+237↑o
.text:0000000140002FE0 ; .rdata:0000000140009310↓o ...
.text:0000000140002FE0 push rbx
.text:0000000140002FE2 sub rsp, 20h
.text:0000000140002FE6 mov rbx, [rdx+40h]
.text:0000000140002FEA mov rcx, rbx ; deviceExtension
可以看到,这原来调用的是ProcessIrpTimerDpc引起蓝屏的。
这时我们突然想到,我在打开麦克风时启用了定时器,关才麦克时取消了定时器,但可能同事是侦听麦克风时,销毁了麦克风再卸载驱动,这时由于麦克风一直在监听态,故没有调用我们的取消定时器操作,这时驱动卸载了,但定时器未销毁,进入了定时器的DPC例程,但驱动内存已经卸载,故导致的蓝屏。