大概一兩年前在《漏洞戰爭:軟件漏洞分析精要》聽到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」那將不會被標出。
參考: