脑残的PsSetCreateProcessNotifyRoutine

Vista之前的系统,XP及Server 2003只有8个坑,就是说前8个调用成功之后,后续的所有调用都会失败,看来通过注册callback的方式来监控进程非常不靠谱。

从内核角度来说,尽量少的调用不仅提高系统响应时间,也降低了不靠谱的驱动所可能带来问题,但限制为区区8个总不是解决办法吧,比如Symantec家的SEP动不动就占3个,腾讯家(Tencent)更牛B,安全管家要用几个,QQ也要用,就连浏览器也要搞个驱动并也要注册个进程创建的回调通知,这也太让人无语了吧。

好在从Vista开始,这个限制从8个变成了64个,翻了整整8倍,呵呵,这下够用了?!

下面是一个典型的XP系统实例,8个回调会被占满了,后起的驱动们只能想其它办法了:

0: kd> x nt!PspCreateProcessNotifyRoutine 80564a40 nt!PspCreateProcessNotifyRoutine = <no type information> 0: kd> dd 80564a40 80564a40  e101894f e15e4eb7 e2031ff6 e1e8b56f 80564a50  e20a8d9f e51c641f e52246b7 e5ad82cf 80564a60  00000008 00000000 86a85d58 8656fac0 80564a70  86b9b5a0 86be5208 86be45a0 00000000 80564a80  00000000 00000000 00000000 00000000 80564a90  00000000 00000000 00000000 00000000 80564aa0  00000000 6d6f7441 00000000 00000001 80564ab0  00000000 00000000 00000000 00000000 0: kd> .for (r $t0=0; $t0 < 8; r $t0=$t0+1) {r $t1 = poi($t0 * 4 + nt!PspCreateProcessNotifyRoutine); .if ($t1 == 0) {.continue;}; r $t1 = $t1 & 0xFFFFFFF8; r $t1 = poi($t1 + 4); r $t0; r $t1; u $t1; ln $t1;} $t0=00000000 $t1=f7310790 TsFltMgr+0x10790: f7310790 55              push    ebp f7310791 8bec            mov     ebp,esp f7310793 83e4f8          and     esp,0FFFFFFF8h f7310796 83ec14          sub     esp,14h f7310799 53              push    ebx f731079a 56              push    esi f731079b 8b35a07b31f7    mov     esi,dword ptr [TsFltMgr+0x17ba0 (f7317ba0)] f73107a1 57              push    edi $t0=00000001 $t1=f771a788 ghcore+0x3788: f771a788 8bff            mov     edi,edi f771a78a 55              push    ebp f771a78b 8bec            mov     ebp,esp f771a78d 33c0            xor     eax,eax f771a78f 390564b471f7    cmp     dword ptr [ghcore+0x4464 (f771b464)],eax f771a795 7508            jne     ghcore+0x379f (f771a79f) f771a797 39056cb471f7    cmp     dword ptr [ghcore+0x446c (f771b46c)],eax f771a79d 741a            je      ghcore+0x37b9 (f771a7b9) $t0=00000002 $t1=ed1a3b00 SYMEVENT+0xcb00: ed1a3b00 8bff            mov     edi,edi ed1a3b02 55              push    ebp ed1a3b03 8bec            mov     ebp,esp ed1a3b05 51              push    ecx ed1a3b06 53              push    ebx ed1a3b07 8b5d08          mov     ebx,dword ptr [ebp+8] ed1a3b0a 56              push    esi ed1a3b0b 33f6            xor     esi,esi $t0=00000003 $t1=ecfeb120 QQFrmMgr+0xe120: ecfeb120 8bff            mov     edi,edi ecfeb122 55              push    ebp ecfeb123 8bec            mov     ebp,esp ecfeb125 51              push    ecx ecfeb126 51              push    ecx ecfeb127 53              push    ebx ecfeb128 8b5d0c          mov     ebx,dword ptr [ebp+0Ch] ecfeb12b 56              push    esi $t0=00000004 $t1=ecd098a0 SysPlant+0x78a0: ecd098a0 55              push    ebp ecd098a1 8bec            mov     ebp,esp ecd098a3 83e4f8          and     esp,0FFFFFFF8h ecd098a6 51              push    ecx ecd098a7 53              push    ebx ecd098a8 56              push    esi ecd098a9 57              push    edi ecd098aa a12480d1ec      mov     eax,dword ptr [SysPlant+0x16024 (ecd18024)] $t0=00000005 $t1=866b41d0 866b41d0 90              nop 866b41d1 90              nop 866b41d2 e9e7c4f466      jmp     QMUdisk+0x26be (ed6006be) 866b41d7 90              nop 866b41d8 90              nop 866b41d9 90              nop 866b41da 90              nop 866b41db 90              nop $t0=00000006 $t1=ecaf8070 BHDrvx86+0x6c070: ecaf8070 8bff            mov     edi,edi ecaf8072 55              push    ebp ecaf8073 8bec            mov     ebp,esp ecaf8075 807d1000        cmp     byte ptr [ebp+10h],0 ecaf8079 750f            jne     BHDrvx86+0x6c08a (ecaf808a) ecaf807b 8b450c          mov     eax,dword ptr [ebp+0Ch] ecaf807e 8b0d48e0b8ec    mov     ecx,dword ptr [BHDrvx86+0x102048 (ecb8e048)] ecaf8084 50              push    eax $t0=00000007 $t1=ee461eba dekfs+0x4eba: ee461eba 8bff            mov     edi,edi ee461ebc 55              push    ebp ee461ebd 8bec            mov     ebp,esp ee461ebf 83ec10          sub     esp,10h ee461ec2 807d1000        cmp     byte ptr [ebp+10h],0 ee461ec6 53              push    ebx ee461ec7 56              push    esi ee461ec8 57              push    edi

Server 2008 X64系统已经可以支持64个注册回调了,这个限制是硬编码在

函数PsSetCreateProcessNotifyRoutine中的:

0: kd> u nt!PspSetCreateProcessNotifyRoutine nt!PspSetCreateProcessNotifyRoutine: fffff800`01c3fab0 48895c2408      mov     qword ptr [rsp+8],rbx fffff800`01c3fab5 48896c2410      mov     qword ptr [rsp+10h],rbp fffff800`01c3faba 4889742418      mov     qword ptr [rsp+18h],rsi …… fffff800`01c3fad4 bb01000000      mov     ebx,1 …… fffff800`01c3fb3e e89d3cf1ff      call    nt!ExDereferenceCallBackBlock (fffff800`01b537e0) fffff800`01c3fb43 4403e3          add     r12d,ebx fffff800`01c3fb46 4183fc40        cmp     r12d,40h fffff800`01c3fb4a 72ae            jb      nt!PspSetCreateProcessNotifyRoutine+0x4a (fffff800`01c3fafa) fffff800`01c3fb4c 66019fb4010000  add     word ptr [rdi+1B4h],bx fffff800`01c3fb53 7518            jne     nt!PspSetCreateProcessNotifyRoutine+0xbd (fffff800`01c3fb6d) ……

此系统上并未安装腾讯管家等类似的防毒程序,但是64个注册回调已有6个被使用,差不多全是M$自家给占用的:

0: kd> x nt!PspCreateProcessNotifyRoutine fffff800`019f8ee0 nt!PspCreateProcessNotifyRoutine = <no type information> 0: kd> dq fffff800`019f8ee0 fffff800`019f8ee0  fffff880`00008c4f fffff880`006d7acf fffff800`019f8ef0  fffff880`006f694f fffff880`007ff5cf fffff800`019f8f00  fffff880`098168af fffff880`0a30216f fffff800`019f8f10  00000000`00000000 00000000`00000000 fffff800`019f8f20  00000000`00000000 00000000`00000000 fffff800`019f8f30  00000000`00000000 00000000`00000000 fffff800`019f8f40  00000000`00000000 00000000`00000000 fffff800`019f8f50  00000000`00000000 00000000`00000000 0: kd> .for (r $t0=0; $t0 < 0x40; r $t0=$t0+1) {r $t1=poi($t0 * 8 + nt!PspCreateProcessNotifyRoutine); .if ($t1 == 0) {.continue}; r $t0; r $t1 = $t1 & 0xFFFFFFFFFFFFFFF0; r $t1 = poi($t1 + 8); r $t1; u $t1; ln $t1;} $t0=0000000000000000 $t1=fffff8000188dbd0 nt!ViCreateProcessCallback: fffff800`0188dbd0 fff3            push    rbx fffff800`0188dbd2 4883ec40        sub     rsp,40h fffff800`0188dbd6 833dc3a2160000  cmp     dword ptr [nt!ViVerifierEnabled (fffff800`019f7ea0)],0 fffff800`0188dbdd 0f8583b6fcff    jne     nt! ?? ::FNODOBFM::`string'+0x21140 (fffff800`01859266) fffff800`0188dbe3 4883c440        add     rsp,40h fffff800`0188dbe7 5b              pop     rbx fffff800`0188dbe8 c3              ret fffff800`0188dbe9 90              nop (fffff800`0188dbd0)   nt!ViCreateProcessCallback   |  (fffff800`0188dbf0)   nt!IopAllocateFileObjectExtension Exact matches: nt!ViCreateProcessCallback = <no type information> $t0=0000000000000001 $t1=fffffa6000e52ffc ksecdd!CredMarshalTargetInfo+0x8cc: fffffa60`00e52ffc 4883ec28        sub     rsp,28h fffffa60`00e53000 488364244800    and     qword ptr [rsp+48h],0 fffffa60`00e53006 4584c0          test    r8b,r8b fffffa60`00e53009 488bc2          mov     rax,rdx fffffa60`00e5300c 7546            jne     ksecdd!CredMarshalTargetInfo+0x924 (fffffa60`00e53054) fffffa60`00e5300e 488d542448      lea     rdx,[rsp+48h] fffffa60`00e53013 488bc8          mov     rcx,rax fffffa60`00e53016 ff15dc00feff    call    qword ptr [ksecdd!BCryptDestroySecret+0x191c8 (fffffa60`00e330f8)] (fffffa60`00e52730)   ksecdd!CredMarshalTargetInfo+0x8cc   |  (fffffa60`00e535f4)   ksecdd!AcquireCredentialsHandleW $t0=0000000000000002 $t1=fffffa600106f830 tcpip+0x69830: fffffa60`0106f830 4d85c0          test    r8,r8 fffffa60`0106f833 7405            je      tcpip+0x6983a (fffffa60`0106f83a) fffffa60`0106f835 e9860b0000      jmp     tcpip+0x6a3c0 (fffffa60`010703c0) fffffa60`0106f83a e911130000      jmp     tcpip+0x6ab50 (fffffa60`01070b50) fffffa60`0106f83f 90              nop fffffa60`0106f840 90              nop fffffa60`0106f841 90              nop fffffa60`0106f842 90              nop $t0=0000000000000003 $t1=fffffa600074e06c CI!I_PEProcessNotify: fffffa60`0074e06c 4584c0          test    r8b,r8b fffffa60`0074e06f 7528            jne     CI!I_PEProcessNotify+0x2d (fffffa60`0074e099) fffffa60`0074e071 53              push    rbx fffffa60`0074e072 4883ec20        sub     rsp,20h fffffa60`0074e076 488bda          mov     rbx,rdx fffffa60`0074e079 ff15f1d1f5ff    call    qword ptr [CI!_imp_IoGetCurrentProcess (fffffa60`006ab270)] fffffa60`0074e07f 488bc8          mov     rcx,rax fffffa60`0074e082 ff1530d0f5ff    call    qword ptr [CI!_imp_PsIsProtectedProcess (fffffa60`006ab0b8)] (fffffa60`0074e06c)   CI!I_PEProcessNotify   |  (fffffa60`0074e0a0)   CI!RSA32Alloc Exact matches: CI!I_PEProcessNotify = <no type information> $t0=0000000000000004 $t1=fffffa6002fac964 dekfs+0x6964: fffffa60`02fac964 48895c2408      mov     qword ptr [rsp+8],rbx fffffa60`02fac969 48896c2410      mov     qword ptr [rsp+10h],rbp fffffa60`02fac96e 56              push    rsi fffffa60`02fac96f 57              push    rdi fffffa60`02fac970 4154            push    r12 fffffa60`02fac972 4155            push    r13 fffffa60`02fac974 4156            push    r14 fffffa60`02fac976 4883ec50        sub     rsp,50h $t0=0000000000000005 $t1=fffffa600c545b2d peauth!I_PEProcessNotify: fffffa60`0c545b2d 48895c2408      mov     qword ptr [rsp+8],rbx fffffa60`0c545b32 57              push    rdi fffffa60`0c545b33 4883ec20        sub     rsp,20h fffffa60`0c545b37 e8cc6bfdff      call    peauth!WARBIRD::Stub_VerifyVerifierCheckSum (fffffa60`0c51c708) fffffa60`0c545b3c 90              nop fffffa60`0c545b3d 360000          add     byte ptr ss:[rax],al fffffa60`0c545b40 00fd            add     ch,bh fffffa60`0c545b42 140a            adc     al,0Ah (fffffa60`0c545b2d)   peauth!I_PEProcessNotify   |  (fffffa60`0c545fe1)   peauth!PEReturnCertChain Exact matches: peauth!I_PEProcessNotify = <no type information>

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注