Matryoshka: Fuzzing Deeply Nested Branches

Abstract

灰盒fuzz近年來取得了令人矚目的進展,從基於啓發式的隨機變異進化到求解單個分支約束。但是,它們很難解決包含深度嵌套條件語句的路徑約束,這些條件語句在圖像和視頻解碼器、網絡包分析器和校驗和工具中很常見。我們提出瞭解決這個問題的方法。首先,我們識別目標條件語句的所有控制流相關條件語句。接下來,我們選擇污染流相關的條件語句。最後,我們使用三種策略來尋找同時滿足所有條件語句的輸入。我們在一個叫做Matryoshka1的工具中實現了這種方法,並將其在13個開源程序上的有效性與其他最先進的fuzzer進行了比較。Matryoshka的累積測線和分支覆蓋率顯著高於AFL、QSYM和Angora。我們手動將Matryoshka發現的碰撞分類爲41個獨特的新漏洞,並獲得12個CVE。我們的評估展示了Matryoshka令人印象深刻的性能的關鍵技術:在目標條件語句的嵌套約束中,Matryoshka只收集那些可能導致目標無法到達的約束,這大大簡化了它必須解決的路徑約束。

introduction

Fuzzing是一種自動化的軟件測試技術,它成功地發現了現實軟件中的許多缺陷。在各種類型的模糊技術中,基於覆蓋的greybox模糊技術尤其流行,它優先於分支探索,以便在難以到達的分支中高效地觸發bug。與符號執行相比,灰盒模糊避免了昂貴的符號約束求解,因此可以處理大型、複雜的程序。

AFL[2]是一種基本的灰盒fuzz。它讓程序報告當前輸入是否在運行時探索了新的狀態。如果當前輸入觸發了一個新的程序狀態,那麼fuzzer將當前輸入作爲種子保存,以便進一步變異[35]。然而,由於AFL只使用粗糙的試探法對輸入進行隨機變異,因此很難實現高代碼覆蓋率。較新的fuzzer使用程序狀態來指導輸入變異,並顯示出比AFL顯著的性能改進,例如Vuzzer[30]、Steelix[26]、QSYM[41]和Angora[13]。以Angora爲例。它使用動態污點跟蹤來確定哪些輸入字節流到保護目標分支的條件語句中,然後只對這些相關字節進行變異,而不是對整個輸入進行變異,以大幅度減少搜索空間。最後,利用梯度下降法尋找分支約束的解。

然而,這些模糊器在解決包含嵌套條件語句的路徑約束時面臨困難。分支約束是保護分支的條件語句中的謂詞。只有當(1)條件語句是可到達的,並且(2)滿足分支約束時,分支纔是可到達的。路徑約束滿足這兩個條件。當一個條件語句s被嵌套時,只有當執行路徑上的一些先前的條件語句P是可到達的時,s纔是可到達的。如果\begin{Bmatrix} s \end{Bmatrix}\cup p中的分支約束共享公共輸入字節,那麼當fuzzer對輸入進行變異以滿足s中的約束時,它可能會使P中的約束失效,從而使s無法訪問。這個問題困擾着前面提到的fuzzer,因爲它們無法跟蹤控制流,並且污染了條件語句之間的流依賴關係。嵌套條件語句在圖像和視頻的編碼器和解碼器、網絡包分析器和校驗和驗證程序中都很常見,它們具有豐富的漏洞歷史。儘管混合執行可以解決一些嵌套的約束。結果表明,混合執行引擎會出現過度約束問題,這使得解決約束的代價太高[41],特別是在實際程序中。

圖1在程序readpng中顯示了這樣一個例子。第6行的謂詞嵌套在第4行的謂詞中。模糊器很難找到到達第6行假分支的輸入,因爲輸入也必須滿足第4行的假分支。當fuzzer試圖改變第6行的謂詞時,它只改變流入緩衝區[0]的輸入字節,但這幾乎肯定會導致png_CRC_finish()中的CRC檢查失敗,這將導致第4行接受真正的分支並返回。

