A Survey of Symbolic Execution Techniques 符號執行綜述

原文 A Survey of Symbolic Execution Techniques

目錄

 

1. 介紹

1.1 例子

1.2 挑戰

1.3 相關工作

1.4 文章的組織

2. 符號執行引擎

2.1 混合符號和具體執行

2.2 符號執行的設計原則

2.3 路徑選擇

2.4 回溯符號執行 Symbolic Backward Execution

3. 內存模型

3.1 完全符號化內存

3.2 地址具體化

3.3 部分內存建模

3.4 延遲初始化

4. 與環境和第三方組件的交互

5. 路徑爆炸

5.1 裁剪不可達路徑

5.2 函數和循環摘要

5.3 路徑歸併與等價

5.4 約束下的符號執行

5.5 利用預置條件和輸入特性

5.6 狀態合併

5.7 利用程序分析和優化技術

6. 約束求解

限制約束。Constraint Reduction.

重用約束的解。Reuse of Constraint Solutions.

懶惰約束。Lazy Constraints.

具體化。Concretization.

處理不確定的約束。Handling Problematic Constraints.

7. 更多的研究方向

7.1 分割邏輯 separation logic (SL)

7.2 不變量

7.3 函數摘要Function Summaries

7.4 程序分析和優化

7.5 符號計算

8. 總結

附錄


1. 介紹

1.1 例子

一個狀態表示 state (stmt, σ, π)

stmt   語句

σ     符號表達式:存儲變量的表達式,具體的和符號化的都有

π     約束關係:執行到該語句需要滿足的條件

 

void foobar(int a, int b) {

    int x = 1, y = 0;

    if (a != 0) {

       y = 3+x;

       if (b == 0)

           x = 2*(a+b);

    }

    assert(x-y != 0);

}

 

                                                                       符號執行樹

1.2 挑戰

內存:符號執行引擎怎樣處理複雜的結構?可能對符號存儲數據和符號表達式描述的地址造成風險

環境和第三方組件:調用庫函數…

狀態空間爆炸:比如循環…

約束求解:SMT(satisfiability modulo theories)求解器可以擴展到數百個變量的複雜約束組合。 然而,諸如非線性算術(比如乘法)之類的構造成爲效率的主要障礙。

對二進制代碼的分析:

1.3 相關工作

符號執行一直是學術界關注的焦點。截至2017年8月,谷歌學術中找到標題包括“符號執行”一詞的有742篇文章。

其他技術綜述:自動測試用例生成

1.4 文章的組織

 

2. 符號執行引擎

在這一節中我們介紹了符號執行的一些重要的設計原則,和執行過程中的關鍵折衷。從具體化和符號化的概念出發,介紹了混合執行的思想。

2.1 混合符號和具體執行

                                                                                         混合符號執行

符號執行理論上可以產生所有可能的控制流路徑,實際上這通常是不可能的,特別是在真實的軟件環境中。複雜的應用程序通常建立在非常複雜的軟件棧之上。一個符號執行引擎靜態地分析整個堆棧,在執行過程中準確評估任何可能的副作用是相當具有挑戰性的。在這種情況下出現的一些問題,用第1.1節純粹符號化的方法很難做到這幾點:

1. 對外部庫調用的徹底探索可能導致狀態的指數爆炸,從而妨礙分析到達感興趣的代碼部分。

2. 對外部第三方組件的調用可能無法由執行器跟蹤。

3. 符號引擎在分析過程中不斷調用SMT求解器。在約束求解中花費的時間是引擎的主要性能障礙之一,程序可能會產生約束,即使是強大的求解器也不能很好地處理。

解決上述問題並使符號執行在實踐中可行的一個基本思想是將具體和象徵性的執行混合起來。

動態符號執行。。。。。。。。。。。。。。。。。。。。。。。。

有選擇的符號執行。。。。。。。。。。。。。。。。。。。。。。

 

搜索策略:深度優先 generational search

  假陰性(即,錯過的路徑)和路徑偏差是動態符號執行的顯着缺點。

 在concolic執行過程中,外部調用,異常,類型轉換和符號指針是關鍵方面,必須由引擎仔細處理以減少路徑偏差的數量。

2.2 符號執行的設計原則

1. 處理:程序應能在不超過給定資源的情況下進行任意長時間的工作。由於龐大數量的控制流路徑,內存消耗是特別關鍵的問題。

