x64 IA-32e


win10 x64内核 IA-32e 笔记

0x0 前言

21年11月份学习了32位的内核,但是准备腾讯比赛发现,是给的64位驱动,所以学习64位。

0x1 x86到x64的改变

IA-32e 模式:内核64位,用户64或32位

​ 强制平坦段,不支持任务切换

Legacy 模式:内核32位,用户32位

​ 支持非平坦段,任务切换,虚拟8086,实模式等

IA-32e:代码段,数据段仍使用64位描述符,强制平坦(FS, GS 除外)

​ TSS段描述符扩展到128位

​ TSS段不用来任务切换,主要保存一堆rsp备用指针

​ 中断门描述符扩展到128位

IA32_EFER_MSR C0000080H

IA32_FS_BASE C0000100H

IA32_GS_BASE C0000101H

IA32_KERNEL_GS_BASE C0000102H

权限切换

系统调用:x64用户程序通过,syscall 进入内核

​ x86用户程序在 ring3 转入 x64 模式再进入内核

中断:只使用了一张idt表,内核可以根据栈上的保存cs判断先前模式

0x2 EFER_MSR

4

可以看见第8位是1 当前系统为64位。

IA-32e模式兼容 0x86 和 0x64 转换的时候不是cpu转换成32位,而是一直在IA-32e模式上。

0x3 GDT表

相比于32位,64位的gdt表描述符会特别少。弱化了段保护。

1

L 决定是否处于64位还是32位

64位cs的段描述符,可以看见没有对描述符做扩展。虚拟地址从32位改变为64位,但是没有扩展。现在的段描述符没有了基址界限(base address limiti)

基址64位现在就放不下,就引出了一个新概念强制平坦 所以现在代码段和数据段仍用了64位描述符

0x4 TSS段描述符改为128位

5

先找一个TSS段,然后查看基址发现什么也没有

6

现在应该找 高位的 fffff801+ 5420200 就能找到TSS段了

TSS段的内容也改变了

2

32位TSS段储存的都是一堆寄存器,现在储存的都是IST指针

7

0的位置空,直接偏移+4 就是RSP0 就是0环的RSP指针 如果一个3环要切换到0环,就会把寄存器放在这个RSP0里面

0x5 IDT表改变成128位

IDT表现在储存的都是中断门描述符

8

可以看到地址是 fffff801+4fa0+0500 学过32位内核的应该知道还是差不多的寻找方法

3

可以看一下改变成128位的idt,主要理解里面的IST 占了3位

9

有什么作用呢,我们可以看一下IST的位置 大多数都是设置为0,可以看一下上面的TSS表,就是对应其中的IST寄存器指针,等于多少的时候,就代表IST几指针寄存器(如04,对应IST4)对应不同的中断

10

可以看一下不同的中断对应的效果,比如2号中断,cpu强制校验,会给一个特殊的栈,8号中断DoubleFault就是蓝屏了 栈已经找不到,就会给一个栈。只要后面没有标记 Stack的就代表没有使用了IST栈指针。

现在idt表存储的都是中断门描述符,陷阱门和调用门,windows不用,任务门是已经不支持了

11

可以看一下 第三中断 就是int 3 (可以在自己电脑上拿ntoskrenl.exe 拉ida)

32位进入的时候要求内核的fs指向KPCR

在64位的时候就变成了不在内核fs指向KPCR,而是用gs寄存器指向KPCR,fs就留给32位用。

注意(强制平坦对 FS,GS是没有用的)

既然FS,GS没有扩展,那怎么办呢,提供了两个地址到这里寻找。

IA32_FS_BASE C0000100H

IA32_GS_BASE C0000101H

FS是读取不到的,因为这个上面说了是针对32位用户的,在内核无法读取

12

而且在用户态时,地址也会一直有改变

13

GS是有的,指向的就是KPCR

11

再看一下这个图,现在在64位内核里不直接写gs的值,(32位的时候都是 push 30h pop fs 这样写进) 现在是直接使用 swapgs指令 把当前的gs基址和gs_base切换

IA32_KERNEL_GS_BASE C0000102H 改变指向KPCR

14

存储了0环进系统之前的某一个TEB

0x6 总结

写笔记记录一下加深记忆,同时分享给大家。忘记了有笔记可以快速回顾。


文章作者: Blue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Blue !
评论
  目录