Windows系统调用中的系统服务表
2021-05-19 08:28
标签:erp sys tps ddb 索引 关于 操作系统 ssd mask Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中的系统服务表 如果这部分不理解,可以查看 Windows内核分析索引目录依次阅读。 我们在之前讲过系统调用过程中,给予eax一个编号,操作系统通过这个编号来执行某个内核函数。 这个函数是通过操作系统的系统服务表来查找的。 现在,我们来探究一下nt!KiFastCallEntry的反汇编代码,看看其如何查看系统服务表找到要执行的函数的。 一、系统服务表结构 Windows一共有两张表,每张表大小10h,每个成员占4h。 如图,其中函数地址表每成员四字节,函数参数表每成员一字节。 参数的数值是以字节为单位。 二、系统服务表在哪里 在Win7 32位中存于 [KTHREAD+0xbc] kd> dt _KTHREAD +0x000 Header : _DISPATCHER_HEADER ······· +0x0bc ServiceTable : Ptr32 Void ···· 该结构地址为第一个表 三、要判断使用哪个表 传入函数序号的第12位,存储的就是关于使用那个表的标志,如果为0,则调用第一张表,如果为2,则调用第二张表。 大于12位的值其实全部是忽略的。 四、找到要执行的函数 如图,通过第0-11位作为序号,找到函数地址表和函数参数表。 以参数表中的数值作为开辟新的栈的大小,之后开辟新的栈,将参数传入进来,之后根据函数地址表来调用内核函数。 五、nt!KiFastCallEntry反汇编代码分析 结合上面内容以及windgb实操来理解下面的反汇编代码。 Windows系统调用中的系统服务表 标签:erp sys tps ddb 索引 关于 操作系统 ssd mask 原文地址:https://www.cnblogs.com/onetrainee/p/11713969.html
ntdll!_KTHREAD 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
文章标题:Windows系统调用中的系统服务表
文章链接:http://soscw.com/index.php/essay/87570.html