2. 避免重複工作:不應該重複執行工作,避免爲分析可能有共同前置的不同路徑,從一開始就多次重啓一個程序。

3. 分析結果重用:以前運行的分析結果應該儘可能地重複使用。特別是,應避免調用昂貴的SMT求解器來求解之前解決過的路徑約束。

2.3 路徑選擇

DFS:佔用內存更小,受到包含循環和遞歸調用的路徑的阻礙

BFS:佔用內存更大,能快速的遍歷早期行爲,需要更長時間完成特定路徑的探索

下面是幾個啓發式搜索:

最大覆蓋率:

最短距離:與程序中特定點的距離

buggy-path優先策略:

loop exhaustion策略:探索訪問循環的路徑,很多溢出和內存錯誤由循環引起

利用FSM(Finite State Machine, 有限狀態機): [Zhang et al., 2015]提出了一種動態符號執行的新方法,以自動找到一個滿足規則屬性的程序路徑,即一個可以由FSM表示的屬性(例如文件使用或內存安全性)。動態符號執行由FSM引導,以便首先探索最有可能滿足屬性的執行路徑的分支。該方法利用靜態和動態分析來計算將被選擇用於探索的路徑的優先級:在符號執行期間動態地計算當前執行路徑已經到達的FSM的狀態,並靜態分析向後的數據流被用於計算未來狀態。如果這兩個集合的交集非空,則可能有滿足該屬性的路徑。

Fitness function:衡量探索路徑到達目標測試覆蓋的距離,優先考慮可能更接近特定分支的路徑。例如目標分支|a-c|==0,路徑的接近度被定義爲|a-c|,越小越接近。

2.4 回溯符號執行 Symbolic Backward Execution

從目標點回溯到程序的入口點。

SBE和CCBSE中逆向探索的一個關鍵要求是程序間控制流程圖的可用性,需要提供了一個完整的程序控制流程。比如C++中的成員函數的被調用關係,怎麼回溯?

反向收集約束時,可能會出現一些實際的優點(第6章)。

3. 內存模型

3.1 完全符號化內存

3.2 地址具體化

       分析的複雜性爆炸時,很難把指針變量限制到足夠小的範圍內。給指針變量一個具體的值,是流行的方案。但是會造成分析引擎錯過一些路徑。

3.3 部分內存建模

       爲了緩解完全符號化的可測性問題(3.1)和具體化後完整性的丟失(3.2)。

       部分內存模型關鍵點:寫總是具體化 ; 讀時,如果假定的可能值的連續區間足夠小,讀就被符號化。

      

       Mayhem、Angr

3.4 延遲初始化

       針對面向對象的高級語言。變量被首次訪問時才初始化。

 

4. 與環境和第三方組件的交互

       文件系統,環境變量,網絡,第三方閉源組件和流行框架 ,符號執行必須考慮周圍的整個軟件堆棧,包括系統庫,內核和驅動程序。

 

5. 路徑爆炸

5.1 裁剪不可達路徑

5.2 函數和循環摘要

       早期只能通過循環來生成摘要,循環通過向迭代中添加一個固定數量來更新符號變量。而且,它們不能處理嵌套循環或多路徑循環,即在其體內具有分支的循環。 Proteus 是一個總結多路徑循環的總體框架。它根據路徑條件中值變化的模式(即是否更新了一個歸納變量)和循環內路徑的交錯(即是否有規律性)對循環進行分類。分類利用控制流圖的擴展形式,然後用於構建對交織進行建模的自動機。自動機以深度優先的方式遍歷,併爲其中所有可行的軌跡構建了分離的彙總,其中軌跡表示循環中的執行。分類確定是否可以精確地或近似地捕獲一個循環(這仍然是實際相關的)。對具有不規則模式或非歸納更新的多路徑循環進行精確的總結,更重要的是對嵌套循環的總結仍然是一個開放的研究問題。

       對控制流程圖中循環路徑的分析,產生模板,該模板將一部分代碼生成的程序狀態描述爲緊湊符號執行樹。 通過利用模板,符號執行引擎可以探索大量減少的程序狀態。 這種方法的缺點是可能會顯着增加約束求解器的負擔。

5.3 路徑歸併與等價

       探索相似性路徑,丟棄不能導致新發現的路徑,在有利的時候將差異抽象出來。

       插值

       無限循環的處理

       後置符號執行

       路徑分割 :有些路徑等價

