Методы борьбы с BSOD для начинающих

Курс молодого бойца

Так уж сложилось, что подрабатываю я в маленькой компании: студенческая жизнь не сахар, сами понимаете. Да и работа не пыльная - в зоне моей ответственности всего десять компьютеров и один сервер. Но в любой бочке меда найдется своя ложка дегтя: сервер работает под управлением Windows Server 2003, который умудряется "падать" чуть ли не каждый день, радостно приветствуя всех желающих синим экраном, а меня - высаживая на конкретную измену.

Руководствуясь принципом, что все хорошее уже придумали за нас, я полез в Интернет в поисках ответа на мучающий меня вопрос, как же бороться с бесконечными BSOD'ами, не перезагружая сервер по пять раз на неделе. И, как всегда, ответ лежал на поверхности: "Используй SoftICE - и будет тебе счастье", - сказали мне на форуме моего любимого wasm.ru. Но SoftICE - порочный путь, решил я, так как поддержка программы официально прекращена, и заставить ее работать под Windows 7, Vista или Server 2k8R2 - занятие крайне трудоемкое и к тому же мало оплачиваемое. Спасение пришло в виде термоядерного отладчика Syser, рекомендованного как качественная замена SoftICE на все том же сайте. Сказано - сделано: с www.sysersoft.com я скачал trial-версию отладчика и погряз в изучении исходного кода драйвера-убийцы, предложенного в качестве тестового примера. Кстати, не обольщайтесь - по ссылке "download freeware" на сайте компании вы скачиваете версию syser, которая умеет работать только в ring 3. Тестовая же версия рассчитана ровно на семь дней, после чего попросит вас либо купить лицензию (что я настоятельно рекомендую), либо удалить сам отладчик. Где взять деньги? Как мне кажется, любая приличная контора при правильном объяснении, куда же уйдут запрошенные средства, купит лицензию на использование отладчика. А если нет.... Задумайтесь, а стоит ли работать в такой компании?

Но вначале - немного истории. Помнится, в далеком прошлом борьбой с неприятельскими экранами смерти у меня на компьютерах занимался любимейший многими отладчик от компании NuMega, и назывался он SoftICE. Многие, включая автора этой статьи, познавали азы отладки именно в "мягком льде". Но настал злосчастный 2006 год, и отладчик тихо умер, так как поддержка его, осуществляемая компанией Compuware (к тому моменту купившей NuMega), была приостановлена. А в далеком-далеком Китае нашлись двое предприимчивых реверсеров, вовремя сообразивших, что отладчик уровня ядра, работающий в новой операционной системе от Microsoft, обязательно купят. И именно тогда Wu Yan Feng и Chen Jun Hao выпустили достойную замену SoftICE, назвав ее Syser Kernel Debugger. Унаследовав лучшее из своего предшественника, Syser успешно вышел на enterprise-рынок. Сочетая в себе подсветку листинга дизассемблера, абсолютно все команды из старичка SoftICE, работу с многопроцессорными системами и толковую поддержку юникода, отладчик от китайских разработчиков является полноценной заменой "мягкому льду". И именно за эти неоспоримые преимущества я и выбрал его героем сегодняшней статьи.

Как нам уже давно известно, театр начинается с вешалки, а Stop Screen (или же Blue Screen of Death ("синий экран смерти")) появляется в случае возникновения некой проблемы, решить которую самостоятельно ядро операционной системы не в состоянии. Это, кстати, кардинально отличает Windows-системы от их *nix собратьев. В то время, как правильные операционные системы выгружают из памяти модуль, из-за которого и возникла проблема, предпочитая впадать в kernel panic лишь в самых безвыходных обстоятельствах, Windows свято исповедует подход "где ошибка - там и BSOD". Конечно, если критическая ошибка, из-за которой и появляется stop screen, таится в дисковой подсистеме, то излечиться от этого достаточно трудно в любой ОС, и, зачастую, гораздо проще заменить весь сервер, чем оплачивать труд обслуживающего его администратора. Конечно, такое встречается крайне редко, чаще всего проблема носит куда более тривиальный характер, и камнем преткновения становится программное обеспечение, установленное пользователем либо администратором. Именно сторонний софт, к слову, открывает большинство брешей в безопасности, которые с удовольствием эксплуатируют хакеры.

 

Операционная система Windows намного безопаснее, чем принято считать в народе, и большинство ошибок в ней возникает именно благодаря стороннему программному обеспечению. В число "неблагонадежных" можно записать, как ни странно, также и драйверы. Производители железа зачастую выпускают на рынок "сырые" версии драйвера, дорабатывая его в обновлениях, но далеко не каждый администратор может позволить себе перезагружать сервер по десять раз на неделе. Ошибка в драйвере нашей звуковой карты не фатальна для операционной системы в целом, однако же суровые редмондские парни даже и не думают спрашивать нас, хотим ли мы продолжить работу, сходу убивая как саму ОС, так и десятки (или же сотни - кому что ближе) сторонних приложений. И, что самое главное, по закону подлости администратор практически никогда не успевает сохранить важные данные.

Если вы внимательно читали MSDN, то должны знать, что дамокловым мечом любой NT-подобной системы служит функция KeBugCheckEx, с нужными параметрами вызываемая ядром из тысячи мест. А если вдоволь "накуриться" NTDDK, мы узнаем, что KeBugCheckEx имеет всего пять аргументов, причем только BugCheckCode содержит проблемный код, а остальные четверо - лишь стороннюю информацию наподобие "в котором часу по местному времени вы могли наблюдать результат". И самое неприятное состоит в том, что под рукой всегда нужно иметь документацию (я уже который год использую для подобных целей PDA, пусть и говорят, что они безнадежно устарели), так как количество специфических BugCheck-аргументов достигает порядка сотни, а держать их все в памяти практически нереально. Возвращаясь к NTDDK, мы узнаем, что BugCheck-коды можно условно разделить на две подгруппы: первая содержит адрес машинной инструкции, вызвавшей исключение; вторая же, наоборот, не содержит, так как ядро диагностирует аварийную ситуацию на последней стадии, что затрудняет поиск "виноватой" инструкции. Представьте, что отладчик поймал надвигающийся stop screen, и вы точно знаете, из-за чего он, собственно, появился. За примером далеко ходить не надо: исключение произошло по адресу 1Eh:KMODE_EXCEPTION_NOT_HANDLED. В этом случае нам не составит труда заглянуть отладчиком прямиком на место катастрофы и буквально за несколько минут восстановить жизнеспособность системы, избежав тем самым и злосчастного синего экрана, и, как следствие, потери важных данных. Естественно, без глубокого знания ассемблера и опыта написания драйверов под NT-системы нам не обойтись. Но это же прекрасный повод вспомнить молодость!

А если все гораздо хуже? Если BugCheck, к примеру, C2h:BAD_POOL_CALLER? Конкретных данных о том, что стало причиной исключения, мы получить не в состоянии, и единственное, что доподлинно известно, - инструкция вызывается из функции распределения памяти. Теоретически можно перейти с ядерного режима на прикладной, где с разрушенным пулом мы сможем поработать минут пять-десять. Этого, в теории, должно хватить на то, чтобы успеть спасти какие-то данные, однако риск обрушения дискового тома сводит всю затею на "нет", заставляя компьютер уходить на перезагрузку, а нас - беспомощно откинуться на спинку кресла.

Но вернемся к нашим баранам. Внимательно изучив исходный код предлагаемого мне драйвера-убийцы, я собрал его при помощи штатного компилятора, входящего в состав NTDDK, который должен быть под рукой у любого уважающего себя Windows-администратора. Обидно, конечно, но поэкспериментировать на рабочем сервере мне никто не дал, а домашняя машина уже который год работает под управлением openBSD, так что я воспользовался старушкой VMWare, уже не раз меня выручавшей. В качестве гостевой операционной системы использовал Microsoft Windows XP Professional SP3, и проблем с установкой отладчика не возникло. Тот, кто хоть раз устанавливал SoftICE на виртуальную машину, думаю, меня поймет.

Предположим, что вы уже скомпилировали наш драйвер и вовсю жаждете приступить к экспериментам. Так чего же мы ждем! Загружаем отладчик и сразу же переходим в консоль, приказывая отладчику перехватывать вызов системной функции KeBugCheckEx командой "bmp KeBugCheckEx x". В прикладном режиме воспользуемся замечательной функцией отладчика, именуемой quick driver load, которая поможет нам загрузить в систему наш драйвер. Если читатель хоть немного знаком с ассемблером, то он уже понял, что драйвер обращается к памяти по нулевому указателю (что противоречит Windows-дхарме), соответственно, выполняя машинную команду MOV EAX, [EAX].

Естественно, обратившись к памяти таким образом, мы тутже получаем исключение, высаживающее операционную систему на конкретную измену. Дабы переместиться обратно на прикладной уровень 1Bh (а ядро работает с кодовым селектором 08h), необходимо сделать следующее: находим функцию KeBugCheckEx и командуем отладчику "d eip". После этого заменяем три первых байта на "С2h 14h 00h". В принципе, нам уже можно возвращаться на прикладной уровень, где, в относительном затишье, сохранить все данные и плавно уйти на перезагрузку. Но если попробовать изменить регистр CS с 08h на 1Bh? Как ни прискорбно, чаще всего это приводит к появлению синего экрана, что бы там ни писали на wasm.ru. Проверено на личном опыте. При наличии упорства и хорошей кармы сие действие можно повторять до бесконечности - рано или поздно можно дождаться штиля и продолжить работу в прикладном режиме. Но не кажется ли вам, что предложенный выше вариант намного более надежен?