爲了評估當前的fuzzer是否難以解決包含嵌套條件語句的路徑約束,我們使用Angora作爲案例研究。我們在13個開源程序上運行它,這些程序讀取結構化輸入,因此可能有許多嵌套的條件語句。表1顯示,在所有程序中,大多數未解決的路徑約束都涉及嵌套的條件語句。在5個程序中,90%以上的未解決約束涉及嵌套條件語句。這表明解決這些約束將顯著提高模糊器的覆蓋率。 

我們設計並實現了一種允許fuzzer探索深度嵌套條件語句的方法。下面以圖2中的程序爲例。假設當前輸入運行第6行的假分支,而fuzzer希望探索第6行的真分支。

  • 確定條件語句之間的控制流依賴關係。第一個任務是標識跟蹤上第6行之前的所有條件語句,這些語句可能使第6行無法訪問。它們包括第2、3和4行,因爲如果其中任何一行使用不同的分支,那麼第6行將無法訪問。第3.3節將描述我們如何使用過程內和過程間的後支配樹來查找這些條件語句。
  • 確定條件語句之間的污染流依賴關係。在前一步確定的條件語句中,只有第2行和第3行的語句與第6行有污染流依賴關係。這是因爲當我們在第6行上進行變異時,這可能會改變第3行的分支選擇,從而使第6行無法訪問。爲了避免這個問題,我們必須保留3號線的分支選擇,這可能需要我們同時改變x和y,但這可能會改變2號線的分支選擇。因此,2號線和3號線與6號線有污染流依賴關係。相比之下,當我們爲了探索6號線的真正分支而進行變異時,4號線的分支選擇從未改變,因此它與6號線沒有污染流依賴關係。第3.4節將描述我們如何找到這些依賴污染流的條件語句。
  • 解決約束。最後,我們需要對輸入進行變異以同時滿足多個依賴條件語句。換言之,我們需要找到一個既到達第6行又滿足其真正分支的新輸入。我們提出三個策略。
  1. 第一種策略保守地假設,如果我們對第6行所依賴的任何條件語句中的任何字節進行變異,那麼第6行將變得不可訪問。因此,在模糊第6.4行(第3.5.1節)時,此策略避免了這些字節的變異
  2. 第二種策略人爲地保留了第6行在對流入第6行的輸入字節進行變異時所依賴的所有條件語句的分支選擇。當它找到一個滿意的輸入時,它驗證程序是否可以在不改變分支選擇的情況下到達第6行。如果是這樣,那麼fuzzer成功地解決了這個問題。否則,模糊器將在跟蹤上回溯,以在3號線和2號線上嘗試此策略。(第3.5.2節)
  3. 最後一種策略試圖找到滿足所有依賴條件語句的解決方案。它定義了一個聯合約束,其中包括每個依賴條件語句的約束。當fuzzer找到一個滿足聯合約束的輸入時,則保證該輸入滿足所有相關條件語句中的約束。(第3.5.3節)

我們的方法假設沒有特殊結構或屬性在被fuzz的程序,比如魔法字節或校驗和函數。相反,我們解決嵌套條件語句的一般方法可以自然地處理這些特殊結構。

我們在一個名爲Matryoshka的工具中實現了我們的方法,並將其在13個開源程序上的有效性與其他最先進的fuzzer進行了比較。Matryoshka共發現41個獨特的新漏洞,並在其中7個程序中獲得了12個CVE。Matryoshka令人印象深刻的性能不僅在於它解決嵌套約束的能力,還在於它如何構造這些約束。傳統的符號執行收集路徑上所有條件語句中的謂詞。相比之下,Matryoshka只在目標分支同時依賴於控制流和污染流的條件語句中收集謂詞。我們的評估表明,後者只佔路徑上所有條件語句的一小部分,這大大簡化了Matryoshka必須解決的約束。

