段描述符與段選擇子


前言:段描述符和段選擇子的學習

知識點:CPU的眼里只有GDT和IDT表,在windows中LDT沒有用到

當我們執行類似 MOV DS, AX 指令時,CPU會查表,根據AX的值來決定查找GDT還是LDT,查找表的什么位置,以及查出多少數據

GDT(全局描述符表)

gdtr是一個寄存器,存儲了GDT表所在位置
gdtr寄存器存儲了48位,正常的windbg命令r gdtr展示的就只有其中的32位

gdtl也是一個寄存器,存儲了GDT表的大小
r gdtl,該命令展示的是GDT表的大小,gdtl大小為4個字節,也就是16位

這里還可以通過windbg的命令是dd address,來進行展示,dd 8003f000,dd的意思是double dword,那么就是4個字節展示

LDT(局部描述符表)

對於windows來說,沒有用到LDT這個表,所以這里直接跳過

段描述符

GDT表中每8個字節的結構體稱作為段描述符

當mov ds,ax 的時候ax為16位,那么剩下的80位是哪里來的呢?其實就是在GDT表存儲的段描述符,每次查詢為8個字節(64位)

重點:下面的圖需要牢記!

DPL是段描述符的權限,數值越大權限越小, 因此當RPL=3時,只能訪問DPL=3的段描述符;當RPL=0時,可以訪問所有段描述符。

自己的問題:mov ds,ax 的時候賦值了16位,但是每次查詢一次GDT表也就8個字節,那么一共也就64(段描述符)+16(段選擇子)=80位,那剩下的16位又是在哪里?感覺是Attribute沒有看到,但是不知道在哪里去看

如何通過windbg來進行查詢段描述符?windbg的命令 dd GDT表的地址,每8個字節都描述着一個段描述符結構體中的數據

段選擇子

段選擇子是一個16位的段描述符,該描述符指向了定義該段的段描述符,其實就是我們在OD調試器中看到的,也就只有這個Selector能夠讓我們直接觀察到,這個selector就是段選擇子!

RPL:請求特權級別。

TI:TI=0(查GDT表) TI=1 (查LDT表)。

Index:處理器將索引值乘以8,再加上GDT或者LDT的基地址,就是要加載的段描述符。

RPL是段選擇子的權限,數值越大權限越小。

段選擇子與GDT表的關系

這里來講下段選擇子和GDT表的關系,之前一直有疑問,既然GDT表中這么多段描述符,那么和段選擇子之間是有什么聯系呢?

這里先講下段選擇子,段選擇子分成三個部分,其中index是索引,那么就代表當前這個段寄存器是跟GDT表中的第index索引有關系。

這里給個例子,比如段選擇子為1B,因為段選擇子是16位,所以實際上是001B,也就是 0000 0000 0001 1011,那么高13位則 0000 0000 0001 1,那么低位也就是0011,那么索引值則是3,那么這里在windbg中進行看的話,索引值為3的地方,那么偏移地址其實就是gdtr+3*8,總結下其實就是gdtr+index*8的偏移地址

實現段描述符到段寄存器

除了MOV指令,我們還可以使用LES、LSS、LDS、LFS、LGS指令修改寄存器.

CS不能通過上述的指令進行修改,CS為代碼段,CS的改變會導致EIP的改變,要改CS,必須要保證CS與EIP一起改,海哥后面會講。

小知識點:fword表示6個字節

LES指令示例如下

//char buffer[6] = {0x66,0x55,0x44, 0x33,0x00, 0xAA}; 無法運行,可能是高位的問題
char buffer[6] = {0x66,0x55,0x44, 0x33,0x11, 0x00}; // 可以運行,目前只感覺只能顯示低兩位
__asm                            
{
    les ecx,fword ptr ds:[buffer] //高2個字節給es,低四個字節給ecx
}

注意:RPL<=DPL(在數值上)

段選擇子的訪問權限RPL和段描述符的DPL的關系

mov ds,ax ,這個指令一定可以成功嗎?答案是不一定的,跟ax此時的的值有關,此時ax就是段選擇子,如果賦值成功,那么ds的段選擇子當前就會變成ax的值。

那么繼續來講,為什么不一定能賦值成功,這個就跟當前ds中的段選擇子對應的段描述符的DPL 和 當前ds這個段選擇子之間RPL的關系

比如ds段選擇子的RPL為3,那么此時賦值成功的ds,那么ds的段描述符的DPL肯定是小於等於3,所以可以這樣說,RPL/DPL的值越小,權限越大!

課堂練習作業

作業一:在windbg查看GDT表的基址和長度

作業二:分別使用dd dq指令查看GDT表

作業三:段描述符查分實驗

拆前五個段描述符

8003f000 0000000000000000 00cf9b000000ffff
8003f010 00cf93000000ffff 00cffb000000ffff
8003f020 00cff300`0000ffff

第一段 00000000`00000000

高字節

Base 第31:24位 ----- 0
G位 第23位 ----- 0
D/B位 第22位 ----- 0
第21位 ----- 0
AVL 第20位 ----- 0
Segment Limit 第16-19位 ----- 0
P 第15位 ----- 0
DPL 第13-14位 ----- 0
S 第12位 ----- 0
Type 第8-11位 ----- 0
Base 第16-23位 ----- 0

低字節

Base Address 第16-31位 ----- 0
Segment Limit 第0-15位 ----- 0

第二段 00cf9b00`0000ffff

0000 0000 1100 1111 1001 1011 0000 0000`0000 0000 0000 0000 1111 1111 1111 1111

高字節

Base 第31:24位 ----- 0000 0000
G位 第23位 ----- 1
D/B位 第22位 ----- 1
默認為0 第21位 ----- 0
AVL 第20位 ----- 0
Segment Limit 第16-19位 ----- 1111
P 第15位 ----- 1
DPL 第13-14位 ----- 00
S 第12位 ----- 1
Type 第8-11位 ----- 1011
Base 第0-7位 ----- 0000 0000

低字節

Base Address 第16-31位 ----- 0000 0000 0000 0000
Segment Limit 第0-15位 ----- 1111 1111 1111 1111

自己再來個ham博客上的練習例子 其中一個段描述符的值為 00cf9b00 0000ffff

0000 0000 1100 1111 1001 1011 0000 0000`0000 0000 0000 0000 1111 1111 1111 1111

高字節:
Base 第31:24位 ----- 0000 0000
G位 第23位 ----- 1
D/B位 第22位 ----- 1
默認為0 第21位 ----- 0
AVL 第20位 ----- 0
Segment Limit 第16-19位 ----- 1111
P 第15位 ----- 1
DPL 第13-14位 ----- 00
S 第12位 ----- 1
Type 第8-11位 ----- 1011
Base 第0-7位 ----- 0000 0000

低字節

Base Address 第16-31位 ----- 0000 0000 0000 0000
Segment Limit 第0-15位 ----- 1111 1111 1111 1111

拆五個段選擇子

0x23 0x2B 0x30 0x3B 0x53

0x0023
0000000000100 0 11
Index: 0x4
TI: 0
RPL: 11

0x002B
0000000000101 0 11
Index: 0x5
TI: 0
RPL: 11

0x0030
0000000000001 1 00
Index: 0x1
TI: 1
RPL: 00

0x003B
0000000000111 0 11
Index: 0x7
TI: 0
RPL: 11

0X0053
0000000001010 0 11
Index: 0xA
TI: 0
RPL: 11


免責聲明!

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



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