码迷,mamicode.com
首页 > 其他好文 > 详细

戏说fs和fs:0

时间:2015-05-27 10:21:47      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:

本文探讨fs 是否等于fs:0

fs是段选择子,16位。
fs:x 是段寻址,寻找到的地址为32位,此值为fs指向的段段内偏移x处的地址。

根据已知FS:0指向TEB
以此源码为例,windbg双调。

.386
.model flat,stdcall
option casemap:none


.code
start:
int 3
nop
nop
end start

windbg捕获断点

kd> !teb
TEB at 7ffde000
    ExceptionList:        0012ffe0
    StackBase:            00130000
    StackLimit:           0012e000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7ffde000
    EnvironmentPointer:   00000000
    ClientId:             00000404 . 00000528
    RpcHandle:            00000000
    Tls Storage:          00000000
    PEB Address:          7ffdf000
    LastErrorValue:       0
    LastStatusValue:      0
    Count Owned Locks:    0
    HardErrorMode:        0

为了dump 描述表GDT,查看GDTR寄存器,当然还有fs寄存器

kd> rm ?
       1 - Integer state (32-bit) or
       2 - Integer state (64-bit), 64-bit takes precedence
       4 - Floating-point state
       8 - Segment registers
      10 - MMX registers
      20 - Debug registers and, in kernel, CR4
      40 - SSE XMM registers
      80 - CR0, CR2 and CR3
     100 - Descriptor and task state

kd> rm 100|1
kd> r
eax=00000000 ebx=7ffdf000 ecx=0012ffb0 edx=7c92e4f4 esi=00360036 edi=00360033
eip=00401000 esp=0012ffc4 ebp=0012fff0 iopl=0         nv up ei pl zr na pe nc
gdtr=8003f000   gdtl=03ff idtr=8003f400   idtl=07ff tr=0028  ldtr=0000
001b:00401000 cc              int     3

查看fs寄存器

kd> .formats fs
Evaluate expression:
  Hex:     0000003b
  Decimal: 59
  Octal:   00000000073
  Binary:  00000000 00000000 00000000 00111011
  Chars:   ...;
  Time:    Thu Jan 01 08:00:59 1970
  Float:   low 8.26766e-044 high 0
  Double:  2.91499e-322

fs的结构划分:
按照intel文档的说明,最低的2位表示将要访问的段的权限级为0,第3位这里是0,表示将要访问的段的段描述符从全局描述符表(即GDT)里面取得,剩下的高13位是所为索引值用的
16位fs按照说明应该分为:(0000000000111)(0)(11)
对应结构为(高13位-GDT索引值) (第3位-段描述符获取位置) (低2位-段权限)

GDT中每个索引所占地址为qword

kd> r gdtr
gdtr=8003f000

kd> dw gdtr+7*8 l4
8003f038  0fff e000 f3fd 7f40

段描述符(qword)与段地址相关的部分:

第4个word的高8位为段起始地址的高8位,第3个word的低8位为段起始地址的高 8-15位,第2个word为段起始地址的低16位
cpu从后往前扫 7f40 取7f, f3fd取fd,e000取e000
我们关心的地址结构为:32bit=8+8+16=(7f)+(fd)+(e000)=7ffde000

kd> dq gdtr+7*8 l1
8003f038  7f40f3fd`e0000fff       7f-fd-e000
kd> dd 7ffde000 l1
7ffde000  0012ffe0
kd> !teb
TEB at 7ffde000
    ExceptionList:        0012ffe0
    StackBase:            00130000
    StackLimit:           0012e000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7ffde000
    EnvironmentPointer:   00000000
    ClientId:             00000404 . 00000528
    RpcHandle:            00000000
    Tls Storage:          00000000
    PEB Address:          7ffdf000
    LastErrorValue:       0
    LastStatusValue:      0
    Count Owned Locks:    0
    HardErrorMode:        0

也就是说:fs:0 的过程为:
1.寻找gdt起始地址 通过gdtr
2.通过fs寻找到在gdt中的地址, 以fs的高13位为索引,地址为gdtr+index*8
3.得到的地址存放的是段描述符,该描述符长度为QWORD。
4.得到fs:0地址。从段地址符中取出高8位+高24位~到低12位前 (8+24)

戏说fs和fs:0

标签:

原文地址:http://blog.csdn.net/bugmeout/article/details/46038177

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!