我們是利用 SOOT[16](A Java Optimization Framework)來對目標程式做靜態分析 以 產 生 測 試案 例 ,在此 我 們 的 分 析 是 建立 在 SOOT 提 供 的一種 中 繼 表 示 (Intermediate Representation, IR ) Jimple code 上面。Jimple code 是一種三地址碼 (3-address code),內建有以函式為單位的控制流程圖(Control Flow Graph, CFG),
我們測試案例產生的實作都是從對函式的控制流程圖做分析開始的,在後面我們 會說明如何藉由程序內的函式控制流程圖來達成整個跨程序的路徑分析。
4-1-1 測試案例產生演算法(Algorithm for test case generation)
Figure 4.1 為我們測試案例產生的演算法,其中給定的輸入為目標程式以及目標 程式的入口函式,最後的輸出為分析過後產生的測試案例。因為整個路徑限制蒐 集是跨程序的,所以首先需要由入口函式的控制流程圖來建立程式的呼叫圖(Call Graph),而對呼叫圖的每個函式都給予一個唯一的函式 ID,這是為了避免路徑
Input : Program P, EntryMethod EM
Output : Test cases for vulnerable paths in P //each method contains : (1) cfg: control flow graph // (2) id: an unique method id /* Method Sequencer:
1. construct the call graph
2. determine the method sequence from the call graph
*/
callgraph := constructCallGraph( EM.cfg);
methodSequence := [m | m ϵ callgraph in backward calling order];
/* Path Constraint Collector:
1. path identification and analysis 2. backward path constraint collecting
*/
Foreach m in methodSequence do // path identification and analysis
m.cfg’ := cfgPreprocessing(m.cfg ); //do loop, sink, call out stmt tagging m.cfg’’ := LoopPathHandling(m.cfg’); //do Trip Count Information tagging //discover all paths from control flow graph in Depth-First Search
pathSet := PathFiltering(m.cfg’’); //locate vulnerable path ssaPathSet := SSATransformation(pathSet); //transform path to SSA form //backward path constraint collection
//pc : path constraint, pcSet : path constraint set, pcTable : path constraint table Foreach p in ssaPathSet do
pc := BackwardPathConstraintCollection(p);
put pc into pcSet;
End
pcTable[m.id] := pcSet End
/* Path Constraint Solver */
pcSet := pcTable [EM.id] ; Foreach pc in pcSet do
TestCase := PathConstraintsSolving(pc);
put TestCase in TestSuite End
Figure 4.1 Algorithm for Test Case Generation
Order)來排序待處理函式順序,接下來函式依照排序開始作路徑限制蒐集直到呼 叫圖的函式都執行過為止,至於排序的順序及原因在後面跨程序的路徑分析中函 式排序的部分會再做詳細的說明。
以上的步驟等同於我們系統架構的 Method Sequencer 元件所負責的部分,有 了正確的順序之後,接著開始對每個函式做跨程序的路徑限制蒐集的部分,也就 是開始系統架構中 Path Constraint Collector 負責的部分,先對原先函式控制流程 圖做前置處理(cfgPreprocessing),會將函式控制流程圖做迴圈、外部程式呼叫、
程式接收點的標記,目的是為了方便之後跨程序的路徑蒐集和迴圈的處理。接著 針 對 標 記 過 的 函 式 控 制 流 程 圖 我 們 就 可 以 做 迴 圈 的 路 徑 分 析 處 理 (LoopPathHadling),會得到一個最終的函式控制流程圖,根據此函式控制流程圖 再以深度優先的方式找出所有的程式路徑,並過濾掉不需要處理的路徑,只保留 可能含有弱點的路徑。接著對過濾後留下的路徑作靜態單一賦值的轉換,這是為 了避免函式內部變數命名衝突的處理,這些處理好的路徑就開始做反向路徑限制 蒐集,每條蒐集好的路徑限制會存放在以函式為單位的路徑限制集合(Path Constraint Set)中,而蒐集完整的路徑限制集合會根據函式的唯一 ID 存放到路徑 限制表之中(Path Constraints Table)。隨著每個函式做跨程序的路徑限制蒐集,到 最後就能從路徑限制表中取得程式的入口函式的完整路徑限制,最後再交給路徑 限制分析工具(Constraint Solver)來產生限制解並產最後的測試案例。
4-1-2 跨程序性的路徑分析(Inter-Procedural Path Analysis)
因為我們整個測試案例產生的系統架構屬於跨程序性的分析,所以無論是函式路 徑的分析與路徑限制蒐集都需要以跨程序性的角度來進行系統的實作。回顧本論 文研究的第三章系統架構流程圖 Figure 3.5,其中函式排序器(Method Sequencer) 和路徑限制蒐集器(Path Constraint Collector)就是為了讓整個系統架構能夠進行 完整跨程序性的分析,而我們要產生完備測試案例的關鍵就是要蒐集完整的路徑 限制。因此概觀來說,目標程式的路徑是我們進行分析的主角,如何以跨程序性
之為跨程序性的路徑分析,其中涵蓋了函式排序器與路徑限制蒐集器負責的工作,
只是以不同的角度能夠更清楚的了解我們實作的重點。在此章節分成三個主要步 驟,首先是函式排序,接著以函式為單位進行路徑辨識與分析和反向的路徑限制 蒐集,Figure 4.2 為函式排序步驟完成後,接下來以函式為單位來作跨程序性的 路徑限制蒐集的示意圖。
確定跨程序性的路徑分析要分析的函式順序之後,從 Figure 4.2 我們可以看 到函式在經過路徑辨識與分析之後會得到一組轉換成 SSA 形式的路徑,接著再 根據這一組路徑進行反向的路徑限制蒐集。其中分成程序內部的(Intra)和跨程序 性的(Inter)路徑限制蒐集,跨程序性的部分會參考路徑限制表(Path Constraint Table)作路徑限制資訊的接合,其中可以看到路徑限制表中的 MID 代表函式的 ID(Method ID),pcSet 代表路徑限制集(Path Constraint Set)。
反向路徑限制蒐集完成後,就會產生一組的路徑限制(Path Constraints),將 這些路徑限制存放到以函式為單位的路徑限制集當中,再根據函式的 ID 將路徑 限制集存放入路徑限制表,等所有的函式都處理過之後就會得到完整的路徑限制
Path Identification and Analysis Method
SSA form paths
Path constraints Path constraint Set Path constraint Table
Backward Path Constraint Collection
Inter
Intra MID
M0
M2 M1
pcSet pcSet-1 pcSet-2 pcSet-3
Check
Put in
Figure 4.2 Path Analysis and Constraints Collection depend on method
表,也就表示所有的路徑限制都蒐集完整。以下會分別對這三個重要的步驟進行 實作細節的說明。
4-1-2-1 函式排序(Method Sequencing)
從前一章對於路徑限制蒐集完備性的考量因素,我們必須要處理函式中有跨程序 的外部函式呼叫(Inter-procedural call out method)情況,當分析的路徑中遇到呼叫 外部函式我們必須也將外部函式進行路徑限制的分析才能確保最後路徑限制蒐 集夠完整。讓我們再回顧第三章 Figure 3.1 的範例程式的第 7~9 行,當我們要 蒐集會到達第 9 行程式接收點(Sink)的路徑限制時,我們發現第 8 行的路徑限制 會受到第 7 行 idCheck 此外部函式的影響。所以在蒐集此路徑限制時如果 idCheck 此外部函式的路徑限制已經蒐集完整,我們就能將 idCheck 的路徑限制資訊結合 近來進一步形成完整的路徑限制蒐集,至於如何結合我們在後面的反向路徑限制 蒐集的部分會有詳細的說明。
由此可知,我們要做路徑限制蒐集的函式優先順序要從被呼叫的外部函式先 做路徑限制蒐集。由上述的例子可知,就是要先蒐集 idCheck 此外部函式的路徑 限制,因此了解函式彼此之間呼叫與被呼叫的關係,就能幫助我們釐清函式要做 路徑限制蒐集的先後順序。所以我們利用靜態分析中跨程序分析(Inter-procedural
M0
M1
M2
M3