亚洲成年人黄色一级片,日本香港三级亚洲三级,黄色成人小视频,国产青草视频,国产一区二区久久精品,91在线免费公开视频,成年轻人网站色直接看

一種基于動(dòng)態(tài)符號(hào)執(zhí)行的軟件缺陷檢測(cè)方法與流程

文檔序號(hào):12747925閱讀:377來(lái)源:國(guó)知局

本發(fā)明屬于計(jì)算機(jī)領(lǐng)域,具體涉及一種基于動(dòng)態(tài)符號(hào)執(zhí)行的軟件缺陷檢測(cè)方法。



背景技術(shù):

源程序經(jīng)過編譯器clang編譯可以生成LLVM(底層虛擬機(jī))中間碼,根據(jù)不同的LLVM中間碼指令類型進(jìn)行分類插樁,插樁操作需要使用LLVM官方源碼的API接口。其中,插樁即利用LLVM官方源碼的API接口在源程序編譯得到的LLVM中間碼中插入預(yù)設(shè)指令,通常包括符號(hào)執(zhí)行和缺陷提取指令等。

符號(hào)執(zhí)行技術(shù)包括傳統(tǒng)符號(hào)執(zhí)行、選擇性符號(hào)執(zhí)行和動(dòng)態(tài)符號(hào)執(zhí)行。傳統(tǒng)的符號(hào)執(zhí)行技術(shù)通過使用符號(hào)變量代替真實(shí)變量模擬程序的執(zhí)行,目標(biāo)程序并不真實(shí)運(yùn)行,因此符號(hào)執(zhí)行得到的程序中的約束條件信息不夠精確;選擇性符號(hào)執(zhí)行可以只對(duì)程序員感興趣的代碼進(jìn)行符號(hào)執(zhí)行,其它地方都使用真實(shí)值執(zhí)行,因此選擇性符號(hào)執(zhí)行具有更高的靈活性;動(dòng)態(tài)符號(hào)執(zhí)行技術(shù)與前兩者都有所不同,動(dòng)態(tài)符號(hào)執(zhí)行是在程序真實(shí)執(zhí)行的過程中同時(shí)進(jìn)行符號(hào)執(zhí)行,符號(hào)執(zhí)行是在插樁后的樁函數(shù)內(nèi)執(zhí)行完成,即在真實(shí)執(zhí)行的過程中通過樁函數(shù)收集約束相關(guān)信息生成路徑約束條件,然后通過約束求解器(如SMT(Satisfiability Modulo Theories)求解器)對(duì)其中一條約束條件取非構(gòu)造出一條新的程序執(zhí)行路徑并求解得到滿足這條新路徑的輸入案例,其中,使用約束求解器求解,即求解得到滿足對(duì)應(yīng)約束條件的程序輸入變量值。由于動(dòng)態(tài)符號(hào)執(zhí)行是在程序真實(shí)執(zhí)行過程中收集約束條件,因此,收集到的約束條件更加精確,生成的測(cè)試案例有效性更高。

軟件質(zhì)量問題在軟件使用非常普遍的今天已經(jīng)越來(lái)越受到人們的重視,軟件缺陷檢測(cè)也日益被越來(lái)越多的研究者和軟件廠商關(guān)注,由于軟件質(zhì)量問題造成重大損失的事件也是不勝枚舉。常見的軟件開發(fā)工具如visual studio、eclipse等可以檢查出一些軟件程序中存在的語(yǔ)法錯(cuò)誤和一些簡(jiǎn)單的邏輯錯(cuò)誤,無(wú)法深入準(zhǔn)確地分析程序執(zhí)行過程中所有可能存在的錯(cuò)誤,就算是專業(yè)的程序缺陷檢測(cè)工具如valgrind也只能檢測(cè)程序一次運(yùn)行過程中所在路徑上的錯(cuò)誤,無(wú)法更加全面地檢測(cè)程序中各個(gè)分支中潛在的缺陷。常規(guī)的軟件測(cè)試也很難發(fā)現(xiàn)程序中隱藏較深的緩沖區(qū)溢出和內(nèi)存泄露等錯(cuò)誤,由于生成的測(cè)試案例對(duì)程序分支覆蓋度的限制也無(wú)法非常全面高效地檢測(cè)程序中的缺陷。



技術(shù)實(shí)現(xiàn)要素:

本發(fā)明基于動(dòng)態(tài)符號(hào)執(zhí)行,在動(dòng)態(tài)符號(hào)執(zhí)行生成的測(cè)試案例對(duì)應(yīng)的每條分支路徑上進(jìn)行缺陷檢測(cè)。因此,本發(fā)明的基于動(dòng)態(tài)符號(hào)執(zhí)行的軟件缺陷檢測(cè)方法包括以下步驟:

