Windows保护模式学习笔记(五)—— 任务段任务门
Windows保護(hù)模式學(xué)習(xí)筆記(五)—— 任務(wù)段&任務(wù)門(mén)
- 要點(diǎn)回顧
- 任務(wù)段
- TSS (Task-state segment )
- TR段寄存器
- TR段寄存器的讀寫(xiě)
- TSS段描述符
- 實(shí)驗(yàn):加載自定義TSS
- 第一步:獲取必要參數(shù)
- 第二步:構(gòu)造TSS段描述符
- 第三步:將TSS段描述符寫(xiě)入GDT表
- 第四步:解除中斷,繼續(xù)執(zhí)行代碼
- 任務(wù)門(mén)
- 任務(wù)門(mén)執(zhí)行過(guò)程
- 實(shí)驗(yàn):通過(guò)任務(wù)門(mén)切換TSS
- 第一步:構(gòu)造任務(wù)門(mén)描述符
- 第二步:將任務(wù)門(mén)描述符寫(xiě)入IDT表
- 第三步:構(gòu)造TSS段描述符
- 第四步:運(yùn)行代碼
要點(diǎn)回顧
答案:TSS (Task-state segment ):任務(wù)狀態(tài)段
任務(wù)段
TSS (Task-state segment )
描述:
TSS是一塊內(nèi)存
大小:104字節(jié)
TSS存儲(chǔ)了一堆寄存器的值
TSS結(jié)構(gòu)圖:
TSS的作用:
TSS的本質(zhì):
CPU通過(guò)TR段寄存器尋找TSS
TR段寄存器
描述:
TR寄存器的值是當(dāng)操作系統(tǒng)啟動(dòng)時(shí),從TSS段描述符中加載出來(lái)的,TSS段描述符在GDT表中
TR.Base = TSS起始地址
TR.Limit = TSS大小
TR段寄存器的讀寫(xiě)
一、將TSS段描述符加載到TR寄存器
指令:LTR
說(shuō)明:
二、讀TR寄存器
指令:STR
說(shuō)明:如果用STR去讀的話,只讀了TR的16位,也就是段選擇子
TSS段描述符
描述:
TSS段描述符是系統(tǒng)段描述符中的一種
結(jié)構(gòu)圖:
Type = 二進(jìn)制1001:說(shuō)明該TSS段描述符未被加載到TR段寄存器中
Type = 二進(jìn)制1011:說(shuō)明該TSS段描述符已被加載到TR段寄存器中
TSS、TSS段描述符、TR段寄存器關(guān)系示意圖:
實(shí)驗(yàn):加載自定義TSS
第一步:獲取必要參數(shù)
在VC6中運(yùn)行如下代碼并在main函數(shù)頭部設(shè)置中斷:
#include <windows.h>DWORD dwOK; DWORD dwESP; DWORD dwCS;void __declspec(naked) func() {dwOK = 1;__asm{int 3mov eax,espmov dwESP,eaxmov ax,csmov word ptr [dwCS],ax//回去的代碼沒(méi)寫(xiě)。。。} }int main(int argc, char* argv[]) {char bu[0x10]; //12ff70int iCr3;printf("input CR3:\n");scanf("%x", &iCr3);DWORD iTss[0x68] = {0x00000000, //link0x00000000, //esp0 //(DWORD)bu0x00000000, //ss00x00000000, //esp10x00000000, //ss10x00000000, //esp20x00000000, //ss2(DWORD)iCr3, //cr30x0040DE50, //eip0x00000000, //eflags0x00000000, //eax0x00000000, //ecx0x00000000, //edx0x00000000, //ebx(DWORD)bu, //esp0x00000000, //ebp0x00000000, //esi0x00000000, //edi0x00000023, //es0x00000008, //cs 0x0000001B0x00000010, //ss 0x000000230x00000023, //ds0x00000030, //fs0x00000000, //gs0x00000000, //dit0x20ac0000};char buff[6];*(DWORD*)&buff[0] = 0x12345678;*(WORD*)&buff[4] = 0xC0;__asm{call fword ptr[buff]}printf("ok=%d \t ESP=%x \t CS=%x \n", dwOK, dwESP, dwCS);return 0; }進(jìn)入反匯編窗口查看 func 函數(shù)起始地址,我這里是0x401020
將地址填入iTss數(shù)組注釋為eip的地方,表示TSS切換后EIP的值
再通過(guò) memory 窗口查看iTss數(shù)組所在地址,記下來(lái)備用
注意:代碼中如有地方發(fā)生修改,需要先停止程序,重新編譯
第二步:構(gòu)造TSS段描述符
Offset in Segment 31:16 = 0x0000 // 暫定G = 0AVL = 0Limit = 二進(jìn)制:0000P = 1DPL = 二進(jìn)制:11Type = 二進(jìn)制:1001Segment Limit = 0068H // Intel規(guī)定TSS段描述符G=0時(shí)Limit必須大于或等于67H Offset in Segment 15:00 = 0x0000 // 暫定由上述參數(shù)構(gòu)造出的門(mén)描述符為:0000E900`00000068
在第一步中,我們已經(jīng)知道iTss數(shù)組所在地址為0x12FDCC
因此,TSS段描述符最終確定為:0000E912`FDCC0068
第三步:將TSS段描述符寫(xiě)入GDT表
我寫(xiě)入的地址是8003f0c0,若寫(xiě)入其他地址,則需要修改buff數(shù)組的后兩個(gè)字節(jié)
這時(shí)候先不要急著繼續(xù)運(yùn)行代碼,先在WinDbg中輸入命令:!process 0 0
獲得當(dāng)前進(jìn)程的Cr3(我這里進(jìn)程名叫TestDoor.exe,之前是用來(lái)做調(diào)用門(mén)的實(shí)驗(yàn),TSS沒(méi)有新建項(xiàng)目)
DirBase的值就是Cr3
第四步:解除中斷,繼續(xù)執(zhí)行代碼
輸入上一步得到的Cr3,回車(chē)
WinDbg成功獲得了中斷信號(hào)
這時(shí)候看一下反匯編代碼
可以確定正在執(zhí)行func函數(shù)的代碼
再看一下寄存器
eip、cs、ss都符合我們想要的結(jié)果
至此,TSS切換成功!
思考:TSS切換完成后,如何回到切換前的下一行繼續(xù)執(zhí)行?
任務(wù)門(mén)
描述:
任務(wù)門(mén)存在于IDT表
任務(wù)門(mén)中包含TSS段選擇子
可以通過(guò)訪問(wèn)任務(wù)門(mén)達(dá)到切換TSS的目的
結(jié)構(gòu)圖:
任務(wù)門(mén)執(zhí)行過(guò)程
實(shí)驗(yàn):通過(guò)任務(wù)門(mén)切換TSS
第一步:構(gòu)造任務(wù)門(mén)描述符
任務(wù)門(mén)描述符結(jié)構(gòu)圖灰色部分默認(rèn)填充為0
P = 1DPL = 二進(jìn)制:11TSS Segment Selector = 0x00C3 // TSS段描述符選擇子由上述參數(shù)及默認(rèn)參數(shù)構(gòu)造出的門(mén)描述符為:0000e500`00C30000
第二步:將任務(wù)門(mén)描述符寫(xiě)入IDT表
第三步:構(gòu)造TSS段描述符
TSS段描述符構(gòu)造具體過(guò)程參照任務(wù)段實(shí)驗(yàn)部分,這里不再詳解,只給出測(cè)試代碼
代碼如下:
#include <windows.h>DWORD dwOK; DWORD dwESP; DWORD dwCS;void __declspec(naked) func() {dwOK = 1;__asm{mov eax,espmov dwESP,eaxmov ax,csmov word ptr [dwCS],axiretd} }int main(int argc, char* argv[]) {char bu[0x10]; //12ff70int iCr3;printf("input CR3:\n");scanf("%x", &iCr3);DWORD iTss[0x68] = {0x00000000, //link0x00000000, //esp0 //(DWORD)bu0x00000000, //ss00x00000000, //esp10x00000000, //ss10x00000000, //esp20x00000000, //ss2(DWORD)iCr3, //cr30x00401020, //eip0x00000000, //eflags0x00000000, //eax0x00000000, //ecx0x00000000, //edx0x00000000, //ebx(DWORD)bu, //esp0x00000000, //ebp0x00000000, //esi0x00000000, //edi0x00000023, //es0x00000008, //cs 0x0000001B0x00000010, //ss 0x000000230x00000023, //ds0x00000030, //fs0x00000000, //gs0x00000000, //dit0x20ac0000};__asm{int 0x20}printf("ok=%d \t ESP=%x \t CS=%x \n", dwOK, dwESP, dwCS);getchar();return 0; }第四步:運(yùn)行代碼
需要輸入Cr3,Cr3獲取流程參照任務(wù)段實(shí)驗(yàn)部分,這里不再詳解
運(yùn)行結(jié)果:
TSS切換成功!
至此,我們已經(jīng)學(xué)會(huì)通過(guò)CALL/JMP以及任務(wù)門(mén)來(lái)切換TSS
思考:既然已經(jīng)可以直接訪問(wèn)任務(wù)段了,為什么還要有任務(wù)門(mén)?
總結(jié)
以上是生活随笔為你收集整理的Windows保护模式学习笔记(五)—— 任务段任务门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Windows保护模式学习笔记(四)——
- 下一篇: Windows保护模式学习笔记(六)——