上面的32位是高地址32位,下面的是低地址32位。
解析段描述符的流程
通过解析段寄存器显示出来的段选择子/段选择符,拿到段描述符,然后解析段描述符来获取对段寄存器的描述内容。
前面的步骤在前面的博客里有体现,这里就专门解析一下段描述符。
解析段描述符
利用前面博客找到的段描述符: 00cff300~0000ffff:
因为小端字节序的原因:高地址:00cff3 00低地址:0000ffff
按照字节解析出来的结果:
Limit: fffff
Base: 00000000
Type:3
S:1
DPL:3
P:1
AVL:0
D/B:0
G:1
修复limit
limit不是仅仅照着段描述符结构体就行了,还需要和段描述符的字段G来结合使用。
当G==0时,limit的单位为字节,当G==1时,limit单位为页,一页==0x1000
所以当G==1时:Limit==(Limit+1)*0x1000 - 1=FFFFFFFF
S
S==0时,表示系统段,为1时表示数据段或代码段
Type
通过S访问了之后,再通过Type来确定到底是什么段。
当S==1时:
这里就可以得到段寄存器的权限了,accessed表示被访问过,然后Type表示是代码段还是数据段。
P
表示该段是否有效,当P为0时无效,1时有效。
AVL
提供给User来适配,自己定义自己用
D/B
D/B也根据数据段/代码段而作用不同。
会修改push的默认栈空间大小。
其实就是修改段寻址大小。如果为1就是四个字节,如果为0就是两个字节。
得到段描述符
通过WinDbg打印出GDT表寄存器,然后根据index索引来获取段描述符:
总结
前面所采用的WinDbg+Ollydbg两个调试器混着用但段寄存器既然一样,大家有没有疑问啊?
其实是因为我把虚拟机的处理器设置为了1,这样只有一个处理器,那么大家的段寄存器内容都是一样的。
段寄存器的属性很多,可以通过解析段选择子,拿到段描述符然后再进行一顿操作。