Как получить смещение в блочном устройстве индексного дескриптора в удаленном разделе

Во время новой установки я случайно отформатировал диск с данными. Я пробовал использовать некоторые инструменты: в первую очередь testdisk, но не добился хороших результатов. (см. мою неудачную запись на суперпользователе).

Итак, я решил прочитать несколько документов о структуре файловой системы ext2 и смог получить некоторые результаты:

Удаленный раздел имеет такое дерево каталогов:

dev
|-scripts
|-projects
|-services
|-...
Medias
|-downloads
|-Musique
|-...
backup
...

Итак, исходя из формата записи каталога ext2:

Directory Entry
Starting_Byte Ending_Byte Size_in_Bytes Field_Description
0   3       4   Inode
4   5       2   Total size of this entry (Including all subfields)
6   6       1   Name Length least-significant 8 bits
7   7       1   Type indicator (only if the feature bit for "directory entries have file type byte" is set, else this is the most-significant 8 bits of the Name Length)
8   8+N-1   N   Name characters

Я попытался найти данные, соответствующие этой структуре.
Я использовал этот скрипт:

    var bindexOf = require('buffer-indexof');

    var currentOffset=0;
    var deviceReadStream = fs.createReadStream("/dev/sdb");

    deviceReadStream.on('error',function(err){
        console.log(err);
    });

    deviceReadStream.on('data',function(data){

        var dirs = ["dev","scripts","services","projects","Medias","downloads","Musique","backup"];
        dirs.forEach(function(dir){

            dirOctetFormat = new Buffer(2);
            dirOctetFormat.writeUInt8(dir.length,0);
            dirOctetFormat.writeUInt8(2,1);// type is directory
            dirOctetFormat= Buffer.concat( [dirOctetFormat, new Buffer(dir)]);

            var offset = bindexOf( data, dirOctetFormat );
            if( offset >= 0 ){    
                console.log( dir + " entry found at offset " + (currentOffset + offset) );
            } 

        });
        currentOffset += data.length;
    });
}

Я нашел данные, которые, похоже, являются записью в каталоге dev:

 ===== Current offset: 233590226944 - 217.5478515625Gio ====== 
scripts entry found at offset 233590227030
services entry found at offset 233590227014
projects entry found at offset 233590228106

Если это так, я получил номера inode его дочерних каталогов: скрипты, проекты, службы, ...

Но я не знаю, что с этим делать! Я попытался определить расположение этих inodes на основе этого руководства, но так как я не смог чтобы найти суперблок удаленной файловой системы, мне просто нужно предположить размер блока, количество блоков, ... и это кажется мне немного нечетким, чтобы надеяться на получение результата.

Итак, не могли бы вы иметь несколько интервалов для всех значений, необходимых для получения смещения inode, и более формальную формулу для получения этого смещения?


person Gaël    schedule 22.07.2015    source источник


Ответы (1)


Если вы только стерли таблицу разделов (или изменили ее), вы все равно можете получить свои данные, если данные не были повторно использованы для чего-то еще.

Файловые системы ext2 имеют номер MAGIC в суперблоке, поэтому для восстановления раздела вам нужно только найти его. Я сделал это на одной машине и смог восстановить не один, а семь разделов на одном диске. У вас есть шансы получить неверные числа, но просто поищите эту магию. Магическое число определяется в include/uapi/linux/magic.h, а значение - #define EXT2_SUPER_MAGIC 0xEF53 (находится по смещению #define EXT2_SB_MAGIC_OFFSET 0x38 --- из файла include/linux/ext2_fs.h)

Для поиска суперблока просто попробуйте найти 0xef53 по смещению 0x38 в одном секторе диска, это отметит первый блок раздела. Будьте осторожны, этот суперблок реплицируется несколько раз в одном разделе, поэтому вы найдете все его копии.

Удачи! (У меня было, когда это случилось со мной)


Изменить (проиллюстрировать примером)

Просто посмотрите магическое число в одном из моих собственных разделов:

