;看看IopInvalidDeviceRequest的实现
;有符号表的情况下,在Windbg的命令窗口输入:u nt!IopInvalidDeviceRequest
;因为是默认的IRP处理例程,可以猜到例程的参数定义:
;NTSTATUS IopInvalidDeviceRequest(
; IN PDEVICE_OBJECT DeviceObject,
; IN PIRP Irp
; )
nt!IopInvalidDeviceRequest:
804fa88e 8bff mov edi,edi
804fa890 55 push ebp
804fa891 8bec mov ebp,esp
804fa893 56 push esi
;取第2个参数(就是Irp)放入esi
804fa894 8b750c mov esi,dword ptr [ebp+0Ch]
;[esi+60h]的地方是Irp->Tail.Overlay.CurrentStackLocation
804fa897 8b4660 mov eax,dword ptr [esi+60h]
;[eax]的意思是_IO_STACK_LOCATION的第1个成员,就是MajorFunction
;16其实是IRP_MJ_POWER
;这里是判断如果是IRP_MJ_POWER,就特别处理(je 8051c34e)
804fa89a 803816 cmp byte ptr [eax],16h
804fa89d 0f84ab1a0200 je nt!IopInvalidDeviceRequest+0x11 (8051c34e)
;如果是IRP_MJ_POWER以外的IRP
;给第2个参数赋值0(IO_NO_INCREMENT)
804fa8a3 32d2 xor dl,dl
;给第1个参数赋值Irp
804fa8a5 8bce mov ecx,esi
;Irp->IoStatus.Status=0C0000010h(STATUS_INVALID_DEVICE_REQUEST)
804fa8a7 c74618100000c0 mov dword ptr [esi+18h],0C0000010h
;_fastcall的方式调用nt!IofCompleteRequest
804fa8ae e85393feff call nt!IofCompleteRequest (804e3c06)
;无论返回值是什么,都设置为0C0000010h(STATUS_INVALID_DEVICE_REQUEST)
804fa8b3 b8100000c0 mov eax,0C0000010h
804fa8b8 5e pop esi
804fa8b9 5d pop ebp
804fa8ba c20800 ret 8;
下面来看看je nt!IopInvalidDeviceRequest+0x11 (8051c34e)
;8051c34e做了什么事呢?马上揭晓
kd> u 8051c34e 8051c3b4
nt!IopInvalidDeviceRequest+0x11:
;和前面联系起来,这时候esi是Irp
8051c34e 56 push esi
;调用nt!PoStartNextPowerIrp esi是作为唯一的参数压栈的
8051c34f e84a8efeff call nt!PoStartNextPowerIrp (8050519e)
;直接跳804fa8a3
8051c354 e94ae5fdff jmp nt!IopInvalidDeviceRequest+0x17 (804fa8a3)
// 根据反汇编的结果,可以写出对应的C代码
NTSTATUS IopInvalidDeviceRequest(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
if (Irp->Tail.Overlay.CurrentStackLocation->MajorFunction == IRP_MJ_POWER) {
PoStartNextPowerIrp(Irp);
}
Irp->IoStatus.Status = 0C0000010h
IofCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}