在Windows系统中,段寄存器有:CS、SS、ES、DS、FS、GS、TR、LDTR等。每个寄存器有4个属性:
-
Selector 16位 (段选择子 可见部分)
-
Atrributes 16位
-
Base 32位
-
Limit 32位
当我们传入一个段选择子,计算机会根据GDT表的段描述符修改寄存器属性。具体细节这里就不过多展开。
而每个寄存器,可见部分在3环和0环都有固定值,其中:
寄存器/环 |
3环 |
0环 |
CS |
1B |
08 |
SS |
23 |
10 |
ES |
23 |
23 |
DS |
23 |
23 |
FS |
3B |
30 |
GS | 0 | 0 |
除CS寄存器,通常我们要修改如:ES、DS、FS等寄存器值可以用MOV、LES、LDS、LFS等指令。
但是想要修改CS段寄存器,我们只能通过CALL和JMP,因为CS段寄存器的修改,意味着EIP的修改,而本次笔记,我们也只记录如何修改CS段寄存器的值。
因为根据有4个属性,共96个字节,在这里,我们简单介绍其中的一些位的含意:
高32位的第8、9、10、11位为Type域,第12位为S位,第13、14位为DPL位、第15位为P位。
P位:判断该寄存器是否有效,有效为1
DPL位:访问我需要什么权限,11为3环的权限,00为0环的权限
S位:1代表代码段或数据段,0代表系统段
Type:(这里只介绍S位为1时),Type4个位分别代表了:
11
(1为代码段 0为数据段) |
10 |
9 |
8 |
1时 |
1为一致性代码 0为非一致性代码 |
可读可写 |
是否访问 |
0时 |
拓展位,1向下拓展 | 可读可写 | 是否访问 |
当然,我们还需要简单介绍一下3个概念:CPL、DPL、RPL。
-
CPL:CPU当前级别
-
DPL:上面已经介绍过了
RPL:段选择子的低2位,代表着,我将用什么级别访问、请求你。
说到RPL,再简单介绍一个段选择子吧。
段选择子16位,前2位为RPL,第三位为TI,代表着查找GDT表,还是LDT表,0为查GDT表;后13位,代表着查找GDT/LDT表的第几个。
这里不仔细介绍,只是简单的介绍一下,因为内容比较多。
当我们了解了段描述符的一些基本属性之后,我们就可以开始进行代码段
在代码段跳转之前,还需要知道,在请求时,会进行一系列检查,其中就包括权限检查。
如果是非一致代码段,要求CPL==DPL,RPL<=DPL
在OD中:JMP 0x48:0x7ffde000
0x48:0000 0000 0100 1000 :代表着我用00权限去访问GDT表第9个,也就是我们修改的那个。
此时CS为1B。
执行后:
CS为何没有变成48呢?是因为我当前CPU还是在3环中,所以我的第2位还是11。
非一致性代码段
JMP FAR 004B:7FFDE000
报异常了,说明权限验证没通过。
原文始发于微信公众号(loochSec):滴水逆向-代码段间跳转
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论