步驟1:對(duì)待檢測(cè)的軟件的源程序中的變量添加符號(hào)化標(biāo)識(shí),然后對(duì)源程序進(jìn)行編譯處理得到底層虛擬機(jī)LLVM中間碼;

步驟2:根據(jù)指令類型,對(duì)LLVM中間碼進(jìn)行分類插樁處理,插入符號(hào)執(zhí)行和缺陷檢測(cè)指令;

步驟3:將插樁處理后的LLVM中間碼編譯生成可執(zhí)行文件;

步驟4:基于生成的可執(zhí)行文件,進(jìn)行動(dòng)態(tài)符號(hào)執(zhí)行與缺陷檢測(cè):

401:基于測(cè)試案例運(yùn)行可執(zhí)行文件(每次運(yùn)行可執(zhí)行文件中的對(duì)應(yīng)程序的一條分支路徑)生成執(zhí)行結(jié)果,即生成對(duì)應(yīng)的條件表達(dá)式,包括符號(hào)執(zhí)行約束條件表達(dá)式集合、缺陷檢測(cè)條件表達(dá)式集合。其中,測(cè)試案例的初始值為隨機(jī)輸入。

在基于測(cè)試案例運(yùn)行可執(zhí)行文件時(shí),可能只生成符號(hào)執(zhí)行約束條件表達(dá)式集合,也可能同時(shí)生成符號(hào)執(zhí)行約束條件表達(dá)式集合和缺陷檢測(cè)條件表達(dá)式集合;若當(dāng)前執(zhí)行結(jié)果存在缺陷檢測(cè)條件表達(dá)式集合,則將當(dāng)前生成的符號(hào)執(zhí)行約束條件表達(dá)式集合和缺陷檢測(cè)條件表達(dá)式集合作為一個(gè)隊(duì)列元素存入預(yù)設(shè)隊(duì)列L中(隊(duì)列L用于軟件缺陷判定),實(shí)現(xiàn)隊(duì)列L的更新;

在生成執(zhí)行結(jié)果后,并行執(zhí)行步驟402、403,即基于生成的符號(hào)執(zhí)行約束條件表達(dá)式集合執(zhí)行步驟402;在執(zhí)行步驟403時(shí),若隊(duì)列L有更新,則基于更新后的隊(duì)列L執(zhí)行步驟403;若無(wú)更新,則直接基于原有的隊(duì)列L執(zhí)行步驟403;

402:判斷所有生成的符號(hào)執(zhí)行約束條件表達(dá)式是否均已取非,若是,則測(cè)試案例生成結(jié)束,并設(shè)置軟件檢測(cè)結(jié)束標(biāo)識(shí);否則,將其中一個(gè)符號(hào)執(zhí)行約束條件表達(dá)式取非并通過第一約束求解器進(jìn)行測(cè)試案例求解,若有解,則將當(dāng)前求解結(jié)果作為測(cè)試案例并執(zhí)行步驟401;若無(wú)解,則繼續(xù)執(zhí)行步驟402;

403:判斷隊(duì)列L是否為空,若為空,則檢測(cè)是否存在軟件檢測(cè)結(jié)束標(biāo)識(shí),若是,則結(jié)束軟件缺陷檢測(cè);若否,則繼續(xù)執(zhí)行步驟403;

若隊(duì)列L不為空,則從隊(duì)列L中取出一個(gè)隊(duì)列元素A并執(zhí)行步驟404,其中隊(duì)列元素A包括符號(hào)執(zhí)行約束條件表達(dá)式集合S和缺陷條件表達(dá)式集和R;

步驟404:從集合R中取出一個(gè)未被求解的缺陷條件表達(dá)式r,將r與集合S合并得到新的條件表達(dá)式集合(r∩S)并通過第二約束求解器進(jìn)行缺陷判定求解,若有解,則顯示對(duì)應(yīng)r的缺陷類型;若無(wú)解,則判斷集合R是否為空,若是,則執(zhí)行步驟403;否則,執(zhí)行步驟404。