Background

Greybox fuzzing是一種流行的程序測試方法,它將程序狀態監測與隨機輸入變異結合起來,效果顯著。然而,目前最先進的greybox fuzzers無法可靠有效地解決嵌套條件語句。使用啓發式(例如,AFL)或原則性變異方法(例如,Angora)的模糊器沒有足夠的關於條件語句之間的控制流和污染流依賴性的信息來設計能夠滿足所有相關分支約束的輸入。其他使用混合混合混合執行的模糊器,如司鑽,由於將路徑的整個符號約束具體化,會遇到性能問題[41,42]。QSYM是一個實用的混合執行fuzzer,但它是專門爲解決路徑上的最後一個約束而定製的,因此面臨着與Angora相同的解決嵌套條件語句的挑戰。

以Angora爲例,我們評估了嵌套條件語句對Angora性能的影響,並在表1中分析了Angora未能解決的8個程序中的約束,其中每個約束對應於程序中的唯一分支。第二列顯示嵌套未解決約束的百分比,這取決於控制流和污染流的其他條件語句(第3.4節)。第三列顯示所有約束(已解決和未解決)中嵌套的百分比。表1顯示,大多數未解決的約束是嵌套的,範圍從57.95%到接近100%。研究還表明,嵌套約束佔所有約束的很大一部分,從44.14%到89.50%。這些結果表明,解決嵌套約束可以大大提高greybox fuzzers的覆蓋率

Design

3.1.problem

最新的覆蓋率引導模糊器,例如Angora[13]、QSYM[41]、VUzzer[30]和REDQUEEN[4],通過解決分支約束來探索新的分支,其中分支約束是保護分支的條件語句中的謂詞。這通常包括以下步驟。首先,使用動態污染分析或類似技術確定影響每個條件語句的輸入字節。然後,確定輸入字節應如何變異,例如計算謂詞的梯度並使用梯度下降、匹配幻數字節或使用符號執行解算器。最後,使用變異的輸入執行程序,並驗證這是否觸發條件語句中的另一個分支。

儘管這種方法在解決許多分支約束方面是有效的,但是當目標條件語句在輸入變異過程中變得不可訪問時,它會失敗。

圖2顯示了一個示例。讓變量x、y和z包含不同的輸入字節。假設當前輸入執行第6行的假分支,目標是探索第6行的真分支。然後,模糊器通過動態字節級污染分析確定它需要更改y中的字節。考慮x和y兩個不同的初始值。

  1. x=0,y=1。如果fuzzer將y變異爲3,那麼程序將不再到達第6行,因爲第3行將採用不同的(false)分支。這使得模糊者在解決分支謂詞時無能爲力,即使存在滿意的賦值y=2。
  2. x=1和y=1。在這種情況下,沒有一個y值可以同時滿足第2行、第3行和第6行的真正分支,除非我們也對x進行了變異。但是,由於x沒有流入第6行的條件語句中,fuzzer不知道它應該對x進行變異,因此無論怎樣,它都無法找到一個滿意的賦值來探索第6行的真正分支用於求解約束的算法。

此示例表明,要執行未探索的分支,有時僅對流入條件語句的輸入字節進行變異是不夠的,因爲這樣做可能會使此語句無法訪問。人們可以天真地對所有輸入字節進行變異,但這會增加許多數量級的搜索空間,使這種方法過於昂貴而不實用

3.2.solution overview

