當我在說跳轉時,說的什么?
CPU有很多指令,不是所有的指令都能夠隨時用,比如
ltr指令就不是隨便什么時候能用,在保護模式下,如果你不安規則來執行指令,CPU就會拋出異常,比如你在INTEL手冊上就能看到如下文本
意思據是說,如果你當前的CPL不是RING0,那么就會拋出GP(0)異常!
所以要正確使用這個指令,你就需要將CPL跳轉到RING0來。這就是跳轉!
RING3到RING0(用戶態到內核態)的特權轉變過程
首先得要有一個RING3的代碼段,并且該代碼段正處于運行狀態
1.定義RING3代碼段
[SECTION .ring3]ALIGN 32[BITS 32]LABEL_CODE_RING3:
.
;此處省略RING3代碼段要做的事情
.
;最后一句轉移到ring0
2.必須為RING3代碼段定義描述符
LABEL_DESC_CODE_RING3: Descriptor 0, SegCodeRing3Len - 1, DA_C + DA_32 + DA_DPL3 ;DA_DPL3表明該代碼段特權等級是RING3
3.為RING3代碼段定義選擇子
SelectorCodeRing3 equ LABEL_DESC_CODE_RING3 - LABEL_GDT +SA_RPL3 ;SA_RPL3表明該選擇子的特權等級也是RING3
4.有了RING3的代碼段,描述符,選擇子,當然應該有RING0
[SECTION .ring0]ALIGN 32[BITS 32]LABEL_CODE_RING0:
.
;此處省略RING0代碼段要做的事情
LABEL_DESC_CODE_DEST: Descriptor 0, SegCodeDestLen - 1, DA_C + DA_32 ; 非一致代碼段 ,該段為RING0
SelectorCodeDest equ LABEL_DESC_CODE_DEST - LABEL_GDT ;RING0代碼段對應的選擇子
到此準備工作已經做好(各級堆棧也需要準備),要從RING3跳轉到RING0,通過這一篇文章,可以通過調用門實現從低級到高級的跳轉,接下來定義調用門,和調用門的選擇子
調用門
LABEL_CALL_GATE_TEST: Gate SelectorCodeDest, 0, 0, DA_386CGate + DA_DPL3;
選擇子
SelectorCallGateTest equ LABEL_CALL_GATE_TEST - LABEL_GDT + SA_RPL3
調用門定義時,需要用到RING0的選擇子。并且調用門和調用門選擇子的特權等級也都是RING3,加入調用門本身就定義為非RING3,那么在RING3代碼中執行跳轉時,就會報錯。
現在來晚上RING3代碼段最后一句,跳轉到RING0
call SelectorCallGateTest:0 ;
準備一大堆,一句話就跳轉了!RING3->RING0。從老幺一下權利躍升到老大!
新聞熱點
疑難解答