Практический пример определения смещения файлов в NTFS (определение виртуального начального сектора раздела). Итак, что нам нужно. 1. Дисковый редактор WinHex (в примере использована версия 15.0 SR-2). 2. Документация Linux NTFS (легко найти в сети), далее [1]. 3. Авторекаверилка R-Studio (в примере версия 4.0 Demo). 4. Моск Smile. Алгоритм поиска смещения. 1. Выбираем реперный файл. Как уже заметили выше, в качестве такого файла удобно использовать документацию от программы. Вы должны точно знать, что этот файл есть на восстанавливаемом разделе, и у Вас должна быть его точная «здоровая» копия. Файл должен быть размером не менее ~1 КБ (чтобы не оказался резидентным). Я выбрал файл ReadMeRu.txt из каталога редактора DMDE. 2. Ищем файловую запись реперного файла. Для этого запускаем WinHex, открываем пострадавший физический диск. Нажимаем Ctrl+F, вводим имя файла ReadMeRu.txt (с расширением), Unicode, Search: Down, чекбоксы оставить неотмеченными, ОК (искать будет долго). Найденные секторы надо проверить на соответствие Файловой записи MFT ([1], п. 4.11), причем запись должна быть используемой (два байта по смещению 0x16 байт от начала записи должны быть 01 00). В моем случае первой нашлась запись другого файла: имя совпадает, но файл из другого каталога – у меня несколько версий DMDE (продолжение поиска дало желанный результат). Я легко определил, что файл не тот, потому что опыт проводился на живой файловой системе… Если ФС повреждена, правильно найти файл подобным образом будет проблематично, т. к. могут быть имена с одинаковым именем в разных каталогах, не говоря уже о других проблемах. Поэтому рационально использовать NTFS-сканер типа того, что есть в R-Studio, но я там не нашел возможности посмотреть начальный сектор файловой записи для выбранного файла. Есть еще мой Media Workshop, но он еще не доделан, хотя сканер уже давно функциклирует (выкладывать в сеть недоделку нет желания). В общем, тут остается неприятный момент с одинаковыми именами в разных каталогах. 3. Ищем содержимое реперного файла. Для этого открываем «живой» экземпляр реперного файла в WinHex, выделяем мышой первую строку, затем меню Edit – Copy block – Hex values (в случае других типов файлов первая строка может не прокатить – там зачастую заголовок, который одинаков для всех файлов такого типа). Теперь открываем проблемный физический диск в WinHex, Alt+Ctrl+X – окно поиска Hex значений. Вставляем искомые значения Ctrl+V, Search: Down, Cond: offset mod 512 = 0, остальные чекбоксы не отмечены, ОК (искать будет долго). Итак, я нашел начало файла, я вижу текст Readme от DMDE. Но я не знаю, от какой версии. Начал искать в браузере WinHex и обнаружил, что это Readme из каталога DMDE, расположенного в «Program Files\DMDE», а не в «Storage\Programs\DMDE\DMDE Win GUI», где я вначале нашел реперный файл. Т. е. опять проблема версий. Лирическое отступление Очевидно, что в моем случае реперный файл выбран неудачно. ИМХО нужен текстовый файл, который имеется на диске в одном экземпляре. Я попробовал на другом ReadMe – от AsmEdit, содержимое нашел правильно с первого раза (примерно в 10% от начала раздела объемом 61 ГБ), но с файловой записью возникли конкретные трудности, потому как имя файла Readme.txt есть и у других программ. В общем, если имя у файла распространенное, нужно искать файловую запись по реконструированной структуре в NTFS-сканере, который может показать для выбранного файла номер начального сектора. Следующим кандидатом стал файл Filemon.hlp (не текстовый) от программы FileMon, поиск содержимого осуществлялся по нескольким первым строкам hex-значений, поиск файловой записи – как обычно, только по имени. Поиск файловой записи дал индексную запись (INDX, [1], п. 4.16), это было очевидно и проблемы не создало. Продолжение поиска дало правильный сектор! Поиск содержимого дал правильный сектор с первого раза. Так что правильный выбор реперного файла имеет очень существенное значение. 4. Определение смещения начала реперного файла по ФС. Смещение начала файла от начала раздела в NTFS определяется как FromCls*ClsSct, где FromCls – начальный кластер файла, ClsSct – количество секторов на кластер. Размер кластера NTFS обычно 8 секторов. Теперь наша задача – найти номер начального кластера. Это несложно сделать в WinHex. Переходим к найденной файловой записи реперного файла ([1], п. 4.11). По смещению 0x14 байт от начала записи смотрим смещение начала списка атрибутов, обычно это 0x38 байт. Переходим по этому смещению и видим начало первого атрибута. В начале заголовка каждого атрибута два четырехбайтовых поля, расположенных последовательно: идентификатор типа атрибута и размер атрибута в файловой записи. Первый атрибут обычно имеет тип 0x10 (STANDARD_INFORMATION), на диске это выглядит как 10 00 00 00 48 00 00 00 (не забываем, что в каждом поле нужно инвертировать последовательность байт, т. е. размер атрибута 0x48 байт, а не 0x48000000). Размеры атрибутов одного типа могут быть различны, 0x48 дано для примера. Атрибуты в файловой записи расположены последовательно, нам нужно найти атрибут с идентификатором 0x80 (DATA). Т.к. размеры атрибутов указаны, мы просто переходим на размер атрибута и оказываемся в начале следующего атрибута. В WinHex Вы можете использовать окно Alt+G (Bytes, Hexadecimal, Current Position) для перемещения по цепочке атрибутов (обычно она включает атрибуты с типами 0x10, 0x30, 0x80; тех что с типом 0x30 может быть две штуки). Итак, вы в начале атрибута 0x80 DATA. Этот атрибут у Вашего реперного файла должен быть нерезидентным (мы специально искали файл не менее килобайта). В таком случае смещаемся от его начала на 0x20 байт и видим смещение списка экстентов, в большинстве случаев оно равно 0x40 байт. Смещаемся от начала атрибута DATA на 0x40 байт – мы в начале списка экстентов (ранлиста). Ранлист – это последовательность структур, указывающая размещение файла. Нас будет интересовать только первый экстент. Сейчас курсор в первом байте ранлиста. Посмотрите на этот байт. Его первая цифра означает количество байт поля смещения экстента, вторая цифра – количество байт поля размера экстента. Далее расположено поле размера экстента, за ним – поле смещения экстента. Например, в моем файле ранлист такой 31 - 04 - 81 2F 32 - 00. Видно, что под размер экстента отведен один байт, под смещение – три байта, размер равен 4 кластерам, а смещение 0x322F81 кластерам (не забываем перевертывать байты). После первого экстента расположен байт 00, он замыкает ранлист (если экстентов несколько, в этом байте начнется следующий экстент, и его смещение задается относительно начала предыдущего экстента). Итак, мы нашли смещение начала файла – это 0x322F81 (3293057) кластер, или 26311688 сектор от начала раздела при размере кластера 8 секторов (будьте внимательны, у Вас может быть другой размер кластера, например встречаются односекторые кластеры после преобразования FAT => NTFS). 5. Определение виртуального начального сектора раздела. Переходим в начало содержимого файла, которое мы нашли ранее. Смотрим номер сектора. Вычитаем из номера сектора смещение реперного файла, рассчитанное по ранлисту (в примере это 26311688), результат – виртуальный начальный сектор раздела, т. е. тот сектор, в котором должен был начинаться раздел для данной файловой системы (не стоит искать там бутсектор). Результат достигнут. После перемещения на 26311688 секторов от начала содержимого файла я наблюдаю на экране бутсектор раздела (эксперимент проведен на живой ФС). Такую процедуру надо повторить для нескольких файлов, чтобы более/менее точно определить смещение. Если смещений несколько, как было отмечено выше, поиск этих смещений гораздо сложнее, у меня нет идей, как это можно сделать простым путем. |