1、代码间的跳转(段间跳转、非调用门值类的)
1、同时修改CS和EIP的指令
JMP FAR/CALL FAR/RETF/INT/IRETED
2、只改变EIP的指令
JMP/CALL/JCC/RET
3、JMP 0x20:0x004183D7 CPU如何执行这行代码?
-首先JMP后面跟了6个字节,分别是0020:004183D7
-0x0020是两个字节,0x004183D7是第四个字节
-如果是这样的话 JMP 0x004183D7,CPU直接修改EIP的值,不需要查表
-JMP 0x20:0x004183D7对于这种指令我们称之为常跳转,这种指令需要进入零环,需要查表,查那一张表是由指令本身决定的
-第一步、段选择子拆分
0x20 对应二进制形式 0000 0000 0010 0000
Index = 二进制0000 0000 0010 0 = 4:说明查询GDT表中下标为4的项
TI = 二进制0 = 0
RPL = 二进制00 = 0
-第二步、查表得到段描述符(通过0x20找到对应的段)
TI = 0:说明需要查询GDT表
Index = 4:找到对应的段描述符
段描述符只有四种情况可以跳转:代码段、调用们、TSS任务段、任务门、(如果0x20对应的是数据段,那么跳转失败)
-第三步、段权限检查
如果是非一直代码段,要求 CPL == DPL && RPL <= DPL (CPL是当前CPU的特级权限)
如果是一直代码段,要求 CPL >= DPL
-第四步、加载段描述符
通过上面的权限检查后,CPU会将段描述符加载到CS段寄存器中
-第五步、执行代码
CPU将CS.Base + Offset(偏移的值)的值写入EIP,然后执行CS:EIP处的代码,段间跳转结束
RPL 我以什么样的权限访问你
DPL 如果你要访问我,你需要具备什么样的权限
拓展、
有点不明白,就算用0x20限制了,我直接JMP 0x004183D7就可以访问任何地址啊,还要这个段间跳转有什么用呢?
答:保护模式是保护内存,主要通过段机制和页机制来保护。当我们启动OD时,
发现段寄存器中的值(除了FS)起始位置和界限没有区别,
但是 WORD Attribute //属性 段描述符高四字节的第8位开始 到第23位结束 是有区别的
例如:一个地址是0x12345678当用段地址A修饰的时候,这个地址可以访问
当用段地址B修饰的时候,这个地址就不可以访问。这就是段的作用
-段的作用主要是保护GDT表和IDT表,GDT一张表是内存,有保护
实验、
1、我修改段描述符的base后无法执行,例如:0x00cffb00:0x0001ffff
2、在JMP far成功后,在OD中发现CS段的base和Limit永远都是0
3、高权限的如何访问低权限的段?
4、记住以上的流程
总结:
对于一致代码段,也就是共享的段
^ 特权高级的程序不允许访问特权级低的数据:核心态不允许访问用户态的数据
^ 特权级低的程序可以访问到特权级高的数据,但特权级不会改变:用户态还是用户态
q
对于普通代码段:也就是非一直代码段
^ 只允许同级别访问
^ 绝对进制不同级别的访问:核心态不是用户,用户态也不是核心态
------------------------------------------------------------------------------------------------------------
执行流程
思考:CPU如何执行 JMP 0x20:0x004183D这行指令
1)段选择子拆分
0x20 二进制:0000 0000 0010 0000 即
RPL = 00
TI = 0
Index = 4
1
2
3
2)查表得到段描述符
TI=0:查GDT表
Index=4:找到对应的段描述符
四种情况可以跳转:
代码段
调用门
TSS任务段
任务门
3)权限检查
一致代码段:要求 CPL >= DPL
非一致代码段:要求 CPL == DPL并且 RPL <= DPL
4)加载段描述符
通过上面的权限检查后,CPU会将段描述符加载到CS段寄存器中
5)代码执行
CPU 将 CS.Base + Offset的值写入EIP,然后执行CS:EIP处的代码
段间跳转到此结束
6)总结
一致代码段(共享的段)
特权级高的程序不允许访问特权级低的数据:核心态不允许访问用户态的数据
特权级低的程序可以访问到特权级高的数据,但特权级不会改变:用户态还是用户态
非一致代码段(普通代码段)
只允许同级访问
绝对禁止不同级别的访问:核心态不是用户态,用户态也不是核心态
注意:直接对代码段进行JMP 或者 CALL的操作,无论目标是一致代码段还是非一致代码段,CPL都不会发生改变.如果要提升CPL的权限,只能通过调用门