1

I'm trying to perform a Ring 3 to Ring 0 transition using Call Gates rather than SYSRET & SYSENTER to see how call gates work on IA-32e (64 Bit) processors.

What I know is Call Gates are special structure that you can put into GDT so it can be used in order to perform transition between different rings.

The structure of call gates are like this :

    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;

I set up a windbg remote Windows kernel debugger. Now let say my dispatch routine (the location where I want to go after the processor transferred from ring 3 to ring 0) is located at 0xfffff8027f258bc0 so I put a hardware breakpoint in this location :

ba e 1 fffff802`7f258bc0

Now I created a call gate structure with the following information :

  • DPL : 0x3
  • Selector : 0x10 (KGDT64_R0_CODE)
  • Type : 0xc
  • p (present) : 0x1
  • and append of offset0_15 & offset16_63 : fffff8027f258bc0

The result structure (in hex) is like this :

00000000 fffff8027f25 ec00 0010 8bc0

Now, as call gates (and every GDT entries) are 128 bit or 0x10 Byte. I choose the GDT's 8th entry to convert it into a call gate thus first find the GDT location using GDTR and then modify its 8th entry (0x8th entry * 0x10 size of every entries).

    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

It's time to use our entry using a far call or a far jmp. my user mode application (which wants to transfer execution to ring 0) executes the following instruction :

00000000`00d2114e ea000000000800  jmp     0008:00000000

But the problem is nothing happens, the user mode application neither crash nor transfer execution to ring 0 (because my hardware breakpoint not triggered.).

Now my question is, what's wrong with my assumptions that makes problem transferring from ring 3 to ring 0?

Update : I also test 0x40 and 0x43 as the selector for far jmp.

Mohammad Sina Karvandi
  • 1,064
  • 3
  • 25
  • 44

0 Answers0