Windows內存管理-分段


0x01原因

分段的產生原屬於安全問題。

一個程序可以自由的訪問不屬於它的內存位置,甚至可以對那些內容進行修改。這也導致安全問題 促使一種內存隔離的手段 分段的產生。

0x02分段原理

處理器要求在加載程序時,先定義該程序所擁有的段,然后允許使用這些段。定義段時需要基地址,段界限,特權級別,類型等。

在一個程序訪問cs,ss,ds,es 這些段時。處理器將會實施檢查,防止內存違規訪問。

因此有了段描述符來描述這些段的內容和權限

0x03段描述符

認識段描述符先定義全局描述符表GDT,為了跟蹤GDT 處理器有一個48位寄存器,也就是gdtr,分別是32位線性地址和16位邊界地址

訪問地址范圍就是0x00000000到0xffffffff 4gb 的映射范圍  界限地址 ffff  就是64kb  一個GDT大小是8個字節 所以GDT最最多可以定義8192個描述符

下面就是段描述符格式

 

 

下面是低位,上面是高位
段基地址:
0-15+16~23+24~31 FFFF FF FF
段界限
0-15+19+16 FFFF F
0xFFFF FFFF:0FFFF 就是GDT的物理地址
 
G粒度位
當為0時 段界限以字節為單位 范圍(1b~1mb) 當為1時,段界限以4KB為界限 范圍(4kb-4gb)
S描述符位:
當為0時 表示是個系統段,當為1時表示代碼段或者數據段(棧段也是特殊的數據段)
DPL特權級位:
分別表示0,1,2,3 其中0是最高位。不同級別的程序相互隔離,嚴格限制互訪。高可以訪問低特權級
P段存在位:
p位表示描述符對應的段是否存在,當內存緊張時,可能只建立了描述符沒有建立內存這時P位就是0 表示段並不存在,p是有處理器負責檢查的 如果是0處理器會產生一個中斷。這一過程由操作系統提供,負責將該段從硬盤換回內存。將p置為1,在多任務多用戶的系統中,這是一種常用的虛擬內存調度策略
D/B操作數大小位或者棧指針大小位或者上部邊界標志位
不同段表示不同意思
代碼段表示 d=0 表示16位 d=1 表示32位 表示使用 eip還是ip
棧段表示 b=0表示使用sp b=1 表示使用 esp
b位也決定上部邊界 b=0 就是 sp寄存器最大值 0xffff b=1 esp最大值 0xffff ffff
L64專用位
暫時不涉及 置0即可
TYPE 描述符子類型位
對於數據段來說
4位 X,E,W,A
代碼段
4位 X,C,R,A
x表示可執行 數據段不可執行 默認為0
數據段的E表示段擴展方向 為0向上擴展 向高地址方向擴展。 為1向下擴展 向低地址擴展通常是棧段。
W=0表示不允許寫入
C表示特權級依從 0表示非依從的代碼段,可以從與它特權級相同的代碼段調用,或者通過門調用
1表示 允許從低特權級的程序轉移到該段執行。
R=0表示不能讀出
A位已訪問位 表示最近這個段是否被訪問過 每當被訪問會被置1 清理由操作系統負責 監視是否還在使用。知道使用頻率,內存緊張時把不常用的段退避到硬盤上,從而實現虛擬內存管理
AVL位
軟件位 用戶使用沒啥用
 
下面通過windbg調試查看gdt表

 

 看到當前的gdtr 寄存器值 和當前 ds cs es值

 

 ds 是23解析規則就是

2        3

0010 0011

00100=4

rpl 請求特權級  3就ring3 權限

tl 0=gdtr 寄存器里面  1=ldtr里面 

ds=23 指的就是GDT表的第5位置 下標在4

 可以看到前5個除了第一個用於指向null的gdt 表 其他的4個把所有類型都包括了 這是因為 微軟沒用分段來隔離內存  因為gdt 大小只能8192個太少了 。

讀取少字節時性能不高,后面改用分頁來隔離內存了,又猶豫cpu只認段描述符這種格式,所以就做了4個把所有類型都包括的描述符 來解決這個問題。

但是fs gs 用的還是分段

這里fs=3b  

111011= 7

 f892a000~00001fff

看內存拆分就是

01 00 00 a0  92 93 c0 f8

00 0a 92 f8-01

g位為1  所以  段界限要*4kb=4096

00 00 01*4kb+0xfff 就是最后的段界限

最后就是

f892a000~1fff


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM