#1 楼
通常,在撰写本文时(4.x),BinDiff的当前版本通过在功能级别上匹配属性来工作。基本上,匹配分为两个阶段:首先生成初始匹配,然后在向下钻取阶段进行细化。
初始匹配
首先BinDiff将基于以下属性的签名与每个函数相关联:
基本块数
这些块之间的边数
子函数的调用数
此步骤为每个二进制文件提供了一组签名,这些签名又用于生成初始匹配集。遵循一对一关系,BinDiff根据上述特征选择这些初始匹配项。
下一步尝试在每个二进制的调用图上找到匹配项:对于经过验证的匹配项,该集合为了找到事件更多的匹配项,将检查匹配函数中被调用函数的集合。只要找到新的匹配项,便会重复此过程。
深入查询
实际上,并非所有功能都将由该功能引起的一对一关系进行匹配。初始匹配策略,因此在确定了初始匹配之后,我们仍然会列出不匹配的功能。
向下钻取阶段的想法是应用多个不同的功能匹配策略,直到找到匹配项为止。应用这些策略的顺序很重要:BinDiff首先尝试假定其具有最高置信度的那些策略。仅当找不到匹配项时,才继续执行下一个策略。重复此操作,直到BinDiff用尽策略或匹配所有功能为止。示例包括MD索引,基于函数名称(即导入)的匹配,调用图边缘MD索引等。
MD-Index纸
基于图的可执行对象比较
可执行对象的结构比较
(免责声明:使用@团队zynamics / google,希望我没有弄乱任何东西,否则soeren会让我难过;-))
评论
所以你还在努力吗?还是仅仅是每个星期五的项目?
– wishi
13年4月2日在21:17
我没有在做它,也从未做过,但是BinDiff并没有被取消,如果那是您的意思!
– newgre
13年4月2日在22:11
Zinamics,BinDiff背后的公司,被Google收购。您可以向一些坐在逆向工程reddit上的员工发送消息。
– sw
13年4月6日在18:20
#2 楼
我只能说几句话关于控制流图的构建,尽管我的回答肯定不是完整的。BinDiff使用静态类型来检测执行流,我想因为执行代码不是。 •总是可能的(例如,对于ring 0驱动程序)或合理的(恶意软件)。实际上,给定的文件将被反汇编,然后应将其拆分为基本块(这些代码具有直接的执行方式,尽管在这种情况下这种定义是正确的)。很明显(例如,考虑到x86架构),诸如
jxx
之类的指令会更改程序的控制流。因此,基本块通常由它们终止。将代码拆分为块的过程并不是一个复杂的任务,更具挑战性的部分是确定跳转目标。例如,这样的内容:...
jz eax
因此我们无法(轻松)理解指向此调用的自动静态分析。琐碎的情况可以被“模仿”,但总的来说,工作非常艰巨而令人沮丧。另一种选择是跟踪程序以查找代码执行的路径(可以手动执行)。
找到这些块后,剩下的唯一一件事就是建立人类可读的图形。
不管怎样,执行流可以改变一堆(异常,另一个线程的热补丁,与系统有关的事件等)。
评论
关于图同态算法的原始文章是一个好的开始。最近,有人提出了一些工具(请参见本文和海报)。但是,此Reddit线程表明对BinDiff进行了一些改进。
–恐怖
13年4月2日在11:31
评论
@Nirlzr:我看不到将标签'bindiff'更改为'tool-bindiff'的效果如何。但是,我可能心有灵犀,所以请告诉我更多......也许您应该在meta.reverseengineering.stackexchange.com/questions/322/…中发声……
@kennytm:啊,我错过了这个。。。很好,谢谢。