段寄存器
- CS:代码段寄存器
- DS:数据段寄存器
- SS:堆栈段寄存器
- ES:附加段寄存器
- FS:在Ring3中fs:[0]的地址指向的是TEB结构
- 在Ring0中指向一个称为KPCR的数据结构,即FS段的起点与KPCR结构对齐
段寄存器读写
- 除CS段外,其他段寄存器都是可以通过MOV、LES、LSS、LDS、LFS指令修改
- CS是代码段,修改CS地址必须同时修改EIP,必须使用跳转指令
- 长跳转指令:JMP FAR、CALL FAR、RETF、INT、IRETED
- 短跳转指令:JMP、CALL、JCC、RET
JMP FAR举例
JMP 0x4B:0x456789A
- 0x4B:0X000000001001 0 11
- RPL=3、TI=0、index=9
- 进入GDT表中查询索引为9的段描述符00cf 9f00 0000ffff
- 判断段描述符是否是代码段、调用门、任务门、TSS任务段
- 假设是代码段,判断是否是一致代码段,一致代码段CPL>=DPL、非一致代码段CPL==DPL且DPL>=RPL
- 将当前段描述符加载至CS段,将CS:BASE+OFFSET的值放入EIP,然后执行CS:EIP的代码
CALL FAR举例
CALL CS:EIP(EIP是废弃的,写什么都可以)
- 跨段不提权(CPL==找打的DPL)
- 堆栈图:PUSH当前CS,PUSH返回地址
- 跨段并提权(CPL=3,DPL=0)
- 运行代码必须使用堆栈,所以SS和CS必须是一致的,提权后会导致CS变化,SS随之变化,会使用一副新堆栈,将栈顶指针SS、ESP、CS寄存器PUSH保存至堆栈中
- 从TSS中找到SS与ESP
- 也是使用RETF返回