如何获取已删除分区中inode的块设备中的偏移量 [英] How to get the offset in a block device of an inode in a deleted partition

查看:270
本文介绍了如何获取已删除分区中inode的块设备中的偏移量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在全新的安装过程中,我意外地格式化了包含数据的磁盘。我曾尝试使用一些工具:测试磁盘,最重要的,但我没有得到好的结果。 (请参阅我的失败帖子)。



所以我决定阅读一些关于 ext2文件系统结构的文档,我可以得到一些结果:



删除的分区有一个目录树:

  dev 
| -scripts
| -projects
| -services
| -...
媒体
| - 下载
| -Musique
| -...
备份
...

,基于ext2目录条目格式:

pre $目录条目
Starting_Byte Ending_Byte Size_in_Bytes Field_Description
0 3 4 Inode
4 5 2此项的总大小(包括所有子字段)
6 6 1名称长度最低有效8位
7 7 1类型指示符(仅当目录条目具有文件类型pe字节被设置,否则这是名字长度的最高有效8位)
8 8 + N-1 N名字符

我试图找到一些符合这个结构的数据。

我使用了这个脚本:

$ $ $ p> var bindexOf = require('buffer-indexof');

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

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

var dirs = [dev,scripts,services,projects,下载,Musique,backup];
dirs.forEach(函数(dir){

dirOctetFormat = new Buffer(2);
dirOctetFormat .writeUInt8(dir.length,0);
dirOctetFormat.writeUInt8(2,1); // type is directory
dirOctetFormat = Buffer.concat([dirOctetFormat,new Buffer(dir)]);
$ b var offset = bindexOf(data,dirOctetFormat);
if(offset> = 0){
console.log(dir +entry found at offset+(currentOffset + offset));
}

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

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

  =====当前抵消:233590226944  -  217.5478515625Gio ====== 
脚本条目在offset 233590227030
服务项目在抵消处找到233590227014
项目找到抵消处233590228106

如果是这样,我得到了其子目录的脚本,脚本,项目,服务... ...

但是我不知道该怎么做!
我尝试根据本指南,$推断这些inode的位置b $ b,但由于我无法找到被删除的文件系统的超级块,我只能猜测块的大小,块的数量,...
,这似乎有点模糊,我希望得到一个结果。所以你可以有一些时间间隔,以获得索引节点的偏移量和更正式的公式来获得这个偏移量?$ b $如果你只删除了分区表(或者修改了分区表),你仍然可以获得你的数据,如果数据还没有被其他东西重用的话。

include / uapi / linux / magic.h 中定义,值为 #define EXT2_SUPER_MAGIC 0xEF53 #define EXT2_SB_MAGIC_OFFSET 0x38 ---来自文件 include / linux / ext2_fs.h



要搜索超级块,只需在偏移 0x38 处找到 0xef53 在磁盘的一个扇区中,它将标记分区的第一个块。请注意,该超级块在一个分区中被复制了好几次,所以你可以找到所有的副本。



祝你好运! (我碰巧遇到过)


$ b

编辑(举个例子)



只要在我自己的分区中看到幻数:

 #hd / dev / sda3 |头-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 93 93 99 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 从块原点,并假定超级块是分区中的第二个块(块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
pre>

显然,这个列表中有许多无趣的行比我们需要的要多,为了找到一个有趣的地方,我们需要用数字进行一些计算。我们已经看到,扇区的长度是512个字节(这是十六进制的 0x200 ),我们可以在偏移量 0x438 ,所以我们期望有效的偏移量只在 0xXXXXXX [02468ace] 38 中,只要选择偏移量以该表达式结束的行,就会得到第一个超级块在$ 0x20100430
Substract 0x430 的有效位置(在第三行)给出分区( 0x20100000 ),然后将结果除以 0x200 ,给出 0x100800 ,或 1050624

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

磁盘/ dev / sda:931.5 GiB,1000 204886016字节,1953525168扇区
单位:1 * 512 = 512字节的扇区
扇区大小(逻辑/物理):512字节/ 4096字节
I / O大小(最小/最佳): 4096字节/ 4096字节
磁盘标识符类型:gpt
磁盘标识符:DF97DAD4-727D-4BB3-BD7B-3C5A584A2747

设备开始结束扇区大小类型
/ dev / sda1 2048 526335 524288 256M EFI系统
/ dev / sda2 526336 1050623 524288 256M BIOS启动
/ dev / sda3 1050624 18628607 17577984 8.4G Linux filesystem< - HERE !!!
/ dev / sda4 18628608 77221887 58593280 28G Linux文件系统
/ dev / sda5 77221888 85035007 7813120 3.7G Linux文件系统
/ dev / sda6 85035008 104566783 19531776 9.3G Linux文件系统
/ dev / sda7 104566784 135817215 31250432 14.9G Linux swap
/ dev / sda8 13​​5817216 155348991 19531776 9.3G Linux文件系统
/ dev / sda9 155348992 1953523711 1798174720 857.4G Linux文件系统


During a fresh installation, I accidentally formatted a disk containing datas. I have tried using some tools: testdisk, foremost, but I did not get good results. (see my unsuccessful post on superuser).

So I have decided to read some docs about ext2 filesystem structure, and I could get some results:

The deleted partition have a directory tree like that:

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

So, based on the ext2 directory entry format:

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

I tried to find some datas matching this structure.
I used this script:

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

I found data which seems to be the directory entry of the dev directory:

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

If it is the case, I got the inode numbers of its children directories: scripts, projects, services,...

But I do not know what to do with that! I tried to deduce the location of these inodes, based on this guide, but as I was unable to find a superblock of the deleted filesystem, I just have to make guesses about the block size, the number of blocks, ... and that seems a little bit fuzzy to me to hope obtaining a result.

So could you have some intervals for all values needed to obtain the offset of an inode, and a more formal formula to get this offset?

解决方案

If you have only erased the partition table (or modified it) you can still get your data, if data has not been reused for something else.

ext2 filesystems have a MAGIC number in superblock, so to recover your partition you have only to search for it. I did this on one machine and was able to recover not one, but seven partitions in one disk. You have some chances to get invalid numbers, but just search for that magic. Magic number is defined in include/uapi/linux/magic.h and value is #define EXT2_SUPER_MAGIC 0xEF53 (it's found at offset #define EXT2_SB_MAGIC_OFFSET 0x38 ---from file include/linux/ext2_fs.h)

To search for the superblock, just try to find 0xef53 at offset 0x38 in one sector of the disk, it will mark the first block of the partition. Be careful, that superblock is replicated several times in one partition, so you'll find all the copies of it.

Good luck! (I had when it happened to me)


Edit (To illustrate with an example)

Just see the magic number in one of my own partitions:

# 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  |................|

Remember it is on offset 0x38 counted from the block origin, and assume the super block is the second block (block 0 reserved for bootcode, so it will be block 1, with two sectors per block, to make 1k blocksize) in the partition, so you'll have to rewind 0x438 bytes from the beginning of the magic number to get the partition origin.

I have run the command on my whole disk, getting the following result:

# 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.|

Clearly, there are much more uninteresting lines in this listing than the ones we need. To locate the one interesting here, we have to do some computing with the numbers. We have seen that sectors are 512 bytes long (this is 0x200 in hex) and we can have the superblock magic at offset 0x438, so we expect valid offsets to be at 0xXXXXXX[02468ace]38 only. Just select the lines with offsets ending in that expression, and you'll get the first superblock valid (in the third line) at offset 0x20100430. Substract 0x430 to give the byte offset of the partition (0x20100000, and then, divide the result by 0x200, giving 0x100800, or 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

这篇关于如何获取已删除分区中inode的块设备中的偏移量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