无需源码重编译,如何替换二进制可执行文件中的指定字符串?
二进制可执行文件字符串替换方案
问题背景
我有一个编译完成的可执行二进制文件mybin,通过grep检测到其中包含字符串Cats:
grep "Cats" mybin Binary file mybin matches
使用grep -a参数可查看具体匹配内容:
grep -a "Cats" mybin <lots of text> (QString)Cats <lots of text>
注:该字符串并非二进制文件中的明文纯文本,无法通过普通文本编辑器直接查看。
我希望将文件中的Cats替换为Bear,同时保证可执行文件仍能正常运行。请问无需修改源码重新编译的情况下,该操作是否可行?若可行:
- 具体操作步骤是什么?
- 有哪些需要注意的陷阱?例如替换字符串是否必须与原字符串长度一致(如
Cats→Bear可行,Cats→Dragons不可行)。
可行性结论
这种操作完全可行,但必须严格遵循二进制文件的操作规则,才能确保程序正常运行。
1. 具体操作步骤
- 先备份原文件,防止操作失误导致文件损坏:
cp mybin mybin.bak - 使用
xxd+sed的组合进行二进制替换(这是最安全且易操作的方式):- 将二进制文件转换为十六进制文本格式:
xxd mybin > mybin.hex - 替换目标字符串对应的十六进制值:
Cats的ASCII十六进制是43617473,Bear的ASCII十六进制是42656172,执行替换:sed -i 's/43617473/42656172/g' mybin.hex - 将修改后的十六进制文本转回二进制文件:
xxd -r mybin.hex mybin.modified
- 将二进制文件转换为十六进制文本格式:
- 验证修改结果:
用grep确认替换成功:
运行grep -a "Bear" mybin.modifiedmybin.modified检查程序是否能正常执行。
2. 关键陷阱与注意事项
- 替换前后字符串长度必须完全一致:二进制文件的所有数据都依赖固定的内存偏移量,字符串长度变化会直接打乱后续指令、数据指针的寻址,几乎必然导致程序崩溃。比如
Cats(4字符)换Dragons(7字符)绝对不可行,同长度替换是安全的基础前提。 - 确认目标字符串仅作为目标文本存在:如果
Cats的十六进制序列恰好出现在机器指令、其他数据结构中,盲目替换会破坏这些关键内容。比如某条指令的字节刚好是43617473,替换后指令失效,程序会直接崩溃。 - 注意字符串的编码类型:如果原字符串是宽字符(如UTF-16),每个字符占2字节,替换时要匹配宽字符的十六进制序列,且保证长度一致。例如
Cats作为UTF-16的十六进制是0043006100740073,替换的Bear需对应0042006500610072。 - 禁止使用普通文本编辑器修改:普通文本编辑器会自动处理换行符、添加隐藏字符或损坏二进制结构,必须使用专门的二进制编辑工具或上述
xxd+sed的方法。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

