如何获取已删除分区中inode的块设备中的偏移量

在全新安装过程中,我不小心格式化了包含数据的磁盘。 我曾尝试使用一些工具:testing磁盘,最重要的,但我没有得到好的结果。 (请参阅我的超级用户不成功的post )。

所以我决定读一些关于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 

我试图find一些匹配这个结构的数据。
我使用这个脚本:

  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; }); } 

我发现数据似乎是开发目录的目录条目:

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

如果是这样的话,我得到了其子目录的inode号码:脚本,项目,服务,…

但我不知道该怎么办! 我试图根据这个指南推断出这些inode的位置,但是由于我找不到被删除的文件系统的超级块,我只能猜测块的大小,块的数量,对我来说似乎有些模糊,希望得到一个结果。

那么你可以有一些间隔为获得一个索引节点的偏移所需的所有值,一个更正式的公式来获得这个偏移?

如果您只删除了分区表(或者修改了分区表),那么如果数据没有被其他东西重用,您仍然可以获取数据。

ext2文件系统在超级块中有一个MAGIC号码,所以要恢复你的分区,你只需要搜索它。 我在一台机器上做了这个,并且能够恢复一个磁盘中的一个,而不是七个分区。 你有机会得到无效的数字,但只是寻找那个魔术。 幻数在include/uapi/linux/magic.h ,值为#define EXT2_SUPER_MAGIC 0xEF53 (位于偏移地址#define EXT2_SB_MAGIC_OFFSET 0x38 —来自文件include/linux/ext2_fs.h

要搜索超级块,只要在磁盘的一个扇区中找到偏移量为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 |.........aU...| 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 ,并且假定超级块是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 ,给出0x1008001050624

 # 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