![]() |
BSOD (Blue Screen Of Death) – это последний вздох системы, после которого душа отделяется от тела (в смысле, дамп памяти сбрасывается на диск), и машина уходит в ребут, унося с собой все несохранённые данные. Здесь мы исследуем природу этого явления, а так-же попытаемся модифицировать само окно. Поскольку на системах х64 требуется подпись драйверов, а так-же предусмотрена защита "Patch Guard", эксперименты буду проводить на ядре Win-XP, хотя это не принципиально и вы можете выбрать любую ОС, т.к. всё сказанное ниже действительно для любой системы класса NT, от Win2k до Win10.
1. Источник угрозы 2. Устройство BSOD 3. Модификация окна 4. Практическое руководство 5. Заключение 1. Источник угрозы Коварные BSOD'ы нам досаждают, когда в ядре происходят события, которые ОС не может решить самостоятельно. Практика показывает, что 90% ошибок отнюдь не фатальны - они вполне совместимы с жизнью, но ядро мастдая Ntoskrnl.exe не спрашивает нас, хотим мы продолжить работу, или предпочитаем внезапно умереть. BSOD - это драматический признак того, что в каком-либо драйвере что-то не так. Из всего списка ошибок можно выделить обращения драйверов к занятой или недоступной памяти ОЗУ, ровно как и освобождение уже свободной. По большому счёту, вся эта конструкция держится на честном слове, и в любой момент может рухнуть как карточный дом. Начиная с Vista-x64 майки ввели цифровую подпись для драйверов - теперь левый дров можно загрузить только в дебаг-режиме работы ОС. Но выдача этой подписи процедура чисто формальная и наивно полагать, что после неё все глюки в драйверах как ветром сдует - ошибки были, есть и будут. Инженеры пытались решить проблему переносом части драйверов с ядра на прикладной уровень (например USB-девайсов), тогда при падении драйвера мы получим обычную мессагу о критической ошибке, после чего система просто перезапустит дров. Однако значительная их часть как и прежде живут в ядре, и это самые глючные драйвера, например звуковых, сетевых, и видео-устройств. На самом деле, большая часть Win-драйверов вовсе не драйвера, а не управляющие никакими девайсами обычные программы, которые просто нуждаются в доступе к тем или иным структурам ядра, до которых невозможно дотянуться через юзер Win32-API. ОС полностью доверяет находящимся на своей территории подопечным и не следит за тем, как они используют её ресурсы. К примеру при закрытии юзер-приложения все его открытые дескрипторы на автомате закрываются, а выделенная память освобождается. Проблема в том, что на драйверы ядра этот механизм не распространяется - процедура Код:
DriverUnload()2. Устройство BSOD Когда в ядре возникает ошибка, система останавливает все потоки, переводит видео-адаптер в текстовый режим (раньше 640х480, сейчас 1024х768), после чего пытается на худой палитре отобразить макс.объём информации на момент краха. Если предварительно была включена опция в свойствах системы, то создаётся дамп ядерной памяти, который позже можно будет распотрошить в поисках проблемы, например командой Код:
!analyzeРоль киллера играет экспортируемая ядром функция Код:
KeBugCheckEx()Код:
[Ctrl+F]Код:
EnterКод:
[Ctrl+Х]Код:
KeBugCheckEx()По идее в ядре имеются две родственные функции: Код:
KeBugCheck()Код:
KeBugCheckEx()Код:
KeBugCheckEx()Код:
KeBugCheckEx()Код:
KeBugCheck2()Код:
KeBugCheck2()Поскольку Код:
KeBugCheck2()Код:
CALLКод:
RETN 14hКод:
KeBugCheck()Код:
MOV EDI,EDIКод:
RETN 14h3. Модификация окна BSOD Теперь, посмотрим на код основной функции Код:
KeBugCheck2()Как говорилось выше, эта внутренняя процедура играет ключевую роль в создании экрана BSOD. Если навести курсор на функцию предыдущего скрина и нажать Enter, мы попадём в святая-святых, пролистав которую можно найти много интересного, например сброс дампа, перевод кода ошибки в текстовый эквивалент, вывод первичных сообщений функцией Код:
DbgPrint()Код:
Ki_xx()Код:
Ke_xx()Но в контексте данной темы нас больше интересуют функции с префиксами Код:
Inbv_xx()Код:
KeBugCheck2()Значит сначала идёт проверка, установлен-ли драйвер дисплея и если нет, то все последующие функции игнорируются. Если-же ок, то Код:
AcquireDisplayOwnership()Код:
ResetDisplay()C-подобный: Код:
InbvSolidColorFillКод:
PUSH 4/0FhНемного иную картину наблюдаем на 64-битных системах Виста+. По сути здесь всё то-же самое, только набор функций Код:
INBV_xx()Код:
KiDisplayBlueScreen()Код:
KeBugCheck2() = 781Код: Код:
0: kd> uf /i /c KeBugCheck2Условимся, что никаких зверских деяний мы совершать не будем, ведь это не тест на выносливость, а обычная жизнь со всеми её пагубными факторами. В процессе тестов нам понадобится несколько раз умышленно сгенерить BSOD, чтоб посмотреть, сработает-ли наш план. Как вариант, можно варварски выдёргивать любой работающий PCI-девайс, или написать читающий нуль-указатель кривой драйвер. Но это всё не наши методы - есть способ попроще. На этапе тестирования системы, инженеры специально оставили один служебный люк, который открывается ключом в определённой ветке реестра. Мы пойдём по пути наименьшего сопротивления, и ограничимся правкой этого ключа. Тогда чтобы сгенерить BSOD, достаточно будет удерживая правую клавишу Код:
[Ctrl]Код:
[Scroll Lock]Код: Код:
Для клавиатуры PS/2: HKLM\SYSTEM\CurrentControlSet\Services\i8042prt\ParametersКод:
PUSH 4Код:
InbvSolidColorFill()Код:
[Enter+Enter+F8+F9]Код:
KeBugCheckEx()Код:
EnterКод:
KeBugCheck2()Код:
InbvSolidColorFill()Код:
PUSH 4Код:
F3=EditКод:
PUSH 00FКод:
InbvSetTextColor()Код:
F9Теперь бросаем пропатченное ядро NtHack.exe обратно в папку system32 (благо на ХР нет сторожа PatchGuard), и чтобы система его подцепила, внесём изменения в файл конфигурации загрузки boot.ini. Здесь просто добавляем вторую строку, в результате чего при загрузке ОС появится возможность выбора ядер: Код: Код:
[boot loader]Код:
[Правый Ctrl + 2 ScrollLock]5. Заключение Ядро Win-XP представляет собой отличный полигон для тестов, особенно в контексте программирования драйверов. Отсутствие всевозможного рода сторожей типа PatchGuard даёт нам полную свободу мыслей, и остаётся лишь реализовать их на практике. По большому счёту это инсайдер ко всем ныне актуальным ОС класса Win, т.к. современные ядра не далеко ушли от классического ядра Win-NT. Если какая-нибудь идея витает в воздухе, можно без последствий протестить её на вирт.машине, и уже потом перенести на физическую с Win-10/11. Как показал данный эксперимент, установив шунт на Код:
KeBugCheckEx() |
Супер
|
Раньше было так, что абсолютно любой малварь-дев был умнее системы и ее создателей, у той же винды особо то и защиты ядра от патча не было, как сейчас(PatchGuard).
Хотя.. Сейчас и PatchGuard обходят. В общем, статья очень полезная. |
В xp можно патчить ядро из юзер через отладочные сервисы(ntsystemdebugcontrol), что было очень удобно, тк не нужен драйвер-пемодуль.
|
| Время: 20:23 |