Голубой экран смерти – это последний вздох системы, после которого душа отделяется от тела. В смысле, дамп памяти падает на диск, и компьютер уходит в перезагрузку, унося с собой все несохраненные данные. Вытащить систему из мира мертвых и взять ситуацию под свой контроль поможет термоядерный отладчик Syser. Пора брать этот инструмент на вооружение!
Windows намного надежнее, чем это принято считать в народе. Моя основная машина (на базе W2K) перезагружается не чаще двух раз в месяц, а файловый сервер (и по совместительству – рабочая станция для цифрового монтажа, также вращающаяся под W2K) бесперебойно проработал полгода и упал лишь из-за броска по питанию, с которым не смог справиться UPS.
Голубые экраны смерти, вспыхивающие время от времени, отлавливаются SoftICE, который мыщъх держит постоянно загруженным. В большинстве случаев он возвращает систему к жизни. Это вопрос чести и хакерской этики. Перезагрузки – тривиальный, но порочный путь. Каждый сбой компьютера, каждый глюк системы мыщъх воспринимает чуть ли не как физическую боль и борется за здоровье машины, как за свое собственное! И пускай меня сочтут ненормальным… главное – методики реанимации системы, разработанные и обкатанные мной, могут принести пользу не только мне. Итак, что нам понадобится?
* Windows Driver Kit (WDK) для всех систем по Vista включительно (wwwmicrosoft.com/whdc/DevTools/)
* Windows Server 2003 SP1 DDK (wwwmicrosoft.com/whdc/devtools/ddk/default.mspx)
* IA-32 Architecture Software Developer's Manual Vol. 3: System Programming Guide (wwwintel.com/products/processor/manuals/)
* Syser 1.95.19000.0894 (wwwsysersoft.com/download/download.php)
По ту сторону BSOD'ов
Голубые экраны вспыхивают всякий раз, когда ядро сталкивается с ситуацией, которую не может разрулить самостоятельно. Если не остановить некорректно работающий код, завершив работу всех механизмов оси в аварийном режиме, ситуация способна пустить систему в разнос. Это, кстати, кардинально отличает NT-подобные системы от мира UNIX, впадающего в BSOD (kernel panic – в их терминологии) только в хардкорных обстоятельствах (все остальное время они просто выгружают порочный драйвер примерно так же, как NT завершает работу некорректно работающего приложения).
Конечно, если ошибка возникнет в драйвере файловой системы, то далеко на такой машине не уедешь. Подавляющее большинство сбоев приходится на драйвера, установленные вирусами, антивирусами, брандмауэрами, звуковыми и видеокартами. Причем, как показывает практика, 90% ошибок отнюдь не фатальны. Они вполне совместимы с жизнью, но ядро не спрашивает нас, хотим ли мы продолжить работу или предпочитаем внезапно умереть (в тот самый момент, когда открыта масса приложений с тучей не сохраненных файлов).
Прежде, чем бросаться в бой, нужно отделить программные ошибки от аппаратных отказов железа (как разогнанного, так и нет). Если голубые экраны вспыхивают в случайное время, каждый раз отображая разные данные (да кто эти данные читает?), то с большой вероятностью мы имеем дело с глюками железа. Пытаться реанимировать компьютер при этом чрезвычайно опасно. Если содержимое оперативной памяти разрушено из-за разгона или некачественного блока питания, то после выхода из BSOD'а операционная система попытается скинуть дисковые буфера. А там у нас что? Правильно, – мусор. И дисковый том отправится к праотцам, что намного хуже, чем потеря оперативных данных.
Впрочем, дефекты программного обеспечения тоже могут приводить к генерации «рандомных» экранов голубой смерти. Следовательно, без полного анализа ситуации здесь не обойтись. Однако не будем падать духом! Рано или поздно мы «объездим» ядро и разберемся во всех тонкостях его организации, а пока ограничимся лишь общей схемой.
Как устроен BSOD
Роль палача в NT-системах играет функция KeBugCheckEx, экспортируемая ядром и вызываемая из сотен (если не тысяч!) мест с теми или иными параметрами. Что это за параметры? Обратившись к NTDDK, мы узнаем, что функция KeBugCheckEx принимает пять аргументов, первый из которых (BugCheckCode) содержит код ошибки, а четыре следующих параметра – места/время/обстоятельства ее возникновения.
Перечень BugCheck-кодов можно найти в том же NTDDK. Там же содержится описание четырех аргументов, специфичных для каждого BugCheck-кода, количество которых чуть меньше сотни. Чтобы не держать в голове кучу ненужной информации, рекомендуется распечатать документацию и всегда хранить ее под рукой.
BugCheck-коды можно разделить на две большие категории. Первая содержит адрес инструкции, вызвавшей исключение (например, 1Eh: KMODE_EXCEPTION_NOT_HANDLED, 0Ah: IRQL_NOT_LESS_OR_EQUAL, 24h: NTFS_FILE_SYSTEM). Это позволяет «заглянуть» отладчиком непосредственно на место аварии, исправить пробоину и, выйдя из отладчика, продолжить плавание (естественно, для этого нужно не только знать ассемблер, но и разбираться в тонкостях драйверостроения, но это – в идеале).
Другая категория BugCheck-кодов не содержит адреса дефективной инструкции, поскольку ядро диагностирует аварийную ситуацию на поздней стадии. Найти виновника в этих случаях затруднительно. Взять хотя бы такой BugCheck-код, как C2h: BAD_POOL_CALLER. Он вызывается из функции распределения памяти, обнаружившей, что память на конкретной измене, но кто ее разрушил и когда – этого система сказать не может.
Поиск диверсанта зачастую отнимает несколько дней кропотливого ручного труда и, что самое неприятное, – исправить разрушенные структуры данных практически невозможно, а, значит, перезагрузки все равно не избежать. Хотя с риском для жизни еще можно вернуться на уровень прикладного режима, попробовав сохранить хотя бы часть данных. Если нам повезет, то с разрушенным пулом (специальной областью ядерной памяти) можно проработать несколько минут, а иногда и дней. В исключительных ситуациях система держится на плаву целую неделю, однако никакого смысла в таком экстриме нет. Риск разрушения дисковых томов очень велик и потому, сохранив все несохраненные данные, лучше все-таки перезагрузиться.