Жизнь после BSOD Крис Касперски и Жирный Хомяк Хакер, номер #085, стр. 085-114-5 Проведем следующий эксперимент. Нажмем <Ctrl-D> для вызова SoftICE, установим точку останова на KeBugCheckEx и запустим наш драйвер-убийцу. Причем точка останова обязательно должна быть аппаратной ("bpm KeBugCheckEx X"), а не программной (bpх KeBugCheckEx), иначе ничего не получится. На этот раз вместо сообщения об ошибке страничного доступа, SoftICE всплывает по срабатыванию точки останова, высвечивая курсором первую команду функции KeBugCheckEx, которая в нашем случае располагается по адресу 8042BF14h. Прокручивая окно дизассемблера вниз, находим первую инструкцию "RET 14h" (в нашем случае она располагается по адресу 8042C1E9h). Это и есть команда выхода из функции, на которую нужно сделать jmp. Для быстрого поиска можно попросить SoftICE сделать search ("s eip l -1 C2,14,00"). Говорим отладчику "r eip = 8042C1E9" (у тебя адрес, скорее всего, будет другим) и давим на <Ctrl-D> для выхода. Отладчик всплывает повторно в той же самой функции. У нас ничего не получилось?! Не торопимся с выводами! Все идет по плану! Игнорирование критических ошибок вызывает целый каскад вторичных исключений, что в данном случае и происходит. Повторяем нашу команду "r eip = 8042C1E9" (для этого достаточно нажать стрелку вверх/<ENTER>) и система возвращается в нормальный режим! Третий раз отладчик уже не всплывает. Мышь немного тормозит, однако гонять ее по коврику вполне реально. Приступаем к созданию драйвера, который будет все это делать за нас. Для начала нам понадобится скелет. Выглядит он так: [скелет псевдодрайвера, не управляющий никакими устройствами, но позволяющий нам выполнять код на уровне ядра] .386 ; использовать команды .386 ЦП .model flat, stdcall ; плоская модель памяти, stdcall-вызовы по умолчанию .code ; секция кода DriverEntry proc ; точка входа в драйвер ; код «драйвера» ; … … … ; возвращаем ошибку конфигурации mov eax, 0C0000182h; STATUS_DEVICE_CONFIGURATION_ERROR ret ; выходим DriverEntry endp end DriverEntry На самом деле это не совсем драйвер. Он не принимает никаких IRP-пакетов, не обслуживает никаких устройств и, вообще, не делает ничего, только загружается и выгружается. Но для нашей затеи этого будет вполне достаточно! Весь код сосредоточен внутри процедуры DriverEntry (своеобразном аналоге функции main языка Си), которая выполняется при попытке загрузки драйвера, инициализируя все, что необходимо. Отсюда можно дотянуться до функции KeBugCheckEx и модифицировать ее по своему усмотрению. Несмотря на то, что процедура DriverEntry выполняется на уровне ядра с максимальными привилегиями, попытка правки машинного кода приводит к нарушению доступа. Это срабатывает защита от непреднамеренного хака ядра некорректным драйвером. Как ее отключить? Путь первый - через реестр. Создаем в разделе HKLM\SYSTEM\CurrentControlSet\Control\SessionManager\Memory Management значение типа REG_DWORD с именем EnforceWriteProtection и значением 0 (это можно делать и с прикладного уровня). Все! Запись в ядро открыта! Кстати говоря, SoftICE именно так и работает. |