本發(fā)明基于動(dòng)態(tài)符號(hào)執(zhí)行,在動(dòng)態(tài)符號(hào)執(zhí)行生成的測(cè)試案例對(duì)應(yīng)的每條分支路徑上進(jìn)行缺陷檢測(cè),能全面地檢測(cè)程序中各個(gè)分支中潛在的缺陷。同時(shí),由于程序執(zhí)行一條路徑上很多個(gè)地方都可能存在缺陷,所以一次符號(hào)執(zhí)行求解可能會(huì)得到很多個(gè)缺陷檢測(cè)條件表達(dá)式,因此在符號(hào)執(zhí)行的基礎(chǔ)上缺陷約束條件表達(dá)式的求解又會(huì)花費(fèi)很多時(shí)間。為了解決這個(gè)問題,本發(fā)明采用多線程技術(shù)將符號(hào)執(zhí)行約束條件表達(dá)式求解和缺陷檢測(cè)條件表達(dá)式求解分離,分別在兩個(gè)不同的線程(本發(fā)明的第一約束求解器和第二約束求解器)上并行執(zhí)行,從而大大提高求解效率,提高軟件缺陷檢測(cè)效率。

進(jìn)一步的,本發(fā)明中對(duì)LLVM中間碼進(jìn)行分類插樁處理具體為:

若當(dāng)前指令是主函數(shù)入口的第一條指令,則在當(dāng)前指令之前插入第一樁函數(shù),第一樁函數(shù)用于讀入符號(hào)化變量的值;

若當(dāng)前指令為主函數(shù)的最后一條指令,則在當(dāng)前指令之前插入第二樁函數(shù),第二樁函數(shù)用于檢測(cè)內(nèi)存泄漏;

若當(dāng)前指令為非主函數(shù)(普通函數(shù))的第一條指令,則在當(dāng)前指令之前插入第三樁函數(shù),第三樁函數(shù)用于標(biāo)記所述普通函數(shù);

若當(dāng)前指令為分配指令,則判斷分配指令是否用于申請(qǐng)數(shù)組空間,若是,則插入第四樁函數(shù),第四樁函數(shù)用于傳遞數(shù)組信息;

若當(dāng)前指令為加載指令,則插入第五樁函數(shù),第五樁函數(shù)用于獲取加載指令參數(shù)的地址;

若當(dāng)前指令為存儲(chǔ)指令,則插入第六樁函數(shù),第六樁函數(shù)用于提取存儲(chǔ)指令的參數(shù)、并存儲(chǔ)符號(hào)執(zhí)行產(chǎn)生的新的符號(hào)變量;

若當(dāng)前指令為二元運(yùn)算指令,則插入第七樁函數(shù),第七樁函數(shù)用于加載二元運(yùn)算指令的參數(shù),用符號(hào)值模擬二元指令運(yùn)算;

若當(dāng)前指令為比較指令,則插入第八樁函數(shù),第八樁函數(shù)用于加載比較指令的參數(shù),模擬比較指令的比較運(yùn)算;

若當(dāng)前指令為分支指令,則插入第九樁函數(shù),第九樁函數(shù)用于標(biāo)記當(dāng)前程序分支;

若當(dāng)前指令為返回指令,則插入第十樁函數(shù),第十樁函數(shù)用于加載返回指令的參數(shù)、并處理返回指令的返回結(jié)果;

若當(dāng)前指令為函數(shù)調(diào)用指令,則判斷調(diào)用函數(shù)是否為分配內(nèi)存或釋放內(nèi)存,若是,則插入第十一樁函數(shù),第十一樁函數(shù)用于檢測(cè)內(nèi)存多次釋放;否則插入第十二樁函數(shù),第十二樁函數(shù)用于加載調(diào)用函數(shù)的參數(shù)并對(duì)函數(shù)返回結(jié)果做處理;

若當(dāng)前指令為轉(zhuǎn)換指令,則插入第十三樁函數(shù),第十三樁函數(shù)用于描述轉(zhuǎn)換關(guān)系;

若當(dāng)前指令為取元素指令,則插入第十四樁函數(shù),第十四樁函數(shù)用于檢測(cè)所取元素是否存在數(shù)組或指針越界。即根據(jù)取元素指令的參數(shù)獲取訪問空間的范圍和當(dāng)前訪問的位置然后比較當(dāng)前訪問的空間是否在合法的區(qū)域,如果是則沒有發(fā)生越界,否則發(fā)生越界。

綜上所述,由于采用了上述方案,本發(fā)明的有益效果是:能全面地檢測(cè)程序中各個(gè)分支中潛在的缺陷,且缺陷檢測(cè)效率高。

具體實(shí)施方式

為使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面結(jié)合實(shí)施方式,對(duì)本發(fā)明作進(jìn)一步地詳細(xì)描述。

實(shí)施例

以待檢測(cè)軟件為C/C++語(yǔ)言編寫的源程序?yàn)槔?,采用本發(fā)明的基于動(dòng)態(tài)符號(hào)執(zhí)行的軟件缺陷檢測(cè)方法完成待檢測(cè)軟件的缺陷檢測(cè),其具體包括下列步驟:

