Windows系统调用中的系统服务表

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

Windows系统调用中的系统服务表

  如果这部分不理解,可以查看 Windows内核分析索引目录依次阅读。

  我们在之前讲过系统调用过程中,给予eax一个编号,操作系统通过这个编号来执行某个内核函数。

  这个函数是通过操作系统的系统服务表来查找的。

  现在,我们来探究一下nt!KiFastCallEntry的反汇编代码,看看其如何查看系统服务表找到要执行的函数的。

一、系统服务表结构

  Windows一共有两张表,每张表大小10h,每个成员占4h。

  如图,其中函数地址表每成员四字节,函数参数表每成员一字节。

  参数的数值是以字节为单位。

  

二、系统服务表在哪里

  在Win7 32位中存于 [KTHREAD+0xbc]

  kd> dt _KTHREAD
    ntdll!_KTHREAD

    +0x000 Header           : _DISPATCHER_HEADER

    ·······

    +0x0bc ServiceTable     : Ptr32 Void

    ····

  该结构地址为第一个表

  

三、要判断使用哪个表

  传入函数序号的第12位,存储的就是关于使用那个表的标志,如果为0,则调用第一张表,如果为2,则调用第二张表。

  大于12位的值其实全部是忽略的。

  

四、找到要执行的函数

  如图,通过第0-11位作为序号,找到函数地址表和函数参数表。

  以参数表中的数值作为开辟新的栈的大小,之后开辟新的栈,将参数传入进来,之后根据函数地址表来调用内核函数。

  

 五、nt!KiFastCallEntry反汇编代码分析

  结合上面内容以及windgb实操来理解下面的反汇编代码。

  1 nt!KiFastCallEntry:
  2 83e8d0c0 b923000000      mov     ecx,23h
  3 83e8d0c5 6a30            push    30h
  4 83e8d0c7 0fa1            pop     fs
  5 83e8d0c9 8ed9            mov     ds,cx
  6 83e8d0cb 8ec1            mov     es,cx
  7 83e8d0cd 648b0d40000000  mov     ecx,dword ptr fs:[40h]
  8 83e8d0d4 8b6104          mov     esp,dword ptr [ecx+4]
  9 83e8d0d7 6a23            push    23h
 10 83e8d0d9 52              push    edx
 11 83e8d0da 9c              pushfd
 12 83e8d0db 6a02            push    2
 13 83e8d0dd 83c208          add     edx,8
 14 83e8d0e0 9d              popfd
 15 83e8d0e1 804c240102      or      byte ptr [esp+1],2
 16 83e8d0e6 6a1b            push    1Bh
 17 83e8d0e8 ff350403dfff    push    dword ptr ds:[0FFDF0304h]
 18 83e8d0ee 6a00            push    0
 19 83e8d0f0 55              push    ebp
 20 83e8d0f1 53              push    ebx
 21 83e8d0f2 56              push    esi
 22 83e8d0f3 57              push    edi
 23 83e8d0f4 648b1d1c000000  mov     ebx,dword ptr fs:[1Ch]  // fs:[1ch] 为SelfProc,故 ebx 指向自己
 24 83e8d0fb 6a3b            push    3Bh
 25 83e8d0fd 8bb324010000    mov     esi,dword ptr [ebx+124h] // esi指向当前线程 KTHREAD(也是ETHREAD,ETHREA包含KTHREAD且在头部)
 26 83e8d103 ff33            push    dword ptr [ebx]
 27 83e8d105 c703ffffffff    mov     dword ptr [ebx],0FFFFFFFFh
 28 83e8d10b 8b6e28          mov     ebp,dword ptr [esi+28h]
 29 83e8d10e 6a01            push    1
 30 83e8d110 83ec48          sub     esp,48h
 31 83e8d113 81ed9c020000    sub     ebp,29Ch
 32 83e8d119 c6863a01000001  mov     byte ptr [esi+13Ah],1
 33 83e8d120 3bec            cmp     ebp,esp
 34 83e8d122 7597            jne     nt!KiFastCallEntry2+0x49 (83e8d0bb)
 35 83e8d124 83652c00        and     dword ptr [ebp+2Ch],0
 36 83e8d128 f64603df        test    byte ptr [esi+3],0DFh
 37 83e8d12c 89ae28010000    mov     dword ptr [esi+128h],ebp
 38 83e8d132 0f8538feffff    jne     nt!Dr_FastCallDrSave (83e8cf70)
 39 83e8d138 8b5d60          mov     ebx,dword ptr [ebp+60h]
 40 83e8d13b 8b7d68          mov     edi,dword ptr [ebp+68h]
 41 83e8d13e 89550c          mov     dword ptr [ebp+0Ch],edx
 42 83e8d141 c74508000ddbba  mov     dword ptr [ebp+8],0BADB0D00h
 43 83e8d148 895d00          mov     dword ptr [ebp],ebx
 44 83e8d14b 897d04          mov     dword ptr [ebp+4],edi
 45 83e8d14e fb              sti
 46 83e8d14f 8bf8            mov     edi,eax
 47
 48 // 判断12位是0还是1,然后决定使用那张表
 49 // 计算结果 ecx与edi  为 0h 或者 10h
 50 83e8d151 c1ef08          shr     edi,8
 51 83e8d154 83e710          and     edi,10h
 52 83e8d157 8bcf            mov     ecx,edi // ECX中存储的值为0x00或者0x10(调用号大于0x1000的话)
 53
 54
 55 // 注意,ServiceTable表开始部分位于 [esi+0BCh] 指针处
 56 // 该地址Notoskrl.exe的表。
 57 // 下一个表结构是Win32k.sys的表
 58 // 因为我们根据表结构,一张表10h(4个成员,每个成员4字节)
 59 // 所以若为win32K.sys, add 10h,自然跳转到关于win32k.sys的这张表
 60 83e8d159 03bebc000000    add     edi,dword ptr [esi+0BCh] // 存储 ServiceTable  这张表
 61
 62 // 系统服务号存到ebx备份一份
 63 83e8d15f 8bd8            mov     ebx,eax // 系统服务号存到ebx备份一份
 64 83e8d161 25ff0f0000      and     eax,0FFFh // 系统调用号,只需要12后12为
 65
 66 // 比较该函数索引号与表函数个数判读,如果索引号>=函数表个数,则说明函数不在这张表中,触发异常
 67 83e8d166 3b4708          cmp     eax,dword ptr [edi+8]
 68 83e8d169 0f8333fdffff    jae     nt!KiBBTUnexpectedRange (83e8cea2)
 69
 70 // 若没有越界,则判断是哪个系统表win32k.sys
 71 // 如果是调用win32k.sys,则执行下面这部分函数,win32k.sys跟图形界面相关,关于动态加载的问题(nt!KeGdiFlushUserBatch。
 72 // 如果是调用Notoskrl.exe,则直接跳转到 83e8d18e
 73 83e8d16f 83f910          cmp     ecx,10h
 74 83e8d172 751a            jne     nt!KiFastCallEntry+0xce (83e8d18e)
 75 83e8d174 8b8e88000000    mov     ecx,dword ptr [esi+88h]
 76 83e8d17a 33f6            xor     esi,esi
 77 83e8d17c 0bb1700f0000    or      esi,dword ptr [ecx+0F70h]
 78 83e8d182 740a            je      nt!KiFastCallEntry+0xce (83e8d18e)
 79 83e8d184 52              push    edx
 80 83e8d185 50              push    eax
 81 83e8d186 ff154c99fb83    call    dword ptr [nt!KeGdiFlushUserBatch (83fb994c)] // win
 82 83e8d18c 58              pop     eax
 83 83e8d18d 5a              pop     edx
 84
 85 // 若为 notoskrl.exe中,从83e8d172直接跳转过来;如果为win32.sys,则需要执行上边过程
 86 83e8d18e 64ff05b0060000  inc     dword ptr fs:[6B0h] // KPCR->+0x6B0 KeSystemCalls 系统调用个数+1
 87 83e8d195 8bf2            mov     esi,edx // edx存储着三环传入函数的指针
 88 83e8d197 33c9            xor     ecx,ecx // 将ecx清零
 89 83e8d199 8b570c          mov     edx,dword ptr [edi+0Ch] //_SYSTEM_SERVICE_TABLE+0ch,得到SSDT参数表地址
 90 83e8d19c 8b3f            mov     edi,dword ptr [edi]    // _SYSTEM_SERVICE_TABLE+0h,函数表的地址
 91 83e8d19e 8a0c10          mov     cl,byte ptr [eax+edx] // eax系统调用号 参数表*系调用号得到的参数个数cl。
 92 83e8d1a1 8b1487          mov     edx,dword ptr [edi+eax*4] // 真正的函数地址edx = eax函数索引*4+edi指向参数地址表
 93 83e8d1a4 2be1            sub     esp,ecx   // 提升堆栈,有多少参数提升多少个
 94 83e8d1a6 c1e902          shr     ecx,2    // 参数总长度/4 == 参数复制的次数(因为在83e8d1b7处使用rep指令一次复制四个字节)
 95 83e8d1a9 8bfc            mov     edi,esp // 设置要复制的地址
 96
 97 //esi存储调用内核函数的指针,跟用户地址函数能访问的最大范围进行判断,如果超出了则跳转到错误处理模块
 98 83e8d1ab 3b351c97fb83    cmp     esi,dword ptr [nt!MmUserProbeAddress (83fb971c)]
 99 83e8d1b1 0f832e020000    jae     nt!KiSystemCallExit2+0xa5 (83e8d3e5)
