• 段间跳转之调用门


    调用门

    也就是在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指令返回,我们可以修改堆栈返回到我们想要的地址处。

  • 相关阅读:
    [LeetCode]题解(python):089-Gray Code
    [LeetCode]题解(python):088-Merge Sorted Array
    [LeetCode]题解(python):086-Partition List
    [LeetCode]题解(python):083-Remove Duplicates from Sorted List
    [LeetCode]题解(python):082-Remove Duplicates from Sorted List II
    [LeetCode]题解(python):081-Search in Rotated Sorted Array II
    [LeetCode]题解(python):080-Remove Duplicates from Sorted Array II
    [LeetCode]题解(python):079-Word Search
    [LeetCode]题解(python):078-Subsets
    软件开发冲刺5
  • 原文地址:https://www.cnblogs.com/revercc/p/14459976.html
Copyright © 2020-2023  润新知