爲了克服第3.1節中的問題,我們的關鍵見解是,當我們模糊條件語句時,必須找到既滿足分支約束又保持語句可訪問的輸入。大多數通過求解分支約束來探索分支的模糊算子只考慮滿足性準則,而沒有考慮可達性準則。我們提出以下步驟來滿足這兩個標準,同時改變輸入。讓我們作爲一個條件語句來跟蹤這個輸入上的程序。我們的目標是改變輸入,讓我們採取不同的分支。我們調用目標條件語句,並說新輸入滿足s。

  1. 確定條件語句之間的控制流依賴關係。標識跟蹤上s之前可能使s無法訪問的所有條件語句。例如,如果s在圖2中的第6行,那麼如果第2、3和4行上的任何條件語句採用不同的分支,那麼第6行將無法訪問。我們稱之爲s的先驗條件語句,這取決於控制流。相比之下,不管5號支線走哪條,6號線總是可以到達的。第3.3節將詳細描述此步驟。
  2. 確定條件語句之間的污染流依賴關係。在s的先前條件語句中,標識那些其相應的輸入字節可能必須進行變異以滿足s的條件語句。例如,讓s成爲圖2中的第6行。在它的三個先驗條件語句中,只有第2行和第3行的那些語句包含可能必須進行變異以滿足s的字節(x和y)。我們稱這些有效的先驗條件語句,這取決於污染流。相比之下,第4行不包含爲滿足s而必須進行變異的輸入字節。第3.4節將詳細描述此步驟。
  3. 解決約束。對有效的先驗條件語句中的字節進行變異以滿足s.第3.5節將詳細描述此步驟。

圖3顯示了Matryoshka的總體設計,說明了在模糊化過程中如何使用這些策略。

3.3. Determine control flow dependency among conditional statements

對於每個條件語句s,我們希望標識它之前的所有條件語句,這些條件語句如果採用不同的分支,可能會導致s無法訪問。路徑上的s的緊接的前置條件語句是s的最後一個前置條件語句,即r和s之間沒有s的前置條件語句。注意,如果s是t的前置條件語句,而t在u中,那麼s是u的一個前置條件語句,這使得我們可以通過傳遞找到s的所有前置條件語句:從s開始,我們反覆找到直接前置條件語句,然後取所有這些語句的並集。

我們提出了兩種不同的方法來分別尋找同一函數和不同函數中的立即前置語句。在我們的優化實現中,我們緩存了所有找到的依賴項,以避免重複計算。

3.3.1 程序內緊接前置條件語句

從條件語句s開始,我們返回跟蹤。當我們找到第一個條件語句r時,1.在同一個函數中,並且2.那不是後支配。那麼r是s的立即前置語句,我們的實現使用了LLVM生成的後支配樹

如果我們找不到這樣的r,那麼s沒有過程內的直接先驗條件語句,我們將搜索它的程序間直接先驗條件語句,如第3.3.2節所述。

3.3.2. 程序間緊接前置條件語句

使用過程間後支配樹進行有效的處理是很簡單的,但是不幸的是,LLVM並沒有提供這樣的信息,所以我們設計了以下方法來查找s的過程間前立即條件語句r滿足以下所有條件:1.r與s在不同的函數中(我們稱之爲fr),並且執行s時,fr仍在堆棧上(即,它沒有返回),並且讓rc是fr執行的最後一個調用指令。rc必須存在,因爲r在比s更深的堆棧幀中,如果rc沒有後支配r(注意r和rc在相同的函數中),那麼r是s的過程間的立即優先語句。

3.3.3不規則的程序間控制流程

除了函數調用之外,程序還可以表現出不規則的過程間控制流,例如涉及exit和longjmp指令的那些流程。如果一個條件語句r至少有一個分支指向一個包含不規則流的基本塊,那麼即使它的幀不在堆棧上,我們也認爲它是它之後所有語句的優先條件語句。如果s是r之後的條件語句,我們將r和r的先驗條件語句添加到s的先驗條件語句集中。在LLVM中,包含不規則過程間控制流的基本塊用不可到達的指令終止。

3.4確定條件語句之間的污染流依賴關係