5.4 約束下的符號執行

        受約束的變量與經典的完全約束的符號變量具有相同的語義,除非在可能產生錯誤的表達式中使用。

        雖然這種技術不夠完善,可能會錯過錯誤,但它仍然可以擴展到在更大的程序中找到bug。

5.5 利用預置條件和輸入特性

       預處理符號執行:在初始化時向π添加更多的約束。狀態空間變小了,但在每個分支的檢測增多了

       循環擴展符號執行[Saxena 2009]

5.6 狀態合併

       例子中利用ite表達式合併狀態

       是否需要合併?

       啓發式狀態合併、動態狀態合併

5.7 利用程序分析和優化技術

       程序分片:這種分析從程序行爲的一個子集開始,從程序中提取忠實地表示該行爲的最小指令序列

       污點分析

       Fuzzing:和符號執行相互結合

       分支預測:

       類型校驗:

       編譯器優化:符號執行幾個要素:程序優化、搜索啓發式、狀態合併、約束求解優化。

              編譯器優化對約束生成和路徑探索的影響,研究很少,是一個開放性的問題。

      

 

6. 約束求解

是否存在一組變量賦值,使問題爲可滿足。

確定是否有一個解,使符號化的公式爲真。

Although SAT is a well-known NP-complete problem, recent advances have moved the boundaries for what is intractable when it comes to practical applications.

雖然SAT(Boolean Satisfiability Problem)是一個著名的NP完全問題,但在實際應用中,最新進展已使難以解決的問題發生了變化。

觀察表明一些問題用更自然的語言來描述比具有邏輯連接詞的布爾公式更具表現力。 因此,SMT將SAT問題推廣到支持理論,以捕獲涉及例如線性算術和陣列上的運算的公式。 SMT求解器將SMT公式中的原子映射到新的布爾變量:SAT決策程序檢查重寫的公式的可滿足性,理論求解器檢查由SAT程序生成的模型。

SMT求解器有幾個獨特的優勢。它們的核心算法是通用的,可以處理許多單獨約束的複雜組合。當添加或刪除約束時,它們可以逐步工作和回溯,並提供對不一致性的解釋。可以以任意方式添加和組合理論,例如,對字符串數組進行推理。決策過程不需要單獨進行:通常,它們是結合在一起的,以減少在較重的任務中的時間開銷,例如,首先用非線性算術公式求解線性部分。不完整的程序也很有價值:只有在無法給出結論性答案的情況下,完整而昂貴的程序才能被調用。所有這些因素都允許SMT求解器解決沒有單個程序可以孤立解決的大問題。

在符號執行器中,約束求解在檢查路徑的可行性、生成符號變量的賦值以及驗證斷言方面起着關鍵的作用。多年來,符號執行器採用了不同的求解器,這取決於所支持的理論和當時的相對性能。

然而,儘管過去幾年取得了重大的進展 - 這也使符號執行成爲現實,但約束求解仍然是符號執行引擎可擴展性的主要障礙之一,也阻礙了在involve expensive theories(例如,非線性算術)或不透明的庫調用的約束下的可行性。

在本節的其餘部分中,我們將討論不同的技術來擴展符號處理所能處理的程序的範圍,並優化約束求解的性能。突出的方法包括:(i)降低約束的規模和複雜性,(ii)公開的一些方法,例如,使用約束求解緩存,延遲約束求解器的查詢,或具體化,(iii)增加符號執行處理約束問題的決策程序。

限制約束。Constraint Reduction.

A common optimization approach followed by both solvers and symbolic executors is to reduce constraints into simpler forms. For example, the expression rewriting optimization can apply classical techniques from optimizing compilers such as constant folding, strength reduction, and simplification of linear expressions.

求解器和符號執行器共同的優化方法是將約束簡化爲更簡單的形式。例如,表達式重寫優化可以應用編譯器優化中的經典技術,如常數摺疊,強度降低,線性表達式的簡化。

重用約束的解。Reuse of Constraint Solutions.

The idea of reusing previously computed results to speed up constraint solving can be particularly effective in the setting of a symbolic executor, especially when combined with other techniques such as constraint independence optimization. Most reuse approaches for constraint solving are currently based on semantic or syntactic equivalence of the constraints.

重用先前計算結果以加快約束求解的思想在符號執行器的設置中尤其有效,特別是在與約束獨立優化等技術相結合時。大多數用於約束求解的重用方法目前都是基於語義或語法等價的約束。

