什么时候可以在可执行二进制文件中编辑字符串?


11

我有一个可执行的二进制文件;让我们称之为a.out。我可以看到二进制文件包含字符串

$ strings a.out
...
/usr/share/foo
....

我需要将字符串更改/usr/share/foo/usr/share/bar。我可以将字符串替换为sed吗?

sed -i 's@/usr/share/foo@/usr/share/bar@' a.out

这看起来很安全。当字符串长度不同时,这也可以工作吗?

Answers:


17

我不知道您的版本sed是否为二进制清除,或者是否会阻塞输入中认为很长的行,但是除非存在这些问题,否则就地编辑字符串应该行得通。要查看是否可以,请将旧版本和新版本与进行比较cmp -l。它应该告诉您两个文件之间仅有的三个差异是否就是这三个字节。

如果字符串的长度相同,则确实可以在已编译的可执行文件中编辑字符串,但是由于字符串在C中的工作方式,因此如果缩短字符串,几乎也可以使用。在C字符串中,NUL终止符之后的所有内容不算在内,因此,如果您NUL在旧的位置之前写一个新的终止符,则可以有效地缩短字符串。

通常,没有办法使用此技巧来延长字符串。


用类似的东西缩短字符串sed -i 's@longstring@foo@' a.out呢?这将使整个二进制文件减小7个字节,这不会破坏二进制文件吗?
Martin Vegter 2015年

是的,它将破坏二进制文件。这就是为什么您必须将字符串转换为完全相同的长度之一,但是NUL按照我的解释将终止符设置在更早的位置(尽管可能太简短了)。问题是您NUL在命令行上没有字节,因此必须将sed程序放入文件中并使用进行引用-f。另一方面,更安全的做法是使用设计用于二进制数据的工具,而不是sed设计用于文本数据的工具。
Celada 2015年

2
好答案。sed可以做很多事情,但是总的来说,这就是二进制编辑器的发明目的。在大型二进制文件中导航时,使用它们可能会遇到挑战,但是它们会让您逐字节更改内容。我hexedit必须检查或更改二进制文件时使用。您可以strings -t x file | less在跳转到编辑器之前,找到要更改的(可打印)字符串的偏移量。

假设我的C程序中有一个字符串:“我的名字叫Robot先生”,我想用“ is”替换“ was”,则\0必须仔细进行填充,因为如果替换是这样的话:“我的名字is \ 0 Mr Robot”,然后在执行字符串操作时,“ \ 0”字符会产生问题,因为其长度会意外减小。
Nehal J Wani

@NehalJWani不,在这种情况下,您必须将整个字符串的剩余部分向前移动一个字节,以便新的,额外的终止符NUL在末尾并与现有相邻NUL
Celada
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.