100
101 // 复制函数参数
102 83e8d1b7 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
103
104
105 // 下面来进行某些必要的检测
106 83e8d1b9 f6456c01        test    byte ptr [ebp+6Ch],1
107 83e8d1bd 7416            je      nt!KiFastCallEntry+0x115 (83e8d1d5)
108 83e8d1bf 648b0d24010000  mov     ecx,dword ptr fs:[124h]
109 83e8d1c6 8b3c24          mov     edi,dword ptr [esp]
110 83e8d1c9 89993c010000    mov     dword ptr [ecx+13Ch],ebx
111 83e8d1cf 89b92c010000    mov     dword ptr [ecx+12Ch],edi
112 83e8d1d5 8bda            mov     ebx,edx
113 83e8d1d7 f6050869f88340  test    byte ptr [nt!PerfGlobalGroupMask+0x8 (83f86908)],40h
114 83e8d1de 0f954512        setne   byte ptr [ebp+12h]
115 83e8d1e2 0f858c030000    jne     nt!KiServiceExit2+0x17b (83e8d574)
116
117 // 如果上面检测没问题,则开始执行函数
118 83e8d1e8 ffd3            call    ebx
119
120 // 判断执行结果并返回给用户层
121 83e8d1ea f6456c01        test    byte ptr [ebp+6Ch],1
122 83e8d1ee 7434            je      nt!KiFastCallEntry+0x164 (83e8d224)
123 83e8d1f0 8bf0            mov     esi,eax
124 83e8d1f2 ff156801e583    call    dword ptr [nt!_imp__KeGetCurrentIrql (83e50168)]
125 83e8d1f8 0ac0            or      al,al
126 83e8d1fa 0f853b030000    jne     nt!KiServiceExit2+0x142 (83e8d53b)
127 83e8d200 8bc6            mov     eax,esi
128 83e8d202 648b0d24010000  mov     ecx,dword ptr fs:[124h]
129 83e8d209 f68134010000ff  test    byte ptr [ecx+134h],0FFh
130 83e8d210 0f8543030000    jne     nt!KiServiceExit2+0x160 (83e8d559)
131 83e8d216 8b9184000000    mov     edx,dword ptr [ecx+84h]
132 83e8d21c 0bd2            or      edx,edx
133 83e8d21e 0f8535030000    jne     nt!KiServiceExit2+0x160 (83e8d559)
134 83e8d224 8be5            mov     esp,ebp
135 83e8d226 807d1200        cmp     byte ptr [ebp+12h],0
136 83e8d22a 0f8550030000    jne     nt!KiServiceExit2+0x187 (83e8d580)
137 83e8d230 648b0d24010000  mov     ecx,dword ptr fs:[124h]
138 83e8d237 8b553c          mov     edx,dword ptr [ebp+3Ch]
139 83e8d23a 899128010000    mov     dword ptr [ecx+128h],edx

  

  

