保护模式(四):任务段与任务门
TSS结构
使用TSS过程
在GDT表中有TSS段描述符,TR寄存器Base Address为TSS位置,Segment Limit为TSS长度
TSS段描述符结构
B位如果为0表示还未加载到TR寄存器中,为1则已经加载
任务门结构
任务门放在IDT表中
实验
构造任务门
eq 8003f500 0000e500`00c30000
构造TSS段描述符
eq 8003f0c0 0000e912`eefc0068
测试代码
// KernalTest.cpp : Defines the entry point for the console application.
//代码借鉴了https://blog.csdn.net/Kwansy/article/details/108896989
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
DWORD dwOk;
DWORD X;
WORD Y;
// 任务切换后的EIP
void __declspec(naked) Test()
{
dwOk = 1;
__asm
{
pushad
pushfd
mov eax,esp
mov X,eax
mov ax,cs
mov Y,ax
pushfd
pushad
iretd
}
}
int main()
{
DWORD Cr3;
char esp[0x1000];
DWORD TSS[0x20];
printf("%x\n",(DWORD)TSS);
printf("input CR3: ");
scanf("%x", &Cr3); // 注意是%x
TSS[0] = 0x00000000; // Previous Task Link
TSS[1] = 0x00000000; // ESP0
TSS[2] = 0x00000000; // SS0
TSS[3] = 0x00000000; // ESP1
TSS[4] = 0x00000000; // SS1
TSS[5] = 0x00000000; // ESP2
TSS[6] = 0x00000000; // SS2
TSS[7] = Cr3; // CR3
TSS[8] = (DWORD)Test; // EIP
TSS[9] = 0x00000000; // EFLAGS
TSS[10] = 0x00000000; // EAX
TSS[11] = 0x00000000; // ECX
TSS[12] = 0x00000000; // EDX
TSS[13] = 0x00000000; // EBX
TSS[14] = (DWORD)esp+0x500; // ESP
TSS[15] = 0x00000000; // EBP
TSS[16] = 0x00000000; // ESI
TSS[17] = 0x00000000; // EDI
TSS[18] = 0x00000023; // ES
TSS[19] = 0x00000008; // CS 0x0000001B
TSS[20] = 0x00000010; // SS 0x00000023
TSS[21] = 0x00000023; // DS
TSS[22] = 0x00000030; // FS 0x0000003B
TSS[23] = 0x00000000; // GS
TSS[24] = 0x00000000; // LDT Segment Selector
TSS[25] = 0x20ac0000; // I/O Map Base Address
__asm
{
int 0x20
}
printf("ok: %d,esp=%x,cs=%x",dwOk,X,Y);
return 0;
}