Восстановление таблицы разделов MBR
Долго решал, нужна ли эта статья? Ведь всё давно уже описано в книгах и статьях Криса Касперски, разными авторами на Хабре и в большом количестве других источников. А опытные сисадмины без всяких статей и этого вашего Интернета давно всё знают потому, что сами застали времена, когда почти всё приходилось делать в машинных кодах и HEX- редакторе. Но компьютерщики первых поколений уходят, а Интернет – штука нестабильная и то, что было доступно вчера – через пару лет уже может быть забыто и безвозвратно утеряно. Так что пусть эта информация теперь будет ещё и здесь.
Часто в результате работы компьютерных вирусов, чьих-то кривых рук, программ, которые предназначены для изменения разметки диска, или из-за появления битого сектора, оказывается повреждена или полностью уничтожена таблица разделов диска или даже вся MBR. Если информации на диске не жалко, то его можно просто заново разметить и радоваться вновь обретённому свободному дисковому пространству. Если же на устройстве перед сбоем была ценная инфа — на помощь придут программы, типа Active Partition Recovery, которые сами найдут и предложат восстановить утраченные разделы без необходимости сливать данные на другой носитель, заново размечать диск, после чего заливать всё взад обратно.
Но автоматические инструменты — оставим доверчивым ламерам. Настоящий же хакер не доверяет свою информацию чужому автоматизированному софту, а делает всё сам в шестнадцатеричном редакторе! Так что берём в руки любимый HEX-редактор, умеющий работать с дисковыми устройствами, завариваем ведро крепкого чая и за работу!
Первым делом, конечно же, нужно любым доступным способом подключить подопытное устройство с повреждённой записью MBR к компу, с рабочей ОС (можно загрузить Live с USB или CD диска). Т.к у меня под рукой есть работающий ноут с Windows XP и портативной версией редактора HxD, то на этой системе я и буду показывать. А вы можете использовать то, что вам удобнее, например какой-нибудь Linux или даже DOS. Правда в новых версиях Windows, вышедших после XP, не проверял – возможно, там система блокирует прямой доступ к дисковым устройствам. В качестве подопытного — 2.5″ SATA винт на 500Gb, подключенный через USB-SATA переходник.
Пока система определяет диск и устанавливает драйвера, сделаем небольшое отступление.
Дело в том, что таблицы разделов обычно встречаются двух видов: MBR (Master Boot Record) и GPT (Guid Partition Table). Так вот, описываемое в данной статье относится только к MBR, которая уже считается устаревшей. Про GPT я постараюсь рассказать как-нибудь в другой раз. Итак, драйвера установились, сразу заходим в управление дисками (если кто забыл — правой кнопкой по значку «Мой компутер»>»Управление»>»Управление дисками») и убеждаемся, что диск присутствует, а разделов на нём нет. Если загрузочная запись снесена полностью, тогда винда ещё выдаст ругательство о том, что диск не инициализирован, и предложит это исправить — пока отказываемся т.к. в первую очередь нам нужны данные, а уже потом, может быть — возможность загрузки.
Открываем в HEX-редакторе нужный диск (для HxD — меню «Дополнительно»> «Открыть диск»… Не забудь снять птичку «Открыть только для чтения») и видим, что в нулевом секторе – там, где должна быть MBR — только нули.
По легенде на диске перед сбоем были разделы, совместимые с Windows – вот и попробуем найти их! А вернее — их первые сектора. Вначале каждого раздела должна быть своя загрузочная запись, длиной которой – 512 байт (один сектор, для большинства устройств). В ней, кроме ассемблерной команды «JMP», хранится разная служебная информация: тип файловой системы, размер кластера, адреса начала файловой таблицы и т.д. В конце каждой загрузочной записи (всего диска или отдельного раздела) обязательно присутствует маркер — сигнатура 0x55AA. Её то и нужно искать! Ctrl+F, в открывшемся окошке вводим «55AA» и указываем, в качестве типа данных «Шестнадцатеричные значения», после чего нажимаем «Enter». У меня нашлось по адресу 0x7EB9, но, так как этот адрес какой-то некрасивый – ищем дальше.
Адрес заветной записи должен быть в конце 512-и байтного блока, а значит, должен заканчиваться каким-то из этих чисел: 0x1FE, 0x3FE, 0x5FE, 0x7FE, 0x9FE, 0xBFE, 0xDFE, 0xFFE. Для возобновления поиска нажимаем «F3» и следующее совпадение находится по адресу 0x7FFE, что уже похоже, на правильный адрес.
Пролистаем чуть выше – в начало сектора, и… кажется, мы нашли загрузочную запись раздела, отформатированного файловой системой NTFS:
Записываем в блокноте (бумажном или программном) номер сектора в шестнадцатеричной системе… Кстати редактор HxD, когда работает с диском, показывает номера секторов, хоть и в десятичной системе. Но, если ваш редактор не показывает номер сектора, можно самому высчитать его, разделив адрес начала сектора на 512 – длину сектора. Для этого вначале переведём 512 в шестнадцатеричный формат, затем уже разделим: 0x7E00 / 512 = 0x7E00 / 0x200 = 0x3F. Или 63 – в десятичной системе.
Что ж, где начинается раздел – мы уже знаем, но для объявления тома в MBR нужно, как минимум, ещё узнать его размер. Размер раздела в загрузочном секторе NTFS в явном виде не указан, но зато указано количество секторов в разделе, без учёта сектора с загрузочной записью и, если верить табличке на Википедии, искать надо 8-и байтовое поле по смещению 0x28, от начала загрузочного сектора.
Вот оно:
Открываем калькулятор, и проверяем: 0x7FFA3F0600000000+1=0x7FFA3F0600000001 секторов в разделе, переводим секторы в гигабайты: 0x7FFA3F0600000001*0x200/1024/1024/1024=16023052 гигабайт. Чё-то дофига выходит, как для полтерабайтного жёсткого диска! А всё потому, что запись на диск делается в обратном порядке: вначале младшие байты, а затем старшие. Записываем байты в обратном порядке и пробуем ещё раз: 0x000000063FFA7F+1=0x000000063FFA80 секторов. Можно отбросить незначащие нули, и перевести в гигабайты: 0x63FFA80*0x200/1024/1024/1024 = 49,99 GB – вот он, размер найденного тома! Для записи в MBR нужен размер в секторах, запишем: 0x63FFA80.
Имеющихся данных уже достаточно, чтобы смонтировать раздел в каком-нибудь Linux или же натравить на него R-studio для быстрого вытаскивания информации и без необходимости выполнять сканирование, но ещё не хватает, чтобы полноценно работать с ним. К тому же, у нас другая цель! Вернёмся пока к хекс-редактору, а точнее – к нулевому сектору диска и запишем по смещению 0x1FE знакомую уже сигнатуру 0x55AA. Сразу перед ней – по адресам 0x1BE-0x1FD, должна размещаться таблица разделов, состоящая из 4-х записей, по 16 байт в каждой. Каждой записи соответствует свой раздел.
Записи имеют такую структуру:
Рассмотрим подробнее.
Флаг активности раздела указывает, загрузочный ли раздел, и может принимать только значения: 0x80 – если загрузочный, или 0x00 – если нет. Пока оставим пустым.
Адреса начала и конца в формате CHS – тоже пока не трогаем т.к. CHS является устаревшим способом адресации и в современных системах используется редко. Обычно в этих полях находятся какие-то заглушки, типа 0xFF – для совместимости, но можно оставить эти поля пустыми.
Адреса LBA (Logical Block Address) – это самые важные поля – именно в них вписываем записанные в блокнотике значения. Только не забываем, про обратную последовательность байт! Тип раздела содержит код типа файловой системы или код расширенного раздела. Допустимые коды можно подсмотреть в табличке, подсмотренной у линуксовой программки cfdisk:
Разнообразие кодов впечатляет!
Какой тут код соответствует NTFS разделу? А их оказывается много разных! 0x17 и 0x27 нас пока не интересуют т.к. скрытый раздел нам не нужен… 0x86 и 0x87 тоже пропускаем потому, что раздел, скорее всего, был самым обычным — статическим. Остаётся 0x07 – записываем. Должно получиться что-то такое:
Сохраняем изменения на диске, переподключаем диск к компу и бегом в «Управление дисками»:
Как видим, ОС распознала раздел и даже увидела на нём данные:
Кажется раньше – до того, как случился сбой, на восстановленном разделе была установлена ОС Windows – значит, имеет смысл сделать раздел активным, записав 0x80 в поле флага. А что произойдёт, если неправильно указать тип раздела? Давайте попробуем 0x87. Опять открываем HxD и оказывается, что ОС уже успела что-то записать, перед таблицей разделов. Трогать не будем – нас это не интересует, а ОС, наверно, знает, что делает. Просто изменим код с 0x07 на 0x87 и сохраним, не забыв переподключить хард-диск:
Ничего страшного не случилось: система по-прежнему видит раздел, но не может распознать на нём файловую систему. Соответственно, доступ к данным в таком случае отсутствует.
Но хватит экспериментов – пора искать остальные разделы! Для ускорения процесса, чтоб не выполнять бессмысленный поиск в адресном пространстве восстановленного раздела пропустим его: для этого к номеру его первого сектора прибавим количество секторов, вычтем 1 сектор, т.к. сектор с загрузочной записью раздела оказался посчитан дважды, и переведём в десятичную систему: 0x063FFA80+0x3F-1= 0x063FFABE=104856254 секторов нужно пропустить. Переходим к сектору и понимаем, что оказались в жо… именно там, где надо – в загрузочной записи второго раздела:
Стоп! Какая ещё загрузочная запись? Здесь же должен быть последний сектор первого раздела! Листаем чуть ниже и… ну вот – ещё одна загрузочная запись, но уже FAT32 раздела:
А запись в предыдущем секторе, скорее всего, сохранилась от прошлых разметок диска. Для проверки этой версии конечно можно внести её в MBR, удалив предварительно уже имеющуюся запись о первом разделе т.к. эти разделы пересекаются и, если предположение верно – раздел окажется повреждённым, и не будет открываться. Но не будем терять времени, а лучше сразу занесём информацию о найденном FAT32 разделе. Номер начального сектора известен, код файловой системы смотрим в таблице выше (выбираем 0x0C – FAT32 с LBA адресацией) – осталось узнать размер раздела и, похоже, тут одной табличкой не обойтись:
Размер тома в таблице не указан, но вначале таблицы есть упоминание об унаследованном блоке BPB, который одинаковый многих файловых систем. В загрузочной записи NTFS-раздела такой блок тоже есть, но, там он скорее оставлен как рудимент, для совместимости со старыми системами т.к. уже не отображает реальных параметров раздела.
Здесь нас интересует только последняя строка – “Large total logical sectors”, которая расположена по смещению 0x20 от начала сектора. Длина этого поля – двойное слово, то есть – 4 байт.
Записываем в блокнотик «0x02800A73». И заметьте, здесь не нужно прибавлять один байт, как это делали, с NTFS-разделом, т.к. в блоке BPB показано общее число секторов, с учётом загрузочного сектора раздела! Теперь на нас есть все данные для занесения в MBR записи, о втором разделе:
И вот он уже виден в системе со всей информацией:
Два раздела есть, но на диске осталось почти 400 гигов свободного пространства, поэтому продолжаем поиск сигнатуры 0x55AA от конца второго раздела и обнаруживаем какую-то непонятную запись – не похожую на загрузочную запись распространённых FS.
Но магическое число 0x55AA расположено в конце сектора, а значит стоит рассмотреть этот сектор подробнее. Вначале сектора идёт какая-то непонятная фигня: нет ни текстового идентификатора файловой системы, ни чего-то похожего на код загрузчика… Ладно, зайдём с другой стороны. В конце сектора, сразу перед числом 0x55AA, виднеется нечто, похожее на таблицу разделов, такую, как в секторе MBR. Тогда возможно, это первый сектор расширенного раздела. Посмотрим, куда ведёт первая из двух записей в нём:
Смещение: 0x3F, и номер сектора: 146801970 (в десятичном формате) – получаем 0x8C00571 или 146802033 в десятичном. Так и есть – ещё один NTFS раздел:
В начальном секторе расширенного раздела имеется две записи – сразу проверим вторую:
Смещение – 0x103FE5CA, а номер сектора – тот же – 146801970, и получаем 0x18FFEAFC или 419425020 в десятичной системе. А там:
Продолжение расширенного раздела! Всего с одной записью в таблице – значит, эта часть расширенного раздела – последняя!
Быстро находим последний сектор логического диска, который она содержит:
419425020(dec)+0x3F+0x21386106= 0x3A384C41 (976768065(dec)), что уже близко к концу всего жёсткого диска. (По данным программы Victoria диск имеет 976768065 секторов.) И вычитаем из этого числа адрес первого сектора первой части расширенного раздела: 0x3A384C41-0x8C00532=0x3178470F – это размер в секторах всего расширенного раздела. Тип раздела – расширенный, в списке кодов есть строка «f W95 ext’d (LBA)» – думаю, это подойдёт. Заполняем третью строку таблицы в MBR собранными данными:
Переподключим винт и увидим в управлении дисками:
Вот так вот одна строка в MBR добавляет два логических диска!
Все разделы открываются, везде сохранились данные, кроме диска F:
Не порядок – кажется, я забыл правильно указать тип ФС после проверки неподходящего кода 0x87. После исправления этой ошибки очень рекомендую скопировать содержимое сектора MBR в какое-нибудь пустое пространство, имеющееся на диске – например в один или несколько следующих за MBR секторов: там почти всегда есть несколько незанятых секторов, которые находятся до начала первого раздела и ОС не будет сама их перезаписывать. Такой трюк позволит быстро восстановить разметку диска в случае, если нулевой сектор жёстким диском был переназначен, но не всегда спасёт от вирусов.
Пока я писал эту статью, решил заглянуть в MBR своего жёсткого, который используется в домашнем ноутбуке, с которого я сейчас и пишу, и был сильно удивлён, увидев там такое:
Это пространство находится между сектором MBR и началом первого раздела, и оно должно быть пустым! Если загуглить почтовый ящик, указанный там (w**smith1***56@posteo.net) и почитать текст, найденный в этом и соседних секторах диска, становится понятно, что этот диск был когда-то зашифрован вирусом-шифровальщиком-вымогателем, который в народе прозвали «Петя». Этот жёсткий диск мне достался вместе с негодным ноутбуком, который я купил пару лет назад. Видимо, вирус поймал его предыдущий владелец. Этот вирус перезаписывает первые 25 секторов жёсткого диска, так что даже если бы владелец ноута скопировал MBR в эти сектора – она бы всё равно не сохранилась. Правда, если бы на диске была GPT, осталась бы её резервная копия в самом конце диска, но и она бы слабо помогла т.к. диск ещё и шифрует случайным ключом данные на самих разделах, а ключ потом выбрасывает!
Ладно, вернёмся к MBR. Таблица разделов восстановлена, но загрузка с диска всё ещё невозможна, потому что на диске нет начального загрузчика. Помните, в самом начале пути ОС предлагала инициализировать диск? Процесс инициализации включает в себя запись этого самого загрузчика, а также запись магической сигнатуры 0x55AA в конец сектора. Теперь время пришло – можно было бы и согласиться, но инициализацию нам уже не предлагают. Поэтому опять открываем хекс-редактор, чтобы удалить сигнатуру из нулевого сектора и скопировать таблицу разделов в пустой файл или в один из пустых секторов (если вы этого ещё не сделали). Сохраняем всё, реконнектим диск и заходим в управление дисками, соглашаемся на предложение инициализации и, с помощью HEX-редактора, возвращаем таблицу разделов из резервной копии в нужные адреса нулевого сектора:
Теперь можно перезагружаться.
Leave a Reply
Свежие записи
Свежие комментарии
- Очередной интересный сон к записи
- Nissan Leaf — поиск причины возникновения ошибки: B2802-73 к записи
- Nissan Leaf — поиск причины возникновения ошибки: B2802-73 к записи
- Nissan Leaf — поиск причины возникновения ошибки: B2802-73 к записи
- Nissan Leaf — поиск причины возникновения ошибки: B2802-73 к записи