原文地址:https://www.cnblogs.com/onetrainee/p/11713969.html

时间: 2024-10-07 07:43:33

Windows系统调用中的系统服务表的相关文章

Windows系统调用中的系统服务表描述符

 Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中的系统服务表描述符 在前面,我们将解过 系统服务表.可是,我们有个疑问,系统服务表存储在哪里呢? 答案就是:系统服务表 存储在 系统服务描述符表中.(其又称为 SSDT Service Descriptor Table)  一.使用PELord函数从ntoskrnl.exe文件中查看SSDT导出函数 如图,可以看出KeServiceDes

Windows系统调用中API从3环到0环(下)

 Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中API从3环到0环(下) 如果对API在三环的部分不了解的,可以查看 Windows系统调用中的API三环部分(依据分析重写ReadProcessMemory函数 上篇:Windows系统调用中API从3环到0环(上) 这篇文章分为上下两篇,其中上篇初步讲解大体轮廓,下篇着重通过实验来探究其内部实现,最终分析两个函数(快速调用与系统中断)

64位Windows操作系统中的注册表

x64系统上有x64.x86两种注册表,记录下. 64 位Windows系统中的注册表分为 32 位注册表项和 64 位注册表项,许多 32 位注册表项与其相应的 64 位注册表项同名. 在64位版本系统的注册表编辑器中,32 位注册表项显示在以下注册表项下: HKEY_LOCAL_MACHINE\Software\WOW6432Node 使用默认的 64 位版本注册表编辑器%systemroot%\Syswow64\regedt.exe,可以查看或编辑 64 位和 32 位的注册表项和项值.

Windows系统调用中API的3环部分(依据分析重写ReadProcessMemory函数)

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中API的3环部分 一.R3环API分析的重要性 Windows所提供给R3环的API,实质就是对操作系统接口的封装,其实现部分都是在R0实现的. 很多恶意程序会利用钩子来钩取这些API,从而达到截取内容,修改数据的意图. 现在我们使用olldbg对ReadProcessMemory进行跟踪分析,查看其在R3的实现,并根据我们的分析来重写一个

Windows系统调用中的现场保存

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中的现场保存 我们之前介绍过三环进零环的步骤,通过中断或者快速调用来实现. 但是我们是否考虑过CPU从三环进入零环时,其三环的寄存器该如何保存. 这一篇文件就来介绍其系统调用中的(三环)现场保存的问题. 一.几个重要的结构体介绍 1. _Ktrap_frame 该结构体简单来说用于三环的寄存器保存,存储于零环,由操作系统维护 详细信息可以查看

[转载]Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取

原文地址:点击打开链接 为什么要写这篇文章 1.      因为最近在学习<软件调试>这本书,看到书中的某个调试历程中讲了Windows的系统调用的实现机制,其中讲到了从Ring3跳转到Ring0之后直接进入了KiFastCallEntry这个函数. 2.      碰巧前天又在网上看到了一篇老文章介绍xxx安全卫士对Windows系统调用的Hook,主要就是Hook到这个函数 3.      刚刚做完毕业设计,对使用中断来实现系统调用的方式记忆犹新. 以上原因导致我最近眼前总是出现系统调用这

windows端口号速查表

windows端口号速查表 1 tcpmux TCP 端口服务多路复用  5 rje 远程作业入口  7 echo Echo 服务  9 discard 用于连接测试的空服务  11 systat 用于列举连接了的端口的系统状态  13 daytime 给请求主机发送日期和时间  17 qotd 给连接了的主机发送每日格言  18 msp 消息发送协议  19 chargen 字符生成服务:发送无止境的字符流  20 ftp-data FTP 数据端口  21 ftp 文件传输协议(FTP)端口

windows 7中修改用户配置文件的路径

在windows 7中用户配置文件的默认位置是在c:\users文件夹中.我建议最好在安装完操作系统之后就将用户配置文件的默认位置改变到其他分区. Warning在视图更改注册表之前,请备份好注册表相关键值. 1. 将c:\user文件夹Copy到新的位置(默认情况下 "Default" directory 是隐藏的,请到 Tools > Folder Options > View (tab) > Show Hidden files, folders, and dri

实体类在Windows程序中的高级应用--------------------》》心境是一种境界。

一.事务 我们在大家学到这,或多或少对事务都有一些理解了.今天的我也对事务有了更深一层的理解对我来说,我想与大家一起分享一下. 解析: 1.ADO.NET提供了事务处理功能 2.C#中开启事务 3.在咱们的SQL后台就不用开启事务了 4.eg.我要在FrmSW的窗体上添加年级,我们首先在数据库中在年级表中对其GradeName设置唯一约束,如果GradeName重复则事务会将其回滚,如GradeName不重复就会输出. string str = "data source=.;initial ca