-
-
[分享] 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环跳转函数如下:
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!