12 中断门与陷阱门

当我们写Win32程序的时候,调用Windows提供的API,程序执行要一步一步从三环到0环,这一个过程就要用到中断门,新的CPU用快速调用。
1.IDT
IDT即中断描述符表,与GDT一样,IDT也是由一系列描述符组成,每个描述符占8个字节,但是IDT第一个描述符不是NULL.
在windbg中查看IDT的基址和大小指令如下:
r idtr
r idtl
在这里插入图片描述
2.IDT表构成
IDT表包括三种门描述符
任务门描述符
中断门描述符
陷阱门描述符
3.中断门描述符结构
该结构可以在架构手册的2431页找到
在这里插入图片描述
当描述符的S位也就是高四字节的第12位为0时,且Type域为1110时,这个描述符就是中断门描述符。其结构跟调用门类似,但是中断门不允许传参数。
接下来我们用中断门做一个读取高2G地址值的实验。
首先我们先来构造一个中段描述符P位一定要构造成1表示有效的描述符,由于我们的测试代码时在三环的,所以DPL应该弄成11
0000ee00 00080000
然后我们用下面代码来做测试:

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

DWORD dwH2GValue;

void _declspec(naked)GetH2GValue()
{
	_asm{
		pushad	//寄存器压栈,其入栈顺序是:EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI .
		pushfd	//将32位标志寄存器EFLAGS压入堆栈
		mov eax,[0x8003F00C]//读高两G内存的值
		mov ebx,[eax]
		mov dwH2GValue,ebx
		popfd
		popad
		iretd
	}
}

void PrintH2GValue()
{
	printf("%x\n", dwH2GValue);
}

int main()
{
	_asm{
		INT 0x20
	}
	PrintH2GValue();
	getchar();
	return 0;
}

同样先记录GetH2GValue的地址,然后补全中断门描述符为:
0040ee00 00081030
然后我们执行r idtr查看一下中断描述符表基址,如下图:
在这里插入图片描述
然后用dq 8003f400查看一下中段描述符表的信息,如下图:
在这里插入图片描述
用eq 8003f500 0040ee00`00081030将描述符写入IDT中,并用g命令继续运行虚拟机
在这里插入图片描述
且换到虚拟机中执行我们的代码,结果如下:
在这里插入图片描述
这里我们就成功读出了数据。
4.陷阱门描述符结构
在这里插入图片描述
从上图可以看出其结构和中断门几乎是一样的,只是Type域不一样
同样我们跟中断门采取一样的步骤做测试,构造的陷阱门描述符为:
0040ef00 00081030
写入IDT表: 在这里插入图片描述
执行结果如下:
在这里插入图片描述
可以看到同样读出数据。
5.陷阱门与中断门的区别
中断门执行时,将IF位置0,陷阱门不会。
IF位(标志位寄存器中下标为9的位)为0代表其不接受可屏蔽中断(可屏蔽中断自行查阅资料)

猜你喜欢

转载自blog.csdn.net/lifeshave/article/details/86552206