内核模式和用户模式
简单的说就是操作系统将一块块内存中的结构体设置了flags检查,内核模式下可以全局访问,用户模式下只能访问用户内容。在windows中常习惯称为ring 0和ring 3。
ring 3访问ring 0内容
既然做了权限检查,而ring 3进程肯定是会要访问ring 0内容,毕竟创建的时候就需要往ring 0里写结构了。
在windows中有常见两种方式。
使用int 2e切换
在windows系统中,使用int 2e进入陷阱门调用系统服务进行模式切换,从ring 3进入ring 0。
在调用系统服务进入ring 0时,系统会自动将cpu中的环境设置好,其中包括1.权限检查,2.内核模式下的栈
,然后进入调用KiSystemService()查询到真正要使用的内核内容。
使用快速系统调用
在上面进入方式中,需要查找在内存中的服务,快速调用是用寄存器取代内存查找。
® 在全局描述符表(GDT)中建立4个段描述符,分别用来描述供SYSENTER 指令进入内核模式时使用的代码段(CS)和栈段(SS),以及SYSEXIT指令从内核模式返回用户模式时使用的代码段和栈段。
® SYSENTER/SYSEXIT 用于指定新的程序指针,也就是SYSENTER指令要跳转到的目标例程地址。Windows系统会将其设置为KiFastCallEntry的地址,因为KiFastCallEntry例程时Windows内核中专门用来受理快速系统调用的。SYSENTER_CS_MSR指定新的代码段,也就是KiFastCallEntry所在的代码段。SYSENTER_ESP_MSR用于指定新的栈指针(ESP)。新的栈段由SYSENTER_CS_MSR加8得来
® 将一小段名为SystemCallSub的代码复制到SharedUserData内存区,该内存区会被映射到每个win32进程的进程空间中。以保证当应用程序每次进行系统调用时,NTDLL.DLL中的残根(stub)函数便调用这段SystemCallStub代码。SystemCallStub的内容因系统硬件的不同而不同。