步驟1:在C/C++語(yǔ)言源程序中添加符號(hào)化標(biāo)識(shí),被標(biāo)識(shí)的變量在程序執(zhí)行過程中會(huì)作為符號(hào)變量,由它們賦值得到的變量也會(huì)成為符號(hào)化變量??梢灾С謽?biāo)識(shí)的變量類型包括:short int;int;unsigned int;char;unsigned char;float;float;double等。

然后基于編譯工具clang對(duì)符號(hào)化標(biāo)識(shí)處理后的源程序進(jìn)行編譯處理,生成LLVM中間碼。

步驟2:對(duì)生成的LLVM中間碼,根據(jù)指令類型進(jìn)行分類插樁處理:

若當(dāng)前指令是main函數(shù)(主函數(shù))入口的第一條指令,則在當(dāng)前指令之前插入用于讀入符號(hào)化變量的值的樁函數(shù);若當(dāng)前指令為主函數(shù)的最后一條指令,則在當(dāng)前指令之前插入用于檢測(cè)內(nèi)存泄漏的樁函數(shù);然后逐條判斷LLVM中間碼的各指令類型并插入對(duì)應(yīng)樁函數(shù):

若當(dāng)前指令為AllocaInst指令(分配指令),則繼續(xù)判斷當(dāng)前指令是否為申請(qǐng)數(shù)組空間,若是,則獲取所申請(qǐng)數(shù)組空間大小,并插入傳遞數(shù)組信息的樁函數(shù);若否,則跳過當(dāng)前指令,繼續(xù)處理下一條指令;

若當(dāng)前指令為StoreInst指令(存儲(chǔ)指令),則插入樁函數(shù),該樁函數(shù)用于提取存儲(chǔ)指令的參數(shù),并存儲(chǔ)符號(hào)執(zhí)行產(chǎn)生的新的符號(hào)變量加載存儲(chǔ)指令的參數(shù);

若當(dāng)前指令為L(zhǎng)oadInst指令(加載指令),則插入用于獲取LoadInst指令參數(shù)的地址的樁函數(shù);

若當(dāng)前指令為CmpInst指令(比較指令),則插入樁函數(shù),該樁函數(shù)用于加載CmpInst指令的參數(shù),模擬CmpInst指令的比較運(yùn)算;

若當(dāng)前指令為BranchInst指令(分支指令),則插入用于標(biāo)記當(dāng)前程序分支的樁函數(shù);

若當(dāng)前指令為CastInst指令(轉(zhuǎn)換指令),則插入用于存儲(chǔ)CastInst指令相關(guān)的參數(shù)關(guān)系的樁函;

若當(dāng)前指令為GetElementPtrInst指令(取元素指令),根據(jù)GetElementPtrInst指令的參數(shù)插入用于檢測(cè)是否存在數(shù)組或者指針的越界的樁函數(shù);

若當(dāng)前指令為BinaryOperator(二元運(yùn)算指令)指令,則插入樁函數(shù),該樁函數(shù)用于加載二元運(yùn)算指令的參數(shù),用符號(hào)值模擬二元指令運(yùn)算的樁函數(shù);

若當(dāng)前指令為ReturnInst指令(返回指令),則插入樁函數(shù),該樁函數(shù)用于加載ReturnInst指令的參數(shù),處理ReturnInst指令的返回結(jié)果。

若當(dāng)前指令為CallInst指令(函數(shù)調(diào)用指令),則判斷所調(diào)用的是否為分配內(nèi)存或釋放內(nèi)存的函數(shù),即是否為malloc或free函數(shù),若是,則插入用于檢測(cè)所調(diào)用函數(shù)是否存在內(nèi)存多次釋放的樁函數(shù);否則插入用于加載所調(diào)用函數(shù)的參數(shù)并對(duì)函數(shù)返回結(jié)果做處理的樁函數(shù)。

即在本實(shí)施例中,若當(dāng)前指令為上述AllocaInst指令、StoreInst指令、CmpInst指令、BranchInst指令、LoadInst指令、CastInst指令、GetElementPtrInst指令、CallInst指令、BinaryOperator指令、ReturnInst指令中的任一一類時(shí),則插入對(duì)應(yīng)的樁函數(shù);若當(dāng)前指令為其他類型時(shí),則直接跳過,即不處理。

步驟3:將插樁處理后的LLVM中間碼編譯生成可執(zhí)行文件test。

步驟4:基于生成的可執(zhí)行文件test,進(jìn)行動(dòng)態(tài)符號(hào)執(zhí)行與缺陷檢測(cè)。

