生活随笔
收集整理的這篇文章主要介紹了
9.任务段(TSS)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在調用門、中斷門與陷阱門中,一旦出現權限切換,那么就會有堆棧的 ,切換。而且,由于CS的CPL發生改變,也導致了SS也必須要切換。
切換時,會有新的ESP和SS(CS是由中斷門或者調用門指定)這2個值從哪里來的呢?
答案: TSS (Task-state segment ),任務狀態段
TSS就是一塊內存,大小104個節。
不要把TSS與任務切換聯系到一起
TSS的意義就在于可以同時換掉一堆寄存器
TSS是段描述符,從GDT表中的加載出來的
系統啟動-》從GDT表中的加載出的TSS-》放到TR寄存器里,系統要用直接找TR寄存器
TSS是系統段,s位為0,TYPE域為:1001或者1011
這兩特征說明他是一個TSS段描述符,type為1001說明這個tss沒有加載到TR寄存器中,1011說明已經加載到TR寄存器中
tss的顆粒位為0(G位)
TR寄存器讀寫:
1)將TSS段描述符加載到TR寄存器
指令: LTR
說明:
用LTR指令去裝載的話僅僅是改變TR寄存器的值(96位)并沒有真正改變TSS
LTR指令只能在系統層使用
加載后TSS段描述符會狀態位會發生改變(1001變1011)
2)讀TR寄存器
指令: STR
說明:如果用STR去讀的話,只讀了TR的16位也就是選擇子(可見部分)
修改TR寄存器
1)在Ringo我們可以通過LTR臨令去修改TR寄存器
2)在Ring3我們可以通過CALL FAR或者JMP FAR指令來修改
用JMP去訪問一個代碼段的時候,改變的是CS和EIP:
JMP 0x48:0x123456如果0x48是代碼段
執行后: CS->0x48 ElP.-x123456
用JMP去訪問一個任務段的時候:
如果0x48是TSS段描述符,先修改TR寄存器,在用TR.Base指向的TSS中的值修改當前的器存器
TSS存在的意義
提權時棧切換用到了 TSS
切換一堆寄存器
測試
修改gdt。
xx00e9xx`xxxx0068
xx為base,填TSS的
#include<windows.h>
#include<stdio.h>typedef struct TSS {DWORD link; // 保存前一個 TSS 段選擇子,使用 call 指令切換寄存器的時候由CPU填寫。// 這 6 個值是固定不變的,用于提權,CPU 切換棧的時候用DWORD esp0; // 保存 0 環棧指針DWORD ss0; // 保存 0 環棧段選擇子DWORD esp1; // 保存 1 環棧指針DWORD ss1; // 保存 1 環棧段選擇子DWORD esp2; // 保存 2 環棧指針DWORD ss2; // 保存 2 環棧段選擇子// 下面這些都是用來做切換寄存器值用的,切換寄存器的時候由CPU自動填寫。DWORD cr3;DWORD eip;DWORD eflags;DWORD eax;DWORD ecx;DWORD edx;DWORD ebx;DWORD esp;DWORD ebp;DWORD esi;DWORD edi;DWORD es;DWORD cs;DWORD ss;DWORD ds;DWORD fs;DWORD gs;DWORD ldt;// 這個暫時忽略DWORD io_map;
} TSS;char st[10] = { 0 }; // 0042b034
DWORD g_esp = 0;
DWORD g_cs = 0;TSS tss = { // 0x00427b400x00000000,//link(DWORD)st, //esp00x00000010,//ss00x00000000,//esp10x00000000,//ss10x00000000,//esp20x00000000,//ss20x00000000,//cr30x0045a0c0,//eip-----填裸函數地址0x00000000,//eflags0x00000000,//eax0x00000000,//ecx0x00000000,//edx0x00000000,//ebx(DWORD)st, //esp0x00000000,//ebp0x00000000,//esi0x00000000,//edi0x00000023,//es 0x00000008,//cs 0x00000010,//ss0x00000023,//ds0x00000030,//fs0x00000000,//gs0x00000000,//ldt0x20ac0000
};void __declspec(naked) func() {//0045a0c0__asm {int 3mov g_esp, espmov eax, 0mov ax, csmov g_cs, eaxiret//中斷返回指令}
}
int main(int argc, char* argv[])
{printf("%x\n", &tss);printf("cr3:\n");scanf("%x", &(tss.cr3));char buffer[6] = { 0, 0, 0, 0, 0x48, 0 };__asm {call fword ptr[buffer]}printf("g_cs = %08x\ng_esp = %08x\n", g_cs, g_esp);getchar();return 0;
}
總結
以上是生活随笔為你收集整理的9.任务段(TSS)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。