回顾上两篇文章我们讲了什么是保护模式,什么是段寄存器,保护模式是保护内存访问与寄存器,我们能否进行内存访问通过段与页的检测,段寄存器的权限划分为段选择子拆分
结构体为
struct segment
{
word slector
word atrribute
dword base
dword limit
}
这篇文章我们讲段寄存器的属性探测
我们在论证的时候我们是看到16位段寄存器但其实段寄存器为96位
这一篇文章就是围绕段寄存器的剩下80位属性的各种探测去写
我们看到的是slector也就是选择子,但段是有选择子,描述符,base和limit的
我们其实是可以使用mov指令对段寄存器进行写入的,我们可以论证一下
好的我们现在先看结构体
32位为描述符也就是atrribute
0为base就是段从哪开始的
FFFFFFFF为limit为段描述覆盖地址
002b也就是选择子我们在上一篇讲过
你可能会疑惑说在od中我看不到96位啊,他在od没有体现不一定说他不存在,我们今天就是论证我们的段寄存器为96位
我们知道002b 0023 0053为选择子,base与limit我们上面也讲到了,属性也就是段描述符是干啥的呢,我们接下来说一下,描述符决定了你是否能对段进行读写或执行
我们接下来总结一下表
{
es 002b 可写 可读 0 0xFFFFFFFF
cs 0023 可读 可执行 0 0xFFFFFFFF
ss 002b 可读可写 0 0xFFFFFFF
fs 0053 可读可写 0x7FFDE000 0xFFF
}
那大家可能就疑惑了,为什么我没写gs寄存器呢,你是不是忘写了
其实不然,gs寄存器在win下并没有使用,他的值总是0 进0环gs就为0了
fs我们接着补充上一篇文章没有提到的
fs段寄存器与线程相关不是我不想提而是我现在讲不了,还有很多知识大家没有学
所以说我们关注点为es附加段,ss栈段,cs代码段与ds数据段
我们的es,ss,ds都是存储数据所以我们要知道这是可写可读的选择子为0023
001b与0023的base和limit都是一样的而fs就不同了详细参考上表
看代码我首先是读ss,那大家要知道,读是读16位,再看第二行,写段寄存器时就不一样了,我们是写96位,写的部分为段结构体部分
我们可以接下去看执行完代码看看效果
之后是可写的为什么呢,因为ss段是可写的
如果我们把ds换成cs呢,那会发现出问题写不进去,因为我们在写完段寄存器之后ds=cs,cs可读可执行不可写
那问题来了,如果段寄存器为16位的话只存在段选择子那一定不会有权限描述,就不会有权限划分从而没有我们上面表的概念
到现在我们已经论证了atrribute的存在
接下来我们论证base
base为基地址,limit为线长
回想汇编写入数据到一个内存地址我们应该怎么写
mov dword ptr ds:[]
那如果我这么写行不行呢
mov dword ptr ds:[0]
显然是不行的 0地址为保留
学完页就行了,现在学段先这么理解
我们先看代码
mov ax,fs
mov ds,fs
mov eax,ds:[0]
mov dword ptr ds:[],eax
我们看代码过前两行我们就需要知道 ds=fs
第三行实际地址为fs.base+0
这个代码是可以执行的
因为什么因为fs的base不等于0
证明了base的存在
我们接着看limit
看代码
mov ax,fs
mov es,ax
mov eax,es:[0x1000]
与上面相同我们es=fs
这行代码肯定是执行不过去的
被limit拦截了,证明了limit的存在
来源:freebuf.com 2021-05-01 14:09:41 by: pwnter
请登录后发表评论
注册