Windows保護模式學習筆記(二)—— 代碼跨段跳轉
原創 lzyddf 最後釋出于2019-10-16 19:17:08 閱讀數 46
Windows保護模式學習筆記(二)—— 代碼跨段跳轉
-
- 前言
- 要點回顧
- 代碼跨段跳轉
-
- 執行流程
-
- 1)段選擇子拆分
- 2)查表得到段描述符
- 3)權限檢查
- 4)加載段描述符
- 5)代碼執行
- 6)總結
-
- 一緻代碼段(共享的段)
- 非一緻代碼段(普通代碼段)
- 實驗
-
- 第一步:
- 第二步:
- 第三步:
- 第四步:
- 總結
前言
一、學習自中級班課程,
滴水程式設計達人
二、海東老師牛逼!
官網:https://bcdaren.com
要點回顧
段寄存器:
ES,CS,SS,DS,FS,GS,LDTR,TR
除CS外,其他的段寄存器都可以通過
MOV,LES,LSS,LDS,LFS,LGS
指令進行修改
思考:CS為什麼不可以直接修改呢?
CS的改變意味着EIP的改變,改變CS的同時必須修改EIP,是以我們無法使用上面的指令來進行修改.
代碼跨段跳轉
段間跳轉分為兩種情況:
- 要跳轉的段是一緻代碼段
- 要跳轉的段是非一緻代碼段
同時修改CS與EIP的指令:
JMP FAR / CALL FAR / RETF / INT /IRETED
隻改變EIP的指令:
JMP / CALL JCC / RET
執行流程
思考:CPU如何執行
JMP 0x20:0x004183D
這行指令
1)段選擇子拆分
0x20 二進制:0000 0000 0010 0000 即
RPL = 00
TI = 0
Index = 4
- 1
- 2
- 3
2)查表得到段描述符
TI=0:查GDT表
Index=4:找到對應的段描述符
四種情況可以跳轉:
- 代碼段
- 調用門
- TSS任務段
- 任務門
3)權限檢查
一緻代碼段:要求
CPL >= DPL
非一緻代碼段:要求
CPL == DPL
并且
RPL <= DPL
4)加載段描述符
通過上面的權限檢查後,CPU會将段描述符加載到CS段寄存器中
5)代碼執行
CPU 将
CS.Base + Offset
的值寫入EIP,然後執行CS:EIP處的代碼
段間跳轉到此結束
6)總結
一緻代碼段(共享的段)
- 特權級高的程式不允許通路特權級低的資料:核心态不允許通路使用者态的資料
- 特權級低的程式可以通路到特權級高的資料,但特權級不會改變:使用者态還是使用者态
非一緻代碼段(普通代碼段)
- 隻允許同級通路
- 絕對禁止不同級别的通路:核心态不是使用者态,使用者态也不是核心态
注意:直接對代碼段進行JMP 或者 CALL的操作,無論目标是一緻代碼段還是非一緻代碼段,CPL都不會發生改變.如果要提升CPL的權限,隻能通過調用門
實驗
第一步:
複制一個非一緻代碼段描述符,寫入GDT表空白處

第二步:
在OD中執行 JMP FAR 指令
執行前,CS = 001B
執行後,CS = 004B
執行成功!
第三步:
将段描述符的 DPL 置為 0,再在OD中執行JMP FAR指令
執行後,程式進入了ntdll,也就是異常子產品,說明執行失敗
失敗原因:
要跳轉的代碼段是一個非一緻代碼段(DPL=0),而程式的CPL=3,權限檢查未通過
非一緻代碼段要求CPL=DPL時才允許跳轉
這樣設計的目的是防止3環的程式跳轉到系統段執行
第四步:
将段描述符Type域的C位改為1,令其成為一緻代碼段
再次執行JMP FAR指令
執行成功!
總結
一、為了對資料進行保護,普通代碼段禁止使用者态的代碼/資料和核心态的代碼/資料互相通路
二、如果選擇一緻代碼段,低級别的程式就可以在不提升CPL權限等級的情況下進行通路,并且不會破壞核心态的資料
三、如果想通路普通代碼段,必須通過"調用門"等方式提升CPL權限