我已经多次阅读了这句话(下面),最近一次在这里,并且一直对如何dd用于修补任何东西感到困惑,更不用说编译器了:
30 年前,我在学校使用的 Unix 系统在 RAM 和磁盘空间方面非常有限。特别是
/usr/tmp文件系统非常小,当有人试图编译一个大程序时会导致问题。当然,无论如何,学生都不应该编写“大型程序”;大型程序通常是从“某处”复制的源代码。我们中的许多人复制/usr/bin/cc到/home/<myname>/cc,并用于dd修补二进制文件以使用/tmp代替/usr/tmp,后者更大。当然,这只会让问题变得更糟——这些副本占用的磁盘空间在那些日子里确实很重要,现在/tmp经常被填满,甚至阻止其他用户编辑他们的文件。在他们发现发生了什么之后,系统管理员做了一个chmod go-r /bin/* /usr/bin/*它“修复”了问题,并删除了我们所有的 C 编译器副本。
(强调我的)
该dd手册页只字未提修补和不认为它可能是重新定意要做到这一点呢。
二进制文件真的可以打补丁dd吗?这有什么历史意义吗?
Mic*_*mer 79
让我们试试吧。这是一个简单的 C 程序:
#include <stdio.h>
int main(int argc, char **argv) {
puts("/usr/tmp");
}
Run Code Online (Sandbox Code Playgroud)
我们将其构建为test:
$ cc -o test test.c
Run Code Online (Sandbox Code Playgroud)
如果我们运行它,它会打印“/usr/tmp”。
让我们找出“ /usr/tmp”在二进制文件中的位置:
$ strings -t d test | grep /usr/tmp
1460 /usr/tmp
Run Code Online (Sandbox Code Playgroud)
-t d 将十进制的偏移量打印到它找到的每个字符串的文件中。
现在让我们制作一个只有“ /tmp\0”的临时文件:
$ printf "/tmp\x00" > tmp
Run Code Online (Sandbox Code Playgroud)
所以现在我们有了二进制文件,我们知道要更改的字符串在哪里,并且我们有一个包含替换字符串的文件。
现在我们可以使用dd:
$ dd if=tmp of=test obs=1 seek=1460 conv=notrunc
Run Code Online (Sandbox Code Playgroud)
这从tmp(我们的“ /tmp\0”文件)读取数据,将其写入我们的二进制文件,使用 1 个字节的输出块大小,在写入任何内容之前跳到我们之前找到的偏移量,并且在完成时明确不截断文件。
我们可以运行打过补丁的可执行文件:
$ ./test
/tmp
Run Code Online (Sandbox Code Playgroud)
程序打印出的字符串文字已经改变,所以它现在包含“ /tmp\0tmp\0”,但是字符串函数一旦看到第一个空字节就会停止。这种修补只允许使字符串更短或相同的长度,而不是更长,但它足以满足这些目的。
所以我们不仅可以使用 修补东西dd,我们刚刚完成了它。
这取决于您所说的“修补二进制文件”是什么意思。
我dd有时使用更改二进制文件。当然dd, .
例如,我有一个包含一些 PNG 数据的二进制文件。使用binwalk找到的偏移量,dd将其解压(通常binwalk还提取的东西,但我的副本是越野车),编辑它gimp,确保编辑的文件大小相同或比原来的更小的(改变偏移是不是你可以很容易做到),然后使用dd将更改后的图像放回原位。
$ binwalk thebinary
[…]
4194643 0x400153 PNG image, 800 x 160, 8-bit/color RGB, non-interlaced
[…]
$ dd if=nickel bs=1 skip=4194641 count=2 conv=swab | od -i
21869 # file size in this case - depends on the binary format
$ dd if=thebinary bs=1 skip=4194643 count=21869 of=theimage.png
$ gimp theimage.png
$ pngcrush myimage.png myimage.crush.png
# make sure myimage.crush.png is smaller than the original
$ dd if=myimage.crush.png of=thebinary bs=1 seek=4194643 conv=notrunc
Run Code Online (Sandbox Code Playgroud)
有时我也希望替换二进制文件中的字符串(例如路径或变量名)。虽然这也可以使用 完成dd,但使用sed. 您只需要确保您替换的字符串与原始字符串的长度相同,这样您就不会最终更改偏移量。
sed -e s@/the/old/save/path@/the/new/save/path@ -i thebinary
Run Code Online (Sandbox Code Playgroud)
或者拿起@MichaelHomer 的例子,其中添加了一个 0 字节:
sed -e 's@/usr/tmp@/tmp\x00tmp@' -i test
Run Code Online (Sandbox Code Playgroud)
当然,您必须在之后验证它是否确实有效。