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

KTRAP_FRAME框架结构图

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

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

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

==========================================================================================

SYSENTER系统服务调用过程

以NtReadFile调用为例。

一.NtDll.Dll中,NtReadFile过程如下:
ntdll!NtReadFile:
7c92d9b0 b8b7000000      mov     eax,0B7h
7c92d9b5 ba0003fe7f      mov     edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d9ba ff12            call    dword ptr [edx]
7c92d9bc c22400          ret     24h

二.0x7ffe0300地址存放0x7c92e4f0,反汇编它:
ntdll!KiFastSystemCall:
7c92e4f0 8bd4          mov     edx,esp
7c92e4f2 0f34          sysenter

因为SYSENTER执行时,CPU并不会向CALL一样保存返回地址和状态信息,所以需要这样一个“桩”(STUB)段,通过它来保存返回信息。同样的,下面的(五)就是利用这里保存的返回信息返回值NtReadFile中。

这里的KiFastSystemCall和(五)中的SystemCallReturn 都是保存在 _KUSER_SHARED_DATA结构中。用户态下的0X7FFE0000和系统态下的0XFFDF0000同时指向它。结构如下:

nt!_KUSER_SHARED_DATA
   +0x000 TickCountLow     : Uint4B
   +0x004 TickCountMultiplier : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
   +0x014 SystemTime       : _KSYSTEM_TIME
   +0x020 TimeZoneBias     : _KSYSTEM_TIME
   +0x02c ImageNumberLow   : Uint2B
   +0x02e ImageNumberHigh  : Uint2B
   +0x030 NtSystemRoot     : [260] Uint2B
   +0x238 MaxStackTraceDepth : Uint4B
   +0x23c CryptoExponent   : Uint4B
   +0x240 TimeZoneId       : Uint4B
   +0x244 Reserved2        : [8] Uint4B
   +0x264 NtProductType    : _NT_PRODUCT_TYPE
   +0x268 ProductTypeIsValid : UChar
   +0x26c NtMajorVersion   : Uint4B
   +0x270 NtMinorVersion   : Uint4B
   +0x274 ProcessorFeatures : [64] UChar
   +0x2b4 Reserved1        : Uint4B
   +0x2b8 Reserved3        : Uint4B
   +0x2bc TimeSlip         : Uint4B
   +0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
   +0x2c8 SystemExpirationDate : _LARGE_INTEGER
   +0x2d0 SuiteMask        : Uint4B
   +0x2d4 KdDebuggerEnabled : UChar
   +0x2d5 NXSupportPolicy  : UChar
   +0x2d8 ActiveConsoleId  : Uint4B
   +0x2dc DismountCount    : Uint4B
   +0x2e0 ComPlusPackage   : Uint4B
   +0x2e4 LastSystemRITEventTickCount : Uint4B
   +0x2e8 NumberOfPhysicalPages : Uint4B
   +0x2ec SafeBootMode     : UChar
   +0x2f0 TraceLogging     : Uint4B
   +0x2f8 TestRetInstruction : Uint8B
   +0x300 SystemCall       : Uint4B
   +0x304 SystemCallReturn : Uint4B
   +0x308 SystemCallPad    : [3] Uint8B
   +0x320 TickCount        : _KSYSTEM_TIME
   +0x320 TickCountQuad    : Uint8B
   +0x330 Cookie           : Uint4B

