中断门描述符
中断门概述
1.系统调用
Windows没有使用调用门,但是使用了中断门。
Windows很多3环API最终都要使用0环的代码,是使用中断门实现的这种功能。
注意:老的CPU是用的中断门而最新的CPU是使用的快速调用。
2.调试
在像OD这种调试工具中按F12下的断点就是将BYTE内容变为0xCC指令位int3这是中断门效果。
中断门和调用门的区别
中断门和调用门很相似他们最大的区别是查表的不同,
调用门是使用的GDT表而中断门使用的是IDT表。
IDT表概述
IDT全名中断描述符表,同GDT表一样,IDT也是由一系列描述符组成的,每个描述符占8个字节,
需要注意的是,IDT表中第一个元素不是NULL。
windbg查询IDT表基地址和长度:
r idtr //查询IDT表基地址
r idtl //查询IDT表长度
GDT相比IDT而言,GDT存在代码段或数据段和系统段三种类型,而IDT全部是系统段。
IDT表的构成
IDT表可以包含3种门描述符:
任务门描述符、中断门描述符、陷阱门描述符。
中断门描述符与调用门描述符
中断门描述符跟调用门描述符的段描述符是一样的。
中断门不允许传递参数,调用门允许传递参数。
中断门属性:
P位=1 DPL=11 S=0 Type域=D110
陷阱门描述符
陷阱门概述
陷阱门与中断门不能传递参数,基本上是一样的。
陷阱门Type域是D111,中断门Type域是D110
陷阱门与中断门的区别
中断门执行时,将IF位清零,但陷阱门不会。
IF位是EFLAGS的第9位,IF为0意味着不在接收可屏蔽中断。
可屏蔽中断:
比如键盘按下按键后CPU能够知道实际上是键盘向CPU发送了一个可屏蔽中断。
可屏蔽中断受IF位影响,如果IF位为0则按按键CPU不会去处理。
不可屏蔽中断:
比如计算机执行的时候突然断电了,断电的时候电源会通过电源管理器向
当前CPU发送一个请求,这个请求不受IF位影响叫不可屏蔽中断,此时不管
IF位为1或者为0,CPU必须立刻马上去处理。
实际上主板上电容可以让CPU在断电后在运行一段时间去做一些清理工作。
TSS段描述符
任务段(TSS)
TSS是一块内存,该数据结构大小为104字节,共26个DWORD属性。
通过TSS可以同时替换一堆寄存器包括通用寄存器和段寄存器。
TSS结构是一个链表,开头4字节指向上一个TSS段选择子,TSS保存了
0环1环2环的ESP、SS、cr3、eip、eflags、eax、ecx、edx、ebx、esp、esi、
edi、es、cs、ss、ds、fs、gs、ldt寄存器。
段描述符:S=0 TYPE=10B1 是任务段描述符 G=0(Limit字节为单位)最大范围0xFFFFF
数据结构:
typedef struct TSS {
DWORD link;
DWORD esp0;
DWORD ss0;
DWORD esp1;
DWORD ss1;
DWORD esp2;
DWORD ss2;
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;//LDT局部描述符表,windows没有使用S=0是系统段
DWORD io_map;//IO权限位图
} TSS;
TSS作用:CPU设计机制用于多线程,任务段可以让一个CPU在同时执行多个任务。
windows并没有使用任务段来进行任务切换,而是讲任务切换需要的寄存器保存在堆栈中。
TR段
寻找TSS任务段,可以通过TR段寄存器找到。
LTR指令:将TSS段描述符加载到TR寄存器可以使用LTR指令,只能在0环使用。
LTR指令说明:
1.用LTR指令会将TSS加载到TR寄存器中,但是没有改变真正的TSS。
2.LTR指令只有在CPL=0的情况下可以使用也就是系统层。
3.记载TSS段描述状态位会发生改变。
JMP FAR、CALL FAR与LTR指令的区别
LTR指令必须运行在0环,LTR指令只修改TR段寄存器,并不会触发TSS进行全部寄存器值切换。
JMP FAR和CALL FAR可以通过段选择子找到对应的GDT段描述符,当DPL=11可以在3环使用,
切JMP FAR和CALL FAR会触发TSS任务段机制使其切换全部寄存器。
JMP FAR和CALL FAR访问任务段的区别
JMP FAR(不会恢复寄存器):
使用JMP FAR实现任务切换时,TSS结构体中的Link值在任务切换之后为0。
JMP FAR不会对EFLAGS寄存器中NT位修改。
CALL FAR(可以恢复之前寄存器):
使用CALL FAR实现任务切换后,Link值是填充为原来的TSS段选择子。
CALL FAR会对EFLAGS寄存器中的NT位修改为1。
NT位对iret指令产生影响NT位如果位0,iret的值从堆栈中取(中断返回),
如果NT位为1,会找TSS数据结构中的Link进行返回。
JMP FAR CALL FAR执行代码段与任务段区别
JMP FAR代码段后假设0x48是段选择子那么CS=0x48
如果0x48是TSS段描述符那边,首先他会修改TR寄存器,
其次使用TR.Base指向的TSS中104字节的值进行全部寄存器的替换。
使用任务段TSS步骤
1.创建104字节的数据结构填充寄存器内容。
2.准备好TSS段描述符写入到GDT表(TYPE域=10B1)。
3.修改TR寄存器
1)在0环可以使用LTR指令去修改TR寄存器。
2)3环可以通过CALL FAR或者JMP FAR指令来修改。
任务门描述符
GDT、LDT、IDT的区别
GDT:全局描述符表
Windbg使用r gdtr和r gdtl命令查看GDT
全局描述符表在系统中只能有一个,且可以被每一个任务所共享,
任何描述符都可以放在GDT中,但中断门和陷阱门放在GDT中不会起作用,
能被多个任务共享的内存就是通过GDT完成的。
LDT:局部描述符表
局部描述符表在系统中可以有多个,通产情况下是域任务数量保持对等,
但任务可以没有局部描述表,任务间不相干的部分也是通过LDT实现的,
这里涉及地址映射问题和GDT一样,中断门和陷阱门放在LDT中不会起作用。
IDT:中断描述符表
Windbg使用!idt查看idt
和GDT一样,中断描述符在系统最大只能有一个,中断描述符表可以存在256个描述符,
分别对应256个中断,因为每个描述符占用8个字节,所以IDT长度可以达到2K,
中断描述符中可以有任务门、中断门、陷阱门、三个门描述符,其他描述符在
中断描述符表中没有意义。
任务门描述符
在任务门描述符中Reserved代表保留的意思,可以用0填充。
TSS Segment Selector位于地16-31位使用一个TSS段描述符填充,
实际上就是TSS的段选择子去GDT全局描述符表里去找TSS描述符。
需要注意的是:任务门存在跨表首先任务门是在IDT中断描述符表中的,
任务门描述符,但其中TSS段选择子中的TSS描述符却写在了GDT全局描述符表中。
任务门执行过程
1.INT 0x20
2.查IDT表,找到中断门描述符
3.通过中断门描述符,查GDT表,找到任务段描述符
4.将任务段描述符加载到TR寄存器之后通过TR寄存器指向的104字节
的TSS段将全部寄存器的值进行修改。
5.IRETD返回
任务门总结:
任务门其实是访问TSS段的一种方式,可以使用JMP FAR或者CALL FAR来使用TSS段,
CPU提供TSS是希望在切换任务的时候用这种方式进行切换,但是Windows和Linux并没有使用。