當前位置:
首頁 > 新聞 > 動態二進位插樁的原理和基本實現過程(一)

動態二進位插樁的原理和基本實現過程(一)

前言

動態二進位插樁(dynamic binary instrumentation ,DBI)技術是一種通過注入插樁代碼,來分析二進位應用程序在運行時的行為的方法。

動態二進位插樁技術,可以在不影響程序動態執行結果的前提下,按照用戶的分析需求,在程序執行過程中插入特定分析代碼,實現對程序動態執行過程的監控與分析。目前,應用廣泛的動態二進位分析平台有Pin,DynamoRIO和Frida等。

最常用動態二進位插樁框架的平台

這篇文章的目的是對動態二進位插樁的原理和基本實現過程進行全面的介紹,其中,我會選擇一些最知名和最常用的動態二進位插樁框架進行具體說明,其中包括Pin,DynamoRIO和Frida。而這三個裡面,我會主要關注Intel公司的Pin平台,該平台提供了豐富的編程介面,開發者可以通過調用編程介面方便的獲取程序動態執行期間的指令、內存和寄存器等信息,實現細粒度的動態監控,因此本文選取Pin平台進行動態分析。

Pin提供了指令、基本塊和系統調用等多個層次插樁分析,其中,RTN是函數級的插樁機制,能夠自動識別API函數;Trace是軌跡層次的插樁機制,能夠自動識別單一入口、多出口的指令軌跡塊。

不過使用動態二進位插樁框架的可不止Pin,DynamoRIO和Frida,還有比如Valgrind,Triton(使用Pin),Q動態二進位插樁,BAP,Dyninst以及許多其他框架。其中有些更成熟,有些則不太成熟。有些功能更多,有些功能更少。儘管Valgrind是最廣為人知且較為成熟的動態二進位插樁框架之一,但它僅適用於Linux。所以,我根本不會用它作為分析對象。

在我插樁發現漏洞的過程中,我一直比較專註Windows上的漏洞。不過,我在本文提供的有關Windows平台的代碼,你一樣可以在Linux上構建,應該非常簡單。而反過來則不可以,原因是在Windows上構建Pin或DynamoRIO時會失敗。請注意,我寫本文的目的是讓你學會編寫references。

為什麼我只選擇動態二進位插樁進行分析

根據維基百科的介紹,插樁指的是監控或測量產品性能水平、診斷錯誤和編寫跟蹤信息的能力。程序員以代碼指令的形式實現插樁,監控系統中的特定組……當應用程序包含插樁代碼時,可以使用管理工具對其進行管理。必須使用插樁來檢查應用程序的性能,插樁方法可以有兩種類型:源插樁(Source instrumentation)和二進位插樁。

顧名思義,源插樁會要求你掌握軟體應用程序的源代碼,否則無法進行插樁。而二進位插樁,可以與任何軟體應用程序一起使用。事實證明,你在Windows操作系統上運行的大多數程序源代碼都是封閉的。這意味著,在這篇文章中,我將只談論二進位插樁。二進位插樁通常又被稱為動態二進位插樁或動態二進位修改(Dynamic Binary Modification)。

在單行語句中,動態二進位插樁是一種將插樁代碼注入正在運行的進程中的技術,這意味著插樁代碼對注入的應用程序來說是完全透明的。

使用動態二進位插樁框架,我們可以一步一步地對目標二進位執行過程進行拆解。但請注意,分析僅適用於已執行的代碼。

為何我只選擇動態程序分析

目前總共有兩種類型的程序分析:靜態程序分析和動態程序分析。在不運行程序的情況下進行的分析就是靜態分析,當我們運行程序時所進行的分析就是動態分析。

根據維基百科的介紹,動態程序分析是通過在真實或虛擬處理器上執行程序,來達到分析目的。而要使動態程序分析有效,必須讓測試程序進行多次且多樣的行為運行,以全方位分析。這時,你可以使用諸如代碼覆蓋之類的軟體測試辦法,以確保觀察到程序的所有行為。

如前面提到的框架那樣,動態二進位修改工具會在正在運行的程序和底層操作系統之間重新引入了一個層,該層會提供一些在程序執行時檢查和修改用戶級程序指令的機會。

不管是多麼複雜的內部系統,只要通過API讓其簡單實用化,允許任何用戶快速構建大量工具來輔助軟體分析,而這正是我將在這篇文章中嘗試展示的內容。

