Windows 系统调用

 

Windows 系统调用

 

Windows 2K 通过 2Eh 中断来实现系统调用的,但是在 XP 后使用 SysEnter 来实现系统调用了,同时 2Eh 中断还是保存着的。不管是 2EH 中断还是 SYSENTER , Windows 对所有的系统调用都会生成下面的 KTRAP_FRAME 堆栈框架。

 

 Windows 系统调用_第1张图片

KTRAP_FRAME 框架结构图

 

用户态下使用 2EH 中断时, CPU 会自动产生 0x78 和 0x74 以保存用户态下的堆栈和指针;若直接是从系统层调用 2EH ,则 CPU 是不会自动保存堆栈的,所以需要程序自己保存。

SYSTENTER 只能是从 RING3( 用户态 ) 到 RING0( 系统态 ) 。和 2EH 中断不同, CPU 执行 SYSENTER 是不会自动在堆栈中保存数据的。所以为了 2EH 时堆栈情况一致,需要处理程序模拟保存一些数据。

2EH 和 SYSENTER 的堆栈一致后,下面真正的系统调用时一样的,最后返回时根据调用的不同返回情况也不同。

 

 Windows 系统调用_第2张图片

附:反汇编的代码,根据 WRK 注释。

 
nt!KiSystemService:
808696a1 6a00            push    0
808696a3 55              push    ebp
808696a4 53              push    ebx
808696a5 56              push    esi
808696a6 57              push    edi
808696a7 0fa0            push    fs
808696a9 bb30000000      mov     ebx,30h
808696ae 668ee3          mov     fs,bx   ;FS=0X30
808696b1 64ff3500000000  push    dword ptr fs:[0]
808696b8 64c70500000000ffffffff mov dword ptr fs:[0],0FFFFFFFFh
808696c3 648b3524010000  mov     esi,dword ptr fs:[124h]  ;ESI=_ETHEAD
808696ca ffb640010000    push    dword ptr [esi+140h]     ;PreviousMode
808696d0 83ec48          sub     esp,48h                  ;
808696d3 8b5c246c        mov     ebx,dword ptr [esp+6Ch]  ;
808696d7 83e301          and     ebx,1
808696da 889e40010000    mov     byte ptr [esi+140h],bl   ;新的PreviousMode
808696e0 8bec            mov     ebp,esp                  
808696e2 8b9e34010000    mov     ebx,dword ptr [esi+134h] ;
808696e8 895d3c          mov     dword ptr [ebp+3Ch],ebx  ;旧的TrapFrame保存至新TrapFrame的EDX中。以实现TrapFrame嵌套。
808696eb 89ae34010000    mov     dword ptr [esi+134h],ebp ;新的TrapFrame保存至EThread中TrapFrame.
808696f1 fc              cld

808696f2 8b5d60          mov     ebx,dword ptr [ebp+60h]
808696f5 8b7d68          mov     edi,dword ptr [ebp+68h]
808696f8 89550c          mov     dword ptr [ebp+0Ch],edx
808696fb c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h
80869702 895d00          mov     dword ptr [ebp],ebx
80869705 897d04          mov     dword ptr [ebp+4],edi

 

80869708 f6462cff        test    byte ptr [esi+2Ch],0FFh
8086970c 0f858afeffff    jne     nt!Dr_kss_a (8086959c)  ;if nz, debugging is active on thread.
80869712 fb              sti
80869713 e9e7000000      jmp     nt!KiFastCallEntry+0x8f (808697ff)

 

nt!KiFastCallEntry2:
80869718 b930000000      mov     ecx,30h
8086971d 8ee1            mov     fs,cx
8086971f b923000000      mov     ecx,23h
80869724 8ed9            mov     ds,cx
80869726 8ec1            mov     es,cx
80869728 648b0d40000000  mov     ecx,dword ptr fs:[40h]
8086972f 8b6104          mov     esp,dword ptr [ecx+4]
80869732 6a23            push    23h
80869734 52              push    edx
80869735 9c              pushfd
80869736 804c240101      or      byte ptr [esp+1],1
8086973b eb4e            jmp     nt!KiFastCallEntry+0x1b (8086978b)
8086973d 648b0d40000000  mov     ecx,dword ptr fs:[40h]
80869744 8b6104          mov     esp,dword ptr [ecx+4]
80869747 6a00            push    0
80869749 6a00            push    0
8086974b 6a00            push    0
8086974d 6a00            push    0
8086974f 6a23            push    23h
80869751 6a00            push    0
80869753 6802020200      push    20202h
80869758 6a1b            push    1Bh
8086975a 6a00            push    0
8086975c e973160000      jmp     nt!KiTrap06 (8086add4)
80869761 ebda            jmp     nt!KiFastCallEntry2+0x25 (8086973d)
80869763 8da42400000000  lea     esp,[esp]
8086976a 8d9b00000000    lea     ebx,[ebx]

