[转](8)JMP FAR段间跳转

 

一、回顾

 

在前面的课程中我们学习了MOV和LES等修改段寄存器的指令,当时老师说过,CS寄存器比较特殊,不能用MOV和"LCS"进行修改,原因是CS和EIP共同决定下一条指令的地址,要修改CS,就必须同时修改EIP,这也是Intel没有提供"LCS"指令的原因。

 

在这里插入图片描述

 

二、JMP FAR 执行流程

 

JMP 0x20:0x004183D7

JMP修改了CS段选择子的值  RPL无论改不改都是3,修改为0也不能加载DPL为0的段描述符 进行跨权。

上面是一条 JMP FAR 指令,CPU执行该指令分为以下5步:

 

(1)拆分段选择子
0x20 = 00100 0 00
RPL = 0
TI = 0
INDEX = 4

 

(2)查GDT表得到段描述符
根据段选择子拆得的下标,找到GDT表第5项。如果P=1,S=1,TYPE高1位=1,则表明这是一个代码段,就可以进行下一步。

 

(3)权限检查
TYPE域高2位是C属性,C=0表示非一致代码段,C=1表示一致代码段。
如果是非一致代码段,要求:CPL == DPL 并且 RPL <= DPL;
如果是一致代码段,要求:CPL >= DPL。

 

(4)加载段描述符
通过上面的权限检查后,CPU会将段描述符加载到CS段寄存器中。

 

(5)执行代码
CPU将 CS.Base + Offset 的值写入EIP 然后执行CS:EIP处的代码,段间跳转结束。

 

三、练习

 

非一致代码段:

 

要求:CPL == DPL 并且 RPL <= DPL
所以,我们需要寻找P=1,DPL=11,S=1,TYPE=10??的段。
解释:我们的程序在3环,CPL=3,根据要求,DPL也一定要是3,P=1段才有效,S=1,TYPE高1位是1才是代码段,TYPE高2位是0才是非一致代码段。
观察GDT,可以发现,满足条件只有第四个,已用红色箭头标出:
在这里插入图片描述
RPL可以取00或11,TI=0,INDEX=00011,所以段选择子可以取0x18或0x1B.
打开OD,观察CS,此时CS=0x1B,为了看到CS的变化,我们取段选择子为0x18.
观察段描述符,BASE=0,LIMIT=FFFFFFFF,所以Offset可以任取,为了方便观察,我们就取EIP后面不远处的一条指令来测试。
在这里插入图片描述

 

将EIP处指令修改为 JMP FAR 0018:0046FEAD,观察执行前后EIP和CS的变化。

 

在这里插入图片描述
在这里插入图片描述

 

和预期有出入,EIP确实修改成功了,但是CS并没有变成0x18,我用原版OD,DTdebug和x64dbg测试过,结果都是一样的,CS没变。
这里我说一下我的分析:可能OD认为CS寄存器指向的段没有改变(1B和18的区别是RPL,但是在GDT里是同一个地方),所以就没更新?
OD这个特性导致我们没办法观察CS的变化,为了解决这个问题,可以把 00cffb00`0000ffff 复制一份到别处。

 

在这里插入图片描述

 

在windbg中使用eq命令可以拷贝数据

 

在这里插入图片描述

 

此时,8003f048 标记了一个段,它的值和8003f018完全相同,区别是在GDT表的位置不同。
然后我们修改段选择子为01001 0 00 或 01001 0 11,比如取前者0x48,再次执行指令,观察EIP和CS变化:
在这里插入图片描述
在这里插入图片描述

 

这次可以看到,EIP和CS都被修改了。但是还是和预想有出入,CS并没有和预想一样改成48,而是改成了4B。并且后面的32bit变成了16bit,我无法解释这些现象。观察得到的结论就是,OD或操作系统会将RPL=00的段选择子改为11.

 


 

2020年11月2日21:53:12 补充:
查阅Intel开发手册,有如下一段话:

 

Current privilege level (CPL) — The CPL is the privilege level of the currently executing program or task. It
is stored in bits 0 and 1 of the CS and SS segment registers. Normally, the CPL is equal to the privilege level of
the code segment from which instructions are being fetched. The processor changes the CPL when program
control is transferred to a code segment with a different privilege level. The CPL is treated slightly differently
when accessing conforming code segments. Conforming code segments can be accessed from any privilege
level that is equal to or numerically greater (less privileged) than the DPL of the conforming code segment.
Also, the CPL is not changed when the processor accesses a conforming code segment that has a different
privilege level than the CPL.

 

说得很清楚了,CS, SS低2位是当前CPL,因为JMP FAR之后还是在3环,所以CS低2位当然是11了。这不是你RPL能决定的。

 


 

接下来,我们把DPL改成0,再次测试

 

kd> eq 8003f048 00cf9b00`0000ffff
kd> g

 

此时CPL!=RPL,执行指令会跳到异常处理。
在这里插入图片描述

 

在这里插入图片描述

 

一致代码段:

 

一致代码段可以让用户态访问内核态(CPL=3时访问0环代码),一致代码段又叫共享段。如果有些内核代码不会对内核造成破坏的,希望用户态程序直接访问的,就可以设置成一致代码段。WINDOWS XP中没有使用一致代码段,所以这个实验我们要自己构造一致代码段。
要求:CPL >= DPL
直接修改 8003f048,将其改为DPL=0的一致代码段,然后我们在3环访问它。

 

kd> eq 8003f048 00cf9f00`0000ffff
kd> g

 

执行 JMP FAR 004B:0046FEAD 指令,观察结果。

即使把段选择子 修改为0048,也是能成功的 说明 CS的 RPL  总是3

在这里插入图片描述

 

结果和预期一致,低权限程序跳转到高权限代码段成功了。


---------------------
作者:hambaga
来源:CSDN
原文:https://blog.csdn.net/Kwansy/article/details/108813337
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值