14 任务门

1.IDT中断描述符表
IDT中包含了三种门描述符:
任务门描述符
中断门描述符
陷阱门描述符
2.任务门描述符
在这里插入图片描述
3.任务门执行过程
INT N
通过N查IDT表,找到任务门描述符
通过任务门描述符查GDT表,找到任务段描述符
使用TSS段中的值修改寄存器
IRETD返回
接下来我们先做一个用任务段一次切换一堆寄存器的值的实验,实验代码如下:

#include <stdio.h>
#include <windows.h>

_declspec(naked)Fun()
{
	_asm{
		int 3
	}
}

int main()
{
	char stack[0x10];//用分配的内存当做栈用
	int iCr3;
	printf("please input CR3:\n");
	scanf("%x",&iCr3);

	//准备104个字节并赋初值
	DWORD iTss[0x68] = {
		0x00000000,//link 存放切换前的段选择子
		0x00000000,//esp
		0x00000000,//ss
		0x00000000,//esp1
		0x00000000,//ss1
		0x00000000,//esp2
		0x00000000,//ss2
		(DWORD)iCr3,//Cr3
		0x00401020,//eip切换Fun()
		0x00000000,//eFlags
		0x00000000,//eax
		0x00000000,//ecx
		0x00000000,//edx
		0x00000000,//ebx
		(DWORD)stack,//esp
		0x00000000,//ebp
		0x00000000,//esi
		0x00000000,//edi
		0x00000023,//es
		0x00000008,//cs
		0x00000010,//ss
		0x00000023,//ds
		0x00000030,//fs
		0x00000000,//gs
		0x00000000,//idt
		0x20ac0000//I/O权限位图
	};
	char buffer[6];
	*(DWORD*)&buffer[0] = 0x12345678;
	*(WORD*)&buffer[4] = 0xC0;
	_asm{
		call fword ptr[buffer]
	}
	return 0;
}

实验设计思路:
1.分配一块104字节的内存
2.TSS赋值
3.准备TSS段描述符(结构可以参考上一篇中的结构图,注意此时的G位为0)
4.修改TR寄存器(可以用LTR、JMP FAR、CALL FAR)
5.构造GDT段描述符(eq 8003f0c0 0000e912`FDCC0068(根据实际情况构造))
6.执行然后提示输入CR3时,我们切换到真机在Windbg中点击debug->break,然后输入指令!process 0 0,找到我们的TSS.exe的DirBase值如下图:
在这里插入图片描述
7.然后输入g继续运行虚拟机,并在虚拟机中输入DirBase值,如下:
在这里插入图片描述
8.回车继续运行后断到windbg中,这时我们输入r命令来查看寄存器可以看到都被改成了我们定义的Tss中的值,如下图:

在这里插入图片描述

接下来我们将上面的代码稍微做一下修改,如下:

#include <stdio.h>
#include <windows.h>

DWORD dwOK;
DWORD dwESP;
WORD dwCS;

_declspec(naked)Fun()
{
	dwOK = 1;
	_asm{
		mov eax,esp
		mov dwESP,eax
		mov ax,cs
		mov dwCS,ax
		iretd
	}
}

int main()
{
	char stack[0x10];//用分配的内存当做栈用
	int iCr3;
	printf("please input CR3:\n");
	scanf("%x",&iCr3);

	//准备104个字节并赋初值
	DWORD iTss[0x68] = {
		0x00000000,//link 存放切换前的段选择子
		0x00000000,//esp
		0x00000000,//ss
		0x00000000,//esp1
		0x00000000,//ss1
		0x00000000,//esp2
		0x00000000,//ss2
		(DWORD)iCr3,//Cr3
		0x00401020,//eip切换Fun()
		0x00000000,//eFlags
		0x00000000,//eax
		0x00000000,//ecx
		0x00000000,//edx
		0x00000000,//ebx
		(DWORD)stack,//esp
		0x00000000,//ebp
		0x00000000,//esi
		0x00000000,//edi
		0x00000023,//es
		0x00000008,//cs
		0x00000010,//ss
		0x00000023,//ds
		0x00000030,//fs
		0x00000000,//gs
		0x00000000,//idt
		0x20ac0000//I/O权限位图
	};
	char buffer[6];
	*(DWORD*)&buffer[0] = 0x12345678;
	*(WORD*)&buffer[4] = 0xC0;
	_asm{
		int 0x20//这里稍作修改
	}
	printf("OK: %x, ESP: %x, CS: %x", dwOK, dwESP, dwCS);
	return 0;
}

我们这时构造任务门描述符写入IDT中,并构造TSS描述符写入GDT中,如下图:
在这里插入图片描述
重复上面的步骤输入CR3
在这里插入图片描述
可以看到执行结果如下
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lifeshave/article/details/86613273
14