为何使用任务门
之前任务段中提到,进行任何切换时可以还可以使用任务门。那么既然存在TSS段描述符了,为何还需要任务门呢?
简要概括,任务门有如下优势:
- 任务门可以放在GDT表中,也可以放在IDT表中,还能放在当前线程的LDT表中,而TSS段描述符只能在GDT表中
- 任务门可以让低权限的线程进行任何切换,任务门的结构中也有DPL属性,当通过任务门去访问TSS描述符时,一旦通过任务门,TSS段描述符就不再进行检查了,即使你是个CPL=3的程序,而TSS段描述符的DPL=0,只要任务门DPL=3,就可以通过任务门完成任务切换,稍后会做这个实验。
- 由于任务门可以位于IDT表中,所以当遇到中断或者异常时,可以切换到独立的任务去处理异常
下面为不同表中,任务门进行任务切换的过程:
任务门描述符
任务门描述符的结构非常简单,真正用到的只有24位,属性位里:DPL一般设置为3,方便应用程序访问,Type则是固定的0101,TSS段选择子,顾名思义,就是一个段选择子,指向位于GDT表中TSS段描述符的位置。其余位均为保留位,置0即可。
任务门实现任务切换
这一步十分简单,仅仅比使用TSS多了一个步骤而已,这里也不细讲了,直接上步骤。
首先,编译源文件,下断点,确定TSS的地址,根据地址构造TSS段描述符:
第二步,根据GDT表中构造好的TSS段描述符位置,在IDT表中构造任务门:
第三步,在Windbg中使用!process 0 0指令确定CR3的值,并填入自己的TSS中:
执行程序,获取到自己构造的TSS表数据,任务切换成功:
总结
任务门总体还是比较简单,由于是通过int 0x20中断进入,因此iretd作为中断返回出来,比起JMP FAR还需要手动修改EFLAGS的NT位和previous task link容易的多。比较遗憾的是,这一部分的小作业,通过任务门进1环,还是失败了。这里稍微说一下我的思路,由于是进入1环(虽然windows没用1环),但我们让他进入1环,就替换1环的寄存器,ESP1和SS1,当然SS1和CS都需要设置CPL值为1,但是原本0环这两个段寄存器控制的都是DPL=0的段,因此我们需要构造一个1环的段描述符,我实验的时候构造了一个1环的非一致代码段描述符和一个1环的数据段描述符,让任务切换后的CS,SS载入段描述符信息用。同时还需要把TSS段描述符的DPL设置为1,其余值保持不变。可惜,几次都死掉了,实验没能成功,群内也没人这个进入1环的实验,以后有人讨论的话会考虑再试试。
任务段任务门这里有些遗憾吧,的确有点复杂,没理解透彻,感觉任务段那讲的也不是很清晰,希望以后我还能看得懂吧,接下来进入页的内容了,保护模式的关键来了,得掌握好。