您的位置:首页 > 其它

6-数据段权限检查

2016-09-14 15:33 267 查看
不妨先来做个实验。打开 OD,双击第一行,把代码改成
mov ax, 0x20; mov ds, ax
,然后按两下 F8 键(单步),发现很正常。如果你把代码改成
mov ax, 0x10; mov ds, ax
,按两下 F8 后,代码跳转到了一个地址以 7 开头的地方去了。



图1 这两行可以正常执行



图2 第二行不能正常执行



图3 图2中的代码执行异常会跳到这里

为了搞清这个原因,我们需要看段描述符 DPL。

段描述符的 DPL

分析段选择子 0x10 和 0x20,这两个描述符分别是
00cf9300-0000ffff
00cff300-0000ffff
,可以发现这两个描述符唯一的不同就在于 DPL 不同,第一个描述符的 DPL = 0,而第二个描述符的 DPL = 3.

原因就在这里。

DPL = 0 的数据段,只允许当前特权级为 0 的程序访问,而 DPL= 3 的数据段,允许当前特权级为 0,1,2,3的程序访问。在 OD 中,当前特权级为 3.

实验

原始数据

|--地址--|------------16进制值----------------|
8003f000  00000000`00000000 00cf9b00`0000ffff
8003f010  00cf9300`0000ffff 00cffb00`0000ffff
8003f020  00cff300`0000ffff 80008b04`200020ab
8003f030  ffc093df`f0000001 0040f300`00000fff
8003f040  0000f200`0400ffff 00000000`00000000
8003f050  80008954`a1000068 80008954`a1680068
8003f060  00009302`2f30ffff 0000920b`80003fff
8003f070  ff0092ff`700003ff 80009a40`0000ffff
8003f080  80009240`0000ffff 00009200`00000000
8003f090  00000000`00000000 00000000`00000000
8003f0a0  8200891b`22e00068 00000000`00000000
8003f0b0  00000000`00000000 00000000`00000000
8003f0c0  00000000`00000000 00000000`00000000
8003f0d0  00000000`00000000 00000000`00000000
8003f0e0  f8009f71`a000ffff 00009200`0000ffff
8003f0f0  8000984f`b2e403b7 00009200`0000ffff
8003f100  f8409337`9400ffff f8409337`9400ffff
8003f110  f8409337`9400ffff 00000000`8003f120


在3环能加载的数据段有哪些?

分析:3环只能加载DPL为3的数据段。

数据段有:
00cf9300`0000ffff DPL = 0
00cff300`0000ffff DPL = 3 --> 可以加载
ffc093df`f0000001 DPL = 0
0040f300`00000fff DPL = 3 --> 可以加载
0000f200`0400ffff DPL = 3 --> 可以加载
00009302`2f30ffff DPL = 0
0000920b`80003fff DPL = 0
ff0092ff`700003ff DPL = 0
80009240`0000ffff DPL = 0
00009200`00000000 DPL = 0
00009200`0000ffff DPL = 0
f8409337`9400ffff DPL = 0
f8409337`9400ffff DPL = 0
f8409337`9400ffff DPL = 0


在0环能加载的数据段有哪些?

分析:0环可以加载DPL=0,1,2,3 的数据段,以下数据段均可以加载

数据段有:
00cf9300`0000ffff DPL = 0
00cff300`0000ffff DPL = 3
ffc093df`f0000001 DPL = 0
0040f300`00000fff DPL = 3
0000f200`0400ffff DPL = 3
00009302`2f30ffff DPL = 0
0000920b`80003fff DPL = 0
ff0092ff`700003ff DPL = 0
80009240`0000ffff DPL = 0
00009200`00000000 DPL = 0
00009200`0000ffff DPL = 0
f8409337`9400ffff DPL = 0
f8409337`9400ffff DPL = 0
f8409337`9400ffff DPL = 0


详细描述这下面代码的执行过程

mov ax,0x23
mov ds,ax

1.  0x23 = 00000000 00100011 --> Index = 4, TI = 0, RPL = 3
对应的描述符是:00cff300`0000ffff --> DPL = 3
2.  检查当前 RPL <= DPL and CPL <= DPL ?
3.  若 2 成立,把 0x23 填充到 ds, 把对应的段描述符加载到段寄存器 ds 的隐式的 80 位中。


总结

数据段权限检查,本质上就是检查能不能把段选择子代入到段寄存器。如果代入成功,表明权限检查通过。如果代入不成功,说明权限不够(CPL在数值上太大了)。

大家注意没有,本篇的标题是——数据段权限检查。为什么不是段权限检查?

因为数据段权限检查简单。这确实是一个无懈可击的理由:)

相比于数据段的权限检查,代码段权限检查要更加严格。后文会给出详细的答案。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息