步驟4-1:基于測(cè)試案例通過系統(tǒng)調(diào)用命令調(diào)用可執(zhí)行文件test運(yùn)行,生成執(zhí)行結(jié)果,test首次運(yùn)行使用隨機(jī)輸入,假設(shè)產(chǎn)生的隨機(jī)值大于8,則生成符號(hào)執(zhí)行約束條件表達(dá)式i≥8,并將其傳遞給第一約束求解器,跳轉(zhuǎn)到步驟4-2;

步驟4-2:同時(shí)執(zhí)行4-2-1和4-2-2;

步驟4-2-1:第一約束求解器得到符號(hào)執(zhí)行約束條件表達(dá)式后求解,由于約束條件i≥8未被標(biāo)記為已經(jīng)取非過,取非后得到i<8,并通過第一約束求解器進(jìn)行測(cè)試案例求解,假設(shè)求解出的結(jié)果是7,然后基于當(dāng)前求解結(jié)果執(zhí)行可執(zhí)行文件test,即跳轉(zhuǎn)步驟步驟4-1.1;

步驟4-2-2:當(dāng)前不存在軟件檢測(cè)結(jié)束標(biāo)識(shí),即符號(hào)執(zhí)行未結(jié)束,對(duì)于i≥8,由于沒有生成任何缺陷檢測(cè)相關(guān)的約束條件,所以此次符號(hào)執(zhí)行對(duì)應(yīng)路徑上沒有缺陷檢測(cè)可檢測(cè)的地方。跳轉(zhuǎn)到步驟4-2-3;

步驟4-2-3:預(yù)設(shè)隊(duì)列L為空,跳轉(zhuǎn)到步驟4-2-2執(zhí)行,等待L不為空或者系統(tǒng)運(yùn)行結(jié)束(L為空且符號(hào)執(zhí)行結(jié)束);

步驟4-1.1:輸入測(cè)試案例值7,讓可執(zhí)行文件test讀取此測(cè)試案例值并執(zhí)行,然后會(huì)生成新的符號(hào)執(zhí)行約束條件表達(dá)式i<8和缺陷檢測(cè)條件表達(dá)式i≥5;因當(dāng)前執(zhí)行結(jié)果存在缺陷檢測(cè)條件表達(dá)式,則將i<8和i≥5作為一個(gè)隊(duì)列元素存入隊(duì)列L中。跳轉(zhuǎn)到步驟4-2.1;

步驟4-2.1:同時(shí)執(zhí)行4-2-1.1和4-2-2.1;

步驟4-2-1.1:由于符號(hào)執(zhí)行沒有發(fā)現(xiàn)新的約束條件,所以符號(hào)執(zhí)行結(jié)束,設(shè)置軟件檢測(cè)結(jié)束標(biāo)識(shí);

步驟4-2-2.1:符號(hào)執(zhí)行已經(jīng)結(jié)束但隊(duì)列不為空,跳轉(zhuǎn)到步驟4-2-3.1;

步驟4-2-3.1:L不為空,從隊(duì)列中取出隊(duì)列元素:i≥5和i<8,跳轉(zhuǎn)到步驟4-2-4;

步驟4-2-4:由于缺陷檢測(cè)條件表達(dá)式i≥5未被求解,因此將i≥5和i<8合并得到5≤i<8,然后對(duì)5≤i<8通過第二約束求解器進(jìn)行缺陷判定求解,當(dāng)前有解,則轉(zhuǎn)至步驟4-2-5;

步驟4-2-5:顯示對(duì)應(yīng)i≥5的缺陷類型,如程序第9行存在越界。跳轉(zhuǎn)到步驟4-2-4.1;

步驟4-2-4.1:所有的缺陷條件表達(dá)式已經(jīng)求解完,跳轉(zhuǎn)到步驟4-2-3.2;

步驟4-2-3.2:隊(duì)列L為空,跳轉(zhuǎn)到步驟4-2-2.2;

步驟4-2-2.2:隊(duì)列L為空且符號(hào)執(zhí)行已經(jīng)結(jié)束,所以缺陷求檢查結(jié)束,軟件缺陷檢測(cè)完畢。

以上所述,僅為本發(fā)明的具體實(shí)施方式,本說(shuō)明書中所公開的任一特征,除非特別敘述,均可被其他等效或具有類似目的的替代特征加以替換;所公開的所有特征、或所有方法或過程中的步驟,除了互相排斥的特征和/或步驟以外,均可以任何方式組合。

當(dāng)前第1頁(yè)1 2 3 
網(wǎng)友詢問留言 已有0條留言
  • 還沒有人留言評(píng)論。精彩留言會(huì)獲得點(diǎn)贊!
1