三.显示MSR,因为SYSENTER和SYSEXIT需要它。
lkd> rdmsr 174
msr[174] = 00000000`00000008  ;RING0下CS
lkd> rdmsr 175
msr[175] = 00000000`f78bb000  ;进入RING0后的ESP
lkd> rdmsr 176
msr[176] = 00000000`804de89f  ;进入RING0后的EIP

XP GDT如下,SYSENTER和SYSEXIT用到这些:
0008 00000000 ffffffff Code RE Ac 0 Bg Pg P  Nl 00000c9b ;RING0下CS
0010 00000000 ffffffff Data RW Ac 0 Bg Pg P  Nl 00000c93 ;RING0下SS
0018 00000000 ffffffff Code RE Ac 3 Bg Pg P  Nl 00000cfb ;RING3下CS
0020 00000000 ffffffff Data RW Ac 3 Bg Pg P  Nl 00000cf3 ;RING3下SS

四.进入RING0
反汇编0x804de89f,nt!KiFastCallEntry.
这个过程分成3部分:
1).每次调用都会创建一个_KTRAP_FRAME框架,第一部分就是创建这个框架
nt!_KTRAP_FRAME
   +0x000 DbgEbp           : Uint4B
   +0x004 DbgEip           : Uint4B
   +0x008 DbgArgMark       : Uint4B
   +0x00c DbgArgPointer    : Uint4B
   +0x010 TempSegCs        : Uint4B
   +0x014 TempEsp          : Uint4B
   +0x018 Dr0              : Uint4B
   +0x01c Dr1              : Uint4B
   +0x020 Dr2              : Uint4B
   +0x024 Dr3              : Uint4B
   +0x028 Dr6              : Uint4B
   +0x02c Dr7              : Uint4B
   +0x030 SegGs            : Uint4B
   +0x034 SegEs            : Uint4B
   +0x038 SegDs            : Uint4B
   +0x03c Edx              : Uint4B
   +0x040 Ecx              : Uint4B
   +0x044 Eax              : Uint4B
   +0x048 PreviousPreviousMode : Uint4B
   +0x04c ExceptionList    : Ptr32 _EXCEPTION_REGISTRATION_RECORD
   +0x050 SegFs            : Uint4B
   +0x054 Edi              : Uint4B
   +0x058 Esi              : Uint4B
   +0x05c Ebx              : Uint4B
   +0x060 Ebp              : Uint4B
   +0x064 ErrCode          : Uint4B
   +0x068 Eip              : Uint4B
   +0x06c SegCs            : Uint4B
   +0x070 EFlags           : Uint4B
   +0x074 HardwareEsp      : Uint4B
   +0x078 HardwareSegSs    : Uint4B
   +0x07c V86Es            : Uint4B
   +0x080 V86Ds            : Uint4B
   +0x084 V86Fs            : Uint4B
   +0x088 V86Gs            : Uint4B

2).直接调用内核中的服务过程
3).从第一部分中创建的框架_KTRAP_FRAME中,返回至RING3状态

第一部分创建框架
nt!KiFastCallEntry:
804de89f b923000000      mov     ecx,23h
804de8a4 6a30            push    30h
804de8a6 0fa1            pop     fs    ;RING0下 FS=0x30
804de8a8 8ed9            mov     ds,cx ;RING3下 0x20 数据段
804de8aa 8ec1            mov     es,cx ;RING3下 0x20 数据段
804de8ac 648b0d40000000  mov     ecx,dword ptr fs:[40h] ;TSS
804de8b3 8b6104          mov     esp,dword ptr [ecx+4] 
804de8b6 6a23            push    23h
804de8b8 52              push    edx
804de8b9 9c              pushfd
804de8ba 6a02            push    2
804de8bc 83c208          add     edx,8
804de8bf 9d              popfd        ;EFLAGS = 2
804de8c0 804c240102      or      byte ptr [esp+1],2 ;EFLAGS设置。
804de8c5 6a1b            push    1Bh
804de8c7 ff350403dfff    push    dword ptr ds:[0FFDF0304h]
804de8cd 6a00            push    0
804de8cf 55              push    ebp
804de8d0 53              push    ebx
804de8d1 56              push    esi
804de8d2 57              push    edi
804de8d3 648b1d1c000000  mov     ebx,dword ptr fs:[1Ch]
804de8da 6a3b            push    3Bh
804de8dc 8bb324010000    mov     esi,dword ptr [ebx+124h]
804de8e2 ff33            push    dword ptr [ebx]
804de8e4 c703ffffffff    mov     dword ptr [ebx],0FFFFFFFFh
804de8ea 8b6e18          mov     ebp,dword ptr [esi+18h]
804de8ed 6a01            push    1
804de8ef 83ec48          sub     esp,48h
804de8f2 81ed9c020000    sub     ebp,29Ch
804de8f8 c6864001000001  mov     byte ptr [esi+140h],1
804de8ff 3bec            cmp     ebp,esp
804de901 0f8565ffffff    jne     nt!KiFastCallEntry2+0x25 (804de86c)
804de907 83652c00        and     dword ptr [ebp+2Ch],0
804de90b f6462cff        test    byte ptr [esi+2Ch],0FFh
804de90f 89ae34010000    mov     dword ptr [esi+134h],ebp
804de915 0f8535feffff    jne     nt!Dr_FastCallDrSave (804de750)
804de91b 8b5d60          mov     ebx,dword ptr [ebp+60h]
804de91e 8b7d68          mov     edi,dword ptr [ebp+68h]
804de921 89550c          mov     dword ptr [ebp+0Ch],edx
804de924 c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h
804de92b 895d00          mov     dword ptr [ebp],ebx
804de92e 897d04          mov     dword ptr [ebp+4],edi
804de931 fb              sti
第一部分执行完后,_KTRAP_FRAME如下图。

第二部分真正的系统调用,此时EAX=系统调用号;EDX=调用参数;ESI=当前线程ETHREAD.
804de932 8bf8            mov     edi,eax
804de934 c1ef08          shr     edi,8
804de937 83e730          and     edi,30h
804de93a 8bcf            mov     ecx,edi
804de93c 03bee0000000    add     edi,dword ptr [esi+0E0h]
804de942 8bd8            mov     ebx,eax
804de944 25ff0f0000      and     eax,0FFFh
804de949 3b4708          cmp     eax,dword ptr [edi+8]
804de94c 0f8330fdffff    jae     nt!KiBBTUnexpectedRange (804de682)
804de952 83f910          cmp     ecx,10h
804de955 751b            jne     nt!KiFastCallEntry+0xcf (804de972)
804de957 648b0d18000000  mov     ecx,dword ptr fs:[18h]
804de95e 33db            xor     ebx,ebx
804de960 0b99700f0000    or      ebx,dword ptr [ecx+0F70h]
804de966 740a            je      nt!KiFastCallEntry+0xcf (804de972)
804de968 52              push    edx
804de969 50              push    eax
804de96a ff1568355680    call    dword ptr [nt!KeGdiFlushUserBatch (80563568)]
804de970 58              pop     eax
804de971 5a              pop     edx
804de972 64ff0538060000  inc     dword ptr fs:[638h]   <--KPRCB.KeSystemCalls增加一个计数
804de979 8bf2            mov     esi,edx
804de97b 8b5f0c          mov     ebx,dword ptr [edi+0Ch]
804de97e 33c9            xor     ecx,ecx
804de980 8a0c18          mov     cl,byte ptr [eax+ebx]
804de983 8b3f            mov     edi,dword ptr [edi]
804de985 8b1c87          mov     ebx,dword ptr [edi+eax*4]
804de988 2be1            sub     esp,ecx
804de98a c1e902          shr     ecx,2
804de98d 8bfc            mov     edi,esp
804de98f 3b35d48e5680    cmp     esi,dword ptr [nt!MmUserProbeAddress (80568ed4)]
804de995 0f83a8010000    jae     nt!KiSystemCallExit2+0x9f (804deb43)
804de99b f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
804de99d ffd3            call    ebx
804de99f 8be5            mov     esp,ebp
804de9a1 648b0d24010000  mov     ecx,dword ptr fs:[124h]
804de9a8 8b553c          mov     edx,dword ptr [ebp+3Ch]
804de9ab 899134010000    mov     dword ptr [ecx+134h],edx

第三部分返回至RING3
nt!KiServiceExit:
804de9b1 fa              cli
<DISPATCH_USER_APC宏>
804de9b2 f7457000000200  test    dword ptr [ebp+70h],20000h
804de9b9 7506            jne     nt!KiServiceExit+0x10 (804de9c1)
804de9bb f6456c01        test    byte ptr [ebp+6Ch],1
804de9bf 7456            je      nt!KiServiceExit+0x66 (804dea17)
804de9c1 648b1d24010000  mov     ebx,dword ptr fs:[124h]
804de9c8 c6432e00        mov     byte ptr [ebx+2Eh],0
804de9cc 807b4a00        cmp     byte ptr [ebx+4Ah],0
804de9d0 7445            je      nt!KiServiceExit+0x66 (804dea17)
804de9d2 8bdd            mov     ebx,ebp
804de9d4 894344          mov     dword ptr [ebx+44h],eax
804de9d7 c743503b000000  mov     dword ptr [ebx+50h],3Bh
804de9de c7433823000000  mov     dword ptr [ebx+38h],23h
804de9e5 c7433423000000  mov     dword ptr [ebx+34h],23h
804de9ec c7433000000000  mov     dword ptr [ebx+30h],0
804de9f3 b901000000      mov     ecx,1
804de9f8 ff152c904d80    call    dword ptr [nt!_imp_KfRaiseIrql (804d902c)]
804de9fe 50              push    eax
804de9ff fb              sti
804dea00 53              push    ebx
804dea01 6a00            push    0
804dea03 6a01            push    1
804dea05 e8f7f3ffff      call    nt!KiDeliverApc (804dde01)
804dea0a 59              pop     ecx
804dea0b ff1530904d80    call    dword ptr [nt!_imp_KfLowerIrql (804d9030)]
804dea11 8b4344          mov     eax,dword ptr [ebx+44h]
804dea14 fa              cli
804dea15 ebaa            jmp     nt!KiServiceExit+0x10 (804de9c1)

804dea17 8b54244c        mov     edx,dword ptr [esp+4Ch]
804dea1b 648b1d50000000  mov     ebx,dword ptr fs:[50h]
804dea22 64891500000000  mov     dword ptr fs:[0],edx

804dea29 8b4c2448        mov     ecx,dword ptr [esp+48h]
804dea2d 648b3524010000  mov     esi,dword ptr fs:[124h]
804dea34 888e40010000    mov     byte ptr [esi+140h],cl

804dea3a f7c3ff000000    test    ebx,0FFh
804dea40 7579            jne     nt!KiSystemCallExit2+0x17 (804deabb)

804dea42 f744247000000200 test    dword ptr [esp+70h],20000h
804dea4a 0f8506090000    jne     nt!KiExceptionExit+0x12c (804df356)

804dea50 66f744246cf8ff  test    word ptr [esp+6Ch],0FFF8h
804dea57 0f84b4000000    je      nt!KiSystemCallExit2+0x6d (804deb11)

804dea5d 66837c246c1b    cmp     word ptr [esp+6Ch],1Bh
804dea63 660fba64246c00  bt      word ptr [esp+6Ch],0
804dea6a f5              cmc
804dea6b 0f878e000000    ja      nt!KiSystemCallExit2+0x5b (804deaff)

804dea71 66837d6c08      cmp     word ptr [ebp+6Ch],8
804dea76 7405            je      nt!KiServiceExit+0xcc (804dea7d)

804dea78 8d6550          lea     esp,[ebp+50h]
804dea7b 0fa1            pop     fs
804dea7d 8d6554          lea     esp,[ebp+54h]
804dea80 5f              pop     edi
804dea81 5e              pop     esi
804dea82 5b              pop     ebx
804dea83 5d              pop     ebp

804dea84 66817c24088000  cmp     word ptr [esp+8],80h
804dea8b 0f87e1080000    ja      nt!KiExceptionExit+0x148 (804df372)
804dea91 83c404          add     esp,4

804dea94 f744240401000000 test    dword ptr [esp+4],1
nt!KiSystemCallExitBranch:
804dea9c 7506            jne     nt!KiSystemCallExit2 (804deaa4)
804dea9e 5a              pop     edx
804dea9f 59              pop     ecx
804deaa0 9d              popfd
804deaa1 ffe2            jmp     edx
nt!KiSystemCallExit:
804deaa3 cf              iretd
nt!KiSystemCallExit2:
804deaa4 f644240901      test    byte ptr [esp+9],1
804deaa9 75f8            jne     nt!KiSystemCallExit (804deaa3)
804deaab 5a              pop     edx
804deaac 83c404          add     esp,4
804deaaf 80642401fd      and     byte ptr [esp+1],0FDh
804deab4 9d              popfd
804deab5 59              pop     ecx
804deab6 fb              sti
804deab7 0f35            sysexit

五.返回RING3
0FFDF0304H和7FDF0304H中执行相同的物理地址,其值为:7c92e4f4h,反汇编这个地址:

7c92e4f4 c3              ret

返回至NtReadFile中。至此,整个调用过程结束。

WINDOWS系统调用 和 SYSENTER系统服务调用过程相关推荐

  1. 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程

    标 题: [原创]使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程. 作 者: shayi 时 间: 2015-02-12,05:19:54 链 ...

  2. 案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程。 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下:

    案例一: 使用IDA PRO+OllyDbg+PEview 追踪windows API 动态链接库函数的调用过程. 首先用文本编辑器写一个C++源程序名为StackFrame.cpp ,代码如下: 1 ...

  3. Windows系统调用学习笔记(四)—— 系统服务表SSDT

    Windows系统调用学习笔记(四)-- 系统服务表&SSDT 要点回顾 系统服务表 实验:分析 KiSystemService 与 KiFastCallEntry 共同代码 SSDT 实验: ...

  4. Windows系统调用学习笔记(一)—— API函数调用过程

    Windows系统调用学习笔记(一)-- API函数调用过程 Windows API 实验1:分析ReadProcessMemory 第一步:定位函数 第二步:开始分析 总结 实验2:分析NtRead ...

  5. Windows系统调用学习笔记(三)—— 保存现场

    Windows系统调用学习笔记(三)-- 保存现场 要点回顾 基本概念 Trap Frame 结构 线程相关的结构体 ETHREAD KTHREAD CPU相关的结构体 KPCR _NT_TIB KP ...

  6. Windows系统调用学习笔记(二)—— 3环进0环

    Windows系统调用学习笔记(二)-- 3环进0环 要点回顾 基本概念 _KUSER_SHARED_DATA 0x7FFE0300 实验:判断CPU是否支持快速调用 第一步:修改EAX=1 第二步: ...

  7. 调用门、堆栈切换与调用过程返回

    论天下大势,合久必分分久必合.上回书我们说了<CPL,RPL和DPL:这三个级别你搞懂了吗?>,这回书我们讲调用门以及堆栈切换. 门描述符 为了提供对具有不同特权级别的代码段的受控访问,处 ...

  8. 全面了解Windows Server 2003 和 Windows XP 附带的系统服务

    简介   系统服务的处理不同于其他设置,因为所有服务的漏洞.对策及潜在影响在本质上都一样.第一次安装 Microsoft Windows Server 2003 时,系统将在启动时创建并配置默认服务. ...

  9. WINDOWS下对音频的处理过程(转)

    WINDOWS下对音频的处理过程 WINDOWS下对音频的处理,大致可分为两部分,即音频的输入.输出,和ACM压缩处理. 一般情况下在WINDOWS下可以调用诸如sndPlaySound等API(MC ...

最新文章

  1. LeetCode简单题之使每位学生都有座位的最少移动次数
  2. 贷还是不贷:如何用Python和机器学习帮你决策?
  3. python猜数游戏流程_python简单猜数游戏实例
  4. LINQ学习之旅——第二站LTQ之标准数据库操作(增查删改)
  5. python中的常见的列表操作及注意事项
  6. Codeforces Round #148 (Div. 2)
  7. mysql date compare_SQLDataCompare下载
  8. 复习Javascript专题(三):面向对象(对象的创建与继承,原型及原型链)
  9. 又发现昆仑通态的一个BUG
  10. 汇添富基金总经理张晖:做选股专家,更以“选股专家”的视角管理公司
  11. java连点方法,Re:连点器(示例代码)
  12. 业务流程图的绘制流程分享(一)
  13. mysql数据库更新数据库语句_详解MySQL数据库之更新语句
  14. 《守望先锋》架构设计和网络同步
  15. PID为0的系统空闲进程连接状态为TIME_WAIT
  16. 数据挖掘—概念空间挖掘FindS算法的C++实现
  17. texstudio暗色主题
  18. 海康威视产品的token更新
  19. 产品设计指南:如何从零设计一款手机端产品(APP)?
  20. Use // eslint-disable-next-line to ignore the next line.Use /* eslint-disable */ to ignore all解决

热门文章

  1. 使用yum快速搭建LAMP和配置phpMyAdmin
  2. Mac使用自带的屏幕共享实现VNC连接KVM时需要输入密码的问题解决
  3. 火狐放不了html5 video MP4格式
  4. keystonejs富文本问题及思考过程
  5. git提交过程中遇到的 index.lock 问题导致无法提交的解决方法
  6. BSON及mongoDB数据类型
  7. PHP 核心知识要点
  8. 使用atomic一定是线程安全的吗
  9. DOS批处理延时技术
  10. xmpp 服务器配置 open fire for windows 及 spark 测试