# hd /dev/sda3 | head -20
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400  40 62 08 00 00 87 21 00  26 ad 01 00 f6 30 15 00  |@b....!.&....0..|
00000410  1d 31 08 00 00 00 00 00  02 00 00 00 02 00 00 00  |.1..............|
00000420  00 80 00 00 00 80 00 00  90 1f 00 00 cf 60 af 55  |.............`.U|
00000430  fc 8a af 55 2d 00 ff ff  53 ef 01 00 01 00 00 00  |...U-...S.......|<- HERE!!!
00000440  36 38 9d 55 00 00 00 00  00 00 00 00 01 00 00 00  |68.U............|
00000450  00 00 00 00 0b 00 00 00  00 01 00 00 3c 00 00 00  |............<...|
00000460  46 02 00 00 7b 00 00 00  5a bf 87 15 12 8f 44 3b  |F...{...Z.....D;|
00000470  97 e7 f3 74 4d 75 69 12  72 6f 6f 74 00 00 00 00  |...tMui.root....|
00000480  00 00 00 00 00 00 00 00  2f 00 61 72 67 65 74 00  |......../.arget.|
00000490  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000004c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 18 02  |................|
000004d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000004e0  08 00 00 00 00 00 00 00  00 00 00 00 93 54 99 ab  |.............T..|
000004f0  aa 64 46 b3 a6 73 94 34  a3 79 46 28 01 01 00 00  |.dF..s.4.yF(....|
00000500  0c 00 00 00 00 00 00 00  e5 61 92 55 0a f3 02 00  |.........a.U....|
00000510  04 00 00 00 00 00 00 00  00 00 00 00 ff 7f 00 00  |................|
00000520  00 80 10 00 ff 7f 00 00  01 00 00 00 ff ff 10 00  |................|

Помните, что это смещение 0x38, отсчитываемое от источника блока, и предположим, что суперблок является вторым блоком (блок 0 зарезервирован для загрузочного кода, поэтому это будет блок 1 с двумя секторами на блок, чтобы сделать размер блока 1k) в разделе, поэтому вам придется перемотать 0x438 байтов с начала магического числа, чтобы получить происхождение раздела.

Я выполнил команду на всем своем диске и получил следующий результат:

# hd /dev/sda | grep " [0-9a-f][0-9a-f]  53 ef" | sed -e 's/^/    /' | head
006f05f0  ee 00 00 11 66 0a 00 00  53 ef 00 00 11 66 2d 00  |....f...S....f-.|
007c21d0  55 2a aa 7d f4 aa 89 55  53 ef a4 91 70 40 c1 00  |U*.}...US...p@..|
20100430  fc 8a af 55 2d 00 ff ff  53 ef 01 00 01 00 00 00  |...U-...S.......|
2289a910  0f 8f 4f 03 00 00 81 fe  53 ef 00 00 0f 84 ce 04  |..O.....S.......|
230d4c70  0a 00 00 00 1c 00 00 00  53 ef 01 00 00 00 00 00  |........S.......|
231b7e50  a0 73 07 00 00 00 00 00  53 ef 0d 00 00 00 00 00  |.s......S.......|
23dbd230  d5 08 ad 2b ee 71 07 8a  53 ef c2 89 d4 bb 09 1f  |...+.q..S.......|
25c0c9e0  06 00 00 00 00 4f 59 c0  53 ef 32 c0 0e 00 00 00  |.....OY.S.2.....|
25d72ca0  b0 b4 7b 3d a4 f7 84 3b  53 ef ba 3c 1f 32 b9 3c  |..{=...;S..<.2.<|
25f0eab0  f1 fd 02 be 28 59 67 3c  53 ef 9c bd 04 30 72 bd  |....(Yg<S....0r.|

Понятно, что в этом листинге гораздо больше неинтересных строк, чем тех, которые нам нужны. Чтобы найти здесь интересный, нам нужно произвести вычисления с числами. Мы видели, что секторы имеют длину 512 байт (это 0x200 в шестнадцатеричном формате), и у нас может быть магия суперблока со смещением 0x438, поэтому мы ожидаем, что допустимые смещения будут только с 0xXXXXXX[02468ace]38. Просто выберите строки со смещениями, заканчивающимися этим выражением, и вы получите первый действительный суперблок (в третьей строке) со смещением 0x20100430. Вычтите 0x430, чтобы получить байтовое смещение раздела (0x20100000, а затем разделите результат на 0x200, получив 0x100800 или 1050624)

# fdisk -l /dev/sda | sed -e 's/^/    /'

Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: DF97DAD4-727D-4BB3-BD7B-3C5A584A2747

Device         Start        End    Sectors   Size Type
/dev/sda1       2048     526335     524288   256M EFI System
/dev/sda2     526336    1050623     524288   256M BIOS boot
/dev/sda3    1050624   18628607   17577984   8.4G Linux filesystem  <-- HERE!!!
/dev/sda4   18628608   77221887   58593280    28G Linux filesystem
/dev/sda5   77221888   85035007    7813120   3.7G Linux filesystem
/dev/sda6   85035008  104566783   19531776   9.3G Linux filesystem
/dev/sda7  104566784  135817215   31250432  14.9G Linux swap
/dev/sda8  135817216  155348991   19531776   9.3G Linux filesystem
/dev/sda9  155348992 1953523711 1798174720 857.4G Linux filesystem
person Luis Colorado    schedule 22.07.2015
comment
Спасибо за ваш ответ. Я уже искал подпись ext2 безрезультатно. - person Gaël; 23.07.2015
comment
если объем большой, вы получите по крайней мере копии суперблока ... или, возможно, вы отформатировали диск с возможностью стереть весь диск. - person Luis Colorado; 23.07.2015
comment
Я думал, что новый раздел перезаписал все копии суперблоков. Но это произошло из-за того, что последовательность написана с прямым порядком байтов, поэтому мне пришлось искать 0x53EF. И я получил много результатов! - person Gaël; 23.07.2015
comment
Копии суперблоков распределены по всему разделу (по одной на каждую группу блоков), поэтому, возможно, вы потеряли более 80% объема. Проблема с прямым порядком байтов проиллюстрирована в моем примере. Просто взгляните на #define и шаблон grep для поиска (я включил команды, чтобы проиллюстрировать их более подробно) - person Luis Colorado; 24.07.2015
comment
Кроме того, я проверил, что предыдущее поле с номером magid - это максимальное разрешенное количество монтировок. По умолчанию это поле инициализируется значением -1 (0xff 0xff). Попробуйте выполнить поиск, используя grep 'ff ff 53 ef', и вы получите много из них. Если вы не изменили максимальный лимит монтирования, это может вам помочь. - person Luis Colorado; 24.07.2015
comment
Кроме того, обычно fdisk -l показывает минимальный / оптимальный размер блока устройства. Это позволяет проверять разные значения смещения. Размер блока 4Kb позволяет вам указывать смещения с ^[0-9a-f]*430 в качестве регулярного выражения вместо того, которое я использовал (для блока размером 1 КБ, ^[0-9a-f]*[02468ace]30 ) - person Luis Colorado; 24.07.2015