如何翻转文件中的一点?


35

我想故意破坏文件以测试btrfs可以自我修复的说法。本文讨论了如何删除文件系统,通过“翻转”一点然后重新安装来损坏照片。在较旧的文件系统中,它只会被破坏,但应该在btrfs中修复。从理论上讲,这是有道理的,但我真的想测试一下。

问题在于本文没有解释如何执行任何操作。
我将如何更改文件系统中非常特定的部分?

我还应该指出,这必须在脱机文件系统上完成,以便btrfs不会认为我的写是故意的。

编辑:尽管这个问题(和讨论)谈论了很多关于btrfs的问题,但我想知道是否存在实现这种损坏的文件系统独立方法(以便可以在不同的RAID类型/控制器/等之间进行比较)。


@Dan我的意思是,如果我直接编辑文件,则btrfs(或与此相关的任何文件系统)会将其视为有效写入。它不会给我要找的腐败。
奥利

这是一个测试文件系统吗(即,您不在乎内容,还是从备份还原完全正常?而且,您是在单个驱动器上使用单个btrfs分区,还是在RAID阵列顶部使用单个分区,或其他配置?
Darth Android

1
如果btrfs支持正确的ioctl(不确定是否支持),则可以使用它filefrag -v来查找文件的确切位置。
derobert 2014年

3
@Oli我怀疑您会在票数和答案方面找到对U&L更感兴趣的受众。另外,这个
2014年

1
在正确的位置拍摄宇宙射线。
smcg 2014年

Answers:


20

我不是专家,但是该btrfs-progs软件包实际上包括专门用于执行此操作的工具,尽管您可能必须从源代码进行构建。无论如何,一旦安装或构建btrfs-progs,您就应该能够使用btrfs-corrupt-blockbtrfs开发人员用来测试文件系统的工具。

现在,就像我说的那样,我没有太多时间来玩btrfs,所以我不知道该工具的确切用法。但是,有了它,您应该能够破坏脱机文件系统,当读取损坏的文件时,该文件系统将被修复(假设您已经设置了RAID或其他东西,以便可以使用另一个副本)。


2
很棒的发现!假设btrfs-corrupt-blockbtrfs开发人员实际上写的是真正的测试,而不是“技巧”,那么这应该完全符合要求。
allquixotic

@allquixotic如果您想了解有关btrfs的更多信息,请参阅linux.conf.au 2012中精彩演讲。就像我说的那样,它btrfs-corrupt-block是由开发人员使用的,因此,如果这是个把戏,那将不是很有用:)
苦苦挣扎

3
@allquixotic这就是开源的魅力:您可以查看btrfs 的源代码并进行检查!当然,这将不是一件容易的事,但是如果您确实愿意,可以这样做。
Bakuriu 2014年

@Bakuriu我完全知道这一点。我从来没有认真怀疑过这btrfs-corrupt-block不是一个真诚的测试,因为有人会在源头上迅速找到它,并将其用作对Oracle的负面PR(至少;以及其他btrfs开发人员/贡献者)。这只是现成的评论。
allquixotic

我想知道OP(@Oli)是否要破坏一个块(即文件系统结构)或一个文件(即文件的内容?前者,不是后者?[文件系统如何知道文件中的哪一位被翻转?某种CRC?]。不过,这个答案可能在右边,所以+1。[但是它可能会比“单个位”变化更多?或更改可以比在任何地方发生的随机事件更容易治愈的东西?]
Olivier Dulac 2014年

16
  1. 获取块设备上单个扇区的值(例如/dev/sda1),偏移量为一百万个扇区偏移量(仅作为示例):

    sudo dd if=/dev/sda1 of=/root/mysector bs=512 count=1 skip=1M
    

    任意选择的1M * 512字节偏移量只是为了确保您不在文件系统的元数据部分中,并且实际上位于包含数据的扇区中。

  2. 通过使用十六进制编辑器更改内容来编辑原始扇区数据。例如,请参见需要一个适用于Linux的十六进制编辑器

  3. 将扇区放回驱动器上,ifof反转和参数:

    sudo dd if=/root/mysector of=/dev/sda1 bs=512 count=1 seek=1M
    

2
除非百万分之一的块实际上是文件的一部分,否则这将不会帮助他进行测试。他如何查找特定文件的开始块?
Darth Android

3
使几乎没有。如果可以将dd命令锁定到文件的确切位置,则这可能是解决此问题的最佳方法。
奥利

@Oli是的,我知道如何在文件系统的扩展系列中做到这一点,但是我对btrfs没有太多的经验。让我看看是否可以找到方法。
gertvdijk 2014年

2
@Oli:您可以简单地循环执行dd逐块输出(即,与上面类似,但“ skip = N”,N在1..max中),直到可以从要编辑的文件中复制一行[尝试生成在其他任何地方都不会发生的行,例如从密码生成器那里获取它,并且足够长的时间?]。然后编辑该特定块。重新挂载,测试更改是否已还原(我怀疑,请参阅我的评论……似乎在文件数据(=内容)与文件系统结构本身(=文件及其内容的组织方式)之间存在混淆)?)
Olivier Dulac 2014年