懶惰約束。Lazy Constraints.

[Ramos and Engler, 2015]採用約束求解查詢超時的方法。在他們最初的實驗中,作者將大多數超時追蹤到符號除法和餘數運算,最壞的情況發生在無符號餘數運算在分母中具有符號值的情況下。

因此,他們實現瞭如下解決方案:當執行器遇到一個涉及大開銷的符號操作的分支語句時,它將同時使用真和假分支,並將對開銷操作結果的延遲約束添加到路徑條件中。當探索到達滿足某個目標的狀態(例如發現一個錯誤)時,該算法將檢查路徑的可行性,並且如果在真實執行中被視爲不可達,則抑制該路徑。

具體化。Concretization.

A concolic executor generates some random input for the program and executes it both concretely and symbolically: a possible value from the concrete execution can be used for a symbolic operand involved in a formula that is inherently hard for the solver, albeit at the cost of possibly sacrificing soundness in the exploration.

concolic執行爲程序生成一些隨機的輸入,並以具體和象徵的方式執行它:當符號執行遇到一個對求解器來說很困難的公式時,具體執行中的一個可能值可以用於這個公式中涉及的一個符號操作數,儘管代價是有可能在探索中犧牲正確性。

  1. void test(int x, int y) {
  2.     if (non_linear(y) == x)
  3.         if (x > y + 10)
  4.             ERROR;
  5. }

 

  1. int non_linear(int v) {
  2.     return (v*v) % 50;
  3. }

由於存在v*v,不支持非線性的求解器無法計算。舉例:concolic執行隨機選擇出x=3,y=5作爲初始輸入,這個具體化執行不會進入第3行的語句。但引擎可以重新使用y的值, ay=5計算出ax=25,走到ERROR。值得注意的是:如果y被固定爲5,將無法生成新的輸入,總是走到ERROR分支,這種情況下,可以重新運行程序,爲y選擇不同的值,比如y=2計算出x=4,不會走到ERROR分支。

[P˘as˘areanu et al., 2011] suggests mixed concrete-symbolic solving, which considers all the path constraints collectable over a path before binding one or more symbols to specific concrete values.

[P˘as˘areanu等人,2011]提出mixed concrete-symbolic solving,它將一個或多個符號綁定到特定的具體值之前,考慮路徑上可收集的所有路徑約束。

處理不確定的約束。Handling Problematic Constraints.

這節主要講涉及非線性算術和庫調用的問題

[Dinges and Agha, 2014a] proposes a concolic walk algorithm that can tackle control-flow dependencies involving non-linear arithmetic and library calls. The algorithm treats assignments of values to variables as a valuation space: the solutions of the linear constraints define a polytope that can be walked heuristically, while the remaining constraints are assigned with a fitness function measuring how close a valuation point is to matching the constraint. An adaptive search is performed on the polytope as points are picked on it and non-linear constraints evaluated on them. Compared to mixed concrete-symbolic solving [P˘as˘areanu et al., 2011], both techniques seek to avoid blind commitment. However, concolic walk does not rely on the solver for obtaining all the concrete inputs needed to evaluate complex constraints, and implements search heuristics that guide the walk on the polytope towards promising regions.

[Dinges and Agha, 2014a]提出了一種concolic walk算法,可以處理涉及非線性算術和庫調用的控制流依賴。該算法將值的賦值作爲估值空間來處理:線性約束的解決方案定義了可以啓發式walk的多面體,而其餘的約束被賦值爲適應度函數,來測量估值點與約束匹配的程度。 在多面體上進行自適應搜索,在其上選取點並對其進行非線性約束評估。 與上一節的mixed concrete-symbolic solving相比,這兩種技術都試圖避免盲目的折中。 然而,concolic walk並不依賴於求解器來獲得評估複雜約束所需的所有具體輸入,並且實現了搜索啓發式,指導多面體在有前途的區域前進。

