Windows系统调用中的系统服务表描述符
|
?Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html Windows系统调用中的系统服务表描述符 在前面,我们将解过 系统服务表。可是,我们有个疑问,系统服务表存储在哪里呢? 答案就是:系统服务表 存储在 系统服务描述符表中。(其又称为 SSDT Service Descriptor Table)
? ? ?一、使用PELord函数从ntoskrnl.exe文件中查看SSDT导出函数 如图,可以看出KeServiceDescriptorTable导出函数。 通过该函数可以查找SSDT表的位置。
? 二、通过Windbg来内存中查看SSDT表 使用Windbg,可以使用 kd> dd nt!KeServiceDescriptorTable 指令来查看SSDT表。 但该指令存在缺点,可以看到第二张表为0,说明如果使用KeServiceDescriptorTable这个公开的导出函数,我们无法看到win32k.sys这张表结构 kd> dd nt!KeServiceDescriptorTable 为了解决上面这个问题,我们只能使用另外一个指令,该指令对应的是一个未公开导出的函数。 如下,可以看到其第二行,win32k.sys系统服务表已经可见。 kd> dd KeServiceDescriptorTableShadow 三、验证ReadMemory真正的内核实现部分 我们在这篇《Windows系统调用中API的三环部分(依据分析重写ReadProcessMemory函数)》中曾提到过直接使用快速调用来摒弃R3层层封装的API,其中给eax一个函数号,现在我们来实战刨析一下。 mov eax,0x115 mov edx,0X7FFE0300 如下,系统描述符的数据结构,其依次分别为
其依次分别为 ServiceTable 83e89d9c,Count 00000000,ServiceLimit ?00000191,ServiceTable?83e8a3e4 使用Windbg来查看其115h序号的函数地址 115h*4 + 83e89d9c (ServiceTable) 得到函数地址为?8406c82c kd> dd 115h*4 + 83e89d9c 再对此进行反汇编可得 kd > u 8406c82c 之后,我们查看该nt!NtReadVirtualMemory函数的参数个数 kd > db 83e8a3e4 + 115
四、通过修改SSDT表增添系统服务函数 我们在 Windows系统调用中API的三环部分(依据分析重写ReadProcessMemory函数) 调用的是 115h 号函数。 现在,我们将该函数地址放到 191 号函数处(之前一共有191个函数,占据0-190位)。 修改思路: 1)将 nt!NtReadVirtualMemory 函数地址 8406c82c 放到 191号处(83e89d9 + 191h*4) kd> ed 83e89d9 + 191h*4 8406c82c 2)? 增大 服务表最大个数。 (因为我们上一节分析其反汇编代码的时候,发现其会进行最大个数的判断) kd> ed 83f75a00+8 192 3)? 修改参数个数表中对应的191号参数个数。(我们之前查阅过其为 14,以字节为单位) kd> eb?83e8a3e4+191 14 4)? 之后,我们运行下列代码。其与《Windows系统调用中API的三环部分(依据分析重写ReadProcessMemory函数)》唯一的不同调用函数号为192,最终效果完全一样。 1 #include "pch.h"
2 #include <iostream>
3 #include <algorithm>
4 #include <Windows.h>
5 void ReadMemory(HANDLE hProcess,PVOID pAddr,PVOID pBuffer,DWORD dwSize,DWORD *dwSizeRet)
6 {
7
8 _asm
9 {
10 lea eax,[ebp + 0x14]
11 push eax
12 push[ebp + 0x14]
13 push[ebp + 0x10]
14 push[ebp + 0xc]
15 push[ebp + 8]
16 sub esp,4
17 mov eax,0x192 // 注意:修改的是这里
18 mov edx,0X7FFE0300 //sysenter不能直接调用,我间接call的
19 CALL DWORD PTR[EDX]
20 add esp,24
21
22 }
23 }
24 int main()
25 {
26 HANDLE hProcess = 0;
27 int t = 123;
28 DWORD pBuffer;
29 //hProcess = OpenProcess(PROCESS_ALL_ACCESS,a);
30 ReadMemory((HANDLE)-1,(PVOID)&t,&pBuffer,sizeof(int),0);
31 printf("%Xn",pBuffer);
32 ReadProcessMemory((HANDLE)-1,&t,0);
33 printf("%Xn",pBuffer);
34
35 getchar();
36 return 0;
37 }
(编辑:邯郸站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |




