Жизнь после BSOD Крис Касперски и Жирный Хомяк Хакер, номер #085, стр. 085-114-3 [фрагмент драйвера-убийцы, пытающийся прочитать двойное слово по нулевому указателю из режима ядра] NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pusRegistryPath) { return *((NTSTATUS *) 0); } Ну и зачем было ронять систему из-за такой ерунды?! Кому наш страшный убийца реально мешает?! Ведь целостность системы ничуть не пострадала! Как объяснить этой тупой NT, что в Багдаде все спокойно? Пора бы вернуться в user mode и продолжить работу в штатном режиме. Если SoftICE был заблаговременно запущен, он отловит это исключение и покажет свой экран, передавая нам все бразды правления. Если нажать «x» (или <Ctrl-D>), то немедленно после выхода из SoftICE вспыхнет синий экран, и чинить тогда будет уже нечего. Но пока мы находимся в отладчике еще можно кое-что предпринять. А предпринять можно следующее: 1) Определить место сбоя (обращение по нулевому указателю), исправить ситуацию (установить валидный указатель), вручную выйти из обработчика исключения, вернув CS:EIP на прежнее место: способ хороший, но, увы, требующий определенного интеллекта, которого у машины нет. 2) Зациклить текущий поток, воткнув в свободное место jmp $ и выйти из отладчика, разрешив прерывания командной r fl=I (если они вдруг были запрещены). Все будет ужасно тормозить, но ось продолжит работать и мы по крайней мере сможем корректно завершить ее работу. 3) Дождаться вызова функции KeBugCheckEx и сразу же выйти из нее, проигнорировав сбой и продолжив нормальное выполнение, правда, никаких гарантий, что система не рухнет окончательно, у нас нет. 4) Способ, предложенный ms-rem, дикий, но иногда работающий: отдать команды r eip=0/r cs=1B, переключающие процессор на прикладной режим. Короче, вариантов много. Попробуем для начала воспользоваться первым способом. Мы знаем, что в данном случае авария произошла из-за ошибки нарушения доступа. Следовательно, процессор возбудил исключение, забросил на вершину стека EIP/CS/FLAGS и передал управление обработчику исключений, внутри которого мы сейчас и находимся. Даем команду "d esp" для отображения содержимого стека и видим (для удобства рекомендую переключить окно дампа в режим двойных слов, воспользовавшись командой "dd"): :d esp 0010:F7443C88 BE67C000 00000008 00200202 804A4431 ..g....... .1DJ. 0010:F7443C98 81116AD0 8649D000 BE8F1D08 BE8F1D08 .j....I......... 0010:F7443CA8 81480020 F7443D34 745FFFFF 83A49E60 .H.4=D..._t`... Адрес инструкции, возбудившей исключение, лежит в первом двойном слове - BE67C000h (у тебя это значение наверняка будет другим). Селектор CS идет следом. Он должен быть равен 08h. Третье двойное слово хранит содержимое регистра флагов - EFLAGS. Теперь мы знаем место сбоя и можем вывести дизассемблерный листинг на экран. В этом нам поможет команда "u *esp" (дизассемблировать содержимое памяти по адресу, который содержится в регистре esp) или "u be67c000": [определение реального места сбоя] :u *esp 0023:BE67C000 MOV EAX,[00000000] 0023:BE67C005 RET 0008 0023:BE67C008 NOP |