HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > БЕЗОПАСНОСТЬ И УЯЗВИМОСТИ > Threat Intel
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 01.01.2026, 08:17
Marylin
Постоянный
Регистрация: 01.09.2019
Сообщений: 378
С нами: 3526561

Репутация: 0
По умолчанию

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
отладчика WinDbg.

Роль киллера играет экспортируемая ядром функция
Код:
KeBugCheckEx()
- она вызывается из сотен мест, о чём свидетельствует лог дизассемблера IDA-Pro. Скопируем файл ядра Ntoskrnlp.exe из папки system32, и отправив его в IDA перейдём на вкладку "Exports". Теперь в окне экспорта жмём комбинацию поиска
Код:
[Ctrl+F]
, вводим маску "KeBugCheckEx", и наконец
Код:
Enter
для перехода к функции. Остаётся установить курсор на имя функции (при этом оно выделяется красным), и нажать
Код:
[Ctrl+Х]
для сбора перекрёстных ссылок "XREF" на указанную функцию. У себя я получил 260 адресов, от куда вызывается
Код:
KeBugCheckEx()
. Как видим, API принимает на грудь 5 аргументов(х), первый из которых хранит код ошибки, а остальные четыре - место/время/обстоятельства её возникновения. Эти аргументы потом сбрасываются в окно BSOD:

По идее в ядре имеются две родственные функции:
Код:
KeBugCheck()
и расширенная
Код:
KeBugCheckEx()
. Первая досталась нам в наследство от Win2k, где она представляла собой трамплин к
Код:
KeBugCheckEx()
, которая и делала всю полезную работу. Начиная с Win-ХР обёрткой является уже сама
Код:
KeBugCheckEx()
, а непосредственно сбором инфы и выводом её в окно BSOD занимается теперь внутренняя (неэкспортируемая) функция ядра
Код:
KeBugCheck2()
. Если вскрыть первую, то становится очевидно, что она просто передаёт 5 указанных выше параметра основной функции
Код:
KeBugCheck2()
:

Поскольку
Код:
KeBugCheck2()
вызывается посредством инструкции
Код:
CALL
, она возвращает управление обратно этому коду, и далее выход
Код:
RETN 14h
. Во времена Win2k был ядерный отладчик "Soft-Ice", который в реальном времени мог перехватывать обращения к трамплину
Код:
KeBugCheck()
. Как результат, в момент критической ошибки отладчик всплывал на входе в функцию, и модифицировав пролог
Код:
MOV EDI,EDI
мы могли джампом прыгнуть сразу в её конец
Код:
RETN 14h
, что позволяло сохранить данные в обход окна BSOD. Такой трюк был возможен даже на Win-XP с отладчиком "Syser" (Айс на хрюше уже не работал). К сожалению начиная с Висты мы потеряли это достояние, и на данный момент нет ни одного дебагера, способного вклиниться в ядро в реальном времени (WinDbg не в счёт, т.к. требует две соединённые шнурком машины).

3. Модификация окна BSOD

Теперь, посмотрим на код основной функции
Код:
KeBugCheck2()
.
Как говорилось выше, эта внутренняя процедура играет ключевую роль в создании экрана BSOD. Если навести курсор на функцию предыдущего скрина и нажать Enter, мы попадём в святая-святых, пролистав которую можно найти много интересного, например сброс дампа, перевод кода ошибки в текстовый эквивалент, вывод первичных сообщений функцией
Код:
DbgPrint()
и многое другое - вот фрагмент. Обратите внимание, что функции с префиксом
Код:
Ki_xx()
не экспортируются ядром наружу (внутренние) от слова "Kernel Internals", в отличии от внешних "Externals"
Код:
Ke_xx()
:

Но в контексте данной темы нас больше интересуют функции с префиксами
Код:
Inbv_xx()
, которые подразумевают "Init Boot Video component" и отображены на сл.скрине. Они так-же вызываются из тушки
Код:
KeBugCheck2()
, а детальную информацию по их аргументам можно найти здесь:

Значит сначала идёт проверка, установлен-ли драйвер дисплея и если нет, то все последующие функции игнорируются. Если-же ок, то
Код:
AcquireDisplayOwnership()
захватывает экран в своё распоряжение, а следующая сбрасывает его в дефолт
Код:
ResetDisplay()
. Последущие две функции для нас в приоритете (выделены в красные блоки) - они задают цвет фона и текста голубого экрана смерти BSOD. Вот их аргументы:

