一、說明
大概一兩年前在《漏洞戰爭:軟件漏洞分析精要》聽到bindiff(和補丁比較法),但一直都沒去使用。前兩天再回頭看書感覺需要使用一翻,整個過程下來還是遇到了一些問題,值得記錄一番。
二、安裝
2.1 jdk安裝
bindiff是一款java程序,因此需要安裝jdk,我裝的是jdk1.8其他版本兼容性不太清楚。
jdk下載地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html
2.2 ida安裝
bindiff需要借助ida pro進行分析,所以需要安裝ida pro。官方說明需要6.8及以上版本,但7.x版本也尚不支持。
ida pro安裝可參考:https://www.cnblogs.com/lsdb/p/7500981.html
2.3 bindiff安裝
下載地址:https://www.zynamics.com/software.html
bindiff同時支持windows、linux、mac;bindiff5只能裝在win8和win10上;下載鏈接不明顯但是是有鏈接的,直接中鍵點擊文件名處即可下載。
雙擊運行安裝程序
接受協議
選擇安裝組件和路徑
指出自己ida pro安裝的目錄
確認安裝
安裝完成
三、bindiff使用
3.1 編寫比較程序
我這里使用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(); }
3.2 使用ida創建數據庫
bindiff不能直接分析exe程序,而只能先使用ida pro的.i64數據庫基礎上進行分析。
因此需要先用ida pro分別打開bindiff1.exe和bindiff2.exe再關閉,以創建.i64數據庫。
3.3 bindiff載入文件並比較
到安裝目錄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"。與我們的改動完全一致。
3.4 將bindiff以ida插件形式使用
在上邊的操作中我們需要先用ida打開文件創建數據庫,再使用bindiff打開比較,這是比較麻煩的。bindiff允許直接以ida插件的形式使用。(在安裝bindiff時已同步安裝為插件所以不需要另行安裝)
先使用ida打開bindiff1.exe,然后使用“Ctrl+6”打開窗口,如下圖所示
點擊“Diff Database...”載入bindiff2.i64。如下圖,仍是類似單獨使用時的那幾個窗口。當然這只是簡單查看比較最后還是要打開bindiff。
3.5 bindiff使用注意點
第一點,相同的高級語言代碼使用不同編譯器編譯出來的內容是有區別的。比如我這里使用cfree編譯,倘若同樣的代碼你用VC++去編譯那函數數量可能會多不少。但當然識別出的改動位置還是一個意思的。
第二點,相同的高級語言代碼使用相同編譯器不同的編譯模式編譯出來的內容是有區別的。比如VC++優化模式和普通模式編譯出的匯編代碼是有區別的。
第三點,bindiff只能識別出匯編指令的區別不能識別出匯編指令操作數的區別。即如上邊“jle 0x401335”和“jg 0x401335”會被不同底色標出,但如果是“jle 0x401335”和“jle 0x401336”那將不會被標出。
參考: