内核喜欢抽象出句柄给用户空间
句柄, Handle, 表达处理、控制之意。内核不会直接暴露指针给用户空间,这样会增大内核风险。相反,内核抽象出Handle给用户态,不管是文件、进程、线程等对象,通过Handle可以隐藏内核细节,统一控制对象。
不可避免,内核态对于Handle必须转换成指针才能处理。ExMapHandleToPointer负责从Handle转换成Pointer. 另外还有ExMapHandleToPointerEx函数同样的功能,多一个PreviousMode参数。
Windows Handle Table采用三级表,Handle查Pointer复杂度为O(1).
Object成员表示Handle对应Object指针。
.NET和内核
.NET没有任何内核技术,完全是用户态中间件技术。
当前是内核模式还是用户模式?
Kernel提供KeGetPreviousMode宏以确定当前代码执行所属模式。
__readgsqword是双下划线开头, 属于编译器Intrinsic.
系统调用例程需要检查是否为用户空间,并做参数验证。
特权级指令
IO指令、系统级寄存器操作(用户内核模式的GDT/IDT/MSR指令等)必须在内核空间或特权级才能运行。
用户模式操作特权级指令会怎样?
用户程序操作特权级指令将导致异常发生。
用户模式可访问的地址空间
只能访问本进程用户空间,正常情况下无法访问任何其他进程的地址空间。
内核模式可访问的地址空间
除了进程本身的用户空间之外,还可以访问整个内核空间,如果有需要,甚至可以访问其他进程的用户空间。
不同进程的内核空间
所有进程的内核模式都是一样的,即内核空间只有一个,不同进程用户空间是多个。系统空间是所有进程共享的。
用户模式和内核模式的切换
用户模式 -> 内核模式
- 异常
- 中断(硬件中断或软件中断)
- 例如按下键盘或鼠标移动中断,或调用了系统调用陷入内核模式(int 2Eh或sysenter)
内核模式 -> 用户模式
- 比较简单, 例如sysexit和iret指令