對於每個條件語句,第3.3節查找其所有先前的條件語句p(s)。設b(s)爲流入s的輸入字節集,其中s是一個或多個條件語句。當我們對輸入進行變異時,只要p(s)中沒有條件語句接受不同的分支,就保證s是可到達的。這似乎表明我們應該避免改變b(p(s))中的任何字節。

另一方面,避免改變b(p(s))中的每個字節可能會阻止fuzzer爲s找到滿意的賦值,如第3.1節所述。以圖2爲例。讓我們模擬程序執行到第6行。根據第3.3.1節,我們確定p(s)由第2、3和4行組成。因此,b(p(s))={x,y,z};。如果我們保持b(p(s))中的所有字節都是不可變的,那麼在試圖找到滿足s的輸入時,就沒有輸入字節可以變異。

出現問題是因爲第3.3節只考慮條件語句之間的控制流依賴性,但是它沒有考慮條件語句之間是否存在污染流依賴關係。我們將s,e(s)的有效先驗條件語句定義爲s的先驗條件語句的子集,如果要找到滿足s的輸入,我們可能需要對在e(s)中流入語句的一些字節進行變異。換言之,如果s的先驗條件語句r不是s的有效先驗條件語句,則流入r的字節無需進行變異以滿足s,這意味着我們可以只考慮有效的先驗條件語句而忽略無效的先驗條件語句。

算法1給出了計算有效先驗條件語句的算法,該算法依賴於以下性質:如果r是s的有效先驗條件語句,q是s的先驗條件語句,q和r共享公共輸入字節,那麼q也是s的有效先驗條件語句。

3.5解決約束

第3.4節確定每個條件語句s的有效優先條件語句。一方面,如果我們自由地改變流入其中任何一個的字節,s可能變得不可訪問。但另一方面,我們可能需要對其中的一些字節進行變異,以滿足s的未探索分支。因此,我們需要確定哪些語句的相關輸入字節可能發生變異。我們提出以下三種替代策略。Matryoshka按照這個順序進行嘗試,併爲每個策略設定時間預算,以確保整體效率。(1)優先考慮可達性(2)優先滿足(3)可達性和可滿足性聯合優化

每個策略標識一組輸入字節上的約束。然後,採用基於梯度的優化方法求解約束條件。這些策略只有當s是嵌套的,即s具有有效的先驗條件語句時才提供好處。如果S不是嵌套的,Matryoshka僅僅使用來自Angora或其他模糊體的現有策略來解決分支約束。因此,Matryoshka在解決嵌套條件語句時表現出更好的性能,同時具有與其他fuzzer相同的能力來解決非嵌套條件語句。

3.5.1優先考慮可達性

這種策略悲觀地假設,如果我們對任何流入條件語句s的任何有效先驗條件語句的字節進行變異,則s可能變得不可訪問。因此,該策略通過避免對流入s的任何有效先驗條件語句的任何字節進行變異來確保s始終是可到達的。形式上,設b(s)爲流入s的字節,b(e(s))爲流入s的有效先驗條件語句的字節。安哥拉變異了b(s)中的所有字節,這可能導致s變得不可訪問。相比之下,Matryoshka的這種策略只對b(s)\b(e(s))中的字節進行變異,即所有流入s但未流入s的有效先驗語句的字節。

以圖2中的程序爲例。當我們模糊s到第3行時,它唯一有效的條件語句是第2行的t。b(s)={x,y}。b(e(s))={x}。使用這種策略,fuzzer只對b(s)\b(e(s))={y}中的字節進行變異。

然而,當我們模糊s到6行時,這個策略失敗了。在這種情況下,其有效的先前聲明由第2行和第3行的聲明組成,因此b(s)={y},b(e(s))={x,y}。但是b(s)\b(dp(s))= \phi。使用這種策略,Matryoshka將無法模糊s,因爲它找不到要變異的字節。

3.5.2優先滿足

