編輯:關於android開發
CPL——當前執行的程序或任務的特權級,它被存儲在cs和ss的第0位和第1位上。
DPL——段或者門的特權級,如果是數據段DPL則規定了可以訪問此段的最低特權級
RPL——通過段選擇子的第0位和第1位表現出來的。處理器通過檢查RPL和CPL來確認一個訪問請求是否合法。RPL保證了操作系統不會越俎代庖地代表一個程序去訪問一個段。
我們先來展示一下特權級錯誤訪問版本。
先把LABEL_DESC_DATA對應的段描述符的DPL修改為1:
LABEL_DESC_DATA: Descriptor 0, DataLen-1, DA_DRW+DA_DPL1 ; Data
繼續修改,把選擇子的RPL改為3:
SelectorData equ LABEL_DESC_DATA - LABEL_GDT + SA_RPL3
運行結果如下:
虛擬機崩潰。因為RPL & CPL 必須 <= DPL
下面就演示一下從低特權轉到高特權的方法:
通過jmp和call所能進行的代碼段間轉移是非常有限的,對於非一致代碼段,只能在相同特權級代碼段之間轉移。遇到一致代碼段也最多能從低到高,而且CPL不會改變。如果想自由地進行不同特權級之間的轉移,顯然需要其他幾種方式,即運用門描述符或者TSS。調用門描述符格式如下:
一個門描述了由一個選擇子和一個偏移所指定的線性地址,程序正是通過這個地址進行轉移的。
以下是通過調用門轉移的目標段:
[SECTION .sdest]; 調用門目標段 [BITS 32] LABEL_SEG_CODE_DEST: ;jmp $ mov ax, SelectorVideo mov gs, ax ; 視頻段選擇子(目的) mov edi, (80 * 12 + 0) * 2 ; 屏幕第 12 行, 第 0 列。 mov ah, 0Ch ; 0000: 黑底 1100: 紅字 mov al, 'C' mov [gs:edi], ax retf SegCodeDestLen equ $ - LABEL_SEG_CODE_DEST ; END of [SECTION .sdest]
下面是代碼段描述符,選擇子及初始化描述符的代碼:
LABEL_DESC_CODE_DEST: Descriptor 0,SegCodeDestLen-1, DA_C+DA_32; 非一致代碼段,32 SelectorCodeDest equ LABEL_DESC_CODE_DEST - LABEL_GDT ; 初始化測試調用門的代碼段描述符 xor eax, eax mov ax, cs shl eax, 4 add eax, LABEL_SEG_CODE_DEST mov word [LABEL_DESC_CODE_DEST + 2], ax shr eax, 16 mov byte [LABEL_DESC_CODE_DEST + 4], al mov byte [LABEL_DESC_CODE_DEST + 7], ah
現在添加調用門:
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate+DA_DPL0
宏Gate的定義在pm.inc中
描述符的屬性是DA_386CGate表明是一個調用門。裡面指定的選擇子是SelectorCodeDest,表明目標代碼段是剛剛新添加的代碼段。偏移地址是0,表示將跳轉到目標代碼段的開頭處。另外,我們把其DPL指定為0.
現在調用門准備就緒,它指向的位置是SelectorCodeDest:0,即標號LABEL_SEG_CODE_DEST處的代碼。
假設我們想由代碼A轉移到代碼B,運用一個調用門G,即調用門G中的目標選擇子指向代碼B的段。代碼B的DPL記做DPL_B,在用call指令時,要求目標代碼DPL_B<=CPL;在用jmp指令時,只能是DPL_B=CPL。
現在添加一個低特權的代碼段ring3和堆棧:
LABEL_DESC_CODE_RING3: Descriptor 0,SegCodeRing3Len-1, DA_C+DA_32+DA_DPL3 LABEL_DESC_STACK3: Descriptor 0, TopOfStack3, DA_DRWA+DA_32+DA_DPL3 ; 堆棧段ring3 [SECTION .s3] ALIGN 32 [BITS 32] LABEL_STACK3: times 512 db 0 TopOfStack3 equ $ - LABEL_STACK3 - 1 ; END of [SECTION .s3] ; CodeRing3 [SECTION .ring3] ALIGN 32 [BITS 32] LABEL_CODE_RING3: mov ax, SelectorVideo mov gs, ax mov edi, (80 * 14 + 0) * 2 mov ah, 0Ch mov al, '3' mov [gs:edi], ax jmp $ SegCodeRing3Len equ $ - LABEL_CODE_RING3 ; END of [SECTION .ring3]
執行如下:
打印了紅色的3,表明我們由ring0到ring3的轉移成功。接下來試驗一下調用門的使用。
把調用門的描述符和選擇子改成特權等級為3.還有從低特權級到高特權級轉移的時候,需要用到TSS,我們來准備一個TSS。
LABEL_DESC_TSS: Descriptor 0, TSSLen-1, DA_386TSS ; TSS [SECTION .tss] ALIGN 32 [BITS 32] LABEL_TSS: DD 0 ; Back DD TopOfStack ; 0 級堆棧 DD SelectorStack ; DD 0 ; 1 級堆棧 DD 0 ; DD 0 ; 2 級堆棧 DD 0 ; DD 0 ; CR3 DD 0 ; EIP DD 0 ; EFLAGS DD 0 ; EAX DD 0 ; ECX DD 0 ; EDX DD 0 ; EBX DD 0 ; ESP DD 0 ; EBP DD 0 ; ESI DD 0 ; EDI DD 0 ; ES DD 0 ; CS DD 0 ; SS DD 0 ; DS DD 0 ; FS DD 0 ; GS DD 0 ; LDT DW 0 ; 調試陷阱標志 DW $ - LABEL_TSS + 2 ; I/O位圖基址 DB 0ffh ; I/O位圖結束標志 TSSLen equ $ - LABEL_TSS
我們需要在特權級變換之前加載它
mov ax, SelectorTSS ltr ax
運行結果如下:
看到字母C表明從低特權級到高特權級的轉移。
【源碼】
Android Studio安裝指南及genymotion配置 第一次安裝Java JDK ,要大於1.7版本,不安裝的話就會出現如下提示: 這時點擊上面的JDK鏈接,
用PopWindow做下拉框,PopWindow做下拉框 最近在做下拉框,本來想用spinner,可是spinner達不到項目要求,跟同學同事問
Android 關於“NetworkOnMainThreadException”,networkonmainthread網絡收集的原因如下,以及解決辦法: 我補充總結一
阿裡巴巴開源Weex 開發教程,開源weexWeex 是什麼 Weex是阿裡發布的一款用WEB方式開發原生app的開源產品 Weex能夠完美兼顧性能與動態性,讓移動開發者