大概一两年前在《漏洞战争:软件漏洞分析精要》听到bindiff(和补丁比较法),但一直都没去使用。前两天再回头看书感受须要使用一翻,整个过程下来仍是遇到了一些问题,值得记录一番。html
bindiff是一款java程序,所以须要安装jdk,我装的是jdk1.8其余版本兼容性不太清楚。java
jdk下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.htmllinux
bindiff须要借助ida pro进行分析,因此须要安装ida pro。官方说明须要6.8及以上版本,但7.x版本也尚不支持。数据库
ida pro安装可参考:http://www.javashuo.com/article/p-sxcciaru-hn.htmlwindows
下载地址:https://www.zynamics.com/software.htmloracle
bindiff同时支持windows、linux、mac;bindiff5只能装在win8和win10上;下载连接不明显可是是有连接的,直接中键点击文件名处便可下载。函数
双击运行安装程序优化
接受协议url
选择安装组件和路径spa
指出本身ida pro安装的目录
确认安装
安装完成
我这里使用cfree建立两个控制台项目bindiff1和bindiff2,分另写入如下两分代码并各自编译。代码的区别就只是把if语句的大于号改成小于号。
bindff1代码:
# include <stdio.h> int main(){ int a = 1; if (a > 1){ printf("if brance\n"); } else{ printf("else brance\n"); } getchar(); }
bindff2代码:
# include <stdio.h> int main(){ int a = 1; if (a < 1){ printf("if brance\n"); } else{ printf("else brance\n"); } getchar(); }
bindiff不能直接分析exe程序,而只能先使用ida pro的.i64数据库基础上进行分析。
所以须要先用ida pro分别打开bindiff1.exe和bindiff2.exe再关闭,以建立.i64数据库。
到安装目录bin文件夹下双击bindiff.jar便可启动bindiff,界面以下:
主菜单----Diffs----New Diff
前后载入bindffi1.i64和bindiff2.i64,点击Diff进行比较
32位操做系统应该成功载入,64位操做系统可能会报错:“Can't find Diff engine at '...\differ64.exe'”
看意思是differ64.exe找不到,打开bindiff安装目录的bin文件夹,将bindiff.exe复制一份命名为bindiff64.exe,此时再从新载入比较便可。
Call Graph----两个文件的函数调用图
Matched Functions----两个文件的函数匹配度
Primary Unmatched Functions----
Secondary Unmatched Functions----
bindiff的主要简单使用是双击打开"Matched Functions"项,按类似度(Similarity)从低到高排序,类似度不为1的函数即为两个文件被改动的位置。
由上图能够看到,bindiff1.exe和bindiff2.exe只有_main类似度不为1,双击_main打开, 两个函数不一样的位置会被以有底色形式标出
以下图能够看到只有一条指令不一样:bindiff1.exe是"jle 0x401335"(小于等于则进入else)而bindiff2是“jg 0x401335”(大于则进入else)
由此咱们能够推断出bindiff2.exe相对于bindiff1.exe作的改动是:bindiff1.exe是"if > else"而bindiff2.exe是"if < else"。与咱们的改动彻底一致。
在上边的操做中咱们须要先用ida打开文件建立数据库,再使用bindiff打开比较,这是比较麻烦的。bindiff容许直接以ida插件的形式使用。(在安装bindiff时已同步安装为插件因此不须要另行安装)
先使用ida打开bindiff1.exe,而后使用“Ctrl+6”打开窗口,以下图所示
点击“Diff Database...”载入bindiff2.i64。以下图,还是相似单独使用时的那几个窗口。固然这只是简单查看比较最后仍是要打开bindiff。
第一点,相同的高级语言代码使用不一样编译器编译出来的内容是有区别的。好比我这里使用cfree编译,假若一样的代码你用VC++去编译那函数数量可能会多很多。但固然识别出的改动位置仍是一个意思的。
第二点,相同的高级语言代码使用相同编译器不一样的编译模式编译出来的内容是有区别的。好比VC++优化模式和普通模式编译出的汇编代码是有区别的。
第三点,bindiff只能识别出汇编指令的区别不能识别出汇编指令操做数的区别。即如上边“jle 0x401335”和“jg 0x401335”会被不一样底色标出,但若是是“jle 0x401335”和“jle 0x401336”那将不会被标出。
参考: