Техника защиты компакт-дисков от копирования

Как подключить дамп памяти


"…в отделе программ весь пол был усеян дырочками от перфокарт и какие-то мужики ползали по раскатанной по полу 20-метровой распечатке аварийного дампа памяти с целью обнаружения ошибки в распределителе памяти ОС-360. К президенту подошел начальник отдела и сообщил, что есть надежда сделать это еще к обеду"

Ю.Антонов "Юность Гейтса"

Дамп памяти (memory dump, также называемый "корой" [от английского core –— сердцевина], crash- или аварийным дампом), сброшенный системой при возникновении критической ошибки –— не самое убедительное средство для выявления причин катастрофы, но ничего другого в руках администратора зачастую просто не бывает. Последний вздох операционной системы, похожий на дурно пахнущую навозную кучу, из которой высовывается чей-то наполовину разложившийся труп, мгновенным снимком запечатленный в момент неустранимого сбоя –— вот что такое дамп памяти во время крушения системы! Копание в нем вряд ли доставит вам удовольствие. Не исключено, что истинного виновника краха системы вообще не удастся найти. Допустим, некий некорректно работающий драйвер вторгся в область памяти, принадлежащую другому драйверу, и наглым образом затер критические структуры данных, сделав из чисел "винегрет". К тому моменту, когда драйвер-жертва пойдет вразнос, драйвер-хищник может быть вообще выгружен из системы, и определить его причастность к крушению системы по одному лишь дампу практически нереально.

Тем не менее, полностью игнорировать факт существования дампа, право же, не стоит. В конце концов, до возникновения инактивных отладчиков ошибки в программах приходилось искать именно так. Избалованность современных программистов визуальными средствами анализа, увы, не добавляет им уверенности в тех ситуациях, когда неумолимая энтропия оставляет их со своими проблемами один на один. Но довольно лирики. Переходим к делу, расписывая каждое действие по шагам.

Первым делом, необходимо войти в конфигурацию системы Пуск à Настройка à Панель управления à Система


(Start à Settings à Control Panel à System) и убедиться, что настройки дампа соответствуют предъявляемым к ним требованиям Дополнительно à Загрузка и восстановление à Отказ системы (Startup/Shutdown à Recovery) в Windows 2000 RUS и Windows NT 4.0 ENG соответственно). Операционная система Windows 2000 поддерживает три разновидности дампов памяти: малый дамп памяти (small memory dump), дамп памяти ядра (kernel memory dump) и полный дамп памяти (complete dump memory). Для изменения настроек дампа вы должны иметь права администратора.

Малый дамп памяти занимает всего лишь 64 Кбайта (а отнюдь не 2 Мбайта, как утверждает контекстная помощь) и включает в себя:

q      копию "голубого экрана смерти";

q      перечень загруженных драйверов;

q      контекст обрушившегося процесса со всеми его потоками;

q      первые 16 Кбайт содержимого ядерного стека "обрушившегося" потока.

Разочаровывающие малоинформативные сведения! Непосредственный анализ дампа дает нам лишь адрес возникновения ошибки и имя драйвера, к которому этот адрес принадлежит. При условии, что конфигурация системы не была изменена после возникновения сбоя, мы можем загрузить отладчик и дизассемблировать подозреваемый драйвер, но это мало что даст. Ведь содержимое сегмента данных на момент возникновения сбоя нам неизвестно, более того —? мы не можем утверждать, что видим те же самые машинные команды, что вызвали сбой. Поэтому малый дамп памяти полезен лишь тем администраторам, которым достаточно одного лишь имени нестабильного драйвера. Как показывает практика, в подавляющем большинстве случаев этой информации оказывается вполне достаточно. Разработчикам драйвера отсылается гневный "бан-рапорт" (вместе с дампом!), а сам драйвер тем временем заменяется другим –— более новым и надежным.




По умолчанию малый дамп памяти записывается в каталог %SystemRoot%\Minidump, где ему присваивается имя Mini, дата записи дампа и порядковый номер сбоя на данный день. Например Mini110701-69.dmp –— 69 дамп системы от 07 ноября 2001 года (не пугайтесь! это просто я отлаживал драйвера).

Дамп памяти ядра содержит намного более полную информацию о сбое и включает в себя всю память, выделенную ядром и его компонентами (драйверами, уровнем абстракции от оборудования и т. д.), а также копию "голубого экрана смерти". Размер дампа памяти ядра зависит от количества установленных драйверов и варьируется от системы к системе. Контекстная помощь утверждает, что эта величина составляет от 50 до 800 Мбайт. Ну, на счет 800 Мбайт авторы явно "загнули", и объем в 50–—100 Мбайт выглядит более вероятным (техническая документация на систему сообщает, что ориентировочный размер дампа ядра составляет треть объема физической оперативной памяти, установленной на системе). Это наилучший компромисс между накладными расходами на дисковое пространство, скорости сброса дампа и информативностью последнего. Весь "джентльменский" минимум информации –— в вашем распоряжении. Практически все типовые ошибки драйверов и прочих ядерных компонентов могут быть локализованы с точностью до байта, включая и те, что вызваны физическим сбоем аппаратуры (правда, для этого вы должны иметь некоторый "патологоанатомический" опыт исследования "трупных" дампов системы). По умолчанию дамп памяти ядра записывается в файл %SystemRoot%\Memory.dmp, затирая или не затирая (в зависимости от текущих настроек системы) предыдущий дамп.

Полный дамп памяти включает в себя все содержимое физической памяти компьютера, занятое как прикладными, так и компонентами ядра системы. Полный дамп памяти оказывается особенно полезным при отладке ASPI/SPTI-приложений, которые в силу своей специфики могут "уронить" ядро даже с прикладного уровня.


Несмотря на довольно большой размер, равный размеру оперативной памяти, полный дамп остается наиболее любимым дампом всех системных программистов (системные же администраторы в своей массе предпочитают малый дамп). Это не покажется удивительным, если вспомнить, что объемы жестких дисков давно перевалили за отметку 100 Гбайт, а оплата труда системных программистов за последние несколько лет даже несколько возросла. Лучше иметь невостребованный полный дамп под рукой, чем кусать локти при его отсутствии. По умолчанию полный дамп памяти записывается в файл %SystemRoot%\Memory.dmp, затирая или не затирая (в зависимости от текущих настроек системы) предыдущий дамп.

Выбрав предпочтительный тип дампа, давайте совершим учебный "падение" системы, отрабатывая методику его анализа в "полевых" условиях. Для этого нам понадобится:

q      комплект разработчика драйверов (Driver Development Kit или сокращенно DDK), бесплатно распространяемый фирмой Microsoft и содержащий в себе подробную техническую документацию по ядру системы; несколько компиляторов Си/Си++ и ассемблера, а также достаточно "продвинутые" средства анализа дампа памяти;

