段间跳转之调用门

调用门

也就是在jmp far,call far时指定的那个段选择子指向的段描述是一个调用门描述符。其中低四个字节的高16位为一个隐藏的段选择子,而高四个字节的高16位与低4个字节的低16位共同组成32位的偏移地址。实际跳转的到的指令的地址为 :隐藏的段选择子指向的段的基地址 + 偏移地址。(其中调用门为系统段其S位为0)

jmp far调用门

一致代码段

如果调用门隐藏的段选择子指向的段描述符为一致代码段,我们jmp far是需要CPL <= 调用门的DPL,RPL <= 调用门的DPL,然后还需要隐藏段选择子的DPL <= CPL。
我们构造一个指向一致代码段的调用门

然后我们jmp far 0x90:0x00000000(其会将0x00000000偏移地址舍弃).执行前cs为0x1B,CPL为3而隐藏的段选择子指向的段的DPL为0。

执行后cs为0x4B,CPL还为3并没有变成0。

非一致代码段

非一致代码段和一致代码段的权限检查就有一点不同,那就是非一致代码段需要DPL = CPL,这也就确定了其CPL在调用前后肯定不会发生变化。

总结:无论是一致代码段还是非一致代码段jmp far利用调用门都不会改变CPL。

call far调用门

一致代码段

如果调用门隐藏的段选择子指向的段描述符为一致代码段,我们jmp far是需要CPL <= 调用门的DPL,RPL <= 调用门的DPL,然后还需要隐藏段选择子的DPL <= CPL。

我们构造和jmp far时一样的调用门,然后执行指令call far 0x90:0x00000000。执行前cs为0x1B,CPL为3而隐藏的段选择子指向的段的DPL为0。

调用后cs变为0x4B,CPL还是3而不是0,所以对于一致代码段call far也不会改变CPL

我们注意执行完call far后堆栈的变化,因为没有改变CPL(权限)所以其不会发生堆栈的切换。

非一致代码段

call far的非一致代码段和一致代码段的权限检查一样。
我们构造一个非一致代码的调用门

我们利用指令 call far 0x8:0x00000000,调用前cs为0x1B,CPL为3而隐藏的段选择子指向的段的DPL为0。ss指向DPL为3。

执行指令后cs为0x8,CPL为0,也就是现在我们具有了0环的权限。ss指向的DPL为0,因为ss的权限(DPL)要与cs的权限(DPL)一致,因为cpl权限提升到0环,所以堆栈切换,地址位于高2GB中esp > 0x80000000。

执行前后堆栈变化如下,其会将ss,esp,cs,返回地址依次保存在堆栈中。通过retf指令返回,我们可以修改堆栈返回到我们想要的地址处。

posted @ 2021-02-28 18:26  怎么可以吃突突  阅读(235)  评论(0编辑  收藏  举报