專利名稱:一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行方法
技術(shù)領(lǐng)域:
本發(fā)明屬于計(jì)算機(jī)軟件安全測(cè)試領(lǐng)域,提供了一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行方法。
背景技術(shù):
軟件測(cè)試是驗(yàn)證軟件質(zhì)量最通用的技術(shù)。高質(zhì)量的軟件產(chǎn)品需求,促使軟件測(cè)試在軟件開發(fā)周期中占據(jù)越來越重要的地位。近幾年發(fā)展起來的動(dòng)態(tài)軟件測(cè)試避免了靜態(tài)軟件測(cè)試人工開銷大、效率低、誤報(bào)率高等缺點(diǎn),成為當(dāng)前軟件測(cè)試的主要方式。動(dòng)態(tài)符號(hào)執(zhí)行是動(dòng)態(tài)軟件測(cè)試的重要技術(shù)之一,其通過自動(dòng)生成測(cè)試用例以獲取高代碼覆蓋率,被用于當(dāng)前許多主流動(dòng)態(tài)軟件測(cè)試工具中。例如NASA的PathFinder,斯坦福大學(xué)的KLEE,伯克利大學(xué)的CREST,微軟的SAGE、Pex、Prefix等測(cè)試軟件采用的都是動(dòng)態(tài)符號(hào)執(zhí)行技術(shù)。利用 動(dòng)態(tài)符號(hào)執(zhí)行自動(dòng)生成測(cè)試用例,在理論上能夠?qū)崿F(xiàn)對(duì)被測(cè)程序全路徑的覆蓋,從而全面、精確的檢測(cè)程序中潛在的漏洞。動(dòng)態(tài)符號(hào)執(zhí)行通過對(duì)被測(cè)程序插裝,跟蹤抽象符號(hào)而非實(shí)際輸入值來分析程序。在首次執(zhí)行時(shí),由用戶提供輸入測(cè)試用例,將輸入數(shù)據(jù)符號(hào)化,符號(hào)執(zhí)行伴隨程序的實(shí)際執(zhí)行,跟蹤輸入數(shù)據(jù)的流通,同時(shí)更新相應(yīng)的符號(hào),在路徑分支處搜集與輸入符號(hào)相關(guān)的分支轉(zhuǎn)移條件表達(dá)式。一次執(zhí)行過程中搜集到的條件表達(dá)式的“與”組成路徑約束條件。該路徑約束條件的解集與該路徑有一一對(duì)應(yīng)的關(guān)系。對(duì)路徑約束條件的某條路徑取反并用求解器求解,求解得到的數(shù)據(jù)作為新測(cè)試用例輸入,能夠驅(qū)動(dòng)下次測(cè)試執(zhí)行不同的路徑,如此,直到所有的可執(zhí)行路徑都被測(cè)試完,最終達(dá)到對(duì)被測(cè)程序的全路徑覆蓋測(cè)試。動(dòng)態(tài)符號(hào)執(zhí)行的實(shí)際執(zhí)行過程可用示例I簡(jiǎn)單說明,首先解釋一次符號(hào)執(zhí)行的過
程。假設(shè)x,y是輸入值,符號(hào)執(zhí)行分別將其對(duì)應(yīng)為符號(hào)4。如果初次執(zhí)行對(duì)(x,y)提供的輸入值為(1000,503),則執(zhí)行路徑為1 — 2 — 3 — 4 — 5 — 6 — 10,第3行if條件語(yǔ)句得到的條件表達(dá)式為4 =1000,第4行的為〈2* Sy。該次執(zhí)行的路徑約束條件將為:(SX =1000)IJ (S;〈2* Sy ),解集為:SX =1000,Sy ={501,502…}。任意解集的集合(如
(1000, 501),(1000,502),(1000,504)等)作為輸入都可使程序沿該路徑執(zhí)行,但用SMT求解器求解只能得到能滿足該表達(dá)式的一組數(shù)據(jù)。I. void f (int x, int y) {
2.int z = 2氺y;
3.if (x == 1000) {
4.if (x < z) {
5.assert (0); /木 error
6.}
7.} else {
8.......9.}
10.}
示例簡(jiǎn)單程序符號(hào)執(zhí)行示例
對(duì)路徑約束條件中的每個(gè)條件表達(dá)式進(jìn)行取操作,可以求得可執(zhí)行其它分支路徑的輸入數(shù)據(jù)。如對(duì)第3行的約束條件取反,并保留它之前的條件表達(dá)式(該示例沒有),將其
后的表達(dá)式去掉,得到的條件表達(dá)式為& !=1000。該預(yù)測(cè)路徑約束條件的解可使程序沿第一個(gè)if語(yǔ)句的else分支執(zhí)行。這里的解集為Sx !=1000,&為任意值,求得的解可能是
(x=0, y=503)。利用以上方式,可以得到程序任何可執(zhí)行路徑對(duì)應(yīng)的輸入數(shù)據(jù),即測(cè)試用例,測(cè)試程序的所有可達(dá)路徑。
如果采用一般的動(dòng)態(tài)隨機(jī)測(cè)試,給x,y賦予隨機(jī)值,則要檢測(cè)出第5行的錯(cuò)誤,需要大量的無(wú)關(guān)測(cè)試,因?yàn)橐WC隨機(jī)取值X的值為1000,并且x〈2*y這個(gè)概率還是很小的。而采用動(dòng)態(tài)符號(hào)執(zhí)行最多需要3次,如圖I所示。從圖中可以看出,如果第一次的輸入值為(x=0,y=0),第一次實(shí)際執(zhí)行完后搜集到的路徑約束條件為Si. !=1000,對(duì)表達(dá)式取反
得& =1000,用求解器求解后得x=1000,用該值更新測(cè)試用例作為第二次的輸入(x=1000,
y=0)。第二次實(shí)際執(zhí)行完后搜集到的路徑約束條件力 =1000) >=2* Sy,對(duì)表達(dá)式
取反得Sx=1000)0 (Sx〈2*Sy (第一條表達(dá)式不需要反復(fù)取反),求解后得到一組滿足該表達(dá)式的解(x=1000,y=501)作為下一次的輸入。第三次實(shí)際執(zhí)行即可觸發(fā)第5行的assert (O)錯(cuò)誤。動(dòng)態(tài)符號(hào)執(zhí)行是一種重要的動(dòng)態(tài)軟件漏洞檢測(cè)方法。在實(shí)際執(zhí)行同時(shí)符號(hào)執(zhí)行,實(shí)際執(zhí)行檢測(cè)該路徑上潛在的漏洞,符號(hào)執(zhí)行能夠生成驅(qū)動(dòng)程序每次執(zhí)行不同路徑的測(cè)試用例。動(dòng)態(tài)符號(hào)執(zhí)行自動(dòng)生成能覆蓋程序所有可執(zhí)行路徑的測(cè)試用例,保證了測(cè)試的精確性、全面性,在理論上可以達(dá)到100%的覆蓋率。與靜態(tài)檢測(cè)和隨機(jī)檢測(cè)相比具有非常高的執(zhí)行效率,因此成為現(xiàn)在軟件測(cè)試領(lǐng)域的研究熱點(diǎn)。但是,動(dòng)態(tài)符號(hào)執(zhí)行還存在著很多需要被完善的地方,比如,路徑爆炸、外部函數(shù)檢測(cè)、浮點(diǎn)指針計(jì)算等。其中路徑爆炸是動(dòng)態(tài)符號(hào)執(zhí)行當(dāng)前面臨的最大挑戰(zhàn),阻礙它實(shí)際應(yīng)用于大中型應(yīng)用程序的測(cè)試。在示例I中只有兩個(gè)分支節(jié)點(diǎn),需要測(cè)試的路徑也只有3條,最多不會(huì)超過4條。但隨著被測(cè)程序的增大或者循環(huán)次數(shù)的增加,整條路徑約束條件長(zhǎng)度也會(huì)線性的增加,每增加一個(gè)條件表達(dá)式,路徑二叉樹的高度加I,程序可執(zhí)行路徑最多可能增加一倍。如示例2所示,在while循環(huán)中有3條件表達(dá)式,如果y的初始值為1,那么該while循環(huán)里最少會(huì)搜集到502*2條條件表達(dá)式(第5行的if語(yǔ)句不一定執(zhí)行到)。隨著路徑長(zhǎng)度的線性增長(zhǎng),需要測(cè)試的路徑按2的冪級(jí)數(shù)增加,當(dāng)有502*2個(gè)條件表達(dá)式時(shí),最多可以有25°2*2條路徑需要被測(cè)試,即所謂的路徑爆炸,在有限的時(shí)間資源條件下,不可能測(cè)試完所有的路徑,不能達(dá)到符號(hào)執(zhí)行要求的精確性、全面性。引起路徑爆炸的原因是路徑約束條件太長(zhǎng),其本質(zhì)因素主要有兩點(diǎn),一是程序太大,分支條件多;二是循環(huán)次數(shù)太大。路徑約束條件與程序長(zhǎng)度、循環(huán)三者之間存在以下近似線性關(guān)系
路徑約束條件的長(zhǎng)度=路徑分支節(jié)點(diǎn)數(shù)+循環(huán)個(gè)數(shù)* (每個(gè)循環(huán)迭代次數(shù)-I) *循環(huán)內(nèi)部分支節(jié)點(diǎn)數(shù)
1.void f (int x, int y) {
2.int z=2氺y;
3.while (y < 502) {
4.if (x > 1000) {
5.if (x < z) { 6.assert(0); /木 error 木/
7.}
8.}else{
9.z=2 氺y;
10.X++;
11.I
12.y++;
13.}
14.}
示例I帶循環(huán)程序的符號(hào)執(zhí)行示例
當(dāng)前國(guó)內(nèi)外已提出了多種解決路徑爆炸問題的方法,下面列出了幾種最普遍使用的方法,并且分析它們存在的一些缺陷。搜索深度限制這是在采用深度優(yōu)先路徑遍歷策略的動(dòng)態(tài)符號(hào)執(zhí)行算法中采用的基本方法,也就是限制路徑二叉樹的搜索深度,當(dāng)達(dá)到一定深度時(shí)就不再往下繼續(xù)搜索。該方法沒有額外的開銷,但會(huì)遺失部分路徑,導(dǎo)致測(cè)試不能覆蓋到所有代碼,容易遺失漏洞??刂蒲h(huán)次數(shù)在程序運(yùn)行時(shí)識(shí)別出循環(huán),并找出循環(huán)次數(shù)控制變量,當(dāng)循環(huán)次數(shù) 達(dá)到給定上限時(shí),跳出循環(huán)。該方法存在跟上面同樣的問題,并且運(yùn)行時(shí)循環(huán)識(shí)別開銷很大。啟發(fā)式搜索算法每次測(cè)試完成后,對(duì)所有條件表達(dá)式取反,生成該路徑上所有未被檢測(cè)過的分支對(duì)應(yīng)的測(cè)試用例。在第一次測(cè)試之后,每次測(cè)試都選擇能夠覆蓋最多代碼塊的測(cè)試用例作為下一次的輸入。該方法是針對(duì)大應(yīng)用程序,采用代碼覆蓋率最大化的思路,延遲路徑爆炸的發(fā)生。每次選擇能最優(yōu)測(cè)試用例開銷非常。以上幾種方法以及未列出的其他方法都存在著不完善的地方。本發(fā)明從引起路徑爆炸原因之一的循環(huán)入手,對(duì)動(dòng)態(tài)符號(hào)執(zhí)行方法進(jìn)行改進(jìn),消除循環(huán)產(chǎn)生的路徑爆炸問題。另一方面,本發(fā)明不需要專門在運(yùn)行時(shí)去識(shí)別循環(huán),找出循環(huán)控變量(難度比較大,而且準(zhǔn)確性不高),所以開銷非常小。該發(fā)明思路來自于上面提到的路徑約束條件滿足的近似線性關(guān)系。分析該關(guān)系式可知,“路徑分支節(jié)點(diǎn)數(shù)”、“循環(huán)個(gè)數(shù)”、“循環(huán)內(nèi)部分支節(jié)點(diǎn)數(shù)”這三個(gè)變量都是程序內(nèi)部固有的,不可改變。但是“每個(gè)循環(huán)迭代次數(shù)”可能受輸入影響大小不定,可能是一次也可能是無(wú)限次。然而,動(dòng)態(tài)符號(hào)執(zhí)行只需要將所有代碼都覆蓋到,因此路徑約束條件只須將該路徑上的每個(gè)分支節(jié)點(diǎn)包含到即可,被測(cè)程序一次執(zhí)行過程中多次符號(hào)執(zhí)行同一段代碼只會(huì)大大增加路徑約束條件的長(zhǎng)度,進(jìn)而增加代碼塊的檢測(cè)次數(shù),但不能覆蓋到新的代碼塊。
發(fā)明內(nèi)容
本發(fā)明的目的在于提供一種利用一種決策圖來消除循環(huán)產(chǎn)生的冗余約束條件表達(dá)式,從而實(shí)現(xiàn)緩解因循環(huán)而導(dǎo)致的路徑爆炸問題的一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行。一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行方法,包括以下步驟
一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行方法,包括以下步驟
(1)通過控制流圖生成及化簡(jiǎn)模塊獲取程序?qū)?yīng)的靜態(tài)控制流圖,并根據(jù)相關(guān)理論將控制流圖化簡(jiǎn)為決策圖,保存在決策圖數(shù)據(jù)結(jié)構(gòu)中;
(2)通過插樁模塊對(duì)被測(cè)程序插樁;
(3)通過實(shí)際執(zhí)行和符號(hào)執(zhí)行模塊,一方面實(shí)際運(yùn)行程序,檢測(cè)本次運(yùn)行路徑中潛在的漏洞;另一方面進(jìn)行符號(hào)執(zhí)行,搜集該執(zhí)行路徑上遇到的分支節(jié)點(diǎn)的條件表達(dá)式,得到約束條件;
(4)通過約束條件映射模塊將符號(hào)執(zhí)行收集到的約束條件保存到?jīng)Q策圖對(duì)應(yīng)的節(jié)點(diǎn)中,如果存在循環(huán),則下一次迭代產(chǎn)生的約束條件將覆蓋上一次保存在決策圖中的約束條件,保證一個(gè)循環(huán)中相同的約束條件僅被保存一次;
(5)通過路徑約束條件獲取模塊在完成一次混合執(zhí)行測(cè)試結(jié)束后,即實(shí)際執(zhí)行和符號(hào)執(zhí)行模塊執(zhí)行測(cè)試結(jié)束后,按深度優(yōu)先搜索策略從決策圖中搜索約束條件,組成路徑約束條件,輸出是精簡(jiǎn)的路徑約束條件;
(6)通過路徑約束條件取反模塊將路徑約束條件的每一個(gè)表達(dá)式取反,并保存該表達(dá)式之前的約束條件,刪除之后的約束條件,形成預(yù)測(cè)路徑約束條件;
(7)通過求解器求解模塊對(duì)預(yù)測(cè)路徑約束條件求解,生成新的測(cè)試用例,該測(cè)試用例能夠驅(qū)動(dòng)下次測(cè)試朝不同的分支路徑執(zhí)行,直到所有的路徑都被測(cè)試完。進(jìn)一步的說,所述步驟(5)中路徑約束條件獲取模塊在一次混合執(zhí)行測(cè)試結(jié)束后,按深度優(yōu)先搜索策略從決策圖中搜索約束條件,搜索方式如下
a)從決策圖的入口點(diǎn)開始訪問內(nèi)容不為空的鄰接節(jié)點(diǎn);
b)從該鄰接節(jié)點(diǎn)不為空的邊中取出約束條件加到路徑約束條件上,并將該邊的內(nèi)容刪除,將該節(jié)點(diǎn)壓入訪問節(jié)點(diǎn)堆棧中,該堆棧中的元素不重復(fù);
c)沿著這條邊訪問以它為進(jìn)入邊的鄰接節(jié)點(diǎn);
d)如果鄰接節(jié)點(diǎn)不為決策圖的出口點(diǎn),并且內(nèi)容不為空,轉(zhuǎn)到b),如果內(nèi)容為空則轉(zhuǎn)
f);
e)如果鄰接節(jié)點(diǎn)為決策圖的出口點(diǎn),則轉(zhuǎn)到f);
f)如果訪問節(jié)點(diǎn)堆棧不為空,則從堆棧中依次彈出一個(gè)節(jié)點(diǎn),直到該節(jié)點(diǎn)的內(nèi)容不為空,轉(zhuǎn)到b),否則轉(zhuǎn)到g)。g)本次搜索完畢。在上邊的搜索算法中用到了兩個(gè)數(shù)據(jù)結(jié)構(gòu)路徑約束條件和訪問節(jié)點(diǎn)堆棧。在動(dòng)態(tài)符號(hào)執(zhí)行中,路徑約束條件是一個(gè)專業(yè)術(shù)語(yǔ),表示所有輸入符號(hào)在一次執(zhí)行過程中所滿足的驅(qū)使這個(gè)過程執(zhí)行的約束條件的“與”。該算法中的路徑約束條件用來保存檢索到的所有約束條件,最后得到的是表示該執(zhí)行路徑的完整路徑約束條件。訪問節(jié)點(diǎn)堆棧用先進(jìn)后出的堆棧方式保存訪問過的所有節(jié)點(diǎn)。
本發(fā)明與現(xiàn)有技術(shù)相比具有以下有益效果
本發(fā)明在現(xiàn)有符號(hào)執(zhí)行方案基礎(chǔ)上進(jìn)行的改進(jìn)。結(jié)合程序的靜態(tài)決策圖,利用(映射,獲取)機(jī)制,消除循環(huán)對(duì)符號(hào)執(zhí)行的影響,從而解決了路徑爆炸產(chǎn)生兩因素之一。本發(fā)明現(xiàn)有技術(shù)相比有非常明顯的效果。其一,決策圖一次生成后將用于整個(gè)符號(hào)執(zhí)行測(cè)試中,開銷非常?。涣硪环矫?,利用(映射,獲取)機(jī)制消除循環(huán)產(chǎn)生的冗余約束條件,不會(huì)丟失任何信息,能夠保證所有代碼塊都被檢測(cè)到,保證了動(dòng)態(tài)符號(hào)測(cè)試的精確性、全面性。
圖I為例I對(duì)應(yīng)的路徑二叉樹,從根到每個(gè)葉子節(jié)點(diǎn)代表不同的可執(zhí)行路徑。分支箭頭上的表達(dá)式為條件轉(zhuǎn)移符號(hào)表達(dá)式,葉子節(jié)點(diǎn)中的數(shù)據(jù)表示對(duì)應(yīng)該路徑的輸入值;
圖2為混合執(zhí)行測(cè)試模塊裝置圖;·
圖3為示例2對(duì)應(yīng)的控制流 圖4為示例2對(duì)應(yīng)的決策圖。
具體實(shí)施例方式本實(shí)施案例詳細(xì)講述了一種實(shí)現(xiàn)本發(fā)明的方式,但本發(fā)明的保護(hù)范圍不僅僅局限于采用這種方式,凡是采用本發(fā)明思想的實(shí)施方式都在本發(fā)明的保護(hù)范圍內(nèi)??刂屏鲌D生成及化簡(jiǎn)模塊
本裝置的功能是利用數(shù)據(jù)結(jié)構(gòu)抽象被測(cè)程序的控制流圖,并將其化簡(jiǎn)為決策圖。輸出為保存在內(nèi)存中的決策圖數(shù)據(jù)結(jié)構(gòu)。下面簡(jiǎn)要介紹抽象及化簡(jiǎn)過程。抽象過程可以利用IDA ρι·ο進(jìn)行,IDA pro是一款商業(yè)靜態(tài)調(diào)試軟件,可以生成可執(zhí)行程序的控制流圖。一個(gè)程序的控制流圖可以用一個(gè)4元組G = OV, B, entry, ezii)表示,N是控制流圖G中節(jié)點(diǎn)的集合,每個(gè)節(jié)點(diǎn)代表程序一個(gè)基本塊?;緣K為程序一段連續(xù)的代碼,只能按順序從第一條語(yǔ)句執(zhí)行到最后一條語(yǔ)句,然后轉(zhuǎn)入其他基本塊。E是控制流圖有向邊的集合,有向邊表示兩個(gè)基本塊之間的控制轉(zhuǎn)移。entry,exit分別表示程序的入口點(diǎn)和出口點(diǎn)。如圖3是示例2的控制流圖。只保留控制流圖中的入口點(diǎn),出口點(diǎn),以及所有的決策點(diǎn),可以將控制流圖轉(zhuǎn)化為決策圖,如圖4所示。決策圖中除入口點(diǎn)和出口點(diǎn)外,其它節(jié)點(diǎn)都表示程序中的分支語(yǔ)句。因?yàn)榉种дZ(yǔ)句根據(jù)條件的真假取值跳轉(zhuǎn)到不同的地方執(zhí)行,所以除入口點(diǎn)和出口點(diǎn)外,其它節(jié)點(diǎn)出度不會(huì)小于2,分別表示條件表達(dá)式取值為“true”或“false”的邊。約束條件映射模塊
該模塊的作用是在軟件測(cè)試過程中,將符號(hào)執(zhí)行產(chǎn)生的約束條件根據(jù)它們的真假取值情況,保存到?jīng)Q策圖中對(duì)應(yīng)節(jié)點(diǎn)的相應(yīng)邊上。因?yàn)闆Q策圖中的節(jié)點(diǎn)與程序的分支語(yǔ)句有一一對(duì)應(yīng)關(guān)系(除入口點(diǎn)和出口點(diǎn)),所以每條分支語(yǔ)句都可以在決策圖中找到與它對(duì)應(yīng)的節(jié)點(diǎn)。如示例2第4行的if語(yǔ)句,在決策圖4中對(duì)應(yīng)的節(jié)點(diǎn)為節(jié)點(diǎn)4,所以第4行收集到的約束條件將保存在節(jié)點(diǎn)4的數(shù)據(jù)結(jié)構(gòu)中。假設(shè)分支節(jié)點(diǎn)的左邊表示“false”,右邊表示“true”,如果表達(dá)式“x>1000”成立,則保存到表示“true”的(4,5)邊上,否則對(duì)表達(dá)式取反,保存到表示“ fal se ”的(4,3 )邊上。約束條件映射是消除循環(huán)產(chǎn)生的冗余約束條件的核心。如果程序中存在著循環(huán),那么循環(huán)迭代產(chǎn)生的約束條件,在保存在決策圖中時(shí),大量存在著覆蓋已保存約束條件的情況。如示例2的while循環(huán),存在三個(gè)分支(分別為3,4,5)。第一次迭代產(chǎn)生的約束條件將保存到?jīng)Q策圖中3,4,5節(jié)點(diǎn)上,第二次循環(huán)產(chǎn)生的約束條件同樣被保存到3,4,5節(jié)點(diǎn)上,只是可能保存的邊不同。路徑約束條件獲取模塊
該模塊的功能是在一次混合執(zhí)行測(cè)試結(jié)束后,按深度優(yōu)先搜索策略從決策圖中搜索約束條件,形成路徑約束條件。輸出是精簡(jiǎn)的路徑約束條件。搜索方式如下a)從決策圖的入口點(diǎn)開始訪問內(nèi)容不為空的鄰接節(jié)點(diǎn)。b)從該鄰接節(jié)點(diǎn)不為空的邊中取出約束條件加到路徑約束條件上,并將該邊的內(nèi)容刪除,將該節(jié)點(diǎn)壓入訪問節(jié)點(diǎn)堆棧中(該堆棧中的元素不重復(fù))。c)沿著這條邊訪問以它為進(jìn)入邊的鄰接節(jié)點(diǎn)。 d)如果鄰接節(jié)點(diǎn)不為決策圖的出口點(diǎn),并且內(nèi)容不為空,轉(zhuǎn)到b)。如果內(nèi)容為空則轉(zhuǎn)f)。e)如果鄰接節(jié)點(diǎn)為決策圖的出口點(diǎn),則轉(zhuǎn)到f)。f)如果訪問節(jié)點(diǎn)堆棧不為空,則從堆棧中依次彈出一個(gè)節(jié)點(diǎn),直到該節(jié)點(diǎn)的內(nèi)容不為空,轉(zhuǎn)到b)。否則轉(zhuǎn)到g)。g)本次搜索完畢。該搜索訪問到的節(jié)點(diǎn)都是此次實(shí)際執(zhí)行路徑上的所有分支節(jié)點(diǎn)。在搜索過程中可能遇到兩條邊中都保存有約束條件的節(jié)點(diǎn),訪問節(jié)點(diǎn)堆棧就是為了保證兩條邊都被訪問到。出現(xiàn)這種情況是因?yàn)樵摴?jié)點(diǎn)被不止一次被執(zhí)行,如循環(huán)內(nèi)的分支節(jié)點(diǎn)。循環(huán)的多次迭代可能會(huì)使分支節(jié)點(diǎn)的兩條轉(zhuǎn)移邊都被執(zhí)行,所以兩條邊中都會(huì)保存約束條件。如決策圖4中(3,4)邊保存的約束條件可能為“Sy〈502”,(3, exit)邊保存的約束條件可能為“Sy+1>=502”。兩個(gè)約束條件都要記錄到路徑約束條件中,因?yàn)樗鼈儗?duì)應(yīng)的路徑不透。訪問節(jié)點(diǎn)堆棧保證了所有被訪問到的節(jié)點(diǎn)都被唯一保存到堆棧中,便于二次訪問該節(jié)點(diǎn),檢測(cè)是否還有未被訪問到的邊。I.插樁模塊
該模塊的功能是對(duì)被測(cè)程序進(jìn)行運(yùn)行時(shí)動(dòng)態(tài)二進(jìn)制插樁。在動(dòng)態(tài)符號(hào)執(zhí)行時(shí),通過對(duì)被測(cè)程序插樁,可以監(jiān)測(cè)符號(hào)的流動(dòng)路徑、操作運(yùn)算,從而收集路徑約束條件,是動(dòng)態(tài)符號(hào)執(zhí)行的一項(xiàng)基本且不可或缺的措施?,F(xiàn)有的二進(jìn)制插樁工具有ATOM、Dynins、Valgrind、PIN、Nirvana、HDTrans等,在本方案中采用PIN作為插樁工具。符號(hào)執(zhí)行和實(shí)際執(zhí)行模塊
本模塊是將實(shí)際運(yùn)行程序和符號(hào)執(zhí)行同時(shí)進(jìn)行,檢測(cè)漏洞并且利用符號(hào)執(zhí)行產(chǎn)生新的測(cè)試用例。該模塊首次執(zhí)行的輸入是用戶提供的數(shù)據(jù),以后每次執(zhí)行的輸入都是前一次符號(hào)執(zhí)行產(chǎn)生的測(cè)試用例。這樣,混合測(cè)試僅在啟動(dòng)時(shí)需要用戶提供輸入,之后自動(dòng)完成程序路徑狀態(tài)空間的檢測(cè)。實(shí)際運(yùn)行程序同時(shí),會(huì)利用現(xiàn)有的動(dòng)態(tài)漏洞檢測(cè)軟件檢測(cè)該運(yùn)行路徑中可能存在的漏洞。符號(hào)執(zhí)行將輸入數(shù)據(jù)符號(hào)化,在執(zhí)行過程中跟蹤符號(hào),并在分支語(yǔ)句上形成條件表達(dá)式。并映射到?jīng)Q策圖數(shù)據(jù)結(jié)構(gòu)中。
路徑約束條件取反模塊
該模塊的功能是將路徑約束條件上的每個(gè)條件表達(dá)式按照符號(hào)執(zhí)行驅(qū)動(dòng)算法取反。取反后的條件表達(dá)式與它之前的條件表達(dá)式組成預(yù)測(cè)路徑約束條件。驅(qū)動(dòng)算法可以一次取反一個(gè)條件表達(dá)式,在求解器求解后產(chǎn)生新測(cè)試用例,驅(qū)動(dòng)下次執(zhí)行?;蛘咭淮瓮瓿伤袟l件表達(dá)式的取反且求解,從 中選出一個(gè)測(cè)試用例驅(qū)動(dòng)下次執(zhí)行。求解器求解模塊
該模塊的功能是對(duì)預(yù)測(cè)路徑約束條件求解,產(chǎn)生可以執(zhí)行到不同路徑的新測(cè)試用例。符號(hào)執(zhí)行產(chǎn)生的路徑約束條件由一系列條件表達(dá)式組成,可以看作SMT問題,對(duì)它們的求解就是判定這些問題是否可解,并給出一組可滿足該問題的具體值。例如,表達(dá)式x-y>0,是可滿足的,可給出滿足該公式的一組值(2,I) ;x2+y2〈0是不可滿足的,不能給出一組(Sx,Sy)值,使該表達(dá)式成立。常見的SMT求解器有STP,CVC, OpenSMT, Yices, Z3等,在本模塊中選擇STP作為路徑約束條件的求解器。該模塊產(chǎn)生的測(cè)試用例將用來驅(qū)動(dòng)下次符號(hào)執(zhí)行,直到所有的路徑都被測(cè)試完。關(guān)鍵詞和專業(yè)術(shù)語(yǔ)解釋
符號(hào)執(zhí)行(symbolic execution)將輸入數(shù)據(jù)映射為特定的符號(hào),通過跟蹤抽象符號(hào)建立符號(hào)表達(dá)式來分析程序,不用關(guān)心實(shí)際輸入值。該符號(hào)代表可執(zhí)行同一條路徑的所有輸入值的集合。代碼覆蓋率覆蓋即被檢測(cè)到,表示已檢測(cè)代碼塊占總代碼塊的百分比,主要用于軟件測(cè)試中度量被測(cè)程序檢測(cè)深入的程度。代碼覆蓋率越高,也就意味著有更多代碼被檢測(cè),越容易發(fā)現(xiàn)軟件漏洞;代碼覆蓋率增量也是一項(xiàng)度量標(biāo)準(zhǔn),其增量越大,越能快速的發(fā)現(xiàn)漏洞。約束條件符號(hào)在執(zhí)行路徑上遇到分支語(yǔ)句形成的滿足分支轉(zhuǎn)移條件的關(guān)系表達(dá)式,通常以數(shù)學(xué)表達(dá)式的方式表示。路徑約束條件表示所有輸入符號(hào)在一次執(zhí)行過程中所滿足的驅(qū)使這個(gè)過程執(zhí)行的約束條件的“與”。是一類可滿足(SMT)問題,用求解器求解可得出滿足該路徑的一組數(shù)據(jù)。測(cè)試用例為某個(gè)特殊目標(biāo)而編制的一組測(cè)試輸入、執(zhí)行條件以及預(yù)期結(jié)果,以便測(cè)試某個(gè)程序路徑或核實(shí)是否滿足某個(gè)特定需求。動(dòng)態(tài)符號(hào)執(zhí)行一種實(shí)際執(zhí)行(concrete execution,分析實(shí)際輸入值)與符號(hào)執(zhí)行(symbolic execution)交錯(cuò)進(jìn)行,自動(dòng)生成輸入測(cè)試用例以達(dá)到對(duì)軟件全路徑覆蓋的動(dòng)態(tài)軟件測(cè)試技術(shù),主要用于軟件漏洞發(fā)掘領(lǐng)域。路徑二叉樹在程序路徑上,每到達(dá)一個(gè)分支語(yǔ)句,都有兩條路徑可選擇,選擇不同的分支就意味著執(zhí)行不同的路徑,動(dòng)態(tài)符號(hào)執(zhí)行是對(duì)程序的全路徑檢測(cè),對(duì)可執(zhí)行路徑上的所有分支的走向形成一棵路徑二叉樹,從根到每個(gè)葉節(jié)點(diǎn)都是一條路徑。路徑爆炸問題程序中每一個(gè)分支條件語(yǔ)句都可能會(huì)使當(dāng)前的路徑再分支出一條新的路徑,并且每一個(gè)分支條件使路徑二叉樹的高度增1,葉節(jié)點(diǎn)增加一倍,使得路徑成“指數(shù)級(jí)”增長(zhǎng),俗稱“路徑爆炸”。SMT問題SMT問題是一種一階邏輯公式的判定問題或者可滿足問題,只需判斷滿足或不滿足,可以給出滿足的一組值,不需要給出精確答案。
SMT求解器一種數(shù)學(xué)工具,用來判定給出的條件表達(dá)式是否可滿足,并且解出滿足條件的一組數(shù)據(jù)。二進(jìn)制級(jí)插樁插樁指在程序中插入額外的代碼以獲得程序在執(zhí)行時(shí)的行為信息。二進(jìn)制級(jí)插樁指對(duì)二進(jìn)制可執(zhí)行文件進(jìn)行插樁,不需要獲得程序的源代碼就可以實(shí)現(xiàn)的插樁方式??刂屏鲌D(CFG)用有向圖表示一個(gè)程序過程的一種抽象數(shù)據(jù)結(jié)構(gòu)。圖中的節(jié)點(diǎn)表 示一個(gè)程序基本塊,基本塊是沒有任何跳轉(zhuǎn)的順序語(yǔ)句代碼塊。圖中的有向邊表示每個(gè)基本塊之間的控制轉(zhuǎn)移。
權(quán)利要求
1.一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行方法,包括以下步驟 (1)通過控制流圖生成及化簡(jiǎn)模塊獲取程序?qū)?yīng)的靜態(tài)控制流圖,并根據(jù)相關(guān)理論將控制流圖化簡(jiǎn)為決策圖,保存在決策圖數(shù)據(jù)結(jié)構(gòu)中; (2)通過插樁模塊對(duì)被測(cè)程序插樁; (3)通過實(shí)際執(zhí)行和符號(hào)執(zhí)行模塊,一方面實(shí)際運(yùn)行程序,檢測(cè)本次運(yùn)行路徑中潛在的漏洞;另一方面進(jìn)行符號(hào)執(zhí)行,搜集該執(zhí)行路徑上遇到的分支節(jié)點(diǎn)的條件表達(dá)式,得到約束條件; (4)通過約束條件映射模塊將符號(hào)執(zhí)行收集到的約束條件保存到?jīng)Q策圖對(duì)應(yīng)的節(jié)點(diǎn)中,如果存在循環(huán),則下一次迭代產(chǎn)生的約束條件將覆蓋上一次保存在決策圖中的約束條件,保證一個(gè)循環(huán)中相同的約束條件僅被保存一次; (5)通過路徑約束條件獲取模塊在完成一次混合執(zhí)行測(cè)試結(jié)束后,即實(shí)際執(zhí)行和符號(hào)執(zhí)行模塊執(zhí)行測(cè)試結(jié)束后,按深度優(yōu)先搜索策略從決策圖中搜索約束條件,組成路徑約束條件,輸出是精簡(jiǎn)的路徑約束條件; (6)通過路徑約束條件取反模塊將路徑約束條件的每一個(gè)表達(dá)式取反,并保存該表達(dá)式之前的約束條件,刪除之后的約束條件,形成預(yù)測(cè)路徑約束條件; (7)通過求解器求解模塊對(duì)預(yù)測(cè)路徑約束條件求解,生成新的測(cè)試用例,該測(cè)試用例能夠驅(qū)動(dòng)下次測(cè)試朝不同的分支路徑執(zhí)行,直到所有的路徑都被測(cè)試完。
2.根據(jù)權(quán)利要求I所述的一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行方法,其特征在于所述步驟(5)中路徑約束條件獲取模塊在一次混合執(zhí)行測(cè)試結(jié)束后,按深度優(yōu)先搜索策略從決策圖中搜索約束條件,搜索方式如下 a)從決策圖的入口點(diǎn)開始訪問內(nèi)容不為空的鄰接節(jié)點(diǎn); b)從該鄰接節(jié)點(diǎn)不為空的邊中取出約束條件加到路徑約束條件上,并將該邊的內(nèi)容刪除,將該節(jié)點(diǎn)壓入訪問節(jié)點(diǎn)堆棧中,該堆棧中的元素不重復(fù); c)沿著這條邊訪問以它為進(jìn)入邊的鄰接節(jié)點(diǎn); d)如果鄰接節(jié)點(diǎn)不為決策圖的出口點(diǎn),并且內(nèi)容不為空,轉(zhuǎn)到b),如果內(nèi)容為空則轉(zhuǎn)f); e)如果鄰接節(jié)點(diǎn)為決策圖的出口點(diǎn),則轉(zhuǎn)到f); f)如果訪問節(jié)點(diǎn)堆棧不為空,則從堆棧中依次彈出一個(gè)節(jié)點(diǎn),直到該節(jié)點(diǎn)的內(nèi)容不為空,轉(zhuǎn)到b),否則轉(zhuǎn)到g); g)本次搜索完畢。
全文摘要
本發(fā)明屬于計(jì)算機(jī)軟件安全測(cè)試領(lǐng)域,提供了一種緩解路徑爆炸的動(dòng)態(tài)符號(hào)執(zhí)行方法。其旨在與提供一種解決路徑爆炸問題的方法,該方法通過將符號(hào)執(zhí)行產(chǎn)生的約束條件在程序靜態(tài)決策圖上的一次映射、獲取過程,能夠消除程序執(zhí)行過程中循環(huán)產(chǎn)生的冗余約束條件,從而消除動(dòng)態(tài)符號(hào)執(zhí)行中因循環(huán)而導(dǎo)致的路徑爆炸問題。本發(fā)明應(yīng)用于軟件測(cè)試。
文檔編號(hào)G06F11/36GK102708045SQ201210106958
公開日2012年10月3日 申請(qǐng)日期2012年4月13日 優(yōu)先權(quán)日2012年4月13日
發(fā)明者侯浩俊, 吉小麗, 張小松, 朱聰, 陳廳 申請(qǐng)人:電子科技大學(xué)