回顧上兩篇文章我們講了什么是保護模式,什么是段寄存器,保護模式是保護內存訪問與寄存器,我們能否進行內存訪問通過段與頁的檢測,段寄存器的權限划分為段選擇子拆分
結構體為
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的存在