比较两个二进制文件

5

如何比较两个二进制文件的差异?

我有程序的两个版本,版本1和版本2。在这两个版本之间,我只做了一些小的更改,但不幸的是,我没有定期备份,因此虽然我有版本2的源代码,但我只有版本1的二进制文件。我需要找出两个版本之间确切的更改内容。我尝试创建两个版本的objdump,然后使用diff查找更改,但这并不起作用,因为偏移量不同,因此diff认为几乎每行都发生了更改。

例如,在版本1中,一行可能是bgez v0,4074d0<daemonize+0xd4>,而在版本2中则是bgez v0,4073d4<daemonize+0xd4>。这些直接从转储文件中复制 - 您可以看到这两行执行相同的操作,但diff无法区分它们。文件太大,我不能手动检查每一行;如何检测功能更改,同时忽略偏移量的差异?


这听起来像是一个现实世界中的NP完全问题。;-) - Al Kepp
不是NP完全问题,因为它可以通过确定有限状态自动机来解决。 - Benubird
NP 和 DFA 是什么意思? - E_Blue
5个回答

4

我最终通过移除原始指令和偏移标记,只保留汇编代码,并使用sed来去除每个数字,然后使用diff过滤掉只有一行变化的更改来解决了这个问题。我有点惊讶它起作用了,但确实有效。


4
这是可能的。我目前正在开发一个项目,它可以从新的/修改后的二进制文件中搜索函数和内存指针地址。它支持x86和x86_64上的Windows PE和ELF二进制文件。还有一篇论文描述了这种方法。对于我的逆向工程项目来说,它非常有用,因为在二进制文件更新时,我必须经常更新所有挂钩和内存地址。但也有其他用途。你可以在这里查看
诀窍是它不依赖于弱文本比较,而是通过使用代码度量标准测量它们之间的几何距离来反汇编二进制文件并比较所有函数。

1
有没有可能将asmDIFF以独立形式发布?据我所见,asm_hint_C和asm_search_C与mmBBQ和lua紧密耦合...这并不一定是件坏事,但使它难以独立使用。 - Sebastian Graf

1
短答案:你不能。
长答案:编写自己的 diff 工具,如果操作码的一个或两个操作数是数字立即值,则可以忽略它们中的一个或另一个。

0
你可以使用sed或awk(或perl等)编写一个过滤器,使所有偏移量在运行diff之前都相同。编写这样的过滤器留给读者作为练习。:-P

你回答了“我该怎么做”的问题,但只是说“可以做到”。虽然从技术上来说是正确的,但这完全没有任何用处。-1 - Benubird

0

类似bsdiff这样的工具可以胜任这项工作吗?


我正在尝试找出这两个程序之间的差异 - 我可能使用不当,但是bsdiff似乎并不是很有用。你会怎么做? - Benubird
@Benubird:bsdiff 在代码级别上生成二进制差异,而不是字节级别。Chrome Courgette 更进一步地添加(或者说删除)了可重定位跳转/偏移量,从差异中留下了真正发生变化的代码部分,而不仅仅是移动了位置。可以将其视为在汇编级别上进行 diff 和 patch,而不是文本级别。 - Necrolis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接