RPL的故事 ——《x86汇编语言:从实模式到保护模式》读书笔记31
關于RPL(請求特權級),網上的資料不少,不過我認為都沒有說明白。希望我可以把這個問題講清楚,如有紕繆,還請您不吝賜教。
要理解RPL,首先要明白訪問數據段時的特權級檢查規則。
1. 訪問數據段時的特權級檢查
為了訪問數據段,數據段的選擇子必須被加載進段寄存器(DS,ES,FS,GS,SS)。在把一個段選擇子加載進段寄存器之前,處理器會進行特權級檢查(如下圖所示)。
在數值上必須滿足以下兩點:
1. CPL<=數據段描述符的DPL
2. RPL<=數據段描述符的DPL
否則,會產生一個一般保護異常,且不加載段選擇子。
2. 為什么要引入RPL
2.1 概述
當低特權級的應用程序使用call far指令通過調用門將控制轉移到較高特權級的非一致代碼段(例如操作系統提供的例程,假設其代碼段的DPL=0)時,會改變當前的特權級,而在目標代碼段的特權級上執行,對于本例來說CPL的數值就會變成操作系統例程段的DPL的數值,即0。如果沒有RPL,那么此時CPL權限是最高的,也就可以去訪問任何數據,這就不安全了。所以引入RPL,讓它代表訪問權限,因此在檢查CPL的同時,也會檢查RPL(正如上文第一節提到的規則)。一般來說如果RPL的數值比CPL大(權限比CPL的低),那么RPL會起決定性作用。
2.2 狡猾的應用程序開發者
舉個例子,比如操作系統提供了一個調用門(這個門對應的目標代碼段的DPL為0),其功能是讀取硬盤的一個扇區到指定的內存位置。這個調用門有3個參數(通過棧來傳遞),分別是邏輯扇區號、數據段選擇子和段內的偏移。
假設有個應用程序(運行在特權級3)的開發者,通過苦心鉆研知道了操作系統數據段的選擇子(其指向的數據段的特權級為0),為了搞破壞,他把這個選擇子作為參數傳給了調用門。如果沒有RPL,那么訪問數據段的檢查規則就是“CPL<=數據段描述符的DPL”。當通過調用門轉移后,CPL從3變成了目標代碼段的特權級0,正好符合檢查規則,于是他的陰謀得逞了。
2.3 善變的CPL
仔細分析這個問題,根源在于CPL變了,搖身一變變成目標代碼段的特權級了。所以引入RPL,讓RPL代表“真實”的CPL,并且再加上一條規則“RPL<=數據段描述符的DPL”,因為RPL=3,所以檢查不會通過。
3. RPL的值是怎么來的
你可能會問,那RPL的值是怎么得來的?難道CPU可以智能識別出CPL變身了,然后自動把CPL變身前的值傳遞給RPL?
不不不,CPU可沒有這么厲害。關于這個問題,我先告訴你一個好消息:RPL的值可以由當前進程隨便寫。就是上文圖中的那個黃色字段,你愛填多少填多少。
這下你樂了吧:)既然隨便寫,那我寫0好了。這樣一來,“RPL<=數據段描述符的DPL”總是成立的。
但是別高興,我還要宣布一條壞消息:操作系統會檢查RPL的值,如果你填寫的RPL在數值上小于CPL(調用者的特權級,而非目標代碼段的特權級),那么操作系統會把RPL打回原形,強制它等于CPL。
4. ARPL指令
為了方便操作系統得到正確的RPL值,處理器提供了ARPL指令。該指令的作用是調整選擇子中RPL字段的值(Adjust RPL Field of Segment Selector),其格式為
arpl r/m16, r16該指令比較兩個選擇子的RPL字段。
目的操作數可以是一個通用寄存器(內容是16位的段選擇子)或者一個指向16位單元的內存地址(該16位單元存放的是段選擇子);
源操作數只能是一個通用寄存器(內容是16位的段選擇子)。
該指令執行時,處理器檢查目的操作數的RPL字段,如果它在數值上小于源操作數的RPL字段,則設置ZF標志,并修正目的操作數的RPL字段,使其等于源操作數的RPL字段值;否則,僅僅把ZF標志清零,其他什么也不做。
ARPL是典型的操作系統指令,通常用于調整應用程序傳遞給操作系統的段選擇子,使其RPL字段的值和應用程序的特權級相匹配。
5. 火眼金睛的操作系統
結合上文2.2節的那個例子,配合下圖來說明。
為了防止惡意的數據訪問,操作系統應該從當前棧中取得用戶程序的代碼段選擇子(調用者代碼段寄存器CS的內容,也就是下圖中的“原CS”)作為源操作數,并且把作為參數傳遞進來的數據段選擇子(下圖中的“參數2”)作為目的操作數,來執行ARPL指令,把數據段選擇子的RPL恢復到調用者的特權級別上。
一旦調整了請求特權級,那么當前特權級CPL=0,RPL=3,數據段描述符的DPL=0,雖然符合“CPL<=數據段描述符的DPL”,但是不符合“RPL<=數據段描述符的DPL”,所以會禁止訪問,并引發異常。這樣一來,狡猾的應用程序開發者的陰謀就不會得逞了。
總結
以上是生活随笔為你收集整理的RPL的故事 ——《x86汇编语言:从实模式到保护模式》读书笔记31的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中星号数字乘字符串_Pyth
- 下一篇: python3.4安装pygame_py