nt!KiFastCallEntry:
80869770 b923000000      mov     ecx,23h
80869775 6a30            push    30h
80869777 0fa1            pop     fs    ;RING0下 FS=0x30
80869779 8ed9            mov     ds,cx ;RING3下 0x20 数据段
8086977b 8ec1            mov     es,cx ;RING3下 0x20 数据段
8086977d 648b0d40000000  mov     ecx,dword ptr fs:[40h]
80869784 8b6104          mov     esp,dword ptr [ecx+4]
80869787 6a23            push    23h
80869789 52              push    edx
8086978a 9c              pushfd
8086978b 6a02            push    2
8086978d 83c208          add     edx,8
80869790 9d              popfd
80869791 804c240102      or      byte ptr [esp+1],2 ;EFLAGS设置。
80869796 6a1b            push    1Bh
80869798 ff350403dfff    push    dword ptr ds:[0FFDF0304h]
8086979e 6a00            push    0
808697a0 55              push    ebp
808697a1 53              push    ebx
808697a2 56              push    esi
808697a3 57              push    edi
808697a4 648b1d1c000000  mov     ebx,dword ptr fs:[1Ch]
808697ab 6a3b            push    3Bh
808697ad 8bb324010000    mov     esi,dword ptr [ebx+124h]
808697b3 ff33            push    dword ptr [ebx]
808697b5 c703ffffffff    mov     dword ptr [ebx],0FFFFFFFFh
808697bb 8b6e18          mov     ebp,dword ptr [esi+18h]
808697be 6a01            push    1
808697c0 83ec48          sub     esp,48h
808697c3 81ed9c020000    sub     ebp,29Ch
808697c9 c6864001000001  mov     byte ptr [esi+140h],1
808697d0 3bec            cmp     ebp,esp
808697d2 758d            jne     nt!KiFastCallEntry2+0x49 (80869761)
808697d4 83652c00        and     dword ptr [ebp+2Ch],0
808697d8 f6462cff        test    byte ptr [esi+2Ch],0FFh
808697dc 89ae34010000    mov     dword ptr [esi+134h],ebp
808697e2 0f8538feffff    jne     nt!Dr_FastCallDrSave (80869620)
808697e8 8b5d60          mov     ebx,dword ptr [ebp+60h]
808697eb 8b7d68          mov     edi,dword ptr [ebp+68h]
808697ee 89550c          mov     dword ptr [ebp+0Ch],edx
808697f1 c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h
808697f8 895d00          mov     dword ptr [ebp],ebx
808697fb 897d04          mov     dword ptr [ebp+4],edi
808697fe fb              sti

KiSystemServiceRepeat:
808697ff 8bf8            mov     edi,eax
80869801 c1ef08          shr     edi,8
80869804 83e730          and     edi,30h
80869807 8bcf            mov     ecx,edi
80869809 03bee0000000    add     edi,dword ptr [esi+0E0h]
8086980f 8bd8            mov     ebx,eax
80869811 25ff0f0000      and     eax,0FFFh
80869816 3b4708          cmp     eax,dword ptr [edi+8]
80869819 0f8333fdffff    jae     nt!KiBBTUnexpectedRange (80869552)
8086981f 83f910          cmp     ecx,10h
80869822 751b            jne     nt!KiFastCallEntry+0xcf (8086983f)
80869824 648b0d18000000  mov     ecx,dword ptr fs:[18h]
8086982b 33db            xor     ebx,ebx
8086982d 0b99700f0000    or      ebx,dword ptr [ecx+0F70h]
80869833 740a            je      nt!KiFastCallEntry+0xcf (8086983f)
80869835 52              push    edx
80869836 50              push    eax
80869837 ff1528478880    call    dword ptr [nt!KeGdiFlushUserBatch (80884728)]
8086983d 58              pop     eax
8086983e 5a              pop     edx
8086983f 64ff0538060000  inc     dword ptr fs:[638h]
80869846 8bf2            mov     esi,edx
80869848 8b5f0c          mov     ebx,dword ptr [edi+0Ch]
8086984b 33c9            xor     ecx,ecx
8086984d 8a0c18          mov     cl,byte ptr [eax+ebx]
80869850 8b3f            mov     edi,dword ptr [edi]
80869852 8b1c87          mov     ebx,dword ptr [edi+eax*4]
80869855 2be1            sub     esp,ecx
80869857 c1e902          shr     ecx,2
8086985a 8bfc            mov     edi,esp
8086985c 3b3514a18880    cmp     esi,dword ptr [nt!MmUserProbeAddress (8088a114)]
80869862 0f83a8010000    jae     nt!KiSystemCallExit2+0x9f (80869a10)
80869868 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
8086986a ffd3            call    ebx

