您的位置:首页 > 其它

保护模式下的段寄存器值转化为线性地址过程

2013-07-23 14:55 375 查看
关键字:
段寄存器、段选择子、全局描述符表、局部描述符表、段描述符、线性地址;

    保护模式下使用段机制的CS,SS,DS,ESt,FS,GS保存的并不是实模式下的段地址,而是一个包含了段选择子和偏移地址的组合值。CPU在读取内存的时候,需要将段寄存器的值解析成为段地址,才能定位找到相应的段。下面我们一步一步解析这个过程。

    知识点:

    段寄存器值=段选择子,简单来说,段选择子就是用来指定段描述符的位置的一个值。



    段选择子格式:



低0-1位表示特权级,为减少复杂度,目前不关注。低第2位表示指定的是描述符表是GDT(0)还是LDT(1),第3-15位指示段描述符在段描述表中的序号,很关键。

    全局描述符表,一个系统只有一个全局描述符表,用来存放一些全局的段描述符(下面有讲述这个术语)。全局描述符表第一个项值规定是空值。全局描述符表的首地址由GDTR寄存器给出,这个值是线性地址,不需要解析。



    GDTR的是一个48位的值,16-47位范围共32位(Base Address)的GDT基地址,0-15位范围共16位(Limit)表示GDT表的大小(以字节计算)。
       在windbg内核模式,可以用r gdtr命令列出32位的基地址,用rgdtl列出16位的GDT大小值。



           r gdtr列出base address 指出段描述符表的基地址,是以平坦线性模式的地址显示,这个是其他段地址使用段选择子的基础。
           r gdtl列出limit以字节为单位,如果limit是1023,则包含1024个字节,GDT包含共有1024/8=128项段描述符。

    段描述符:共64位值,下图中的下部分是低32位,上部分是高32位。此段描述符中指出的段地址为:(32:24)(23:16)(15:00)这个值(共32位),就是我们所求的线性段地址了。



局部描述符表寄存器LDTR表示当前任务的LDT表在GDTR中的索引,其格式是典型的段选择子。(结合全局描述符表理解)

段机制和页机制一起工作原理示意图,页基制需要另一篇文章详细介绍。



使用windbg来做上述过程的实验:
1. 使用r命令列出寄存器值

kd> r
eax=00000001 ebx=00000000 ecx=8080a188 edx=8292eadc esi=8080a188 edi=00000029
eip=82868bc0 esp=8292eaf8 ebp=8292eca4 iopl=0         nv up ei pl nz na po nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00200202

2. 以cs为例,因为其值0008是段寄存器值=段选择子,我们使用.formats命令显示二进制数

kd> .formats 0008
Evaluate expression:
  Hex:     00000008
  Decimal: 8
  Octal:   00000000010
  Binary:  00000000 00000000 00000000 00001000
  Chars:   ....
  Time:    Thu Jan 01 08:00:08 1970
  Float:   low 1.12104e-044 high 0
  Double:  3.95253e-323

第2位为0,表示使用的是全局描述符表,我们使用r gdtr命令查看全局描述符表的首地址。

kd> r gdtr
gdtr=80b95000

第3-15位值为1,表示使用的是全局描述符表的第1个项(从0开始,第0项一定为0);我们查看全局描述符表的内容:

kd> dd 80b95000
80b95000  00000000 00000000 0000ffff 00cf9b00
80b95010  0000ffff 00cf9300 0000ffff 00cffa00
80b95020  0000ffff 00cff300 600020ab 80008b1c
80b95030  1c003748 82409393 00000fff 0040f200
80b95040  0400ffff 0000f200 00000000 00000000
80b95050  f0000068 82008992 f0680068 82008992
80b95060  00000000 00000000 00000000 00000000
80b95070  500003ff 800092b9 00000000 00000000

可见第0项的确为0,第一项内容为0000ffff 00cf9b00。根据段描述符的格式,段描述符中指出的段地址为:(32:24)(23:16)(15:00)这个值(共32位)为线性地址。

kd> .formats 0000ffff
Evaluate expression:
  Hex:     0000ffff
  Decimal: 65535
  Octal:   00000177777
  Binary:  00000000 00000000 11111111 11111111
  Chars:   ....
  Time:    Fri Jan 02 02:12:15 1970
  Float:   low 9.18341e-041 high 0
  Double:  3.23786e-319

kd> .formats 00cf9b00
Evaluate expression:
  Hex:     00cf9b00
  Decimal: 13605632
  Octal:   00063715400
  Binary:  00000000 11001111 10011011 00000000
  Chars:   ....
  Time:    Sun Jun 07 19:20:32 1970
  Float:   low 1.90656e-038 high 0
  Double:  6.72208e-317

得出(32:24)(23:16)(15:00)这三个地方的值都为0,所以找到的线性段地址为0。也就是cs=0008指定的线性段地址为0.
我们为验证结果,使用dg命令查看段选择子所指定的段描述符的内容

kd> dg 0008
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0008 00000000 ffffffff Code RE Ac 0 Bg Pg P  Nl 00000c9b

结果正确。
3. 再以fs=0030为例验证。

kd> .formats 0030
Evaluate expression:
  Hex:     00000030
  Decimal: 48
  Octal:   00000000060
  Binary:  00000000 00000000 00000000 00110000
  Chars:   ...0
  Time:    Thu Jan 01 08:00:48 1970
  Float:   low 6.72623e-044 high 0
  Double:  2.37152e-322

可见低第2位为0,指定的是全局描述符表。同样使用r gdtr找全局描述符基地址,然后定位第110b的段描述符:

kd> r gdtr
gdtr=80b95000

kd> dd 80b95000+6*8 l2
80b95030  1c003748 82409393

kd> .formats 1c003748 
Evaluate expression:
  Hex:     1c003748
  Decimal: 469776200
  Octal:   03400033510
  Binary:  00011100 00000000 00110111 01001000
  Chars:   ..7H
  Time:    Tue Nov 20 13:23:20 1984
  Float:   low 4.24231e-022 high 0
  Double:  2.321e-315
kd> .formats 82409393
Evaluate expression:
  Hex:     82409393
  Decimal: -2109697133
  Octal:   20220111623
  Binary:  10000010 01000000 10010011 10010011
  Chars:   .@..
  Time:    ***** Invalid
  Float:   low -1.41483e-037 high -1.#QNAN
  Double:  -1.#QNAN

得出的线性段地址二进制值为:  10000010    10010011     00011100
00000000   B
转变为16进制为:82931c00;
使用dg来验证线性段地址:

kd> dg 30
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0030 82931c00 00003748 Data RW Ac 0 Bg By P  Nl 00000493

结果正确。

参考资料:
Intel64 and IA-32 Architectures Software Developer's Manual.pdf

张银奎《软件调试》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息