系统服务的调用过程
一、CPU的内部支持
1. int 0x2e 进入 iret返回 (中断门切换)
★.利用中断进入内核,0x2e对应的是KiSystemService
★.每个处理器有一个任务环境,初始化时系统会给CPU在GDT中构造TSS段,并且记录在KPCR中,其中记录着内核栈的地址。线程切换的时候会把处理器的TSS.ESP0 设置为当前的内核栈地址
所以r3和r0使用的是不同的栈
★.iret从内核栈中弹出eip cs eflag esp ss 返回用户态
2. sysenter sysexit
★.IA32_SYSENTER_CS IA32_SYSENTER_ESP IA32_SYSENTER_EIP在系统初始化时被设置,分别保存指定跳转后的 cs、ss; esp ; eip
★.sysenter指令将装载这些寄存器 切换到r0。 继续执行sysexit则负责恢复这些寄存器并且回到r3,ecx是用户态的esp,edx是eip
二、系统的切换实现
NtCreateFile
kd> u ntdll!ntcreatefile
ntdll!ZwCreateFile:
7c9511f8 b827000000 mov eax,27h ;系统服务号
7c9511fd ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c951202 ff12 call dword ptr [edx]
7c951204 c22c00 ret 2Ch
支持快速系统调用的话,edx里存的是这个值
kd> u 7c95ed50 ntdll!KiFastSystemCall:
7c95ed50 8bd4 mov edx,esp
7c95ed52 0f34 sysenter ;走KiFastCallEntry
ntdll!KiFastSystemCallRet:
7c95ed54 c3 ret
不支持的话,调用到这里
ntdll!KiIntSystemCall:
7c95ed60 8d542408 lea edx,[esp+8]
7c95ed64 cd2e int 2Eh ;走KiSystemService
7c95ed66 c3 ret
不管走哪种方式