Переход по кольцу с использованием ворот вызова - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь выполнить переход от кольца 3 к кольцу 0, используя ворота вызовов, а не SYSRET & SYSENTER, чтобы посмотреть, как работают ворота вызовов на процессорах IA-32e (64-разрядных).

Что я знаю, так это Call Gates - это специальная структура, которую вы можете вставить в 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;

Я установил удаленный отладчик ядра Windows для windbg.Теперь допустим, что моя процедура отправки (место, куда я хочу перейти после того, как процессор перешел с кольца 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 байт.Я выбираю 8-ую запись GDT, чтобы преобразовать ее в шлюз вызовов, поэтому сначала найдите местоположение GDT с помощью GDTR, а затем измените его 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.

...