[保护模式]段间跳转和跨段跳转
文章目錄
- 段間跳轉
- 段寄存器
- 段間跳轉
- 段間跳轉的執行流程
- 1.段選擇子拆分
- 2.查表得到段描述符
- 3.權限檢查
- 4.加載段描述符
- 5.代碼執行
- 總結
- 跨段跳轉
- 短調用
- 長調用
- 跨段不提權
- 跨段提權
- 總結
段間跳轉
代碼跨段,本質就是修改CS段寄存器
段寄存器
段寄存器有下面幾個:ES CS SS DS FS GS LDTR TR。除了CS以外,其他的段寄存器都可以通過MOV LES LSS LDS LFS LGS指令進行修改。
那么CS為什么不能直接修改呢?因為cs.base+eip=真正執行的地址。CS的改變意味著EIP的改變,改變CS的同時必須修改EIP,所以我們無法使用上面的指令來進行修改
段間跳轉
段間跳轉有兩種情況,即要跳轉的段是一致代碼段還是非一致代碼段。那么如果想要修改CS,可以使用下面的指令同時修改EIP和CS段寄存器
jmp far call far retf int ireted段間跳轉的執行流程
jmp far的指令格式為
jmp 0x20 0x12345678CPU在遇到這行代碼時,執行流程如下:
1.段選擇子拆分
0x20對應的二進制數為0000 0000 0010 0000
RPL=00 代表請求特權等級為0環權限
TI=0 代表查GDT表
Index=4代表查GDT表第5項(下標為4)
2.查表得到段描述符
通過段選擇子的Index找到對應的段描述符后,滿足四種情況則繼續執行:代碼段 調用門 TSS任務段 任務門
3.權限檢查
如果GDT表項是非一致代碼段,要求:CPL==DPL并且RPL<=DPL
如果GDT表項是一致代碼段,要求CPL>=DPL
原因在于一致代碼段允許權限低的代碼段訪問權限高的代碼段,而非一致代碼段只能被同等級權限或更高權限的代碼訪問。
4.加載段描述符
通過上面的權限檢查后,CPU會將段描述符加載到CS段寄存器中
5.代碼執行
CPU將cs.base+offset的值寫入EIP,然后執行CS:EIP處的代碼,段間跳轉結束
總結
對于一致代碼段:也就是共享的段
- 特權級高的程序不允許訪問特權級低的數據:內核態不允許訪問用戶態的數據
- 特權級低的程序可以訪問到特權級高的數據,但特權等級不會改變:用戶態還是用戶態
對于非一致代碼段:
- 只允許同級訪問
- 絕對禁止不同級別的訪問
直接對代碼段進行JMP或者CALL的操作,無論目標是一致代碼段還是非一致代碼段,CPL都不會發生改變。如果要提升CPL的權限,只能通過調用門。
跨段跳轉
一致代碼段允許特權級低的代碼訪問特權級高的代碼,那么如果遇到非一致代碼段怎么辦呢?那么就需要提權了。也就是所謂的跨段跳轉。
我們通過JMP FAR可以實現段間跳轉,如果要實現跨段跳轉就必須用CALL FAR。CALL FAR比JMP FAR要復雜,JMP并不影響堆棧,但CALL指令會影響
短調用
普通的調用指令格式為:call 立即數/寄存器/內存。短調用執行時會先將返回地址壓入到堆棧,然后修改EIP。堆棧圖如下:
而ret指令則相當于是pop eip+jmp eip。call和ret指令影響的寄存器有ESP和EIP。
長調用
跨段不提權
指令格式:CALL CS:EIP(EIP是廢棄的),其堆棧圖如圖所示:
長調用執行時會將當前的CS段寄存器和返回地址壓入到堆棧,RETF指令執行時則會將當前的CS和返回地址彈出堆棧。CALL指令執行完成之后當前的EIP會指向哪由CS指向的段描述符決定。發生改變的寄存器有:ESP EIP CS
跨段提權
指令格式:CALL CS:EIP(EIP是廢棄的),其堆棧圖如圖所示:
跨段提權時當前CS的寄存器的CPL會發生改變,CS發生改變必然伴隨著SS的改變。所以跨段提權的長調用執行后會將SS ESP CS和放回地址都壓入到堆棧中。
發生改變的寄存器:ESP EIP CS SS。
總結
總結
以上是生活随笔為你收集整理的[保护模式]段间跳转和跨段跳转的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows内核实验005 Inlin
- 下一篇: [保护模式]调用门