Windows保护模式学习笔记(二)—— 代码跨段跳转

要点回顾

段寄存器:
ES,CS,SS,DS,FS,GS,LDTR,TR
除CS外,其他的段寄存器都可以通过MOV,LES,LSS,LDS,LFS,LGS指令进行修改

思考:CS为什么不可以直接修改呢?
CS的改变意味着EIP的改变,改变CS的同时必须修改EIP,所以我们无法使用上面的指令来进行修改.


代码跨段跳转

段间跳转分为两种情况:

  1. 要跳转的段是一致代码段
  2. 要跳转的段是非一致代码段

同时修改CS与EIP的指令:
JMP FAR / CALL FAR / RETF / INT /IRETED

只改变EIP的指令:
JMP / CALL JCC / RET

执行流程

思考:CPU如何执行 JMP 0x20:0x004183D这行指令

1)段选择子拆分

0x20 二进制:0000 0000 0010 0000 即

RPL = 00
TI = 0
Index = 4
2)查表得到段描述符

TI=0:查GDT表
Index=4:找到对应的段描述符
四种情况可以跳转:

  1. 代码段
  2. 调用门
  3. TSS任务段
  4. 任务门
3)权限检查

一致代码段:要求 CPL >= DPL
非一致代码段:要求 CPL == DPL并且 RPL <= DPL

4)加载段描述符

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

5)代码执行

CPU 将 CS.Base + Offset的值写入EIP,然后执行CS:EIP处的代码

段间跳转到此结束

6)总结
一致代码段(共享的段)
  1. 特权级的程序不允许访问特权级的数据:核心态不允许访问用户态的数据
  2. 特权级的程序可以访问到特权级的数据,但特权级不会改变:用户态还是用户态
非一致代码段(普通代码段)
  1. 只允许同级访问
  2. 绝对禁止不同级别的访问:核心态不是用户态,用户态也不是核心态

注意:直接对代码段进行JMP 或者 CALL的操作,无论目标是一致代码段还是非一致代码段,CPL都不会发生改变.如果要提升CPL的权限,只能通过调用门

实验

第一步:

复制一个非一致代码段描述符,写入GDT表空白处
复制段描述符
在这里插入图片描述

第二步:

在OD中执行 JMP FAR 命令

执行前,CS = 001B
执行前
执行后,CS = 004B
执行后
执行成功!

第三步:

将段描述符的 DPL 置为 0,再在OD中执行JMP FAR命令
DPL置0
执行前
执行后,程序进入了ntdll,也就是异常模块,说明执行失败
执行后
失败原因
要跳转的代码段是一个非一致代码段(DPL=0),而程序的CPL=3,权限检查未通过
非一致代码段要求CPL=DPL时才允许跳转

这样设计的目的是防止3环的程序跳转到系统段执行

第四步:

将段描述符Type域C位改为1,令其成为一致代码段
Type域C=1
再次执行JMP FAR命令
执行前
执行后
执行成功!

总结

一、为了对数据进行保护,普通代码段禁止用户态的代码/数据和内核态的代码/数据相互访问

二、如果选择一致代码段,低级别的程序就可以在不提升CPL权限等级的情况下进行访问,并且不会破坏内核态的数据

三、如果想访问普通代码段,必须通过"调用门"等方式提升CPL权限

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值