使用呼叫门进行环过渡

时间:2019-01-03 22:01:36

标签: 64-bit gdt

我正在尝试使用呼叫门而不是SYSRET&SYSENTER执行从Ring 3到Ring 0的过渡,以了解呼叫门如何在IA-32e(64位)处理器上工作。

我知道的是呼叫门是一种特殊的结构,您可以将其放入GDT中,以便可以在不同的环之间执行过渡。

呼叫门的结构如下:

    typedef struct CALL_GATE
{
    unsigned __int32 offset0_15 : 16;
    unsigned __int32 selector :16;
    union {
        struct {
            unsigned __int16 ist : 3;
            unsigned __int16 ignored : 5;
            unsigned __int16 type : 5;
            unsigned __int16 dpl : 2;
            unsigned __int16 p : 1;
        } part;
        unsigned __int16 all;
    } dummy;
    unsigned __int64 offset16_63 : 48;
    unsigned __int32 reserved : 32;


}CALL_GATE, *PCALL_GATE;

我设置了一个windbg远程Windows内核调试器。现在,让我说说调度例程(处理器从环3转移到环0后我想去的位置)位于0xfffff8027f258bc0,所以我在此位置放置了一个硬件断点:

ba e 1 fffff802`7f258bc0

现在,我使用以下信息创建了呼叫门结构:

  • DPL:0x3
  • 选择器:0x10(KGDT64_R0_CODE)
  • 类型:0xc
  • p(显示):0x1
  • 并加上offset0_15和offset16_63:fffff8027f258bc0

结果结构(十六进制)如下:

00000000 fffff8027f25 ec00 0010 8bc0

现在,作为呼叫门(以及每个GDT条目)为128位或0x10字节。 我选择GDT的第8个条目将其转换为呼叫门,因此首先使用GDTR找到GDT的位置,然后修改其第8个条目(0x8个条目*每个条目的大小为0x10)。

    kd> r gdtr 
gdtr=fffff8028185afb0
kd> eb fffff8028185afb0+(0x8 * 0x10) 00 00 00 00 ff ff f8 02 7f 25 ec 00 00 10 8b c0

是时候使用远距离呼叫或远距离jmp使用我们的条目了。 我的用户模式应用程序(希望将执行转移到环0)执行以下指令:

00000000`00d2114e ea000000000800  jmp     0008:00000000

但是问题是什么也没有发生,用户模式应用程序既不会崩溃也不会将执行转移到环0(因为未触发我的硬件断点。)。

现在我的问题是,我的假设使问题从环3转移到环0怎么了?

更新:我还测试了0x40和0x43作为远jmp的选择器。

0 个答案:

没有答案