首页
社区
课程
招聘
[分享] X86系统调用_上(Ring3)
发表于: 2020-6-3 21:20 5722

[分享] X86系统调用_上(Ring3)

2020-6-3 21:20
5722

1). 在操作系统调用Windows API时,无论是 Kernel32.dll 还是 User32.dll 或者是 GDI.dll 最终调用的都是 Ntdll.dll 中的函数进入R0(不调用R0的函数除外)

2). 我们以 WriteProcessMemory 函数为例子,其在 Kernel32.dll 中,我们查看其的代码实现,如下:发现其最终调用的是位于 Ntdll.dll 中的 NtWriteVirtualMemory 函数, 我们进入 Ntdll.dll 查询

3). 发现其并没有做任何处理,而是 Call  0x7FFE0300 函数, eax 的值是系统服务号(SSDT表的索引)

在这里我们需要了解R0和R3的共享内存块,也就是一个共享的结构体 _KUSER_SHARED_DATA, 其结构如下(微软目前公布的结构体成员如下):

所谓共享内存块指的是任何一个R3的进程中都有一个线性地址和R0的一个线性地址指向了同一块物理页

在回到之前 Call  0x7FFE0300函数,我们通过上面可以知道是 _KUSER_SJARED_DATA 结构体成员的

用 WinDbg 查看对应函数

用 IDA 查看函数流程, edx 指向了 R3 的ESP

发现只是调用了一个汇编指令 sysenter

在这里我们要明白,在08年前,操作系统进入0环,都是通过 INT 0x2E 进入对应的0环的分发函数, 之后用 sysenter 指令替代了调用门,因为 sysenter 指令更加的高效

通过 sysenter 进入0环,系统默认会去 MSR 寄存器中获取对应的 CS(MSRAddr: 174H)、EIP(MSRAddr: 176H)、ESP(MSRAddr: 175H)(参考INTEL白皮书)

我们用WinDbg查看对应的数据, EIP对应的0环跳转函数如下:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 2
支持
分享
最新回复 (3)
雪    币: 881
活跃值: (9856)
能力值: ( LV13,RANK:385 )
在线值:
发帖
回帖
粉丝
2
总结一下: 之前通过int 2E 进入. 后面 出了两个快速调用. sysenter 以及 sysexit  当xp后面cpu支持快速调用的时候.会为其分配三个函数. KiIntSystemCall KiFastSystemCall KiFastSystemCallRet  利用CPUID来判断是否支持快速调用. 如果不支持.则调用KiInitSystemCall 其实内部就是封装的Int 2E 如果支持则调用KiFastSystemCall 内部就是Sysenter  参考毛德操老师的 内核系统调用.
2020-6-4 09:05
2
雪    币: 1290
活跃值: (2332)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
感谢
2020-6-4 17:55
0
雪    币: 259
活跃值: (283)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
666
2020-6-4 18:00
0
游客
登录 | 注册 方可回帖
返回
//