q      драйвер W2K_KILL.SYS или любой другой драйвер-убийца операционной системы, например BDOS.EXE от Марка Русиновича, позволяющий получить дамп в любое удобное для нас время, не дожидаясь возникновения критической ошибки (бесплатную копию программы можно скачать с адреса http://www.sysinternals.com);

q      файлы символьных идентификаторов (symbol files), необходимые отладчикам ядра для его нормального функционирования и делающие дизассемблерный код более наглядным. Файлы символьных идентификаторов входят в состав "зеленого" набора MSDN, но, в принципе, без них можно и обойтись, однако переменная окружения _NT_SYMBOL_PATH по любому должна быть определена, иначе отладчик i386kd.exe работать не будет;

q      одна или несколько книжек, описывающих архитектуру ядра системы.


Очень хороша в этом смысле книга " Внутреннее устройство Windows 2000" Марка Руссиновича и Дэвида Соломона, интересная как системным программистам, так и администраторам.

Итак, установив DDK на свой компьютер и завершив все приложения, запускаем драйвер-убийцу и… под "скрипящий" звук записывающегося дампа, система немедленно выбрасывает "голубой экран смерти" (BSOD — Blue Screen Of Death), свидетельствующий о возникновении неустранимого сбоя системы с краткой информацией о нем, кратко информирующий нас о причинах сбоя (см. рис. 3.4 xx).

*** STOP: 0x0000001E (0xC0000005, 0xBE80B000, 0x00000000, 0x00000000)

KMODE_EXEPTION_NOT_HALTED

*** Address 0xBE80B000 base at 0xBE80A000, Date Stamp 389db915 – w2k_kill.sys

Beginning dump of physical memory

Dumping physical memory to disk: 69

 

 

 

 

Рис.унок 3.4. "Голубой экран смерти" (BSOD – Blue Screen Of Death), свидетельствующий о возникновении неустранимого сбоя системы с краткой информацией о нем

Для большинства администраторов "голубой экран смерти" означает лишь одно –— системе "поплохело" настолько, что она предпочла смерть позору неустойчивого функционирования. Что же до таинственных надписей, сопровождающих эти экраны, то они остаются сплошной загадкой. Но только не для настоящих профессионалов!

Мы начнем с левого верхнего угла экрана и, зигзагами спускаясь вниз, трассируем все надписи по порядку.

q      *** STOP: — буквально означает "останов [системы]" и не несет в себе никакой дополнительной информации;

q      0x0000001E — представляет собой код Bug Check, содержащий категорию сбоя. Расшифровку кодов Bug Check можно найти в DDK. В данном случае это 0x1E –— KMODE_EXEPTION_NOT_HALTED, о чем и свидетельствует символьное имя расположенное строкой ниже. Краткое объяснение некоторых, наиболее популярных кодов Bug Check приведено в таблице 3.1.


Определение рейтинга популярности кодов Bug  Check осуществлялось путем подсчета упоминаний о них в конференциях Интернет (спасибо старику Googl'у). Полноту фирменной документации она, разумеется, не заменяет, но некоторое представление о целесообразности скачивания 70 Мбайт DDK все-таки дает;

q      "арабская вязь" в круглых скобках –— это четыре Bug Check-параметра, физический смысл которых зависит от конкретного кода Bug Check и вне его контекста теряет всякий смысл; применительно к KMODE_EXEPTION_NOT_HALTED –— первый Bug Check-параметр содержит номер возбужденного исключения. Судя по таблице 3.1, это –— STATUS_ACCESS_VIOLATION –— доступ к запрещенному адресу памяти –— и четвертый Bug Check-параметр указывает какой именно. В данном случае он равен нулю, следовательно, некоторая машинная инструкция попыталась совершить обращение по null-pointer, соответствующему инициализированному указателю, ссылающемуся на невыделенный регион памяти. Ее адрес содержится во втором Bug Check-параметре. Третий Bug Check-параметр в данном конкретном случае не определен;

q      *** Address 0xBE80B00 –— это и есть тот адрес, по которому произошел сбой. В данном случае он идентичен второму Bug Check-параметру, однако так бывает далеко не всегда (коды Bug Check собственно и не подряжались хранить чьи-либо адреса).

q      base at 0xBE80A00 –— содержит базовый адрес загрузки модуля-нарушителя системного порядка, по которому легко установить "паспортные" данные самого этого модуля.

Внимание!

Далеко не во всех случаях правильное определение базового адреса вообще возможно.

Воспользовавшись любым подходящим отладчиком (например, Soft-Ice от Нумега или i386kd от Microsoft), введем команду, распечатывающую перечень загруженных драйверов с их краткими характеристиками (в i386kd это осуществляется командой !drivers).


Как одним из вариантов, можно воспользоваться утилитой drivers.exe, входящей в NTDDK. но, какой бы вы путь не избрали, результат будет приблизительно следующим:

kd> !drivers!drivers

Loaded System Driver Summary

Base       Code Size       Data Size      Driver Name            Creation Time

80400000 142dc0 (1291 kb) 4d680 (309 kb) ntoskrnl.exe  Wed Dec 08 02:41:11 1999

80062000   cc20 (  51 kb)  32c0 ( 12 kb)      hal.dll  Wed Nov 03 04:14:22 1999

f4010000   1760 (   5 kb)  1000 (  4 kb)  BOOTVID.DLL  Thu Nov 04 04:24:33 1999

bffd8000  21ee0 ( 135 kb)  59a0 ( 22 kb)     ACPI.sys  Thu Nov 11 04:06:04 1999

be193000  16f60 (  91 kb)  ccc0 ( 51 kb)   kmixer.sys  Wed Nov 10 09:52:30 1999

bddb4000  355e0 ( 213 kb) 10ac0 ( 66 kb)    ATMFD.DLL  Fri Nov 12 06:48:40 1999

be80a000    200 (   0 kb)   a00 (  2 kb) w2k_kill.sys  Mon Aug 28 02:40:12 2000

TOTAL:   835ca0 (8407 kb) 326180 (3224 kb) (    0 kb     0 kb)

Обратите внимание на выделенную полужирным черным цветом строку с именем w2k_kill.sys, найденную по ее базовому адресу 0xBE80A00. Это и есть тот самый драйвер, который нам нужен! А впрочем, этого можно и не делать, поскольку имя "неправильного" драйвера и без того присутствует на "голубом экране смерти";

q      две нижние строки отражают прогресс "сброса" дампа на диск, развлекая администратора чередой быстро меняющихся циферок на это время.

Таблица 3.1. Физический смысл наиболее популярных кодов Bug Check с краткими пояснениями

Категория

Описание

hex-код

Символьное имя

0x0A

IRQL_NOT_LESS_OR_EQUAL

Драйвер попытался обратиться к странице памяти на уровне DISPATCH_LEVEL или более высоком, что и привело к краху, поскольку менеджер виртуальной памяти работает на более низком уровне;

источником сбоя может быть и BIOS, и драйвер, и системный сервис (особенно этим грешат вирусные сканеры и FM-тюнеры);

как вариант –— проверьте кабельные терминаторы на SCSI-накопителях и Master/Slayer на IDE, отключите кэширование памяти в BIOS;

если и это не поможет, обратитесь к четырем параметрам кода Bug Check, содержащим ссылку на память, к которой осуществлялся доступ, уровень IRQ (Interrupt ReQuest), тип доступа (чтение/запись) и адрес машинной инструкции драйвера

0x1E:

KMODE_EXCEPTION_NOT_HANDLED

Компонент ядра возбудил исключение и "забыл" его обработать; номер исключения содержится в первом Bug Check-параметре; обычно он принимает одно из следующих значений:

0x80000003 (STATUS_BREAKPOINT): встретилась программная точка останова –— отладочный рудимент, по небрежности не удаленный разработчиком драйвера;

(0xC0000005) STATUS_ACCESS_

VIOLATION: доступ к запрещенному адресу (четвертый Bug Check-параметр уточняет к какому) –— ошибка разработчика;

(0xC000021A) STATUS_SYSTEM_

PROCESS_TERMINATED: сбой процессов CSRSS и/или Winlogon, источником которого могут быть как компоненты ядра, так и пользовательские приложения; обычно это происходит при заражении машины вирусом или нарушении целостности системных файлов;

(0xC0000221) STATUS_IMAGE_

CHECSUM_MISMATCH: целостность одного из системных файлов оказалась нарушена;

второй Bug Check-параметр содержит адрес машинной команды, возбудившей исключение

0x24

NTFS_FILE_SYSTEM

Проблема с драйвером NTFS.SYS, обычно возникающая вследствие физического разрушения диска, реже –— при остром недостатке физической оперативной памяти

0x2E

DATA_BUS_ERROR

Драйвер обратился по несуществующему физическому адресу; если только это не ошибка драйвера; оперативная память и/или кэш-память процессора (видеопамять) неисправны или же работают на запредельных тактовых частотах

0x35

NO_MORE_IRP_STACK_LOCATIONS

Драйвер более высокого уровня обратился к драйверу более низкого уровня посредством IoCallDriver-интерфейса, однако свободного пространства в стеке IRP (I/O Request Packet)

не оказалось и передать весь IRP-пакет целиком не удалось;

это гибельная ситуация, не имеющая прямых решений; попытайтесь удалить один или несколько наименее нужных драйверов, быть может тогда система заработает

0x3F

NO_MORE_SYSTEM_PTES

Результат сильной фрагментации таблицы страниц PTE (Page Table Entry), приводящей к невозможности выделения затребованного драйвером блока памяти; обычно это характерно для аудио- или видеодрайверов, манипулирующих огромными блоками памяти и к тому же не всегда их вовремя освобождающих; для решения проблемы попробуйте увеличить количество PTE (до 50 000 максимум) в следующей ветке реестра:

HLLM\SYSTEM\CurrentControlSet\

Control\Session­Manager\

Memory Management\SystemPages

0x50

PAGE_FAULT_IN_NONPAGED_AREA

Обращение к несуществующей странице памяти, вызванное либо неисправностью оборудования (как правило –— оперативной, видео или кэш-памяти), либо некорректно спроектированным сервисом (этим грешат многие антивирусы, в том числе Касперский и Доктор Веб), либо разрушениями NTFS-тома (запустите программу chkdsk.exe с ключами /f и /r), также попробуйте запретить кэширование памяти в BIOS

0x58

FTDISK_INTERNAL_ERROR

Сбой RAID-массива, –— при попытке загрузки с основного диска система обнаружила, что он поврежден, тогда она обратилась к его зеркалу, но таблицы разделов не оказалось и там.

0x76

PROCESS_HAS_LOCKED_PAGES

Драйвер не смог освободить залоченные [Y94] [n2k95] страницы после завершения операции ввода-вывода; для определения имени дефективного драйвера следует обратиться к ветке HKLM\SYSTEM\CurrentControlSet\

Control\Session Manager\

Me­mory Management, и установить параметр TrackLockedPages типа DWORD в значение 1, потом перезагрузить систему, после чего та будет сохранять трассируемый стек и, если нехороший драйвер вновь начнет чудить, возникнет BSOD с кодом Bug Check: 0xCB, позволяющим определить виновника

0x77

KERNEL_STACK_INPAGE_ERROR

Страница данных памяти ядра по техническим причинам недоступна, если первый код Bug Check не равен нулю, то он может принимать одно из следующих значений:

(0xC000009A) STATUS_INSUFFICIENT_RESOURCES –— недостаточно системных ресурсов;

(0xC000009C) STATUS_DEVICE_DATA_

ERROR –— ошибка чтения с диска (bad-сектор?);

(0xC000009D) STATUS_DEVICE_NOT_

CONNECTED –— система не видит привод (неисправность контроллера, плохой контакт шлейфа);

(0xC000016A) STATUS_DISK_

OPERATION_FAILED –— ошибка чтения диска (bad-сектор или неисправный контроллер);

(0xC0000185) STATUS_IO_DEVICE_

ERROR –— неправильное "термирование" SCSI-привода или конфликт IRQ IDE-приводов;

нулевое же значение первого кода Bug Check указывает на неизвестную аппаратную проблему;

такое сообщение может появляться и при заражении системы вирусами, и при разрушении диска старыми "докторами", и при отказе RAM –— войдите в консоль восстановления и запустите программу chkdsk.exe с ключом /r

0x7A

KERNEL_DATA_INPAGE_ERROR###

Страница данных памяти ядра по техническим причинам недоступна, второй Bug Check-параметр содержит статус обмена, четвертый –— виртуальный страничный адрес, загрузить который не удалось;

возможные причины сбоя — те же дефектные сектора, попавшие в файл-подкачки pagefile.sys, сбои дискового контроллера, ну и вирусы, наконец

0x7B

INACCESSIBLE_BOOT_DEVICE

Загрузочное устройство недоступно, –— таблица разделов повреждена или не соответствует файлу boot.ini;

также такое сообщение появляется при замене материнской платы с интегрированным IDE-контроллером (или замене SCSI-контроллера), поскольку всякий контроллер требует "своих" драйверов и при подключении жесткого диска с установленной Windows NT на компьютер, оснащенный несовместимым оборудованием, операционная система просто откажется грузиться и ее необходимо будет переустановить (опытные администраторы могут переустановить непосредственно сами дисковые драйвера, загрузившись с консоли восстановления);

также не помешает проверить общую исправность оборудования и наличие вирусов на диске

0x7F

UNEXPECTED_KERNEL_MODE_TRAP

Исключение процессора, необработанное операционной системой; обычно возникает вследствие неисправности оборудования (как правило –— разгона CPU), его несовместимости с установленными драйверами или алгоритмическими ошибками в самих драйверах;

проверьте исправность оборудования и удалите все посторонние драйвера;

первый Bug Check-параметр содержит номер исключения и может принимать следующие значения:

0x00 –— попытка деления на нуль;

0x01 –— исключение системного отладчика;

0x03 –— исключение точки останова;

0x04 –— переполнение;

0x05 –— генерируется инструкцией BOUND;

0x06 –— неверный опкод;

0x07 –— двойной отказ (Double Fault);

описание остальных исключений содержится в документации на процессоры Intel и AMD

0xC2

BAD_POOL_CALLER

Текущий поток вызвал некорректный pool-request, что обычно происходит по причине алгоритмической ошибки, допущенной разработчиком драйвера; однако, судя по всему, и сама система не остается без ошибок, поскольку для устранения этого "голубого экрана смерти" Microsoft рекомендует установить SP2

0xCB

DRIVER_LEFT_LOCKED_PAGES_IN_

PROCESS

После завершения процедуры ввода/вывода, драйвер не может освободить заблокированные страницы (см. PROCESS_HAS_LOCKED_PAGES);

первый Bug Check-параметр содержит вызываемый, а второй Bug Check-параметр, вызывающий адрес; последний, четвертый параметр указывает на UNICODE-строку с именем драйвера

0xD1

DRIVER_IRQL_NOT_LESS_OR_EQUAL

То же самое, что и IRQL_NOT_LESS_OR_EQUAL

0xE2

MANUALLY_INITIATED_CRAS

Сбой системы, спровоцированный вручную, путем нажатия "горячей" комбинации клавиш <Ctrl>+<Scroll Loock>, при условии, что параметр CrashOnCtrlScroll реестра

HKLM\System\CurrentControlSet\

Services\i8042prt\Parameters содержит ненулевое значение

0x7A

KERNEL_DATA_INPAGE_ERROR

Страница данных памяти ядра по техническим причинам недоступна, второй Bug Check-параметр содержит статус обмена, четвертый –— виртуальный страничный адрес, загрузить который не удалось;

возможные причины сбоя — те же дефектные сектора, попавшие в файл pagefile.sys, сбои дискового контроллера, ну и вирусы, наконец


Содержание раздела