使用 dd 来获取干净的 MBR 代码在 pfSense 上不起作用

使用 dd 来获取干净的 MBR 代码在 pfSense 上不起作用

尝试在 shell 命令下使用 pfsense 2.7.0 live disk(pfsense 基于 freebsd)清理磁盘上的 mbr 代码部分。

存在/dev/da0我的驱动器遵循建议的清洁代码,仅保留分区的 mbr 代码,命令应该是:

dd if=/dev/zero of=/dev/da0 bs=446 count=1

然而......结果是:

dd: /dev/da0: Invalid argument
1+0 records in
0+0 records out
0 bytes transferred in 0.000089 secs (0 bytes/sec)

相反...如果我仅使用它作为代码,dd if=/dev/zero of=/dev/da0它只会删除所有内容而不会出现错误:(

我正在虚拟机中进行此测试,以便我可以多次恢复高清来测试这段文字...但是这件事让我头疼...

编辑:看来如果我使用bs=512orbs=1M它不会给出错误。但是这样做也会删除分区表部分......

编辑2:我尝试使用该命令dd if=/dev/da0 of=/tmp/mbr_file bs=512 count=1,它为我创建了一个带有 mbr 的文件,我想知道我可以使用哪些命令以二进制模式编辑该文件,将前 446 个字节填充为 0,然后使用它dd if=/tmp/mbr_file of=/dev/da0 bs=512 count=1来恢复它。

我可以用什么?六?

答案1

自从我上次使用 BSD 系统以来已经有很长一段时间了,我对它们关于磁盘设备的记忆是必须写入完整的块(或多个块)。情况似乎仍然如此,尤其是对于/dev/da0.

一般的方法是读取一个块,更新它的相关部分,然后再次写回整个块。在这里,我们也将保留原始块的备份,如下所示block0.backup

dd if=/dev/da0 bs=512 count=1 | tee block0.backup >block0
dd if=/dev/zero bs=446 count=1 conv=notrunc of=block0
dd if=block0 bs=512 of=/dev/da0

(这是真正需要的罕见情况之一dd,而不是cat。)

如果您需要恢复到备份,

dd if=block0.backup bs=512 of=/dev/da0

答案2

好吧,我做了很多测试并得出了这个结论......

因为 pfsense 是 freebsd 的一个该死的剥离版本,并且缺少很多工具,所以我必须这样做来清除磁盘中的前 446 个字节,保留位于第一个 512 字节块的最新 66 字节处的分区表。

dd if=/dev/da0 of=/tmp/mbr_file_original bs=512 count=1
dd if=/dev/zero of=/tmp/mbr_file_zerofilled bs=446 count=1
cat /tmp/mbr_file_original | ( dd of=/dev/null bs=446 count=1; dd bs=66 count=1 ) > /tmp/mbr_file_partitions_table
cat /tmp/mbr_file_partitions_table >> /tmp/mbr_file_zerofilled
mv /tmp/mbr_file_zerofilled /tmp/mbr_file_new
dd if=/tmp/mbr_file_new of=/dev/da0 bs=512 count=1

然后测试复制的 mbr 内容

dd if=/dev/da0 of=/tmp/mbr_file_test bs=512 count=1
hexdump /tmp/mbr_file_test | less

简而言之,我所做的是:

  • 将 mbr 复制到 mbr_file_original
  • 创建了一个名为 mbr_file_zerofilled 的零填充 446 字节文件
  • 然后因为有人是的,我在看着你,几乎删除了所有有用的工具,甚至是十六进制编辑器,只留下这个黑客可用,使用这一行cat mbr_file | ( dd of=/dev/null bs=446 count=1; dd bs=66 count=1 ) > mbr_file_partition_table从原始 mbr_file 中提取最后 66 个字节。
  • 此时,为了清楚起见,我使用 cat 连接了 2 个文件并重命名为 mbr_file_new,然后使用 dd 将 mbr 保存回 da0 设备

这次没有错误,因为我一次使用了 512 字节。

答案3

几个答案正确地指出,将字符写入字符设备,将块写入块设备。

我不知道 pfSense 包含哪些工具以及省略哪些工具,但在功能齐全的 FreeBSD 系统上,以下内容可以工作:

我会将示例/boot/pmbr图像写入我的测试磁盘/dev/md0并使用它作为起点:

# gpart bootcode -b /boot/pmbr md0
bootcode written to md0

这使得第一块看起来md0像:

# dd if=/dev/md0 count=1 | hexdump -v
1+0 records in
1+0 records out
512 bytes transferred in 0.000053 secs (9723673 bytes/sec)
0000000 31fc 8ec0 8ec0 8ed8 bcd0 0e00 1abe bf7c
0000010 061a e6b9 f301 e9a4 8a00 fa80 7280 8a0b
0000020 7536 8004 80c6 f238 0272 80b2 d1e8 b600
0000030 bb01 0e00 91be e807 00ac 8166 003e 450e
0000040 4946 7520 660d 3e81 0e04 4150 5452 0275
...
00001a0 be11 000b 6015 4fb8 900f 9090 9090 9090
00001b0 9090 9090 9090 9090 0000 0000 0000 0000
00001c0 0000 0000 0000 0000 0000 0000 0000 0000
00001d0 0000 0000 0000 0000 0000 0000 0000 0000
00001e0 0000 0000 0000 0000 0000 0000 0000 0000
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
0000200

要创建清零的 MBR 引导记录,我将复制该pmbr映像:

# cp -vp /boot/pmbr mbr.zeroed
/boot/pmbr -> mbr.zeroed

并用于hexedit在偏移量 0x0-0x1b7 处放置零。
Ctrl-X Y保存并退出。

最后,我会告诉gpart您将该文件写回 MBR。

# gpart bootcode -b mbr.zeroed md0
bootcode written to md0

现在我们有:

# dd if=/dev/md0 count=1 | hexdump -v
1+0 records in
1+0 records out
512 bytes transferred in 0.000106 secs (4847613 bytes/sec)
0000000 0000 0000 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
0000030 0000 0000 0000 0000 0000 0000 0000 0000
0000040 0000 0000 0000 0000 0000 0000 0000 0000
...
00001a0 0000 0000 0000 0000 0000 0000 0000 0000
00001b0 0000 0000 0000 0000 0000 0000 0000 0000
00001c0 0000 0000 0000 0000 0000 0000 0000 0000
00001d0 0000 0000 0000 0000 0000 0000 0000 0000
00001e0 0000 0000 0000 0000 0000 0000 0000 0000
00001f0 0000 0000 0000 0000 0000 0000 0000 aa55
0000200

相关内容