該策略樂觀地希望滿足條件語句s的變異輸入也能到達s,它有一個前向階段和一個後向階段。在前向階段,它對流入s的字節進行變異,同時人爲地保留s的所有有效先驗條件語句的分支選擇,從而保證s始終是可到達的。如果它找到滿足S的目標分支的輸入,則它正常運行該輸入程序(不人爲地修復分支選擇)。如果此跟蹤仍然到達並選擇目標分支,則它將成功。否則,它將進入回溯階段。在這個階段中,它從s開始,然後按照這個順序向後模糊s的每個有效先驗語句。當它模糊一個這樣的語句r時,它避免了對可能流入s的任何字節或r之後的s的任何有效的先驗條件語句進行變異。當fuzzer成功地模糊了所有這些有效的先驗條件語句時,這個過程就成功了。算法2顯示了該算法。

以圖2中的程序爲例。當我們模糊s到第6行時,它的有效先驗條件語句在第3行和第2行。設正確輸入爲x=1;y=1。在這個輸入下,第2行和第3行都取真分支,第6行取假分支。我們的目標是在6號線找到真正的分支。使用這種策略,在前向階段,模糊器會變異y,同時人爲地強制程序在2號線和3號線上採用真正的分支。如果fuzzer發現賦值y=2滿足第6行的真正分支,但由於x=1;y=2不滿足第3行,它將進入回溯階段。在此階段,它將首先模糊3號線。儘管這條線受到兩個值fx;yg的影響,因爲y流入第6行,fuzzer只會改變x。如果找到一個滿意的賦值x=0,它將嘗試在x=0;y=2的情況下運行程序,而不會人爲地強制執行分支選擇。由於此輸入到達第3行並滿足目標(true)分支,因此模糊化成功。

相比之下,假設fuzzer在模糊第6行時找到了一個滿意的賦值y=3。在回溯階段,當模糊3號線時,由於它只能變異x,因此無法找到滿意的賦值。因此,s的模糊化失敗了。

3.5.3可達性和可滿足性的聯合優化

第3.5.1節和第3.5.2節中的兩種策略每次搜索一個約束的解決方案。第3.5.1節僅對不會使目標條件語句不可訪問的輸入字節進行變異,而第3.5.2節則嘗試一次滿足目標條件語句及其有效的先前條件語句。然而,他們沒有找到一個解決方案,我們必須共同優化多個約束。

讓s成爲目標條件語句。設f_{i}(x)\leq 0,\forall i\in [1,n] 表示s的有效先驗條件語句的約束,並且f_{0}(x)\leq 0 表示s的約束。x是表示輸入字節的向量。表2顯示瞭如何將每種類型的比較轉換爲f(x)\leq 0 。我們的目標是找到一個滿足所有f_{i}(x)\leq 0,i\in [0,n] 。注意,每個f_{i}(x)是一個黑箱函數,用條件語句i中的表達式表示輸入x的計算。由於f_{i}(x)的解析形式不可用,許多常用的優化技術,如Lagrange乘子,不適用。

我們提出了一個優化問題的解。定義g(x)= \sum_{i=0}^{n}R(f_{i}(x))) 。其中糾正R(x)=0\vee x (二進制\vee運算符輸出其操作數的較大值)。因此,g(x)=0僅當f_{i}(x)\leq 0,\forall i\in [1,n]。換句話說,我們將n個優化組合成一個優化。現在我們可以使用梯度下降算法,類似於安哥拉使用的梯度下降算法,來找到一個解g(x)=0。注意到當我們用分化計算g(x)的梯度時,我們需要人工地維持分支選擇有效的先決條件聲明,以確保這是可以實現的。

讓我們重新查看圖2中的程序。設[x,y]=[1,3]爲初始輸入。當我們模糊第6行的目標條件語句s以探索真正的分支時,我們不能僅通過變異y來求解分支約束。使用聯合優化,我們將第3行和第2行的s的分支約束及其有效的先驗條件語句結合起來構造(通過式1和表2):

