保护模式(四):任务段与任务门

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;
}

 

posted @ 2020-12-24 20:16  Harmonica11  阅读(186)  评论(0编辑  收藏  举报