Восстановление таблицы разделов 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 я постараюсь рассказать как-нибудь в другой раз. Итак, драйвера установились, сразу заходим в управление дисками (если кто забыл — правой кнопкой по значку «Мой компутер»>»Управление»>»Управление дисками») и убеждаемся, что диск присутствует, а разделов на нём нет. Если загрузочная запись снесена полностью, тогда винда ещё выдаст ругательство о том, что диск не инициализирован, и предложит это исправить — пока отказываемся т.к. в первую очередь нам нужны данные, а уже потом, может быть — возможность загрузки.

Окно диспетчера дисков Windows XP

Открываем в HEX-редакторе нужный диск (для HxD —  меню «Дополнительно»> «Открыть диск»… Не забудь снять птичку «Открыть только для чтения») и видим, что в нулевом секторе – там, где должна быть MBR — только нули.

Здесь была MBR

По легенде на диске перед сбоем были разделы, совместимые с Windows – вот и попробуем найти их! А вернее — их первые сектора. Вначале каждого раздела должна быть своя загрузочная запись, длиной которой – 512 байт (один сектор, для большинства устройств). В ней, кроме ассемблерной команды «JMP», хранится разная служебная информация: тип файловой системы, размер кластера, адреса начала файловой таблицы и т.д. В конце каждой загрузочной записи (всего диска или отдельного раздела) обязательно присутствует маркер — сигнатура 0x55AA. Её то и нужно искать! Ctrl+F, в открывшемся окошке вводим «55AA» и указываем, в качестве типа данных «Шестнадцатеричные значения», после чего нажимаем «Enter». У меня нашлось по адресу 0x7EB9, но, так как этот адрес какой-то некрасивый – ищем дальше.

Адрес заветной записи должен быть в конце 512-и байтного блока, а значит, должен заканчиваться каким-то из этих чисел: 0x1FE, 0x3FE, 0x5FE, 0x7FE, 0x9FE, 0xBFE, 0xDFE, 0xFFE. Для возобновления поиска нажимаем «F3» и следующее совпадение находится по адресу 0x7FFE, что уже похоже, на правильный адрес.

Пролистаем чуть выше – в начало сектора, и… кажется, мы нашли загрузочную запись раздела, отформатированного файловой системой NTFS:

Так начинается загрузочная запись NTFS-раздела

Записываем в блокноте (бумажном или программном) номер сектора в шестнадцатеричной системе… Кстати редактор HxD, когда работает с диском, показывает номера секторов, хоть и в десятичной системе. Но, если ваш редактор не показывает номер сектора, можно самому высчитать его, разделив адрес начала сектора на 512 – длину сектора. Для этого вначале переведём 512 в шестнадцатеричный формат, затем уже разделим: 0x7E00 / 512 = 0x7E00 / 0x200 = 0x3F. Или 63 – в десятичной системе.

Что ж, где начинается раздел – мы уже знаем, но для объявления тома в MBR нужно, как минимум, ещё узнать его размер. Размер раздела в загрузочном секторе NTFS в явном виде не указан, но зато указано количество секторов в разделе, без учёта сектора с загрузочной записью и, если верить табличке на Википедии, искать надо 8-и байтовое поле по смещению 0x28, от начала загрузочного сектора.

Format of Extended BPB for NTFS (73 bytes):

Вот оно:

Количество секторов в томе, не считая загрузочного

Открываем калькулятор, и проверяем: 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 адресацией) – осталось узнать размер раздела и, похоже, тут одной табличкой не обойтись:

Format of full DOS 7.1 Extended BIOS Parameter Block (79 bytes) for FAT32:

Размер тома в таблице не указан, но вначале таблицы есть упоминание об унаследованном блоке BPB, который одинаковый многих файловых систем. В загрузочной записи NTFS-раздела такой блок тоже есть, но, там он скорее оставлен как рудимент, для совместимости со старыми системами т.к. уже не отображает реальных параметров раздела.

Format of standard DOS 3.31 BPB for FAT12FAT16 and FAT16B (25 bytes):

Здесь нас интересует только последняя строка – “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-редактора, возвращаем таблицу разделов из резервной копии в нужные адреса нулевого сектора:

Теперь можно перезагружаться.

Суббота, Май 9th, 2020 Восстановление информации

Leave a Reply