【问题标题】:x86 - changing privilege level from CPL0 to CPL3x86 - 将权限级别从 CPL0 更改为 CPL3
【发布时间】:2012-07-17 01:05:27
【问题描述】:

我正在编写一些低级操作系统代码(64 位),并试图弄清楚如何从 CPL0 切换到 CPL3。问题是我遇到的英特尔开发人员手册中的这个小句子:''......处理器不允许将程序控制从以 CPL 0,1 或 2 运行的过程转移到以 0,1 或 2 运行的过程CPL 或 3,返回时除外。 "

TSS(任务状态段)甚至没有堆栈指针,那么 CPL3 代码将用于堆栈什么?我知道这是可能的(否则操作系统将如何启动任何应用程序代码)但我找不到任何文档。似乎您必须将一些 CPL3 代码的地址推送到堆栈上以诱骗处理器运行 CPL3 代码,但这听起来有点草率。你们知道更好的方法吗?非常感谢任何帮助。

【问题讨论】:

  • 当您说 TSS 甚至没有堆栈指针时,您的意思是您的 CPL3 代码只是第一次启动?编辑:您正在寻找的可能在内核堆栈上:stackoverflow.com/questions/4709582/…

标签: x86 privilege


【解决方案1】:

在 x86 中,如果你想将控制权从更高的特权级传递回更低的特权级,你必须使用 iret 指令。根据 iret 指令预期的结构(ss、esp、eflags、cs && eip)手动创建栈顶并调用 iret。

注意,示例适用于 x86。 x64 采用相同的方式,但使用了另一个寄存器,并且预期的堆栈布局可能略有不同。

VOID FASTCALL JumpFromCr0ToCr3(CONST ULONG cr3_eip, CONST USHORT cr3_cs , CONST ULONG cr3_flags, CONST ULONG cr3_esp, CONST USHORT cr3_ss)
{
    __asm
    {                               //        |     |
        push dword ptr [ESP + 0xC]; // ss     |  eip|<- stack pointer before iretd 
        push dword ptr [ESP + 0xC]; // esp    |   cs|
        push dword ptr [ESP + 0xC]; // flags  |flags|
        push            EDX       ; // cs     |   cs|
        push            ECX       ; // eip    |  eip|
                                  ;           -------
        iretd                     ;             top
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 2016-01-18
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多