在写一个有关完成例程的driver时,遇到一个Crash:DRIVER_CORRUPTED_EXPOOL(C5)。Windbg直接分析dump file,不容易找到错误,因为错误发生的指令并非是我的Driver模块内。
挂上DriverVerifier后,设置special pool,Windbg 中analyze -v显示以下错误信息
DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION (d6)N bytes of memory was allocated and more than N bytes are being referenced.This cannot be protected by try-except.When possible, the guilty driver's name (Unicode string) is printed onthe bugcheck screen and saved in KiBugCheckDriver.Arguments:Arg1: 86e69003, memory referencedArg2: 00000000, value 0 = read operation, 1 = write operationArg3: fac08771, if non-zero, the address which referenced memory.Arg4: 00000000, (reserved)
Debugging Details:------------------
READ_ADDRESS: 86e69003 Special pool
FAULTING_IP: DynamicAttach+771fac08771 0fb64203 movzx eax,byte ptr [edx+3]
定位到我的完成例程中的代码:
if (Irp->PendingReturned) { > IoMarkIrpPending(Irp); }
IoMarkIrpPending宏:
#define IoGetCurrentIrpStackLocation( Irp ) / ( (Irp)->Tail.Overlay.CurrentStackLocation )
#define IoMarkIrpPending( Irp ) ( / IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED )
看Arg3,就是fac08771处指令引发了Crash。
0: kd> ub fac08771DynamicAttach+0x75a:fac0875a 8b4860 mov ecx,dword ptr [eax+60h]fac0875d 894df0 mov dword ptr [ebp-10h],ecxfac08760 8b550c mov edx,dword ptr [ebp+0Ch] //取完成例程第2个参数,即Irpfac08763 0fb64221 movzx eax,byte ptr [edx+21h] // Irp->PendingReturnedfac08767 85c0 test eax,eaxfac08769 7416 je DynamicAttach+0x781 (fac08781)fac0876b 8b4d0c mov ecx,dword ptr [ebp+0Ch] //取完成例程第2个参数,即Irpfac0876e 8b5160 mov edx,dword ptr [ecx+60h] //取(Irp)->Tail.Overlay.CurrentStackLocation0: kd> u fac08771DynamicAttach+0x771:fac08771 0fb64203 movzx eax,byte ptr [edx+3] //取(Irp)->Tail.Overlay.CurrentStackLocation->Control时Crashfac08775 83c801 or eax,1
当取(Irp)->Tail.Overlay.CurrentStackLocation->Control时Crash,因为该地址是无效地址。所以为了避免Crash,之前要判断一下:
if (Irp->PendingReturned) {
if(MmIsAddressValid(&pIrpSp->Control))
IoMarkIrpPending(Irp); }
不过这只是表面现象,未完待续。