API函数调用过程3环
比较重要的3环DLL:
Kernel32.dll
User32.dll
GDI32.dll
Ntdll.dll
以ReadProcessMemory为例
对于大部分3环的WinAPI,都只是一个接口,
例如ReadProcessMemory是三环的函数,由kernel32.dll提供,而该函数只是调用了NtReadVirtualMemory
基本上带Nt开头函数,都是由Ntdll.dll提供,而Ntdll.dll是进0环的一个dll,所以在
ntdll中可以发现,mov eax, 3Fh
,这里提供了一个编号,通过这个编号,找到对应的函数,进入0环
API函数调用过程 3环进0环
_KUSER_SHARED_DATA
在User层和Kernel层分别定义了一个_KUSER_SHARED_DATA结构区域,用于共享数据
使用固定的地址值进行映射,
User层中的地址为0x7FFE0000
Kernel层中的地址为0xFFDF0000
指向的是同一个物理页,但在User层是只读,Kernel层是可写的
进0环需要修改哪些寄存器:
- CS的权限由3变为0,意味着需要新的CS
- SS与CS的权限永远一致,需要新的SS
- 权限发生切换的时候,堆栈也需要切换,需要新的ESP
- 进0环后代码的位置,需要EIP
是否支持快速调用
支持:ntdll.dll!KiFastSystemCall
mov edx, esp
sysenter
不支持:ntdll.dll!KiIntSystemCall
该函数通过中断门的方式实现3环进0环,
lea edx, [esp+arg_4]
int 2Eh
retn
不管是通过快速调用还是通过中断门方式,其本质都是一样的,都是通过寻找CS、SS、ESP、EIP四个寄存器的方式进入0环。
中断门的方式进入0环,需要的CS、EIP在IDT表中,所以需要查内存,SS和ESP由TSS提供
而快速调用的本质就是绕过查内存,直接将CS、SS、ESP、EIP的值存储到MSR寄存器中,通过查MSR寄存器提高进入0环的速度,所以称为快速调用
通过中断门进0环:
- 固定中断号为0x2E
- CS/EIP由门描述符提供 ESP/SS由TSS提供
- 进入0环后执行的内核函数:NT!KiSystemService
通过sysenter指令进入0环:
- CS/ESP/EIP由MSR寄存器提供,SS不是直接存在MSR寄存器中的,而是通过计算得到的
- 进入0环后执行的内核函数:NT!KiFastCallEntry
内核模块:ntoskrnl.exe/ntkrnlpa.exe
未完待续。。。
Comments NOTHING