8086986c 8be5            mov     esp,ebp  ;恢复旧的TrapFrame
8086986e 648b0d24010000  mov     ecx,dword ptr fs:[124h]
80869875 8b553c          mov     edx,dword ptr [ebp+3Ch]
80869878 899134010000    mov     dword ptr [ecx+134h],edx
nt!KiServiceExit:
8086987e fa              cli
8086987f f7457000000200  test    dword ptr [ebp+70h],20000h
80869886 7506            jne     nt!KiServiceExit+0x10 (8086988e)
80869888 f6456c01        test    byte ptr [ebp+6Ch],1
8086988c 7456            je      nt!KiServiceExit+0x66 (808698e4)
8086988e 648b1d24010000  mov     ebx,dword ptr fs:[124h]
80869895 c6432e00        mov     byte ptr [ebx+2Eh],0
80869899 807b4a00        cmp     byte ptr [ebx+4Ah],0
8086989d 7445            je      nt!KiServiceExit+0x66 (808698e4)
8086989f 8bdd            mov     ebx,ebp
808698a1 894344          mov     dword ptr [ebx+44h],eax
808698a4 c743503b000000  mov     dword ptr [ebx+50h],3Bh
808698ab c7433823000000  mov     dword ptr [ebx+38h],23h
808698b2 c7433423000000  mov     dword ptr [ebx+34h],23h
808698b9 c7433000000000  mov     dword ptr [ebx+30h],0
808698c0 b901000000      mov     ecx,1
808698c5 ff152c108080    call    dword ptr [nt!_imp_KfRaiseIrql (8080102c)]
808698cb 50              push    eax
808698cc fb              sti
808698cd 53              push    ebx
808698ce 6a00            push    0
808698d0 6a01            push    1
808698d2 e8dfe3fbff      call    nt!KiDeliverApc (80827cb6)
808698d7 59              pop     ecx
808698d8 ff1530108080    call    dword ptr [nt!_imp_KfLowerIrql (80801030)]
808698de 8b4344          mov     eax,dword ptr [ebx+44h]
808698e1 fa              cli
808698e2 ebaa            jmp     nt!KiServiceExit+0x10 (8086988e)
808698e4 8b54244c        mov     edx,dword ptr [esp+4Ch]
808698e8 648b1d50000000  mov     ebx,dword ptr fs:[50h]
808698ef 64891500000000  mov     dword ptr fs:[0],edx
808698f6 8b4c2448        mov     ecx,dword ptr [esp+48h]
808698fa 648b3524010000  mov     esi,dword ptr fs:[124h]
80869901 888e40010000    mov     byte ptr [esi+140h],cl
80869907 f7c3ff000000    test    ebx,0FFh
8086990d 7579            jne     nt!KiSystemCallExit2+0x17 (80869988)
8086990f f744247000000200 test    dword ptr [esp+70h],20000h
80869917 0f850b090000    jne     nt!Kei386EoiHelper+0x12c (8086a228)
8086991d 66f744246cf8ff  test    word ptr [esp+6Ch],0FFF8h
80869924 0f84b4000000    je      nt!KiSystemCallExit2+0x6d (808699de)
8086992a 66837c246c1b    cmp     word ptr [esp+6Ch],1Bh
80869930 660fba64246c00  bt      word ptr [esp+6Ch],0
80869937 f5              cmc
80869938 0f878e000000    ja      nt!KiSystemCallExit2+0x5b (808699cc)
8086993e 66837d6c08      cmp     word ptr [ebp+6Ch],8
80869943 7405            je      nt!KiServiceExit+0xcc (8086994a)
80869945 8d6550          lea     esp,[ebp+50h]
80869948 0fa1            pop     fs
8086994a 8d6554          lea     esp,[ebp+54h]
8086994d 5f              pop     edi
8086994e 5e              pop     esi
8086994f 5b              pop     ebx
80869950 5d              pop     ebp
80869951 66817c24088000  cmp     word ptr [esp+8],80h
80869958 0f87e6080000    ja      nt!Kei386EoiHelper+0x148 (8086a244)
8086995e 83c404          add     esp,4
80869961 f744240401000000 test    dword ptr [esp+4],1  ;判断 CS最后一位是否为1,即是否从RING3调用来的。
nt!KiSystemCallExitBranch:
80869969 7506            jne     nt!KiSystemCallExit2 (80869971) ;若不是,即从RING3调用的。
8086996b 5a              pop     edx    ;EIP                     ;下面是从RING0调用的。直接返回。没有堆栈切换。
8086996c 59              pop     ecx    ;CS
8086996d 9d              popfd          ;EFLAGS
8086996e ffe2            jmp     edx    ;返回.下面的语句是不执行的。
nt!KiSystemCallExit:
80869970 cf              iretd  ;INT调用返回。下面的语句不执行。
nt!KiSystemCallExit2:    ;若是从RING3调用的。
80869971 f644240901      test    byte ptr [esp+9],1  ;判断EFLAGS的TF =1?
80869976 75f8            jne     nt!KiSystemCallExit (80869970) ;=1,则表示是通过INT调用的。
80869978 5a              pop     edx     ;返回的EIP(RING3)      ;=0,则表示是通过SYSENTER调用的。
80869979 83c404          add     esp,4
8086997c 80642401fd      and     byte ptr [esp+1],0FDh
80869981 9d              popfd
80869982 59              pop     ecx     ;返回的堆栈指针(RING3)
80869983 fb              sti
80869984 0f35            sysexit         ;返回。下面的语句不执行。

你可能感兴趣的:(汇编)