我想知道 BinDiff軟件的基本原理(也許還有一些關於優化和啟發式的東西)。有人對它有很好的教學方法嗎?
我想知道 BinDiff軟件的基本原理(也許還有一些關於優化和啟發式的東西)。有人對它有很好的教學方法嗎?
通常,在撰寫本文時(4.x),BinDiff的當前版本通過匹配功能級別的屬性來工作。基本上,匹配分為兩個階段:首先生成初始匹配,然後在向下鑽取階段中對其進行完善。
首先,BinDiff將基於每個函數的以下屬性:
此步驟為每個二進製文件提供了一組簽名,這些簽名又用於生成初始匹配集。遵循一對一的關係,BinDiff根據上述特徵選擇這些初始匹配項。
下一步嘗試在每個二進制的調用圖上找到匹配項:對於經過驗證的匹配項,一組為了找到事件更多匹配項,將檢查匹配函數中被調用的函數。只要找到新的匹配項,就會重複此過程。
在實踐中,並非所有功能都將由初始匹配引起的一對一關係進行匹配策略,因此在確定了初始匹配之後,我們仍然有一系列不匹配的功能。向下鑽取階段的想法是應用多個不同的功能匹配策略,直到找到匹配項為止。應用這些策略的順序很重要:BinDiff首先嘗試假定其具有最高置信度的那些策略。只有找不到匹配項時,才繼續執行下一個策略。重複此操作,直到BinDiff用盡策略或匹配所有功能為止。示例包括MD索引,基於函數名稱(即導入)的匹配,調用圖邊緣MD索引等。
(免責聲明:正在@團隊zynamics / google上工作,希望我沒有弄亂任何東西,否則soeren會把我烤死;-))
我只能說幾句關於控制流圖的構建,儘管我的回答絕對不是完整的。
BinDiff使用靜態類型的檢測執行流,我想是因為執行代碼並非總是可能的(例如,對於ring 0驅動程序)或合理的(惡意軟件)。實際上,給定的文件將被反彙編,然後應將其拆分為基本塊(這些代碼具有直接的執行方式,儘管在這種情況下這種定義是正確的)。很明顯(例如考慮x86架構),諸如 jxx
之類的指令會更改程序的控制流。因此,基本塊通常由它們終止。將代碼拆分為塊的過程並不是一項複雜的任務,更具挑戰性的部分是確定跳轉目標。
例如:
... jz eax
因此,我們無法(輕鬆)理解指向此調用的自動靜態分析。瑣碎的情況可以被“模仿”,但總的來說,工作非常艱鉅而令人沮喪。另一種選擇是跟踪程序以查找代碼執行的路徑(可以手動執行)。找到這些塊後,剩下的唯一一件事就是建立人類可讀的圖形。
可以改變執行流程的方式(異常,其他線程的熱補丁,與系統有關的事件等)。