饿,一直不知道关机回调是哪个,搞的当时弄系统回调时也没检测,今天看NT FILE SYSTEM INTERNALS才知道是
IoRegisterShutdownNotification(IN PDEVICE_OBJECT DeviceObject
)
那就来玩下压
lkd> u IoRegisterShutdownNotification L30
nt!IoRegisterShutdownNotification:
8056ab64 8bff mov edi,edi
8056ab66 55 push ebp
8056ab67 8bec mov ebp,esp
8056ab69 57 push edi
8056ab6a 68496f5368 push 68536F49h//标记
8056ab6f 6a0c push 0Ch//och大小
8056ab71 6a00 push 0//非分页内存
8056ab73 e808b3fdff call nt!ExAllocatePoolWithTag (80545e80)
8056ab78 8bf8 mov edi,eax
8056ab7a 85ff test edi,edi
8056ab7c 7507 jne nt!IoRegisterShutdownNotification+0x21 (8056ab85)
8056ab7e b89a0000c0 mov eax,0C000009Ah//分配内存失败了,返回****
8056ab83 eb21 jmp nt!IoRegisterShutdownNotification+0x42 (8056aba6)
8056ab85 56 push esi
8056ab86 8b7508 mov esi,dword ptr [ebp+8]//到这里这个[ebp+8]就是DEVICE_OBJECT
8056ab89 8bce mov ecx,esi
8056ab8b 897708 mov dword ptr [edi+8],esi
8056ab8e e8bd8dfbff call nt!ObfReferenceObject (80523950)//引用下这个DRIVEROBJECT
8056ab93 8bd7 mov edx,edi
8056ab95 b9e0285580 mov ecx,offset nt!IopNotifyShutdownQueueHead (805528e0)
8056ab9a e8d59bf8ff call nt!IopInterlockedInsertHeadList (804f4774)//插入805528e0处的链表
8056ab9f 804e1d08 or byte ptr [esi+1Dh],8//设置DEVICE_OBJECT标志
8056aba3 33c0 xor eax,eax
8056aba5 5e pop esi
8056aba6 5f pop edi//failed
8056aba7 5d pop ebp
8056aba8 c20400 ret 4
nt!IopInterlockedInsertHeadList:
804f4774 8bff mov edi,edi
804f4776 53 push ebx
804f4777 56 push esi
804f4778 57 push edi
804f4779 8bf2 mov esi,edx//edx是分配的内存基址
804f477b 8bf9 mov edi,ecx//ecx是链表头
804f477d ff1514874d80 call dword ptr [nt!_imp__KeRaiseIrqlToDpcLevel (804d8714)]
804f4783 8b17 mov edx,dword ptr [edi]
804f4785 8bda mov ebx,edx
804f4787 3bdf cmp ebx,edi
804f4789 7502 jne nt!IopInterlockedInsertHeadList+0x19 (804f478d)
804f478b 33db xor ebx,ebx
804f478d 8916 mov dword ptr [esi],edx
804f478f 897e04 mov dword ptr [esi+4],edi//前面分配的地址现在内容为:[IopNotifyShutdownQueueHead ],IopNotifyShutdownQueueHead ,DeviceObject
804f4792 897204 mov dword ptr [edx+4],esi//填入回调队列中去
804f4795 8ac8 mov cl,al
804f4797 8937 mov dword ptr [edi],esi//填2次?
804f4799 ff151c874d80 call dword ptr [nt!_imp_KfLowerIrql (804d871c)]
804f479f 5f pop edi
804f47a0 5e pop esi
804f47a1 8bc3 mov eax,ebx
804f47a3 5b pop ebx
804f47a4 c3 ret
//开虚拟机断这个函数IoRegisterShutdownNotification
nt!RtlpBreakWithStatusInstruction:
80528bdc cc int 3
kd> bp IoRegisterShutdownNotification
kd> g
Breakpoint 3 hit
nt!IoRegisterShutdownNotification:
8056ab64 8bff mov edi,edi
kd> r
eax=c0000034 ebx=00000000 ecx=0000bb40 edx=804ff6f5 esi=81578ce8 edi=8055bd80
eip=8056ab64 esp=f9bfa584 ebp=f9bfa5b0 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
nt!IoRegisterShutdownNotification:
8056ab64 8bff mov edi,edi
kd> g
Breakpoint 4 hit
nt!IoRegisterShutdownNotification+0x14:
8056ab78 8bf8 mov edi,eax
kd> r
eax=8157c138 ebx=00000000 ecx=00000000 edx=8157d128 esi=81578ce8 edi=8055bd80
eip=8056ab78 esp=f9bfa57c ebp=f9bfa580 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000246
nt!IoRegisterShutdownNotification+0x14:
8056ab78 8bf8 mov edi,eax
kd> g
Breakpoint 5 hit
nt!IoRegisterShutdownNotification+0x21:
8056ab85 56 push esi
kd> r
eax=8157c138 ebx=00000000 ecx=00000000 edx=8157d128 esi=81578ce8 edi=8157c138
eip=8056ab85 esp=f9bfa57c ebp=f9bfa580 iopl=0 nv up ei ng nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000282
nt!IoRegisterShutdownNotification+0x21:
8056ab85 56 push esi//是WMIxWDM的驱动对象
kd> dt nt!_DRIVER_OBJECT 81578ce8
+0x000 Type : 4
+0x002 Size : 168
+0x004 DeviceObject : 0x815789f0 _DEVICE_OBJECT//注意这里
+0x008 Flags : 4
+0x00c DriverStart : (null)
+0x010 DriverSize : 0
+0x014 DriverSection : (null)
+0x018 DriverExtension : 0x81578d90 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "/Driver/WMIxWDM"
+0x024 HardwareDatabase : (null)
+0x028 FastIoDispatch : 0x8055ba00 _FAST_IO_DISPATCH
+0x02c DriverInit : 0x806a0a4c long nt!WmipDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : (null)
+0x038 MajorFunction : [28] 0x805fbe6c long nt!WmipOpenCloseCleanup+0
引用完之后。。
kd> dd [ebp+8]
f9bfa588 815789f0 00000000 806a0376 81578ce8//确实是DEIVCEOBJECT
f9bfa598 00340032 806a0a12 00380037 806a09ae
f9bfa5a8 002c002a 806a09e6 f9bfa67c 8056b750
f9bfa5b8 00000000 00000000 80087000 00000001
f9bfa5c8 00000000 00000018 00000000 f9bfa5f8
f9bfa5d8 00000050 00000000 00000000 0020001e
f9bfa5e8 e12e76f8 806a0a4c 81578ce8 0000003c
f9bfa5f8 0020001e 806a0356 f9bfa64c 00000000
继续下去
当开始调用 call nt!IopInterlockedInsertHeadList 时
各个参数意思:
ecx指向队列头我的是805528e0 ,edi和edx分别指向分配的内存地址,esi是DeviceObject
进去IopInterlockedInsertHeadList:
先提高IRQL到DPC级
当填完回调队列时,变成
kd> dd 805528e0
805528e0 8157c138 8157c138 805528e8 805528e8
805528f0 805528f0 805528f0 805528f8 805528f8
80552900 80552900 80552900 80552908 80552908
80552910 80552910 80552910 00000000 00000000
80552920 80552620 80552960 00000000 00000000
80552930 00000000 00000000 00000000 00000000
80552940 00000000 00000000 00000000 00000000
80552950 00000000 00000000 00000000 00000000
kd> dd 8157c138
8157c138 805528e0 805528e0 815789f0 00000000
8157c148 0a030003 70696d57 00000000 00000000
8157c158 00000000 00000000 0a240003 646f6e44
8157c168 815c3dc8 00000000 8157d008 00000000
8157c178 00000001 00000000 00000308 00000302
8157c188 00000301 00000302 00000000 00000000
8157c198 00000000 00000000 00000000 00000000
8157c1a8 00000000 00000000 00000000 00000000