16

@Oli-嗨,我叫Jim Salter,是写这篇文章的人。我正在使用虚拟机,这使事情变得更简单。我所做的是从JPEG文件开始的,然后在十六进制编辑器中将其打开。我使用的特定版本是Bless,您可以使用简单的apt-get install bless将其安装在Ubuntu中。

在Bless中打开JPEG后,我按了几次向下翻页以完全了解JPEG的“内容”,然后仅突出显示大约50个字节的数据,然后将其复制并粘贴到文本编辑器中(在我的情况下,gEdit)。这给了我一些要寻找的东西。

现在,我将JPEG保存到VM的每个阵列中。阵列后面的存储是一系列.qcow2文件。将JPEG保存到数组中后,可以将与每个数组关联的.qcow2文件加载到Bless中,然后搜索它们-它们不是很大,除了JPEG和一些元数据外,只能找到该50字节模式我已突出显示并复制出JPEG。瞧,我有腐败的块!此时,我可以使用Bless手动编辑存储在VM虚拟磁盘上的JPEG的各个字节,而且重要的是,在每个阵列上的编辑方式也完全相同

唯一的麻烦是,就本文中测试的RAID5阵列而言,我必须确保编辑的是条带中数据的实际副本,而不是条带本身的奇偶校验-这是在磁盘上的小映像。否则为空数组,因此该条带中的FOLLOWING块中没有任何数据,从而使奇偶校验块包含该数据块中未更改的数据。如果我不小心编辑了奇偶校验块而不是数据块,则图像将显示为不变。

最后一点-您不需要虚拟机来执行此操作-您可以使用裸机以​​相同的方式执行相同的操作;这将使您更加痛苦,因为您需要使用整个原始驱动器而不是使用小的.qcow2文件,并且您必须拉出驱动器并将它们放入另一台计算机中,或者引导到实时(或只是备用)环境中以使其混乱。(我完全以此方式测试了ZFS的数据恢复,但是在7年前的真正的裸机上,当我第一次对下一代文件系统产生兴趣时。)

希望这可以帮助!


4

您可以尝试在打开的文件上执行的小程序。FIBMAP ioctl(2)

通过快速的网络搜索,我发现了此博客文章http://smackerelofopinion.blogspot.tw/2009/06/fibmap-ioctl-file-system-block-number.html详细说明了如何执行此操作-它甚至还会为您提供链接可以编译和运行自己的示例程序。

$ git clone git://kernel.ubuntu.com/cking/debug-code
$ cd debug-code/block-mapper-fibmap
$ make
$ sudo ./fibmap /path/to/your/image-file.jpg

这正是hdparm --fibmap(@falconer提到的)实现方式。

找到块编号后,您可以使用dd功夫来修改文件,如@gertvdijk所示。或者,也许您可​​以修改fibmap.c上面的程序来为您做位翻转,绕过文件系统层直接写入设备文件(程序的三个参数:1.文件的路径,2.包含文件的设备文件系统,3.您要修改的偏移量和位)。

免责声明:我没有测试过,不能保证该FIBMAP ioctl(2)会在回环设备或BTRFS文件系统中的文件工作,但我强烈希望它我。猜测 hdparm在执行前会检查设备类型ioctl(2)上的文件,因此是失败。)


3
sudo hdparm --fibmap /PATH/TO/FILE

将为您提供文件所在的LBA。之后,您可以使用@gertvdijk的答案。


不幸的是,这似乎不起作用。这0,39: device not found in /dev是因为它是btrfs,或者是(更可能是)因为我正在回送保留的文件上使用它。我将尝试使用“适当的” VM来完成此操作。
奥利(Oli)

@Oli嗯。我认为这hdparm适用于每个文件系统,但事实并非如此。
falconer 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.