C-подобный:


Код:
InbvSolidColorFill
(
)
--
--
--
--
--
--
--
--
--
--
PUSH
4
=
синий цвет фона
  PUSH
1
DFh
=
480
px
(
координата Y
)
PUSH
27
Fh
=
640
px
(
координата X
)
PUSH ESI
=
0x0
(
левый
/
верхний угол
)
InbvSetTextColor
(
)
--
--
--
--
--
--
--
--
--
--
PUSH
0
Fh
=
белый цвет текста
Таким образом, манипулируя аргументами
Код:
PUSH 4/0Fh
мы можем изменить вид окна, например сделать фон зелёным(2) или красным(1), а текст чёрным(0). Разрешение экрана 640х480 трогать нельзя, т.к. оно задаётся в другом месте, а здесь определяется лишь периметр для заливки цветом.

Немного иную картину наблюдаем на 64-битных системах Виста+. По сути здесь всё то-же самое, только набор функций
Код:
INBV_xx()
завёрнут в фантик
Код:
KiDisplayBlueScreen()
, о чём прямым текстом сообщает нам отладчик WinDbg. Обратите внимание на кол-во инструкций в теле
Код:
KeBugCheck2() = 781
, и это не считая размеров вызываемых изнутри функций. Это говорит о том, что система проделывает огромный объём работы, прежде чем склеить ласты с отображением окна BSOD:

Код:


Код:
0: kd> uf /i /c KeBugCheck2
   nt!KeBugCheck2 (fffff800`0215a2f0), 781 instructions

    call to nt!KeQueryCurrentStackInfo     (fffff800`02066df4)
    call to nt!memmove                     (fffff800`0208ce80)
    call to hal!HalpPrepareForBugcheck     (fffff800`025ff6b4)
    call to nt!VfNotifyVerifierOfEvent     (fffff800`02511a30)
    call to nt!KiSaveCurrentEtwTraceBuffer (fffff800`0210f900)
    call to nt!KiScanBugCheckCallbackList  (fffff800`0210b6d0)
    call to hal!HalReturnToFirmware        (fffff800`025f1dc4)
    call to nt!KiPcToFileHeader            (fffff800`0210b7a0)
    call to nt!MmIsSpecialPoolAddress      (fffff800`0205698c)
    call to nt!MmIsSpecialPoolAddressFree  (fffff800`020fa2d0)
    call to nt!MmIsSessionAddress          (fffff800`0201d9a4)
    call to nt!MmLocateUnloadedDriver      (fffff800`020e47a0)
    call to nt!KeBugCheckUnicodeToAnsi     (fffff800`020e5350)
    call to nt!KiDumpParameterImages       (fffff800`02159de0)
    call to nt!DbgPrintEx                  (fffff800`02076348)
    call to nt!KiBugCheckDebugBreak        (fffff800`02159c10)
    call to hal!HalSendNMI                 (fffff800`025fb5a0)
    call to hal!KeStallExecutionProcessor  (fffff800`025f78e4)
    call to nt!KiDisplayBlueScreen         (fffff800`0215a070)
4. Практическое руководство

Условимся, что никаких зверских деяний мы совершать не будем, ведь это не тест на выносливость, а обычная жизнь со всеми её пагубными факторами. В процессе тестов нам понадобится несколько раз умышленно сгенерить BSOD, чтоб посмотреть, сработает-ли наш план. Как вариант, можно варварски выдёргивать любой работающий PCI-девайс, или написать читающий нуль-указатель кривой драйвер. Но это всё не наши методы - есть способ попроще.

На этапе тестирования системы, инженеры специально оставили один служебный люк, который открывается ключом в определённой ветке реестра. Мы пойдём по пути наименьшего сопротивления, и ограничимся правкой этого ключа. Тогда чтобы сгенерить BSOD, достаточно будет удерживая правую клавишу
Код:
[Ctrl]
2 раза жмякнуть
Код:
[Scroll Lock]
и всё.. система уйдёт в анабиоз. Ошибка известна как "MANUALLY_INITIATED_CRASH = 0xE2", или вручную сгенерированный глюк. Никаких последствий он нам не сулит, и предусмотрен мягкими специально для тестов. Значит открываем сл.ветку реестра, и создаём в ней ключ-дворд "CrashOnCtrlScroll" - значение(1) активирует фишку, а нуль отключает:

