我的硬盘驱动器出现故障,无法写入或读取磁盘的第一个扇区。它仅给出I / O错误,仅此而已。磁盘上的其他区域似乎(大部分)正常。我正在尝试挂载分区(ext4),看看是否可以访问一些我想恢复的文件。由于该mount
命令支持一个offset
选项,因此即使分区表不可读也不可写,我也应该能够挂载文件系统。问题是如何找到偏移量。ext4工具似乎都没有这个特殊功能。
我的硬盘驱动器出现故障,无法写入或读取磁盘的第一个扇区。它仅给出I / O错误,仅此而已。磁盘上的其他区域似乎(大部分)正常。我正在尝试挂载分区(ext4),看看是否可以访问一些我想恢复的文件。由于该mount
命令支持一个offset
选项,因此即使分区表不可读也不可写,我也应该能够挂载文件系统。问题是如何找到偏移量。ext4工具似乎都没有这个特殊功能。
Answers:
暂时没有标准偏移量,因为您当然可以在任意位置启动分区。但是让我们假设您正在寻找第一个分区,并且该分区或多或少地接受了默认设置。假设您使用的是传统的DOS分区表,那么可能有两个地方可以找到它:
现在,继续,您将要选择自己喜欢的十六进制转储工具,并了解一些有关ext4 Disk Layout的知识。特别是,它以1024字节的填充开始,而ext4会忽略该填充。接下来是超级块。您可以通过在偏移量0x38(从超级块开始,或从分区开始,从0x438或十进制1080)处检查幻数0xEF53来识别超级块。幻数为little-endian。因此,它实际上以0x53EF的形式存储在磁盘上。
这是这样的xxd -a
:
0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
*
0000400: 0040 5d00 0084 7401 33a0 1200 33db a600 .@]...t.3...3...
0000410: 4963 5300 0000 0000 0200 0000 0200 0000 IcS.............
0000420: 0080 0000 0080 0000 0020 0000 6637 0952 ......... ..f7.R
0000430: 6637 0952 0200 1600 53ef 0100 0100 0000 f7.R....S.......
0000440: 9938 f851 004e ed00 0000 0000 0100 0000 .8.Q.N..........
请注意,当您将偏移量设置为挂载(或lostup)时,必须将偏移量填充到填充开始的位置,而不是超级块。
现在,如果它不是第一个分区,或者不是在两个(三个)预期位置之一中,则基本上可以搜索魔术数字0xEF53。这就是testdisk
(建议在评论中)为您做的。
testdisk
找不到。谢谢大家的帮助。
dd if=/dev/sda skip=$start_sector | xxd -a | grep '[02468]30: .... .... .... .... 53ef'
来获取一些可能的匹配项。可能不是很快,但是您可以在找到更好的方法的同时让它运行。
testdisk
,所以我只需要添加tl;dr:
标题的编辑
基于@derobert的答案,我编写了一个程序(gist),该程序将解析来自输入流的内容dd
并扫描每个扇区以查找类似于ext分区开始的内容。
它的运行速度至少与dd
从硬盘读取数据的速度一样快。删节版在下面。
最简单的用法是sudo dd if=/dev/xxx | ext2scan
,尽管您可能希望修改dd
命令以提高块大小或选择要搜索的区域。
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main() {
unsigned char const MAGIC[2] = {0x53, 0xef};
unsigned char const ZEROS[512] = {0};
long long int sector = 0;
char buf[4][512];
int empty1, empty2;
while (read(STDIN_FILENO, buf[sector&3], 512) > 0) {
if (!memcmp(buf[sector&3] + 0x38, MAGIC, 2)) {
printf("Found a possible ext2 partition at sector %lld", sector-2);
empty1 = !memcmp(buf[(sector-2)&3], ZEROS, 512);
empty2 = !memcmp(buf[(sector-1)&3], ZEROS, 512);
if (empty1 && empty2) printf(" (first two sectors are empty :)\n");
}
sector++;
}
}
注意:它不仅会发现分区的开始,而且还会发现其中的超级块。
无论哪种情况,我都建议使用dumpe2fs
来分析结果。您可以将可疑超级块的开始转储到文件中(根据我的非正式测试,至少前六个扇区),如果是超级块,则将dumpe2fs
(其中包括)告诉您其他超级块的相对位置。
猜测分区从何处开始并施加一些蛮力:
bsz=512 # or 1024, 2048, 4096 higher = faster
for i in {2..10000000}; do
echo "--->$i<---"
mount -o offset=$(($bsz*$i)) -t ext4 /dev/whatever /mnt/foo
if [ $? == 0 ]; then # whahoo!
echo Eureka
break
fi
done
我想这可能会花费一些时间,但是如果您已经在testdisk上花费了6个小时,也许值得尝试一下。
echo "--->$i<---"
因为如此,否则无法进行评估。我认为您可以增加到bsz
4096,这样可以加快处理速度。
尝试其他选项(例如,使用debugfs和fsck.ext4):
debugfs:
您必须先安装debugfs(而不是发生故障的硬盘本身):
http://blesseddlo.wordpress.com/2010/10/12/using-debugfs/
(本质上是在启用写功能的情况下使用“ debugfs -w”,然后使用“ lsdel”列出所有已删除的文件)。或者你可以使用
这是fsck.ext4:
http://linuxexpresso.wordpress.com/2010/03/31/repair-a-broken-ext4-superblock-in-ubuntu/
另一个是“ sleuthkit”(“ sudo apt-get install sleuthkit”),它具有“ istat”之类的命令,用于提供有关inode的块信息-您可以从中获取偏移量,从而轻松地阻塞数据内容。
https://www.ibm.com/developerworks/cn/linux/l-cn-ext4resize/
(顺便说一句,如果通过debugfs的“ show_super_stats”命令将块大小设置为1024,则可以看到块1与磁盘的起始位置之间的偏移量为1024个字节,并且每个块组也可以具有多个块。)
我有一个电子书固件映像,其中包括ext3fs分区映像,以便进行装载和编辑,我必须使用bgrep工具扫描映像以查找ext3fs幻数的所有位置,0x53EF
然后尝试使用找到的偏移量进行装载。
这是执行安装的简化脚本:
#!/bin/sh
FW_IMAGE=$1
MOUNT_POINT=$2
FS_TYPE=ext3
EXTFS_MAGIC_NUM=53ef
MAGIC_OFFSET=1080
OFFSETS=`bgrep $EXTFS_MAGIC_NUM $FW_IMAGE | awk '{print toupper($NF)}'`
for OFFSET in $OFFSETS; do
OFFSET=`echo "ibase=16; $OFFSET" | bc`
OFFSET=`expr $OFFSET - $MAGIC_OFFSET`
sudo mount -t $FS_TYPE -o loop,offset=$OFFSET $FW_IMAGE $MOUNT_POINT 2>/dev/null
if [ $? -eq 0 ]; then
echo "Success! Offset is: $OFFSET."
break
fi
done
这未经测试,但是我认为您可以使用此SU Q&A中讨论的方法:从Linux和ext3 / 4的原始设备中的偏移量反向查找inode /文件?。
看起来您可以使用文件的索引节点+磁盘偏移量+块大小来确定文件的偏移量。