首页
社区
课程
招聘
1
[原创]x64内核实验2-段机制的变化
发表于: 2023-10-6 16:44 9832

[原创]x64内核实验2-段机制的变化

2023-10-6 16:44
9832

x64内核实验2-段机制的变化

ia-32e模式简介

x86下的段描述符结构图如下
图片描述
在x86环境下段描述符主要分为3个部分的内容:base、limit、attribute,而到了64位环境下段的限制越来越少,主要体现在base和limit已经不再使用而是直接置空,也就是默认强制为平坦模式

ia-32e模式使用的是64位内核文件,legacy是兼容模式使用的还是32位内核文件,我们这里不关注兼容模式
ia-32e模式下是支持32位和64位的文件的,此模式下就是之前说的强制平坦模式并且取消掉了任务门切换的能力(可能是本来在32位的环境下各个操作系统的实现就没有使用任务切换所以cpu在64位下把这个能力删掉了)
ia-32e模式的启动流程跟32位下差不多也是进来是实模式然后在msr寄存器里设置一些位开启ia-32e模式模式
ia-32e模式下的系统调用跟32位下差不多是通过syscall进入0环

rdmsr 命令可以查看msr寄存器的值

1
2
3
4
5
6
7
8
9
10
11
12
13
0: kd> rdmsr c0000080
msr[c0000080] = 00000000`00000d01
0: kd> .formats d01
Evaluate expression:
  Hex:     00000000`00000d01
  Decimal: 3329
  Decimal (unsigned) : 3329
  Octal:   0000000000000000006401
  Binary:  00000000 00000000 00000000 00000000 00000000 00000000 00001101 00000001
  Chars:   ........
  Time:    Thu Jan  1 08:55:29 1970
  Float:   low 4.66492e-042 high 0
  Double:  1.64474e-320

可以看到我的模式是d01通过.formats查看具体描述可以看到我当前的二进制位第8位是1(第八位是第九个)说明处于IA-32e模式

这里我们先介绍这些后面慢慢遇到了在说

非系统段描述符的变化

首先看一下白皮书里对64位代码段描述符给出的图
图片描述
可以看到大部分段描述符的长度依旧是64位,但是基址和界限已经不再存储了,而是默认平坦,留下的大部分内容和32位是一致的,因为图例给出的是代码段所以s位是1type的第一位也是1,要说的是L位现在描述的是32位还是64位段

有区别的地方在于只有s位=1的时候段描述符是64位,s=0的时候段描述符是128位,这是因为在64位环境下我们的数据段和代码段都是强制平坦模式无需关注base和limit而系统段不是这样在系统段里存了段选择子和offset而64位环境下offset也就有64位所以他必须扩到16个字节来存储offset

举例说明就是如果是1就是64位,如果L=1那么push Xax会被翻译为push rax反之则是push eax

下面我们分析几个段描述符看一下

1
2
3
4
5
6
7
8
9
10
11
0: kd> r gdtr
gdtr=fffff80580a99fb0
0: kd> dq fffff80580a99fb0
fffff805`80a99fb0  00000000`00000000 00000000`00000000
fffff805`80a99fc0  00209b00`00000000 00409300`00000000
fffff805`80a99fd0  00cffb00`0000ffff 00cff300`0000ffff
fffff805`80a99fe0  0020fb00`00000000 00000000`00000000
fffff805`80a99ff0  80008ba9`80000067 00000000`fffff805
fffff805`80a9a000  0040f300`00003c00 00000000`00000000
fffff805`80a9a010  00000000`00000000 00000000`00000000
fffff805`80a9a020  00000000`00000000 00000000`00000000

00209b00 00000000 g=0 d=0 l=1 avl=0 p=1 dpl=0 s=1 type=1011
说明是一个64位的代码段描述符 dpl=0
00409300 00000000 g=0 d=1 l=0 avl=0 p=1 dpl=0 s=1 type=0011
说明是一个64位数据段描述符 dpl=0
这里要说明一下这个l位只对代码段生效
00cffb00 0000ffff g=1 d=1 l=0 avl=0 p=1 dpl=3 s=1 type=1011
是一个3环32位代码段
00cff300 0000ffff g=1 d=1 l=0 avl=0 p=1 dpl=3 s=1 type=0011
是一个3环32位数据段
00000000 fffff805 80008ba9 80000067这就是一个系统tss段
他的base是fffff805 80a98000系统段我们后面再说

怎么去验证呢,在windbg中可以使用dg命令加上段的偏移就可以显示目标段描述符的详细信息
如下可以看到我们分析的是对的

1
2
3
4
5
6
7
8
9
10
0: kd> dg 10
                                                    P Si Gr Pr Lo
Sel        Base              Limit          Type    l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0010 00000000`00000000 00000000`00000000 Code RE Ac 0 Nb By P  Lo 0000029b
0: kd> dg 3*8
                                                    P Si Gr Pr Lo
Sel        Base              Limit          Type    l ze an es ng Flags
---- ----------------- ----------------- ---------- - -- -- -- -- --------
0018 00000000`00000000 00000000`00000000 Data RW Ac 0 Bg By P  Nl 00000493

系统段的变化


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2023-10-6 16:52 被幺幺满地乱爬编辑 ,原因:
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2024-1-3 00:32
最新回复 (1)
雪    币: 3995
活跃值: (31436)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2023-10-7 09:25
1
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册