Код:


Код:
Для клавиатуры PS/2:  HKLM\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
Для USB-клавиатуры :  HKLM\SYSTEM\CurrentControlSet\Services\kbdhid\Parameters
Для правки аргумента
Код:
PUSH 4
функции
Код:
InbvSolidColorFill()
как нельзя лучше подходит двоичный редактор HIEW, хотя вы можете использовать любой по своему усмотрению. Значит открываем скопированный из папки system32 файл ядра Ntoskrnlp.exe, переименуем его например в NtHack.exe, и вскормим HIEW'у. Далее жмём в HIEW цепочку клавиш
Код:
[Enter+Enter+F8+F9]
для просмотра экспорта, и прокручиваем список до функции
Код:
KeBugCheckEx()
. Теперь зайдя в функцию по
Код:
Enter
жмём(1) для входа в
Код:
KeBugCheck2()
, и мотаем листинг пока не упрёмся в
Код:
InbvSolidColorFill()
. Здесь установив курсор на
Код:
PUSH 4
активируем режим правки клавишей
Код:
F3=Edit
, и вводим для чёрного фона значение(0), для зелёного(2), или для красного(1). Аналогичным образом можно изменить и цвет текста
Код:
PUSH 00F
в аргументе
Код:
InbvSetTextColor()
. Клавиша
Код:
F9
сохраняет изменения. Лично я выставил красный цвет фона(1) по такой схеме (напомню, что в дефолте было 4=синий):

Теперь бросаем пропатченное ядро NtHack.exe обратно в папку system32 (благо на ХР нет сторожа PatchGuard), и чтобы система его подцепила, внесём изменения в файл конфигурации загрузки boot.ini. Здесь просто добавляем вторую строку, в результате чего при загрузке ОС появится возможность выбора ядер:

Код:


Код:
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS

[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional RU" /execute /fastdetect
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Hacked Windows XP" /execute /fastdetect /kernel=NtHack.exe
После всех телодвижений загружаемся с кастомного ядра, и как появится рабочий стол жмём комбинацию клавиш
Код:
[Правый Ctrl + 2 ScrollLock]
. Упс, как и положено система падает в BSOD, однако нашему взору предстаёт не голубой, а "Красный экран смерти", что может послужить пруфом к теории выше:

5. Заключение

Ядро Win-XP представляет собой отличный полигон для тестов, особенно в контексте программирования драйверов. Отсутствие всевозможного рода сторожей типа PatchGuard даёт нам полную свободу мыслей, и остаётся лишь реализовать их на практике. По большому счёту это инсайдер ко всем ныне актуальным ОС класса Win, т.к. современные ядра не далеко ушли от классического ядра Win-NT. Если какая-нибудь идея витает в воздухе, можно без последствий протестить её на вирт.машине, и уже потом перенести на физическую с Win-10/11. Как показал данный эксперимент, установив шунт на
Код:
KeBugCheckEx()
, мы можем полностью избавиться от BSOD'ов как от системного механизма, и это далеко не единственный пример.
 
Ответить с цитированием

  #2  
Старый 01.01.2026, 14:05
qwerty120
Новичок
Регистрация: 03.01.2025
Сообщений: 0
С нами: 718213

Репутация: 0
По умолчанию

Супер
 
Ответить с цитированием

  #3  
Старый 28.01.2026, 00:28
Gemfory
Новичок
Регистрация: 03.01.2026
Сообщений: 0
С нами: 192549

Репутация: 0
По умолчанию

Раньше было так, что абсолютно любой малварь-дев был умнее системы и ее создателей, у той же винды особо то и защиты ядра от патча не было, как сейчас(PatchGuard).
Хотя.. Сейчас и PatchGuard обходят.

В общем, статья очень полезная.
 
Ответить с цитированием

  #4  
Старый 28.01.2026, 18:25
Ахимов
Новичок
Регистрация: 21.12.2025
Сообщений: 0
С нами: 210647

Репутация: 0
По умолчанию

В xp можно патчить ядро из юзер через отладочные сервисы(ntsystemdebugcontrol), что было очень удобно, тк не нужен драйвер-пемодуль.
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.