g([x,y])=R(x-2+\varepsilon )+R(x+y-3+\varepsilon )+R(1-y+\varepsilon ) (\varepsilon=1)

在初始輸入[x,y]=[1,3],g([x,y])=2.使用梯度下降,我們將找到g([x,y])=0的解,其中[x,y]=[0,2]。

3.6檢測隱含有效先驗條件語句

如果我們不能找到條件語句之間的所有控制流和污染流依賴關係,那麼第3.5節中的變異策略可能會失敗。第3.3節和第3.4節分別描述了查找所有顯式控制流和污染流依賴項的算法。但是,它們無法找到隱式流。圖4顯示了這樣一個例子。第13行的條件語句在函數foo中導致隱式污染流進入fun-ptr,然後隱式確定控制流是程序調用函數條還是其他函數。另外,第3行導致隱式污染流進入變量k,其值將決定第6行謂詞的值。因此,第13行和第3行的條件語句都應該是第7行目標語句的有效前置條件語句。但是,由於污染流是隱式的,因此第3.4節中的算法找不到它們。

隱式污染流可以用控制流圖來識別[23]。如果謂詞被污染,那麼該方法污染在條件語句的任一分支中獲取新值的所有變量。對於字節級污點跟蹤,此方法將謂詞的污點標籤添加到上述每個變量中。例如,考慮圖4中第3行的謂詞。由於變量k和n在這個條件語句的一個分支中被賦予了新的值,這個方法將謂詞的污點標籤(即變量y的污點標籤)添加到變量k和n中。但是,這個方法經常導致過度污點或污點爆炸,因爲它可能會添加對分析毫無用處的污染標籤。例如,在上面的例子中,雖然添加到變量k的污染標籤捕獲了從第3行到第6行的隱式污染流依賴關係,但是添加到變量n的污染標籤是無用的,因爲它無助於識別條件語句之間的新污染流依賴關係。更糟糕的是,這些無用的污染標籤將進一步傳播到程序的其他部分,導致污染爆炸。

我們提出了一種新的方法來識別條件語句之間的隱式控制流和污染流依賴關係,而不會產生巨大的分析開銷或污染爆炸。洞察是,我們不需要識別所有的隱式流,而只需要識別那些導致目標條件語句在輸入變異期間變得不可訪問的流。讓我們成爲目標條件語句,它在原始輸入上是可到達的,但在變異輸入上是不可到達的。我們運行程序兩次。首先,我們在原始輸入上運行程序,並在s之前的路徑上記錄所有條件語句的分支選擇。然後,我們使用一種特殊的處理方法在變異輸入上運行程序:當我們遇到條件語句時,我們記錄它的分支選擇,但強制它接受上次運行時的分支選擇(在原始輸入上)。因此,兩次運行的路徑具有相同的條件語句序列。我們按照相反的時間順序檢查從程序開始到s的路徑上的所有條件語句。對於每個這樣的語句t,如果它還不是由第3.4節中的算法識別的顯式有效優先語句,並且如果它在第一次運行(在原始輸入上)和第二次運行(在變異輸入上)中的分支選擇不同,它有一個潛在的控制流或與S的污點流依賴關係,以測試這種依賴性是否真的存在,我們用一個特殊的處理在突變輸入上運行程序:我們強制所有以下條件語句像第一次運行一樣進行分支選擇:(1)路徑上t之前的所有條件語句 (2)所有顯式有效先驗條件語句 (3)所有隱式有效先驗條件語句

如果程序不再到達s,那麼t確實與s有隱式控制流或污染流依賴關係,我們將它標記爲S的隱式有效的先驗條件語句。

該算法的複雜性在S之前的條件語句的數目是線性的,它受突變字節的影響,但不是依賴於S的控制流。然而,由於MatRysHKA在輸入的一小部分上通過梯度下降來改變輸入;我們應該測試的語句數量可能很少

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