KiSystemService 是由用户态进内核态的系统调用,简单分析,写在这里。

进入函数之前

pushfd                                                                  // ebp+70
push Argument_1                                                         // ebp+6c
push call ip                                                            // ebp+68

call

nt!KiSystemService:
80542451 6a00            push    0                                      // ebp+64
80542453 55              push    ebp                                    // ebp+60
80542454 53              push    ebx                                    // ebp+5c
80542455 56              push    esi                                    // ebp+58
80542456 57              push    edi                                    // ebp+54
80542457 0fa0            push    fs                                     // ebp+50
80542459 bb30000000      mov     ebx,30h                         
8054245e 668ee3          mov     fs,bx
80542461 64ff3500000000  push    dword ptr fs:[0]                       // ebp+4c

fs的值设为30h,根据 System Programming Guide 3.4.1 Segment Selectors 的定义,实际上是 GDTR 第6个值,解析这个数据得到虚拟地址。 直接用dg命令查看段选择子的值。

0: kd> dg 30h
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 ffdff000 00001fff Data RW Ac 0 Bg Pg P  Nl 00000c93

然后得到这个base地址,据说 这个地址是存放着一个 _KPCR(Processor Control Region) 结构,第一个成员指向 _NT_TIB 的一个地址,存放当前CPU的各种信息,该结构体最后一个成员是0x120 _KPRCB,它的第4个成员指向 线程控制块 CurrentThread。

80542468 64c70500000000ffffffff mov dword ptr fs:[0],0FFFFFFFFh
80542473 648b3524010000  mov     esi,dword ptr fs:[124h]               // CurrentThread _KTHREAD
8054247a ffb640010000    push    dword ptr [esi+140h]                  // _KTHREAD->PreviousMode
80542480 83ec48          sub     esp,48h
80542483 8b5c246c        mov     ebx,dword ptr [esp+6Ch]               // Argument_1
80542487 83e301          and     ebx,1
8054248a 889e40010000    mov     byte ptr [esi+140h],bl                // 修改 PreviousMode
80542490 8bec            mov     ebp,esp
80542492 8b9e34010000    mov     ebx,dword ptr [esi+134h]              // _KTHREAD->TrapFrame

TrapFrame nt!_KTRAP_FRAME

0: kd> dt nt!_KTRAP_FRAME 
   +0x000 DbgEbp           : Uint4B
   +0x004 DbgEip           : Uint4B
   +0x008 DbgArgMark       : Uint4B
   +0x00c DbgArgPointer    : Uint4B
   ...

据说 是指中断、自陷、异常进入内核后,在堆栈上形成的一种数据结构。

80542498 895d3c          mov     dword ptr [ebp+3Ch],ebx               // 存起来
8054249b 89ae34010000    mov     dword ptr [esi+134h],ebp              // 你明白吧
805424a1 fc              cld                                           // Clear Direction Flag
805424a2 8b5d60          mov     ebx,dword ptr [ebp+60h]               // 开头保存的那个 ebp
805424a5 8b7d68          mov     edi,dword ptr [ebp+68h]               // eip
805424a8 89550c          mov     dword ptr [ebp+0Ch],edx               // Argument_1
805424ab c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h          // DbgArgMark 据说是个 Magic Number
805424b2 895d00          mov     dword ptr [ebp],ebx
805424b5 897d04          mov     dword ptr [ebp+4],edi
805424b8 f6462cff        test    byte ptr [esi+2Ch],0FFh               // _KTHREAD->DebugActive
805424bc 0f858afeffff    jne     nt!Dr_kss_a (8054234c)

如果老夫没有看错的话,这个应该是保存TrapFrame吧。咳咳。

nt!Dr_kss_a
8054234c f7457000000200  test    dword ptr [ebp+70h],20000h            // EFLAGS VM Virtual-8086 Mode
80542353 750d            jne     nt!Dr_kss_a+0x16 (80542362)           

nt!Dr_kss_a+0x9:
80542355 f7456c01000000  test    dword ptr [ebp+6Ch],1
8054235c 0f8460010000    je      nt!KiSystemService+0x71 (805424c2)

