Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #72, ДЕКАБРЬ 2004 г.

Абсолютный ноль

Николай «GorluM» Андреев

Хакер, номер #072, стр. 072-068-3


Надо научиться модифицировать эти таблицы (или хотя бы одну из них), а для этого нужно знать три вещи:

а) формат таблиц,

б) как модифицировать (формат ячейки),

в) где находится таблица для модификации.

Формат таблиц фактически заключается в размере ячеек и их количестве. К примеру, IDT состоит из 8-байтных дескрипторов, формат которых нам не важен, но если тебе это очень интересно – загляни в интеловский мануал. Максимальное количество дескрипторов в IDT – 256 штук. GDT может быть побольше и содержать аж до 8192 8-байтных дескрипторов, правда, винда использует только 1024, а нулевой дескриптор вообще не может быть использован (попробуй – увидишь BSoD).

Для того чтобы попасть в нулевое кольцо привилегий, нужно добавить в одну из этих таблиц новую запись – шлюз, в котором бы содержались все необходимые данные, такие как уровень привилегий, с которого осуществляется переход, адрес функции, запускаемой после перехода, и т.п. Самым популярным у вирмейкеров шлюзом является калгейт. Формат у него такой:

Формат калгейта

typedef struct _CALLGATE_DESCRIPTOR {

// младшая часть смещения

USHORT offset_0_15;

// селектор смещения

USHORT selector;

// счетчик параметров - нуля хватит

UCHAR param_count :4;

// четыре нуля

UCHAR some_bits :4;

// тип записи, калгейт – 1100b, т.е. 12 в десятичной

UCHAR type :4;

// системный сегмент - ноль

UCHAR app_system :1;

// с какого уровня будем пользоваться – с третьего

UCHAR dpl :2;

// пустая ли запись – нет, не пустая

UCHAR present :1;

// старшая часть смещения

USHORT offset_16_31;

} CALLGATE_DESCRIPTOR, *PCALLGATE_DESCRIPTOR;

Члены этой структуры, после имени которых стоят двоеточия и цифры, – это битовые поля. Достаточно заполнить структуру, записать ее в свободное место в таблице (оно определяется по биту present, равному нулю) и вызвать дальний адрес, у которого селектор бы указывал на наш шлюз, а смещение было бы равно нулю (оно игнорируется камнем), – и все. Вроде бы все очень просто и понятно (особенно когда на программу саму посмотришь), но где хранится эта LDT?

Получить адрес таблицы очень просто, нужно воспользоваться инструкциями sgdt (для таблицы GDT) или sidt (для IDT), которые можно выполнять на любом кольце. Они извлекут из регистров IDTR и GDTR 48-битную структуру и запишут по заданному тобой адресу. В структуре младшие 16 бит – это предел таблицы, а старшие 32 – это ее виртуальный адрес. Вроде бы на этом повествование должно закончиться, ведь для модификации есть все данные. Не тут-то было! Эти регистры сообщают, что таблицы находятся в верхних двух гигах памяти! Вот подстава, туда же нет доступа из ринг3!

Тут-то и заканчивается мой пересказ интеловского мануала и начинается описание хакерского способа.

Назад на стр. 072-068-2  Содержание  Вперед на стр. 072-068-4