Windows内核情景分析-系统调用3

系统调用1和系统调用2说了这么多,还未进入int 0x2e所对应的系统服务函数KiSystemService(),这里来看下这个函数内部的处理;通过0x2e和IDTR从IDT中 查询获取对应的方法KiSystemService()。

  • 所以这里 int 0x2e  对应  KiSystemService 入口
  • sysenter 对应的是 KiFastCallEntry 入口,这里不要被这些函数给搞乱了。

 系统空间堆栈

 每个线程有自己的系统空间堆栈,其系统空间的SS和ESP保存在TSS数据结构里面。TR寄存器存放当前线程的TSS地址,当从用户空间进入系统空间,CPU根据TR寄存器从TSS获取系统空间的SS和ESP。

KiSystemService()

 从SharedCode开始的代码是共同的,前奏SYSCALL_PORLOG部分则是专门针对自陷指令系统调用的。

KPCR 处理器控制区(Processor Control Region)

 Windows内核特殊的基本要求,当CPU在内核运行,那么FS指向KPCR的数据结构,且每个CPU(核心?)都有自己的KPCR结构,其次,要使ESI 指向当前线程KTHREAD结构,这两个过程将在SYSCALL_PORLOG宏中实现,再次,KPCR结构存放在固定的虚拟地址,这就可以通过构造特殊的段选择子使得其指向该地址;在保护模式中段寄存器存放的是段选择子,共16bit,特殊的结构使其最终指向GDT或者LDT,如下图:

这里就是特殊构造的段选择子(FS),使其指向KPCR结构 

KPCR结构大小0x120 Byte:

  

其中子结构PRCB 结构(部分,见下图):注意在+0x004处指向了当前运行的线程KTHREAD结构体,所以通过KPRC能够获取线程的很多信息(在线程切换后会去更新PRCB结构开始的相关数据?)

先前模式 

 指在进入KiSystemService这个函数的前夕,CPU处于何种状态(系统态或者用户态);由于windows运行在内核中发起系统调用,所以如果从内核中发起的调用,那么这里先前模式就是系统态,从用户系统调用进入的则为用户态。这里通过将先前模式保存当当前线程KTHREAD结构中对应的先前模式字段中,为了可以方便,高效访问先前模式;先前模式的作用就是用来区分是从内核还是用户空间进入的,所以在系统调用返回的时候要做不同的处理。其次,系统调用是可以嵌套的了,这里会在赋值先前模式字段时,先将原有的内容入栈。KTHREAD 中字段TrapFrame也要更新指向当前的调用堆栈框架。

其次,内核版函数Zwxxxxxx(),通常就是模拟自陷指令的效果,把一些寄存器的内容压入系统空间堆栈,然后调用进行系统调用,先前模式就是系统态。

注:这里所涉及细节需要结合书籍内容理解,上面所说的并不完整,只是挑出容易让人混的内容,需要细细推敲。

参考:https://blog.csdn.net/hu3167343/article/details/7612595    

猜你喜欢

转载自blog.csdn.net/shabihundan/article/details/81490613