[Dinges and Agha, 2014b] describes symcretic execution, a novel combination of symbolic backward execution (SBE) (Section 2) and forward symbolic execution. The main idea is to divide exploration into two phases. In the first phase, SBE is performed from a target point and a trace is collected for each followed path. If any problematic constraints are met during the backward exploration, the engine marks them as potentially satisfiable by adding a special event to the trace and continues its reversed traversal. Whenever an entry point of the program is reached along any of the followed paths, the second phase starts. The engine concretely evaluates the collected trace, trying to satisfy any constraint marked as problematic during the first phase. This is done using a heuristic search, such as the concolic walk described above. An advantage of symcretic over classic concolic execution is that it can prevent the exploration of some unfeasible paths. For instance, the backward phase may determine that a statement is guarded by an unsatisfiable branch regardless of how the statement is reached, while a traditional concolic executor would detect the unfeasibility on a per-path basis only when the statement is reached, which is unfavourable for statements “deep” in a path.

[Dinges and Agha,2014b]描述了symcretic execution,後向符號執行SBE和前向符號執行的新穎組合。在第一階段,從目標點執行SBE,並且爲每個後續路徑收集軌跡。如果在向後探索過程中遇到任何有問題的約束條件,引擎就會通過向追蹤添加一個特殊事件, 將其標記爲可能滿足的並繼續其反向遍歷來,只要程序的入口點沿任何後續路徑到達,那麼就開始第二階段,引擎具體地評估收集的軌跡,試圖滿足在第一階段期間標記約束,這是通過啓發式搜索完成的,比如上面描述的concolic walk。與傳統的concolic執行相比,一個優點是它可以阻止探索一些不可行的路徑。例如,SBE階段可以確定一個狀態是由一個不可滿足的分支到達的,而不管這個狀態是如何得到的,而一個傳統的concolic執行者只有當這個狀態被達到時纔會根據每個路徑檢測到不可行性,對於在路徑中很“深”的狀態這是不利的。

7. 更多的研究方向

7.1 分割邏輯 separation logic (SL)

檢查指針程序的內存安全屬性是程序驗證中的一個主要挑戰。

SL主要思想:二元運算符*被用來把堆分成兩部分,其參數分別保存

A x [n : y] 表示有x指向一個記錄,該記錄在y的n字段,而A保留堆的其餘部分。

程序狀態被建模爲一個符號堆Π|Σ:Π是與變量相關的純謂詞的有限集合,而Σ是堆謂詞的有限集合。符號堆是使用抽象語義根據程序代碼符號執行的SL公式。 通常使用SL規則來支持符號堆的包含,推斷哪些堆部分不受語句影響,並確保經由抽象(例如,使用擴展操作符)來終止符號執行。

7.2 不變量

Loop invariants play a key role in verifiers that can prove programs correct against their full functional specification.

循環不變量在驗證者證明程序的正確與完整的功能規範中發揮關鍵作用。

An invariant is an inductive property that holds when the loop is first entered and is preserved for an arbitrary number of iterations.

不變量是一個歸納屬性,它在第一次進入循環時被保留,並被保存在任意次的迭代中。

困難:沒有該領域專家的人工干預,計算循環不變量很困難。事實上,驗證實踐的經驗表明,與其他規範元素(如方法前置/後置條件)相比,提供循環不變式要困難得多。

幾個研究:

Termination analysis

Predicate abstraction

7.3 函數摘要Function Summaries

函數摘要(第5.2節)主要用於靜態和動態程序分析,尤其是程序驗證。

7.4 程序分析和優化

我們認爲,符號執行可能會從編程語言領域的相關問題的解決方案中獲益。例如,在並行計算社區中,諸如循環合併等轉換可以通過平滑索引的迭代空間來將嵌套循環重構爲單個循環。這樣的轉換可能會簡化符號探索,增強搜索啓發式和狀態合併策略。

Loop unfolding 循環展開

Program synthesis

7.5 符號計算

SAT雖然是NP問題,但過去幾十年也有一些實際的應用方法。

In particular, advances in symbolic computation have produced powerful methods such as Gr¨obner bases for solving systems of polynomial constraints, cylindrical algebraic decomposition for real algebraic geometry, and virtual substitution for non-linear real arithmetic formulas [Abraham, 2015].

特別是符號計算方面的進步已經產生了強大的計算方法,如用於求解多項式約束系統的Gr¨obner基,用於實數代數幾何的圓柱代數分解,以及用於非線性實數算式的虛擬替換。

While SMT solvers are very efficient at combining theories and heuristics when processing complex expressions, they make use of symbolic computation techniques only to a little extent, and their support for non-linear real and integer arithmetic is still in its infancy [Abraham, 2015]. To the best of our knowledge, only Z3 [De Moura and Bjørner, 2008] and SMT-RAT [Corzilius et al., 2015] can reason about them both.