我們經常會出於各種原因來觀察和修改程序的運行行為,這其中就包括軟體或硬體開發人員、系統工程師、漏洞捕獲者、惡意軟體分析師、終端用戶等。動態二進位插樁框架可以提供對每個執行的用戶級指令的訪問,除了可能發生的少量運行時刻和內存開銷之外,該程序將與本機執行相同地運行。

靜態分析的主要優點是它可以確保100%的代碼覆蓋率,通過動態分析,為了確保代碼覆蓋率更高,我需要多次運行程序,並使用不同的輸入,以便分析採用不同的代碼路徑。但是,在某些情況下,由於軟體應用程序太大,執行靜態分析的成本太高。

正如我之前提到的,動態二進位插樁框架會直接在二進位文件或可執行文件中運行,這樣我們就不需要程序的源代碼,也不需要重新編譯或重新鏈接程序,這個優勢就允許我們分析許多軟體。

動態二進位系統不但會和「guest」 執行的程序同時運行,還會在運行中執行所有請求或所需的修改。這種動態方法還可以處理動態生成代碼的程序(其分析的工作量相當大),即自修改代碼(self-modifying code)。如果你上網搜一下,就會發現很多情況下,動態二進位插樁框架被用於分析具有自修改代碼的惡意軟體。例如,請查看Blackhat Europe 2017的一篇演示文稿,或者,關於如何用Pin解壓Skype的帖子。

動態二進位插樁框架被用於解決計算機體系結構問題,大量用於軟體工程、程序分析和計算機安全。比如,軟體工程師希望用它來深入了解他們開發的軟體,系統的分析其性能和運行行為。動態二進位插樁框架的一個常見用途是模擬新的CPU指令。由於動態二進位系統在執行之前可以訪問每條指令,因此硬體工程師實際上可以使用這些系統來測試當前不受硬體支持的新指令。他們可以模擬新的指令行為,而不是執行特定的指令。同樣,他們也可以使用相同的方法來替換錯誤指令,並正確模擬所需行為。無論如何,從計算機安全的角度來看,動態二進位插樁系統可用於流程分析、污點分析、模糊測試、代碼覆蓋、生成測試歷程、逆向工程、調試、漏洞插樁,甚至是修補漏洞以及自動利用。

使用動態二進位系統的兩種主要方式和三種執行模式

使用動態二進位系統有兩種主要方式,其中第一個方式是最常見的,至少在計算機安全中,是在動態二進位系統的控制下從頭到尾執行程序。當我們想要實現完整的系統模擬或模擬時,我由於需要完全控制並進行代碼覆蓋,就要在動態二進位系統的控制下從頭到尾執行程序。第二個方式就是動態二進位系統可以被附加到一個已經運行的程序中,且以完全相同的方式被調試器從正在運行的程序中附加或分離。如果我們想知道某個程序在特定時刻正在做什麼,那麼第二個方式就會非常有用。

此外,大多數動態二進位插樁框架都有三種執行模式:解釋模式( Interpretation mode)、探測模式(probe mode)和JIT模式(just-in-time mode)。JIT模式是最常見的實現方式,也是最常用的模式,即使動態二進位插樁系統支持多種執行模式。在JIT模式下,原始二進位文件或可執行文件實際上從未被修改或執行過。因為,此時二進位文件被視為數據,修改後的二進位文件副本將在新的內存區域中生成(但只針對二進位文件的執行部分,而不是整個二進位文件),此時執行的就是這個修改後的文件副本。而在解釋模式中,二進位文件也被視為數據,每條指令都被用作具有相應功能的替代指令的查找表(由用戶實現) 。在探測模式中,二進位文件實際上是通過使用新指令來覆蓋舊的指令,來達到修改目的的,不過這會導致運行開銷增大,但在某些體系結構(如x86)中,該方式卻很好用。

無論採用哪種執行模式,一旦我們通過動態二進位插樁框架控制了程序的執行,就能夠將插樁添加到執行程序中。我們可以在代碼塊之前和之後插入想要的代碼,甚至也可以完全替換它們。

你可以在下圖中看到執行過程:

其中還包含不同程度的運行許可權級別:

1.指令級(Instruction level);

2.基本塊級(Basic block level);

3.函數級(Function level);

可以看出,運行許可權級別的選擇將決定你對程序執行所控制的程度。顯然,這會對性能的分析產生直接影響。另外,請注意,在大多數情況下,對整個程序進行插樁是不切實際的。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 嘶吼RoarTalk 的精彩文章:

針對沙特人權活動家和研究人員的NSO間諜軟體
如何使用cycript繞過應用程序的PIN保護

TAG:嘶吼RoarTalk |