nt!Dr_kss_a+0x16:
80542362 0f21c3          mov     ebx,dr0
80542365 0f21c9          mov     ecx,dr1
80542368 0f21d7          mov     edi,dr2
8054236b 895d18          mov     dword ptr [ebp+18h],ebx
8054236e 894d1c          mov     dword ptr [ebp+1Ch],ecx
80542371 897d20          mov     dword ptr [ebp+20h],edi
80542374 0f21db          mov     ebx,dr3
80542377 0f21f1          mov     ecx,dr6
8054237a 0f21ff          mov     edi,dr7
8054237d 895d24          mov     dword ptr [ebp+24h],ebx
80542380 894d28          mov     dword ptr [ebp+28h],ecx
80542383 33db            xor     ebx,ebx
80542385 897d2c          mov     dword ptr [ebp+2Ch],edi
80542388 0f23fb          mov     dr7,ebx
8054238b 648b3d20000000  mov     edi,dword ptr fs:[20h]
80542392 8b9ff8020000    mov     ebx,dword ptr [edi+2F8h]
80542398 8b8ffc020000    mov     ecx,dword ptr [edi+2FCh]
8054239e 0f23c3          mov     dr0,ebx
805423a1 0f23c9          mov     dr1,ecx
805423a4 8b9f00030000    mov     ebx,dword ptr [edi+300h]
805423aa 8b8f04030000    mov     ecx,dword ptr [edi+304h]
805423b0 0f23d3          mov     dr2,ebx
805423b3 0f23d9          mov     dr3,ecx
805423b6 8b9f08030000    mov     ebx,dword ptr [edi+308h]
805423bc 8b8f0c030000    mov     ecx,dword ptr [edi+30Ch]
805423c2 0f23f3          mov     dr6,ebx
805423c5 0f23f9          mov     dr7,ecx
805423c8 e9f5000000      jmp     nt!KiSystemService+0x71 (805424c2)

接下来。

nt!KiSystemService+0x71:
805424c2 fb              sti                                          // Set Interrupt Flag
805424c3 e9e7000000      jmp     nt!KiFastCallEntry+0x8f (805425af)

nt!KiFastCallEntry+0x8f:
805425af 8bf8            mov     edi,eax                              // eax 里保存着 SSDT 表的编号
805425b1 c1ef08          shr     edi,8                                // edi/256
805425b4 83e730          and     edi,30h                              // 12-14位
805425b7 8bcf            mov     ecx,edi                              // edi 验证 shadow ssdt
805425b9 03bee0000000    add     edi,dword ptr [esi+0E0h]             // _KTHREAD->ServiceTable
805425bf 8bd8            mov     ebx,eax
805425c1 25ff0f0000      and     eax,0FFFh                            // 低12位
805425c6 3b4708          cmp     eax,dword ptr [edi+8]                // ServiceTable->NumberOfServices
805425c9 0f8333fdffff    jae     nt!KiBBTUnexpectedRange (80542302)

nt!KiFastCallEntry+0xaf:
805425cf 83f910          cmp     ecx,10h
805425d2 751b            jne     nt!KiFastCallEntry+0xcf (805425ef)

nt!KiFastCallEntry+0xb4:
805425d4 648b0d18000000  mov     ecx,dword ptr fs:[18h]               // _NT_TIB _TEB 当前线程控制块
805425db 33db            xor     ebx,ebx
805425dd 0b99700f0000    or      ebx,dword ptr [ecx+0F70h]            // _PEB GdiBatchCount
805425e3 740a            je      nt!KiFastCallEntry+0xcf (805425ef)

nt!KiFastCallEntry+0xc5:
805425e5 52              push    edx
805425e6 50              push    eax
805425e7 ff1548d75580    call    dword ptr [nt!KeGdiFlushUserBatch (8055d748)]
805425ed 58              pop     eax
805425ee 5a              pop     edx

nt!KiFastCallEntry+0xcf:
805425ef 64ff0538060000  inc     dword ptr fs:[638h]                  // _KPRCB->KeSystemCalls
805425f6 8bf2            mov     esi,edx                              // 
805425f8 8b5f0c          mov     ebx,dword ptr [edi+0Ch]              // ParamTableBase
805425fb 33c9            xor     ecx,ecx
805425fd 8a0c18          mov     cl,byte ptr [eax+ebx]                // Params
80542600 8b3f            mov     edi,dword ptr [edi]                  // ServiceTable 第一个函数地址
80542602 8b1c87          mov     ebx,dword ptr [edi+eax*4]            // 计算函数地址
80542605 2be1            sub     esp,ecx                              // param num 
80542607 c1e902          shr     ecx,2
8054260a 8bfc            mov     edi,esp
8054260c 3b3534315680    cmp     esi,dword ptr [nt!MmUserProbeAddress (80563134)]  // 7fff0000
80542612 0f83a8010000    jae     nt!KiSystemCallExit2+0x9f (805427c0)

nt!KiFastCallEntry+0xf8:
80542618 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]  // 复制到esp
8054261a ffd3            call    ebx                                  // 调用

nt!KiFastCallEntry+0xfc:
8054261c 8be5            mov     esp,ebp

nt!KiFastCallEntry+0xfe:
8054261e 648b0d24010000  mov     ecx,dword ptr fs:[124h]              // kthread
80542625 8b553c          mov     edx,dword ptr [ebp+3Ch]              // 
80542628 899134010000    mov     dword ptr [ecx+134h],edx             // 恢复_KTRAP_FRAME
8054262e fa              cli
8054262f f7457000000200  test    dword ptr [ebp+70h],20000h
80542636 7506            jne     nt!KiServiceExit+0x10 (8054263e)

基本流程就这样。还有一些错误处理的分支没有写出来,有时间再看吧。

  • No labels