С появлением Windows 7 и Windows Server 2k8R2 технологии борьбы с синими экранами шагнули далеко вперед, по сравнению с Windows Vista или, тем более, Windows XP. Но, все равно, универсальное решение для борьбы со stop screen, осенним листопадом падающих на компьютеры пользователей, еще не изобретено, поэтому стоит взять на вооружение вышеописанный метод - поверьте, он не раз спасет "жизнь" операционной системы, установив планку перезагрузки компьютера на отметку "раз-два в месяц". Но нет худа без добра: знание ассемблера все равно понадобится, а это лишний повод открыть запылившийся учебник!

Кристиан КАРМАК


Код драйвера

.686
.MMX
.model flat, stdcall

extern DbgPrint:PROC
.code

DriverEntry proc
; INT 03

push offset to_die
CALL DbgPrint
pop eax

XOR EAX,EAX
MOV EAX,[EAX]; //вызванный нами BSOD

push offset happy
CALL DbgPrint
pop eax

mov eax, 0C0000182h; STATUS_DEVICE_CONFIGURATION_ERROR;
RET; 
RETN 8;

DriverEntry endp
.data
to_die DB "*] good die young! [*",0Dh,0Ah,0
happy DB "*] welcome to real world, boy! [*",0Dh,0Ah,0
mystring1 DD offset DriverEntry
end DriverEntry
Версия для печатиВерсия для печати

Номер: 

18 за 2010 год

Рубрика: 

Software
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!
 

Комментарии

Аватар пользователя Al
Я что-то не понял, а зачем надо тратить столько времени и денег на эту прогу? Я могу поверить словам автора "Windows Server 2003, который умудряется "падать" чуть ли не каждый день", но не могу поверить, что это происходит по вине винды. У меня ВСЕ серверы с виндой 2003 R2 и 2008 R2 работают месяцами без перезагрузок (могли бы и годами, но иногда их приходится перезагружать или выключать по внешним причинам), а BSOD на сервере я видел в последний раз на 2000-м серваке лет семь назад, когда он поругался с кривым драйвером от HASP. При этом с новым драйвером он подружился и работал годами. Поэтому мой вывод - описанные BSOD'ы - исключительно кривые руки автора, кривое железо и левый софт. Следовательно ценность статьи - нулевая, т.к. - см выше, все работает на самом деле отлично.
Аватар пользователя Savely
Вроде и неплохо написанная статья. Но идея - бред полный. Присоединяюсь к Al в мысли, что автору надо поправить что-то в консерватории, а не лазить дебаггером куда не надо.

Хе, а статейка-то списана у Касперски... Но сам посыл перевран ужасно.

http://www.xakep.ru/post/44314/default.asp

Аватар пользователя mike
>вывод - описанные BSOD'ы - исключительно кривые руки автора, кривое железо и левый софт.

Впрочем, автор это в статье признаёт.

Аватар пользователя Инкогнито
Присоединяюсь. Серверное железо под Windows 2003 Server работает в режиме 24/7 с 2-3 перезагрузками в год. В этом году была 1 перезагрузка по причине сбоя используемой программы (без BSOD) и 1 плановое отключение на время ремонта электросети. Хотя, не спорю, видел BSOD и другие глюки на 2003-м, установленном на обычном ПК, где еще проинсталлировано пару сотен прикладных программ и подключена куча устройств, включая довольно "левые" считыватели RFID-карт и контроллеры управления некоторыми внешними механизмами. Но чтобы комп падал каждый день, это что ж такого надо намудрить?
Аватар пользователя Бывший автор
mike (old student)

14 мая 2010 года, 08:23

Впрочем, автор это в статье признаёт.

Помню, кто-то в другом топике статью хвалил...

Аватар пользователя mike
Ну я хвалил. И здесь не ругаю. Правда, статья запоздала на неск. лет, ИМХО.
Аватар пользователя Бывший автор
Это урок всем критикам: газету надо оценивать не по количеству "знакомых букаф" и полезности отдельных статей для 1/16 читающей аудитории, или для себя лично, а по разнообразию и свежести инфы.

ИМХО: сегодня важнее всего - новости.

Аватар пользователя Инкогнито
mike (old student)

14 мая 2010 года, 14:32

статья запоздала на неск. лет, ИМХО.

Нет комментариев

Аватар пользователя Savely
>статья запоздала на неск. лет, ИМХО.

Ессно, на Хакере она датируется 04.07.2008. И даже тогда она уже не блистала новизной, половина задачи у Касперски была представить Syser как альтернативу SoftIce. А "автор КВ" перевернул весь смысл с ног на голову...

Аватар пользователя MON
"Обидно, конечно, но поэкспериментировать на рабочем сервере мне никто не дал"

Я б тоже не дал ковырять студенту сервер ;)))

И для чего? Если не исправен драйвер, в большинстве случаев он указывается в BSODe.

Из названия статьи: "для начинающих" и "курс молодого бойца",НО:

"Естественно, без глубокого знания ассемблера и опыта написания драйверов под NT-системы нам не обойтись"

;)))