儘管SMT解算器在處理複雜表達式時非常有效地將理論和啓發式算法相結合,但是它們只是在一定程度上利用了符號計算技術,而且它們對非線性實數和整數算術的支持還處於起步階段[Abraham,2015]。 據我們所知,只有Z3 [De Moura andBjørner,2008]和SMT-RAT [Corzilius et al。,2015]可以推測這兩者。

8. 總結

在過去的十年中,符號執行技術已經發生了重大變化,導致重大的突破。2016年,DARPA網絡大挑戰賽主機系統可以檢測並修復未知軟件中的漏洞,如Angr和Mayhem,贏得$ 2 M的Mayhem也是第一個在DEF CON 24黑客大會上進行Capture-The-Flag比賽的自主軟件。

事件表明,基於符號執行的自動漏洞檢測工具可以與人類專家競爭,爲未來幾十年潛在影響軟件可靠性的前所未有的應用鋪平道路。

本次調查討論了符號執行的一些關鍵方面和挑戰。爲了解釋符號執行者的基本設計原理和主要的優化技術,我們把注意力集中在整數運算的單線程應用上。多線程程序的符號執行例如[Khurshid et al., 2003, Sen, 2007, Bucur et al., 2011, Farzan et al., 2013, Bergan et al., 2014, Guo et al., 2015],而用於處理浮點數據的程序的技術例如[Meudec, 2001, Botella et al., 2006, Lakhotia et al., 2010, Collingbourne et al., 2011, Barr et al., 2013, Collingbourne et al., 2014, Ramachandran et al., 2015]。

我們希望這次調查能夠幫助非專家把握好符號執行這一令人興奮的研究領域的重大發明,激發進一步的工作和新的思路。

 

附錄

工具:

Symbolic engine

References

Project URL (last retrieved: August 2016)

CUTE

[Sen et al., 2005]

DART

[Godefroid et al., 2005]

jCUTE

[Sen and Agha, 2006]

https://github.com/osl/jcute

KLEE

[Cadar et al., 2006, Cadar et al., 2008]

https://klee.github.io/

SAGE

[Godefroid et al., 2008, Elkarablieh et al., 2009]

BitBlaze

[Song et al., 2008]

http://bitblaze.cs.berkeley.edu/

CREST

[Burnim and Sen, 2008]

https://github.com/jburnim/crest

PEX

[Tillmann and De Halleux, 2008]

http://research.microsoft.com/en-us/projects/pex/

Rubyx

[Chaudhuri and Foster, 2010]

Java PathFinder

[P˘as˘areanu and Rungta, 2010]

http://babelfish.arc.nasa.gov/trac/jpf

Otter

[Reisner et al., 2010]

https://bitbucket.org/khooyp/otter/

BAP

[Brumley et al., 2011]

https://github.com/BinaryAnalysisPlatform/bap

Cloud9

[Bucur et al., 2011]

http://cloud9.epfl.ch/

Mayhem

[Cha et al., 2012]

SymDroid

[Jeon et al., 2012]

S2E

[Chipounov et al., 2012]

http://s2e.epfl.ch/

FuzzBALL

[Martignoni et al., 2012, Caselden et al., 2013]

http://bitblaze.cs.berkeley.edu/fuzzball.html

Jalangi

[Sen et al., 2013]

https://github.com/Samsung/jalangi2

Pathgrind

[Sharma, 2014]

https://github.com/codelion/pathgrind

Kite

[do Val, 2014]

http://www.cs.ubc.ca/labs/isd/Projects/Kite

SymJS

[Li et al., 2014]

CIVL

[Siegel et al., 2015]

http://vsl.cis.udel.edu/civl/

KeY

[Hentschel et al., 2014]

http://www.key-project.org/

Angr

[Shoshitaishvili et al., 2015, Shoshitaishvili et al., 2016]

http://angr.io/

Triton

[Saudel and Salwan, 2015]

http://triton.quarkslab.com/

PyExZ3

[Ball and Daniel, 2015]

https://github.com/thomasjball/PyExZ3

JDart

[Luckow et al., 2016]

https://github.com/psycopaths/jdart

CATG

https://github.com/ksen007/janala2

PySymEmu

https://github.com/feliam/pysymemu/

Miasm

https://github.com/cea-sec/miasm

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章