两个人的电影免费视频_国产精品久久久久久久久成人_97视频在线观看播放_久久这里只有精品777_亚洲熟女少妇二三区_4438x8成人网亚洲av_内谢国产内射夫妻免费视频_人妻精品久久久久中国字幕

一種程序控制流錯(cuò)誤檢測(cè)方法

文檔序號(hào):6584136閱讀:704來(lái)源:國(guó)知局
專利名稱:一種程序控制流錯(cuò)誤檢測(cè)方法
技術(shù)領(lǐng)域
本發(fā)明涉及一種針對(duì)程序控制流錯(cuò)誤的檢測(cè)方法,尤其是對(duì)在空間輻射環(huán)境下由硬件瞬態(tài)故障所導(dǎo)致的控制流錯(cuò)誤進(jìn)行檢測(cè)的方法。

背景技術(shù)
空間探測(cè)活動(dòng)投入大、風(fēng)險(xiǎn)高,對(duì)計(jì)算可靠性有著極高的要求。太空中影響空間探測(cè)器安全的主要因素是宇宙射線的輻射,因?yàn)橛钪姝h(huán)境中存在大量包括電子、質(zhì)子、粒子和重離子在內(nèi)的高能粒子,當(dāng)由這些粒子構(gòu)成的宇宙射線轟擊航天計(jì)算機(jī)的半導(dǎo)體電路時(shí),就可能導(dǎo)致PN結(jié)構(gòu)中的存儲(chǔ)電量發(fā)生瞬態(tài)變化,這種瞬態(tài)故障通常也被稱為單粒子效應(yīng)SEE(Single Event Effect)。雖然單粒子效應(yīng)一般不會(huì)對(duì)硬件設(shè)備造成持久傷害,但是卻可以通過(guò)改變傳輸信號(hào)和存儲(chǔ)單元值等方式影響系統(tǒng)的正常運(yùn)行,嚴(yán)重時(shí)甚至?xí)斐上到y(tǒng)崩潰,所以一直是航天計(jì)算機(jī)所面臨的最主要威脅之一。而現(xiàn)代處理器逐步采用深亞微米制造工藝,在性能得到大幅提高的同時(shí),處理器對(duì)于能引起瞬態(tài)故障的各種噪聲干擾也變得越來(lái)越敏感,同時(shí)單芯片所集成的晶體管數(shù)呈指數(shù)級(jí)增長(zhǎng),也使得芯片整體的瞬態(tài)故障率快速增加。當(dāng)前,在繼性能和功耗之后,瞬態(tài)故障所導(dǎo)致的處理器可信性問題已日益成為業(yè)界關(guān)注的熱點(diǎn)。
硬件瞬態(tài)故障對(duì)系統(tǒng)可靠性影響的具體體現(xiàn)可分為數(shù)據(jù)流錯(cuò)誤和控制流錯(cuò)誤。數(shù)據(jù)流錯(cuò)誤主要指故障影響應(yīng)用程序使用的寄存器和存儲(chǔ)器中的數(shù)據(jù)等;而控制流錯(cuò)誤指的是故障改變了程序正常執(zhí)行軌跡,例如一條存儲(chǔ)指令被SEE篡改成分支指令,無(wú)條件跳轉(zhuǎn)指令的目標(biāo)地址被瞬態(tài)故障臨時(shí)修改。當(dāng)發(fā)生控制流錯(cuò)誤后,程序行為會(huì)變得復(fù)雜且難以預(yù)測(cè)有時(shí)由于執(zhí)行了非法的指令而被操作系統(tǒng)或底層硬件檢測(cè)出,也有可能導(dǎo)致程序進(jìn)入死循環(huán),最壞的情況是程序正常退出而執(zhí)行結(jié)果卻是錯(cuò)誤的。以往的實(shí)際經(jīng)驗(yàn)和各種故障注入實(shí)驗(yàn)結(jié)果表明,控制流錯(cuò)誤占瞬態(tài)故障所引起的各種系統(tǒng)錯(cuò)誤總數(shù)的33%~77%。所以,對(duì)于航天計(jì)算機(jī)這樣的高可靠計(jì)算機(jī)系統(tǒng)來(lái)說(shuō),必須具備一定的控制流錯(cuò)誤檢測(cè)能力。
在空間環(huán)境中,為了防止空間輻射的影響,航天計(jì)算機(jī)一般使用經(jīng)過(guò)特殊硬件工藝設(shè)計(jì)與加工的抗輻照器件。抗輻照器件通過(guò)硬件冗余實(shí)現(xiàn)容錯(cuò),具有很高的可靠性,能夠有效解決空間輻射所導(dǎo)致的硬件瞬態(tài)故障問題。但是抗輻照器件設(shè)計(jì)非常復(fù)雜、研制周期長(zhǎng)、產(chǎn)業(yè)規(guī)模和產(chǎn)量都很小、價(jià)格非常昂貴,而且抗輻照器件的性能通常落后于同時(shí)代的商用器件COTS(Commercial Off-The-Shelf)很多代。此外,目前專門針對(duì)控制流錯(cuò)誤也已提出一些通過(guò)改造硬件實(shí)現(xiàn)的檢測(cè)技術(shù),例如Watchdog輔助處理器技術(shù)。Watchdog技術(shù)先對(duì)程序的控制流結(jié)構(gòu)進(jìn)行分析,并為這種高層結(jié)構(gòu)附上標(biāo)簽,然后由Watchdog處理器在運(yùn)行時(shí)監(jiān)測(cè)主處理器產(chǎn)生的總線事務(wù)。但是這種技術(shù)對(duì)于具有緩存的現(xiàn)代主處理器無(wú)法使用,除非協(xié)處理器是主處理器的一部分。總的來(lái)說(shuō),基于硬件實(shí)現(xiàn)的容錯(cuò)技術(shù)或需要修改硬件的體系結(jié)構(gòu),或要開發(fā)和配置具有檢錯(cuò)能力的專門設(shè)備,實(shí)現(xiàn)成本太高是主要問題。
計(jì)算機(jī)發(fā)展的歷史表明,很多原本用硬件實(shí)現(xiàn)的方法同樣可以用軟件來(lái)實(shí)現(xiàn),在COTS微處理器上,通過(guò)實(shí)現(xiàn)面向硬件瞬態(tài)故障的軟件容錯(cuò)技術(shù)可以彌補(bǔ)COTS器件在容錯(cuò)能力方面的不足。國(guó)內(nèi)外已經(jīng)開展很多實(shí)驗(yàn)探討在空間環(huán)境中應(yīng)用COTS處理器,結(jié)果表明面向硬件故障的軟件容錯(cuò)方法可以有效提高基于COTS器件的空間計(jì)算機(jī)的可靠性,能夠很好地應(yīng)對(duì)空間輻射的影響,同時(shí)在COTS器件上利用軟件容錯(cuò)方法所實(shí)現(xiàn)的性能可以比抗輻照器件高一個(gè)數(shù)量級(jí),而成本卻要降低一個(gè)數(shù)量級(jí)。所以,隨著計(jì)算機(jī)硬件資源的極大豐富,以犧牲部分性能來(lái)?yè)Q取較高的可靠性已成為可能,并且軟件容錯(cuò)方法在成本、功耗和靈活性方面都有擁有巨大的優(yōu)勢(shì)。實(shí)際上,基于COTS器件的軟件容錯(cuò)方法目前已經(jīng)成為各國(guó)航天領(lǐng)域的核心機(jī)密技術(shù)之一! 針對(duì)控制流錯(cuò)誤,目前軟件容錯(cuò)方法通常是以基本塊為單位,在程序正常指令流中插入一些額外指令以實(shí)現(xiàn)對(duì)程序的控制流的校驗(yàn)。一個(gè)基本塊是一個(gè)依次順序執(zhí)行的指令序列,其中除最后一條指令外其他指令都不能是程序控制指令(程序控制指令指能夠改變程序原來(lái)執(zhí)行順序的指令,通常包括條件分支指令、無(wú)條件跳轉(zhuǎn)指令、函數(shù)調(diào)用指令和函數(shù)返回指令等),除第一條指令外其它指令都不能是程序控制指令的轉(zhuǎn)移目標(biāo)?;诨緣K,程序可以表示為由基本塊以及連接基本塊之間的有向邊所構(gòu)成的控制流圖,其中的有向邊表示實(shí)際的程序控制流轉(zhuǎn)移。如果從基本塊Bi到基本塊Bj有一條邊,則表示程序中存在Bi到Bj的路由,Bi記為Bj的前驅(qū)基本塊,Bj記為Bi的后繼基本塊。
程序運(yùn)行時(shí),在執(zhí)行一個(gè)指令后會(huì)轉(zhuǎn)向執(zhí)行另一條指令,這個(gè)過(guò)程稱為一次控制流轉(zhuǎn)移?;诨緣K和程序控制流圖,合法的控制流轉(zhuǎn)移有下面兩層含義 1)基本塊內(nèi)部控制流轉(zhuǎn)移發(fā)生在一個(gè)基本塊內(nèi)部。由于基本塊內(nèi)部指令順序執(zhí)行,所以除了塊最后一條指令外,每個(gè)指令只有唯一的后繼指令。
2)基本塊之間控制流轉(zhuǎn)移發(fā)生在基本塊之間。對(duì)于基本塊的最后一條指令,其后繼指令可能有多個(gè),但都必須是控制流圖中所屬基本塊的后繼基本塊的第一條指令。
除此之外的所有控制流轉(zhuǎn)移都是非法的,控制流錯(cuò)誤檢測(cè)技術(shù)的目標(biāo)就是要盡可能高效地檢測(cè)出所有非法的控制流轉(zhuǎn)移。
當(dāng)前,軟件實(shí)現(xiàn)的控制流檢測(cè)方法通常采用基于基本塊的標(biāo)簽分析法(SignatureAnalysis)?;緣K標(biāo)簽是基本塊的數(shù)字標(biāo)識(shí),在預(yù)處理(如編譯)時(shí)為每個(gè)基本塊分配唯一的標(biāo)簽(稱為靜態(tài)標(biāo)簽AS,Assigned Signature),程序在運(yùn)行過(guò)程中根據(jù)當(dāng)前控制流由插入的檢測(cè)指令維持一個(gè)標(biāo)簽(稱為動(dòng)態(tài)標(biāo)簽DS,Dynamic Signature),然后將兩個(gè)標(biāo)簽進(jìn)行比較,匹配則說(shuō)明控制流沒有被破壞,否則表示控制流出現(xiàn)了錯(cuò)誤。
美國(guó)斯坦福大學(xué)提出的CFCSS方法就是這方面的典型代表。作為針對(duì)基本塊之間的控制流錯(cuò)誤進(jìn)行檢測(cè)的方法,CFCSS在編譯時(shí)為每個(gè)基本塊生成一個(gè)靜態(tài)標(biāo)簽,并且為每個(gè)基本塊計(jì)算與其前驅(qū)基本塊的靜態(tài)標(biāo)簽之間的異或差異值D。在運(yùn)行時(shí),CFCSS使用一個(gè)通用寄存器G保存產(chǎn)生的動(dòng)態(tài)標(biāo)簽。當(dāng)進(jìn)入一個(gè)基本塊后,先將G與當(dāng)前基本塊的D值異或運(yùn)算產(chǎn)生新的動(dòng)態(tài)標(biāo)簽。由于運(yùn)算之前G值等于前驅(qū)基本塊的靜態(tài)標(biāo)簽,所以運(yùn)算得到的結(jié)果應(yīng)該與當(dāng)前基本塊的靜態(tài)標(biāo)簽相等,否則說(shuō)明檢測(cè)到控制流錯(cuò)誤。其他的標(biāo)簽分析法的基本原理與CFCSS相同,只是在基本塊標(biāo)簽和檢測(cè)指令序列的設(shè)計(jì)方面各有區(qū)別,由此導(dǎo)致錯(cuò)誤檢測(cè)率和性能消耗等方面存在差異。
但是總的來(lái)說(shuō),基于軟件實(shí)現(xiàn)的控制流錯(cuò)誤檢測(cè)方法目前主要存在以下幾個(gè)方面的問題 (1)存在檢測(cè)盲點(diǎn)已有方法能夠檢測(cè)出絕大部分的控制流錯(cuò)誤,但是各種方法也都不同程度地存在檢測(cè)盲點(diǎn)。例如CFCSS無(wú)法檢測(cè)從一個(gè)基本塊的內(nèi)部直接跳轉(zhuǎn)到其后繼基本塊的頭部的控制流錯(cuò)誤。單粒子效應(yīng)可能修改控制流指令本身,例如把不等于分支指令變成等于分支指令,這導(dǎo)致條件判斷指令本應(yīng)執(zhí)行THEN分支,結(jié)果錯(cuò)誤地跳轉(zhuǎn)到ELSE分支。由于這種錯(cuò)誤分支在程序控制流結(jié)構(gòu)上是合法的,但語(yǔ)義卻是錯(cuò)誤的,通常被稱為偽分支。偽分支會(huì)導(dǎo)致程序正常退出而執(zhí)行結(jié)果卻是錯(cuò)誤,所以危險(xiǎn)性很大,同時(shí)它也是控制流錯(cuò)誤檢測(cè)中的難點(diǎn),目前很多方法不能解決這個(gè)問題。
(2)基本塊內(nèi)部的控制流錯(cuò)誤檢測(cè)已有的控制流檢測(cè)方法主要關(guān)注基本塊之間的控制流正確性,而對(duì)于基本塊內(nèi)部的控制流錯(cuò)誤并沒有比較完善的解決辦法。有方法在靜態(tài)分析時(shí)對(duì)基本塊包含的指令進(jìn)行計(jì)數(shù),然后運(yùn)行時(shí)每執(zhí)行一條指令則執(zhí)行一條將計(jì)數(shù)減1的指令,當(dāng)執(zhí)行到基本塊出口時(shí),計(jì)數(shù)器的值應(yīng)該為0。但這種方式增加的指令與基本塊本身包含的指令一樣多,對(duì)程序性能影響顯然太大。
(3)過(guò)程間的控制流錯(cuò)誤檢測(cè)這是控制流檢測(cè)中的一個(gè)難點(diǎn)問題。有的方法在實(shí)現(xiàn)時(shí)不考慮過(guò)程間的控制流檢測(cè),即不把函數(shù)調(diào)用指令作為劃分基本塊的一個(gè)依據(jù);有的方法雖然實(shí)現(xiàn)了過(guò)程間的控制流錯(cuò)誤檢測(cè),但是難以處理嵌套調(diào)用和遞歸調(diào)用等復(fù)雜情況。
(4)無(wú)法解決可靠性和性能之間的矛盾為了解決檢測(cè)盲點(diǎn),有些方法設(shè)計(jì)了一些復(fù)雜的檢測(cè)指令序列。但是由于加入了過(guò)多的檢測(cè)指令,對(duì)程序性能的影響也隨之增大,甚至檢測(cè)指令自身受瞬態(tài)故障影響而出錯(cuò)的概率也變大。
因?yàn)橐延熊浖?shí)現(xiàn)的控制流錯(cuò)誤檢測(cè)方法存在上述問題,必須研究檢測(cè)效率更高而對(duì)程序本身性能影響較小的控制流錯(cuò)誤檢測(cè)方法。


發(fā)明內(nèi)容
本發(fā)明要解決的技術(shù)問題是克服已有方法存在的檢測(cè)盲點(diǎn)(如偽分支),提高控制流錯(cuò)誤的檢測(cè)率,解決基本塊內(nèi)部的控制流檢測(cè)和過(guò)程間的控制流檢測(cè)等難點(diǎn)問題,并且對(duì)程序本身性能的影響較小。
為了解決上述技術(shù)問題,本發(fā)明提出的技術(shù)方案為首先,基于程序匯編代碼標(biāo)識(shí)基本塊并確定基本塊之間的路由關(guān)系;然后根據(jù)用戶對(duì)基本塊內(nèi)部控制流檢測(cè)的需求和基本塊的構(gòu)成特征,確定單個(gè)基本塊最多需要多少條內(nèi)部控制流檢測(cè)指令,在此基礎(chǔ)上設(shè)計(jì)基本塊標(biāo)簽,并為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽;最后在程序中的每個(gè)基本塊的頭部、內(nèi)部和尾部分別插入檢測(cè)指令。
具體技術(shù)方案為 第一步,通過(guò)編譯器將需要進(jìn)行控制流錯(cuò)誤檢測(cè)的程序編譯成匯編代碼,例如在GCC中可以使用‘-S’參數(shù)生成匯編程序。
第二步,基于程序匯編代碼標(biāo)識(shí)出程序的基本塊并確定基本塊之間的路由關(guān)系,具體細(xì)分為三個(gè)步驟 2.1依次遍歷程序匯編代碼的指令序列,根據(jù)指令操作碼字段識(shí)別出程序控制指令(程序控制指令指能夠改變程序原來(lái)執(zhí)行順序的指令,通常包括條件分支指令、無(wú)條件跳轉(zhuǎn)指令、函數(shù)調(diào)用指令和函數(shù)返回指令等)。然后基于程序控制指令標(biāo)注基本塊的入口指令,具體方法為所有函數(shù)的第一條指令標(biāo)注為基本塊的入口指令;對(duì)于條件分支指令和無(wú)條件跳轉(zhuǎn)指令,分支或跳轉(zhuǎn)的目標(biāo)指令標(biāo)注為基本塊的入口指令;所有程序控制指令的后繼指令標(biāo)注為基本塊的入口指令。在標(biāo)注入口指令的同時(shí),還根據(jù)指令的操作數(shù)字段識(shí)別出程序中所有使用過(guò)的寄存器,得出哪些寄存器還沒有被程序使用過(guò)。
2.2重新依次遍歷匯編程序的指令序列,將一個(gè)被標(biāo)注為基本塊入口指令到下一個(gè)入口指令之間的指令劃分為一個(gè)基本塊。如果基本塊的入口指令有標(biāo)識(shí)符,就以標(biāo)識(shí)符作為基本塊的名稱?;緣K以函數(shù)為單位按照在程序代碼中出現(xiàn)的順序列表組織,形成函數(shù)基本塊列表,且在函數(shù)基本塊列表中,第一個(gè)基本塊標(biāo)記為函數(shù)入口基本塊,最后一個(gè)基本塊被標(biāo)記為函數(shù)退出基本塊。所有函數(shù)基本塊列表構(gòu)成程序總的基本塊列表。
2.3依次遍歷匯編程序的所有基本塊,按照基本塊的最后一條指令確定基本塊之間的路由關(guān)系,具體方法如下如果基本塊最后一條指令是條件分支指令和無(wú)條件跳轉(zhuǎn)指令,則根據(jù)指令的分支或跳轉(zhuǎn)目標(biāo)地址查找對(duì)應(yīng)的目標(biāo)基本塊,在程序?qū)?yīng)的控制流圖中從當(dāng)前塊向該目標(biāo)基本塊劃一條有向邊;如果基本塊的最后一條指令是條件分支指令或普通指令(即不是無(wú)條件跳轉(zhuǎn)指令、函數(shù)調(diào)用指令和函數(shù)返回指令),則在控制流圖中從當(dāng)前塊向其直接后繼基本塊劃一條有向邊;如果基本塊最后一條指令是函數(shù)調(diào)用指令,則在控制流圖中從當(dāng)前塊向被調(diào)用函數(shù)的入口基本塊劃一條有向邊,并且從被調(diào)用函數(shù)的退出基本塊向當(dāng)前塊在所屬函數(shù)基本塊列表中的下一個(gè)塊劃一條有向邊,表示函數(shù)返回的控制流轉(zhuǎn)移。
第三步,根據(jù)用戶對(duì)基本塊內(nèi)部控制流錯(cuò)誤檢測(cè)的需求和基本塊的構(gòu)成特征,設(shè)計(jì)基本塊標(biāo)簽(含靜態(tài)標(biāo)簽和動(dòng)態(tài)標(biāo)簽)的格式,并為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽?;緣K內(nèi)部控制流錯(cuò)誤是很多控制流檢測(cè)方法的檢測(cè)盲點(diǎn),但是基本塊包含的指令數(shù)有限,控制流錯(cuò)誤導(dǎo)致恰好轉(zhuǎn)移到基本塊自身的概率非常小,即內(nèi)部控制流錯(cuò)誤發(fā)生概率比較低。如果每執(zhí)行一條指令就進(jìn)行一次內(nèi)部控制流校驗(yàn),成本顯然太高。一般情況下基本塊所包含的指令數(shù)越多,則出現(xiàn)內(nèi)部控制流錯(cuò)誤的概率越大,所以采用一種可配置的方法——當(dāng)基本塊內(nèi)部的指令計(jì)數(shù)每超過(guò)閾值Ω時(shí)才進(jìn)行一次內(nèi)部控制流校驗(yàn),Ω由用戶根據(jù)可靠性、性能的需求及程序運(yùn)行環(huán)境自定義。具體步驟包括 3.1依次遍歷程序中所有基本塊,根據(jù)基本塊的規(guī)模(即包含指令的條數(shù))對(duì)閾值Ω的比例∑,計(jì)算在該基本塊的內(nèi)部檢測(cè)指令計(jì)數(shù)(即需要多少條內(nèi)部控制流檢測(cè)指令),該內(nèi)部檢測(cè)指令計(jì)數(shù)等于

再根據(jù)程序中每個(gè)基本塊的內(nèi)部檢測(cè)指令計(jì)數(shù),得到整個(gè)程序中所有基本塊最大的內(nèi)部檢測(cè)指令計(jì)數(shù)。
3.2根據(jù)程序中所有基本塊最大的內(nèi)部檢測(cè)指令計(jì)數(shù),設(shè)計(jì)基本塊標(biāo)簽?;緣K標(biāo)簽由基本標(biāo)簽編碼和用于基本塊內(nèi)部控制流檢測(cè)的編碼兩部分組成。每個(gè)基本塊的基本標(biāo)簽編碼是該基本塊在程序總基本塊列表中的序列號(hào)的二進(jìn)制編碼,是唯一的;而基本塊內(nèi)部控制流檢測(cè)的編碼則是該塊所需的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)的二進(jìn)制編碼,占整個(gè)基本塊標(biāo)簽的最末幾位。在基本塊標(biāo)簽的末端為塊內(nèi)部控制流檢測(cè)分配

位編碼,N為3.1步分析得出的整個(gè)程序中一個(gè)基本塊中最多需要的內(nèi)部檢測(cè)指令條數(shù)。
3.3依次為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽。所有靜態(tài)標(biāo)簽中用于基本塊內(nèi)部控制流檢測(cè)的編碼都保持為0。
3.4步驟2.1已確定有哪些寄存器還沒有被程序使用,從這些空閑寄存器中選擇四個(gè)寄存器分別定義為DSR、ASR、SVR和RAR,分別保存程序運(yùn)行過(guò)程中產(chǎn)生的動(dòng)態(tài)標(biāo)簽DS、靜態(tài)標(biāo)簽AS、標(biāo)簽差異值SV(Signature Variance)和函數(shù)調(diào)用返回地址RA(ReturnAddress)。其中,SV是兩個(gè)基本塊的靜態(tài)標(biāo)簽異或運(yùn)算的結(jié)果,具體表征了實(shí)際控制流在基本塊之間的轉(zhuǎn)移。如果程序沒有四個(gè)空閑寄存器可供使用,則通知用戶無(wú)法實(shí)現(xiàn)控制流錯(cuò)誤檢測(cè),用戶可以選擇采用編譯器的其它寄存器分派策略以重新生成匯編程序。
第四步,依次在程序每個(gè)基本塊的頭部、內(nèi)部和尾部分別插入相應(yīng)指令,因?yàn)槌绦蚧緣K是以函數(shù)為單位列表組織,插入控制流檢測(cè)指令時(shí)也是以函數(shù)為單位進(jìn)行。具體步驟包括 4.1進(jìn)入一個(gè)函數(shù)后,首先針對(duì)函數(shù)入口基本塊(記為Bentry)和函數(shù)退出基本塊(記為Bexit)進(jìn)行特殊處理在調(diào)用函數(shù)的基本塊(記為Bcaller)把返回的目的基本塊(即在調(diào)用函數(shù)的基本塊列表中當(dāng)前基本塊的下一個(gè)塊,記為Breturn)的靜態(tài)標(biāo)簽通過(guò)寄存器RAR傳遞給被調(diào)用函數(shù),被調(diào)用函數(shù)的Bentry塊把RAR中的數(shù)據(jù)寫到分配給本函數(shù)的棧區(qū)間,最后被調(diào)用函數(shù)的Bexit塊把保存的Breturn靜態(tài)標(biāo)簽從棧區(qū)間重新讀出,實(shí)現(xiàn)對(duì)過(guò)程間控制流的跟蹤。具體包括三個(gè)步驟 4.1.1首先確定分配給本函數(shù)的棧區(qū)間中是否有空閑單元可用于存放RAR中的數(shù)據(jù)。通常編譯器為每個(gè)函數(shù)實(shí)際分配的棧區(qū)間會(huì)有一些空閑區(qū)域,如果確實(shí)沒有空閑區(qū)域,則修改Bentry塊入口處用于分配棧區(qū)間的指令,使得該函數(shù)的棧區(qū)間有一個(gè)機(jī)器字長(zhǎng)的空閑存儲(chǔ)單元可用于控制流檢測(cè)使用。例如把指令“sub $sp=$sp,36”改成“sub $sp=$sp,40”,可以將函數(shù)的棧區(qū)間增加4個(gè)字節(jié)($sp是棧地址寄存器)。然后從函數(shù)的棧區(qū)間的空閑區(qū)域中,選擇其中一個(gè)機(jī)器字長(zhǎng)的存儲(chǔ)單元,記為mem。
4.1.2在Bentry塊分配棧區(qū)間的指令后加入指令“store RAR,mem”,表示把RAR中的數(shù)據(jù)寫到分配給本函數(shù)棧區(qū)間的mem單元之中。
4.1.3如果Bentry塊入口處修改了分配棧區(qū)間的指令,則相應(yīng)修改Bexit塊入口處回收棧區(qū)間的指令,使得函數(shù)棧區(qū)間的分配和回收保持一致。例如把指令“add $sp=$sp,36”改成“add $sp=$sp,40”。
4.2在當(dāng)前基本塊頭部(即基本塊第一條指令之前,對(duì)于函數(shù)入口基本塊來(lái)說(shuō)則在4.1.2步驟的指令“store RAR,mem”之后)插入指令“xor DSR=DSR,SVR”,表示將動(dòng)態(tài)標(biāo)簽與標(biāo)簽差異值異或運(yùn)算生成新的動(dòng)態(tài)標(biāo)簽。進(jìn)入一個(gè)基本塊時(shí),寄存器DSR值應(yīng)該等于其前驅(qū)基本塊的靜態(tài)標(biāo)簽,SVR中應(yīng)該是前驅(qū)基本塊的靜態(tài)標(biāo)簽與當(dāng)前基本塊的靜態(tài)標(biāo)簽經(jīng)過(guò)異或運(yùn)算得到的標(biāo)簽差異值SV。所以,如果當(dāng)前基本塊不需要進(jìn)行內(nèi)部控制流檢測(cè),指令“xor DSR=DSR,SVR”運(yùn)算結(jié)果會(huì)使得DSR值等于分派給當(dāng)前基本塊的靜態(tài)標(biāo)簽,否則DSR值應(yīng)該等于當(dāng)前基本塊的靜態(tài)標(biāo)簽加上對(duì)應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)。
4.3按照設(shè)定的Ω值,在基本塊內(nèi)部插入將DSR減1的內(nèi)部控制流檢測(cè)指令。依次遍歷基本塊的指令序列,每隔Ω大小的指令數(shù)就插入一條內(nèi)部控制流檢測(cè)指令“sub DSR=DSR,1”,直到剩下的指令總數(shù)不大于Ω值。這樣做的結(jié)果是根據(jù)Ω參數(shù)將基本塊劃分為更小的區(qū)域,每個(gè)小區(qū)域中包含指令數(shù)小于等于Ω,然后在每?jī)蓚€(gè)區(qū)域之間插入的內(nèi)部檢測(cè)指令可以確保執(zhí)行基本塊內(nèi)部指令時(shí)必須經(jīng)過(guò)這些點(diǎn)。如果因?yàn)榘l(fā)生內(nèi)部控制流錯(cuò)誤而繞過(guò)這些內(nèi)部檢測(cè)指令,直接從一個(gè)區(qū)域跳轉(zhuǎn)另一個(gè)區(qū)域,那么執(zhí)行到塊尾時(shí)動(dòng)態(tài)標(biāo)簽中用于塊內(nèi)檢測(cè)的幾位肯定不都為0,即DSR與當(dāng)前基本塊的靜態(tài)標(biāo)簽AS肯定不同,將會(huì)檢測(cè)到該錯(cuò)誤。對(duì)于那些本身包含指令的數(shù)目小于Ω值的基本塊則不需要進(jìn)行內(nèi)部控制流檢測(cè),基本塊內(nèi)部保持不變。
4.4當(dāng)執(zhí)行到一個(gè)基本塊的末尾時(shí),動(dòng)態(tài)標(biāo)簽寄存器DSR的值應(yīng)該等于分配給該塊的靜態(tài)標(biāo)簽。在基本塊的尾部(即基本塊最后一條指令之后,如果最后一條指令是程序控制指令,則在該程序控制指令之前),按照基本塊的類型將DSR與后繼基本塊的靜態(tài)標(biāo)簽進(jìn)行異或運(yùn)算,產(chǎn)生新的標(biāo)簽差異值SV。具體方法如下 4.4.1如果當(dāng)前基本塊既不是函數(shù)調(diào)用基本塊又不是函數(shù)退出基本塊,而且只有一個(gè)后繼基本塊,設(shè)該后繼基本塊靜態(tài)標(biāo)簽為ASnext,則在當(dāng)前基本塊的尾部插入指令“xorSVR=DSR,ASnext”,表示直接把后繼塊的靜態(tài)標(biāo)簽值A(chǔ)Snext與DSR進(jìn)行異或運(yùn)算,求得新的標(biāo)簽差異值后賦給SVR。如果后繼基本塊需要進(jìn)行塊內(nèi)控制流檢測(cè),ASnext等于后繼基本塊靜態(tài)標(biāo)簽加上相應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)。
4.4.2如果當(dāng)前基本塊的最后一條指令是分支指令(即有兩個(gè)合法后繼基本塊),則采取分支預(yù)測(cè)方法提前判斷將要執(zhí)行哪條分支,然后把所預(yù)測(cè)分支對(duì)應(yīng)的后繼基本塊的靜態(tài)標(biāo)簽與DSR進(jìn)行異或運(yùn)算,求得新的標(biāo)簽差異值SV。具體方法是設(shè)ASthen和ASelse分別表示分支條件滿足和不滿足的目的基本塊靜態(tài)標(biāo)簽。首先在當(dāng)前基本塊的尾部插入指令“xor SVR=DSR,ASthen”,表示先假設(shè)分支條件滿足,將DSR與ASthen進(jìn)行異或運(yùn)算求SVR值。然后在“xor SVR=DSR,ASthen”之后插入分支預(yù)測(cè)指令“br L1′,brcond”,分支條件“brcond”與實(shí)際的分支指令相同,而分支的目標(biāo)“L1′”必須是一個(gè)沒有在程序中出現(xiàn)過(guò)的語(yǔ)句標(biāo)示符,具體指向4.5步驟即將插入的校驗(yàn)DSR數(shù)據(jù)的指令。最后在“br L1′,brcond”之后插入指令“xor SVR=DSR,ASelse”,表示將DSR與分支條件不滿足的目的基本塊的靜態(tài)標(biāo)簽進(jìn)行異或運(yùn)算求得SVR值。如果分支條件滿足,分支預(yù)測(cè)指令“br L1′,brcond”執(zhí)行結(jié)果將使得程序跳過(guò)指令“xor SVR=DSR,ASelse”,即SVR中的值是DSR與ASthen異或運(yùn)算的執(zhí)行結(jié)果,否則SVR中的值是DSR與ASelse異或運(yùn)算的運(yùn)算結(jié)果。如果后繼基本塊需要進(jìn)行內(nèi)部控制流檢測(cè),則ASthen或ASelse分別等于其靜態(tài)標(biāo)簽加上對(duì)應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)。
4.4.3如果當(dāng)前基本塊是函數(shù)調(diào)用基本塊,其后續(xù)執(zhí)行的基本塊是被調(diào)用函數(shù)的入口基本塊。先在當(dāng)前基本塊的尾部插入指令“xor SVR=DSR,AScallee”,實(shí)現(xiàn)DSR與被調(diào)用函數(shù)入口基本塊靜態(tài)標(biāo)簽AScallee的異或運(yùn)算,并把標(biāo)簽差異值賦予SVR。然后在“xor SVR=DSR,AScallee”之后插入指令“movRAR=ASreturn”,表示把函數(shù)調(diào)用返回的目的基本塊(即當(dāng)前基本塊在所屬函數(shù)的基本塊列表中的下一個(gè)塊)的靜態(tài)標(biāo)簽ASreturn賦予寄存器RAR。同樣,如果后續(xù)執(zhí)行的被調(diào)用函數(shù)的入口基本塊或者函數(shù)返回的目的基本塊需要進(jìn)行基本塊內(nèi)部的控制流檢測(cè),則AScallee或ASreturn分別等于其靜態(tài)標(biāo)簽加上對(duì)應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)。
4.4.4如果當(dāng)前基本塊是函數(shù)退出基本塊,其后續(xù)執(zhí)行基本塊的靜態(tài)標(biāo)簽由4.1.2步驟存放在本函數(shù)棧區(qū)間的mem存儲(chǔ)單元中。先在當(dāng)前基本塊的尾部插入指令“l(fā)oad RAR,mem”,表示從mem中讀出數(shù)據(jù),寫回到寄存器RAR中。然后在“l(fā)oad RAR,mem”后插入指令“xor SVR=DSR,RAR”,表示將DSR與RAR進(jìn)行異或運(yùn)算求新標(biāo)簽差異值。最后在“xor SVR=DSR,RAR”后插入指令“clear mem”,表示將使用的內(nèi)存單元mem中的數(shù)據(jù)清除。
4.5在基本塊的尾部加入校驗(yàn)DSR數(shù)據(jù)的指令“br faultDet,DSR!=AScurrent”,其中AScurrent表示分派給當(dāng)前基本塊的靜態(tài)標(biāo)簽。當(dāng)正常執(zhí)行到基本塊尾部時(shí),寄存器DSR中的值應(yīng)該等于AScurrent,如果不相同則表示檢測(cè)到控制流錯(cuò)誤,則轉(zhuǎn)向錯(cuò)誤處理例程。該指令放在最后插入可以防止出現(xiàn)在校驗(yàn)指令之后再改變控制流的檢測(cè)盲點(diǎn)。但如果基本塊的最后一條指令是程序控制指令,那么校驗(yàn)DSR數(shù)據(jù)的指令仍要在程序控制指令之前插入。
第五步,通過(guò)編譯器,將插入了控制流檢測(cè)指令的匯編程序重新匯編并鏈接,生成可執(zhí)行的實(shí)現(xiàn)控制流錯(cuò)誤檢測(cè)的程序。
與已有的控制流檢測(cè)方法相比,采用本發(fā)明可以達(dá)到以下技術(shù)效果 (1)本發(fā)明是一種純軟件方法,不需要修改底層機(jī)器硬件。而且本發(fā)明是通過(guò)在程序編譯時(shí)自動(dòng)向程序插裝一些檢測(cè)指令,能夠做到對(duì)用戶屏蔽具體實(shí)現(xiàn),對(duì)被加固的程序也無(wú)特別限制,不需要操作系統(tǒng)的多線程支持。
(2)本發(fā)明對(duì)控制流錯(cuò)誤的檢測(cè)率很高,能夠解決很多傳統(tǒng)軟件實(shí)現(xiàn)的控制流檢測(cè)方法的檢測(cè)盲點(diǎn)。例如偽分支問題,由于本發(fā)明實(shí)現(xiàn)了分支預(yù)測(cè)機(jī)制,在執(zhí)行原有分支指令之前,先執(zhí)行同樣的指令進(jìn)行分支判斷,相當(dāng)于對(duì)分支指令進(jìn)行了冗余計(jì)算,所以能夠過(guò)解決控制流指令本身出錯(cuò)的問題。故障注入實(shí)驗(yàn)的結(jié)果表明,本發(fā)明的控制流錯(cuò)誤檢測(cè)率在99.2%以上。
(3)本發(fā)明能夠有效解決基本塊內(nèi)部的控制流檢測(cè)問題,而且檢測(cè)效率很高。假設(shè)基本塊中原有指令n條,加入了m條的內(nèi)部檢測(cè)指令,如果是按指令數(shù)平均劃分區(qū)域,那么被漏檢的可能向前跳轉(zhuǎn)的內(nèi)部控制流錯(cuò)誤有(m+1)×((n/(m+1))!)個(gè)。假設(shè)所有可能的前向內(nèi)部控制流錯(cuò)誤的概率相同,那么對(duì)于前向內(nèi)部控制流錯(cuò)誤的檢測(cè)率可以達(dá)到1-(m+1)×((n/(m+1))!)/((n+m)!)。設(shè)n=30,m=1,代入計(jì)算得可能漏檢的錯(cuò)誤僅占3.18×10-22。所以雖然只加入了很少的內(nèi)部檢測(cè)指令,但是對(duì)于基本內(nèi)部控制流的檢測(cè)率非常高。本發(fā)明對(duì)于內(nèi)部控制流錯(cuò)誤檢測(cè)的優(yōu)勢(shì)還在于可以根據(jù)具體需求進(jìn)行配置,用戶可以根據(jù)可靠性、性能的需求及程序運(yùn)行環(huán)境自定義Ω值,通過(guò)設(shè)置Ω來(lái)決定實(shí)施塊內(nèi)部控制流檢測(cè)的力度,而對(duì)于不需要內(nèi)部控制流檢測(cè)機(jī)制的基本塊來(lái)說(shuō)則沒有額外開銷。相比已有方法來(lái)說(shuō),本發(fā)明在成本和靈活性方面要好很多。當(dāng)然如果基本塊內(nèi)部控制流錯(cuò)誤恰好發(fā)生在4.3步所劃分區(qū)域的內(nèi)部(這種情況發(fā)生概率非常小),那么仍然不能檢測(cè)這種控制流錯(cuò)誤。
(4)本發(fā)明能夠有效解決過(guò)程間控制流檢測(cè)的難點(diǎn)問題。由于在調(diào)用函數(shù)時(shí)通過(guò)RAR將返回目的基本塊標(biāo)簽傳遞給了調(diào)用函數(shù),而且RAR中值存放在被調(diào)用函數(shù)的棧區(qū)間,所以本發(fā)明可以很好地處理嵌套調(diào)用和遞歸調(diào)用等復(fù)雜情況。
(5)本發(fā)明對(duì)程序本身性能影響很小,除內(nèi)部的控制流檢測(cè)指令外,單個(gè)基本塊最多插入5條指令(對(duì)應(yīng)于函數(shù)入口基本塊同時(shí)有兩個(gè)合法后繼基本塊的特殊情況),最少只插入2條指令。已有性能分析實(shí)驗(yàn)的結(jié)果表明,在使用本發(fā)明的控制流檢測(cè)后,程序的性能開銷僅為15%~37%。



圖1是基本塊標(biāo)簽的格式; 圖2是本發(fā)明的總流程圖; 圖3是本發(fā)明的第二步標(biāo)識(shí)程序的基本塊并確定基本塊之間的路由關(guān)系的流程圖; 圖4是本發(fā)明的第三步基本塊標(biāo)簽格式設(shè)計(jì)和靜態(tài)標(biāo)簽分配的流程圖; 圖5是本發(fā)明的第四步向被檢測(cè)程序加入控制流檢測(cè)指令的流程圖。

具體實(shí)施例方式 圖1是基本塊標(biāo)簽格式的示意圖。
基本塊標(biāo)簽由基本標(biāo)簽編碼和用于基本塊內(nèi)部控制流檢測(cè)的編碼兩部分組成。每個(gè)基本塊的基本標(biāo)簽編碼是對(duì)基本塊在程序總基本塊列表中的序號(hào)進(jìn)行的編碼,是唯一的;而基本塊內(nèi)部控制流檢測(cè)的編碼則是該塊所需的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)的二進(jìn)制編碼,占整個(gè)基本塊標(biāo)簽的最末幾位。
圖2是本發(fā)明的總流程圖。包括以下步驟 第一步,首先通過(guò)編譯器將需要進(jìn)行控制流檢測(cè)的程序編譯成匯編代碼。
第二步,基于程序匯編代碼標(biāo)識(shí)出程序的基本塊并確定基本塊之間的路由關(guān)系,即程序的控制流結(jié)構(gòu)。
第三步,根據(jù)用戶對(duì)基本塊內(nèi)部控制流檢測(cè)的需求和基本塊的構(gòu)成特征,設(shè)計(jì)基本塊標(biāo)簽,并為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽。
第四步,以函數(shù)為單位依次在程序每個(gè)基本塊的頭部、內(nèi)部和尾部分別插入控制流檢測(cè)指令。
第五步,通過(guò)編譯器,將插入控制流檢測(cè)指令的匯編程序重新匯編并鏈接,生成可執(zhí)行的實(shí)現(xiàn)控制流檢測(cè)的程序。
圖3是本發(fā)明的第二步標(biāo)識(shí)程序的基本塊并確定基本塊之間的路由關(guān)系的流程圖,主要包括三大步驟 1.依次遍歷匯編程序的指令序列,根據(jù)其中的程序控制指令標(biāo)注基本塊的入口指令。同時(shí)根據(jù)指令的操作數(shù)字段識(shí)別出程序中所有使用過(guò)的寄存器,最后得出哪些寄存器還沒有被程序使用過(guò)。
2.重新依次遍歷匯編程序的指令序列,將一個(gè)被標(biāo)注為基本塊入口指令到下一個(gè)入口指令之間的指令劃分為一個(gè)基本塊。
3.依次遍歷程序的所有基本塊,根據(jù)基本塊的最后一條指令確定基本塊之間的路由關(guān)系。
圖4是本發(fā)明的第三步基本塊標(biāo)簽格式設(shè)計(jì)和靜態(tài)標(biāo)簽分配的流程圖,該過(guò)程主要包括四個(gè)步驟 1.依次遍歷程序中所有基本塊,根據(jù)基本塊包含的指令的條數(shù)對(duì)閾值Ω的比例,計(jì)算在該基本塊的內(nèi)部檢測(cè)指令計(jì)數(shù)(即需要多少條內(nèi)部控制流檢測(cè)指令),得到整個(gè)程序中所有基本塊最大的內(nèi)部檢測(cè)指令計(jì)數(shù)。
2.根據(jù)整個(gè)程序中所有基本塊最大的內(nèi)部檢測(cè)指令計(jì)數(shù),設(shè)計(jì)基本塊標(biāo)簽。
3.依次為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽AS。在所有靜態(tài)標(biāo)簽中,用于基本塊內(nèi)部控制流檢測(cè)的幾位編碼都保持為0。
4.從沒有被程序使用的空閑寄存器中選擇四個(gè),分別指派給DSR、ASR、SVR和RAR。這四個(gè)寄存器分別用于保存程序運(yùn)行過(guò)程中產(chǎn)生的動(dòng)態(tài)標(biāo)簽DS,基本塊的靜態(tài)標(biāo)簽AS,標(biāo)簽差異值SV和函數(shù)調(diào)用返回地址RA。
圖5是本發(fā)明的第四步插入控制檢測(cè)指令的流程圖,表示分別向每個(gè)基本塊頭部、內(nèi)部和尾部插入指令,該過(guò)程主要包括三大步驟 1.根據(jù)基本塊的類型在基本塊頭部插入指令如果基本塊是函數(shù)入口基本塊,則先插入指令“store RAR,mem”,“mem”是該函數(shù)的空閑棧區(qū)間中的存儲(chǔ)單元;然后對(duì)于所有基本塊,需要插入指令“xor DSR=DSR,SVR”。
2.根據(jù)基本塊包含的指令數(shù)在基本塊內(nèi)部插入內(nèi)部控制流檢測(cè)指令按照用戶定義的基本塊內(nèi)部檢測(cè)指令的間隔指令閾值Ω,依次每隔Ω大小的指令數(shù)就插入內(nèi)部檢測(cè)指令“sub DSR=DSR,1”,直到剩下的指令總數(shù)不大于Ω。
3.根據(jù)基本塊的類型及其后繼基本塊,在基本塊的尾部插入指令。
1)如果當(dāng)前基本塊不是函數(shù)調(diào)用基本塊和函數(shù)退出基本塊,而且只有一個(gè)后繼基本塊,則插入如下指令 xor SVR=DSR,ASnext 其中ASnext表示后繼基本塊的靜態(tài)標(biāo)簽。如后繼基本塊需要進(jìn)行塊內(nèi)的控制流檢測(cè),則ASnext等于后繼基本塊的靜態(tài)標(biāo)簽加上相應(yīng)的塊內(nèi)部控制流檢測(cè)指令計(jì)數(shù)。
2)如果當(dāng)前基本塊不是函數(shù)調(diào)用基本塊和函數(shù)返回基本塊,而且有兩個(gè)后繼基本塊(即基本塊最后一條指令是分支指令),則依次插入如下代碼 xor SVR=DSR,ASthen br L1′,brcond xor SVR=DSR,ASelse L1′ 新插入的3條指令實(shí)現(xiàn)了分支預(yù)測(cè)功能,其中ASthen和ASelse分別表示分支條件滿足的后繼塊和分支條件不滿足的后繼塊的靜態(tài)標(biāo)簽。且分支預(yù)測(cè)指令“br L1′,brcond”的指令操作碼和分支條件“brcond”與實(shí)際的分支指令相同,但是分支的目標(biāo)改成L1′,而且L1′必須是一個(gè)沒有在程序中出現(xiàn)過(guò)的語(yǔ)句標(biāo)示符。同樣,如果后繼基本塊需要進(jìn)行內(nèi)部控制流檢測(cè),則ASthen或ASelse分別等于其靜態(tài)標(biāo)簽加上對(duì)應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)。
3)如果當(dāng)前基本塊是函數(shù)調(diào)用基本塊,則依次加入如下指令 xor SVR=DSR,AScallee mov RAR=ASreturn 其中,“xor SVR=DSR,AScallee”表示把DSR與被調(diào)用函數(shù)的入口基本塊的靜態(tài)標(biāo)簽AScallee異或運(yùn)算求標(biāo)簽差異值,指令“mov RAR=ASreturn”表示把函數(shù)返回的目的基本塊的靜態(tài)標(biāo)簽ASreturn賦予寄存器RAR。同樣,如果被調(diào)用函數(shù)的入口基本塊和把函數(shù)返回的目的基本塊需要進(jìn)行塊內(nèi)部的控制流檢測(cè),則AScallee或ASreturn分別等于其靜態(tài)標(biāo)簽加上對(duì)應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)。
4)如果當(dāng)前基本塊是函數(shù)退出基本塊,則依次加入如下指令 load RAR,mem xor SVR=DSR,RAR clear mem 其中,指令“l(fā)oad RAR,mem”表示從保存函數(shù)返回目的基本塊靜態(tài)標(biāo)簽的內(nèi)存區(qū)域mem中讀出數(shù)據(jù),寫回到寄存器RAR中。然后由指令“xor SVR=DSR,RAR”將DSR與RAR進(jìn)行異或運(yùn)算求標(biāo)簽差異值。“clear mem”表示需要將使用的內(nèi)存區(qū)域中的數(shù)據(jù)清除。
對(duì)于所有類型的基本塊,在尾部最后插入指令 br faultDet DSR?。紸Scurrent 表示把當(dāng)前塊的靜態(tài)標(biāo)簽AScurrent與DSR進(jìn)行比較。如果不相等,則意味著檢測(cè)到控制流錯(cuò)誤,需要轉(zhuǎn)向錯(cuò)誤處理例程。
當(dāng)指令集中沒有可以把寄存器和立即數(shù)直接進(jìn)行比較的指令,則要先插入指令 mov ASR=AScurrent 表示先把AScurrent讀取到寄存器ASR中,然后插入 br faultDet DSR?。紸SR 表示將ASR與DSR進(jìn)行比較。
權(quán)利要求
1.一種程序控制流錯(cuò)誤檢測(cè)方法,其特征在于包括以下步驟
第一步,通過(guò)編譯器將需要進(jìn)行控制流錯(cuò)誤檢測(cè)的程序編譯成匯編代碼;
第二步,基于程序匯編代碼標(biāo)識(shí)出程序的基本塊并確定基本塊之間的路由關(guān)系,具體分為三個(gè)步驟
2.1依次遍歷程序匯編代碼的指令序列,根據(jù)指令操作碼字段識(shí)別出程序控制指令,然后基于程序控制指令標(biāo)注基本塊的入口指令,方法為所有函數(shù)的第一條指令標(biāo)注為基本塊的入口指令;對(duì)于條件分支指令和無(wú)條件跳轉(zhuǎn)指令,分支或跳轉(zhuǎn)的目標(biāo)指令標(biāo)注為基本塊的入口指令;所有程序控制指令的后繼指令標(biāo)注為基本塊的入口指令;在標(biāo)注入口指令的同時(shí),還根據(jù)指令的操作數(shù)字段識(shí)別出程序中所有使用過(guò)的寄存器,得出哪些寄存器還沒有被程序使用過(guò);
2.2重新依次遍歷匯編程序的指令序列,將一個(gè)被標(biāo)注為基本塊入口指令到下一個(gè)入口指令之間的指令劃分為一個(gè)基本塊;如果基本塊的入口指令有標(biāo)識(shí)符,就以標(biāo)識(shí)符作為基本塊的名稱;基本塊以函數(shù)為單位按照在程序代碼中出現(xiàn)的順序列表組織,形成函數(shù)基本塊列表,且在函數(shù)基本塊列表中,第一個(gè)基本塊標(biāo)記為函數(shù)入口基本塊,最后一個(gè)基本塊被標(biāo)記為函數(shù)退出基本塊;所有函數(shù)基本塊列表構(gòu)成程序總的基本塊列表;
2.3依次遍歷匯編程序的所有基本塊,按照基本塊的最后一條指令確定基本塊之間的路由關(guān)系,具體方法如下如果基本塊最后一條指令是條件分支指令和無(wú)條件跳轉(zhuǎn)指令,則根據(jù)指令的分支或跳轉(zhuǎn)目標(biāo)地址查找對(duì)應(yīng)的目標(biāo)基本塊,在程序?qū)?yīng)的控制流圖中從當(dāng)前塊向該目標(biāo)基本塊劃一條有向邊;如果基本塊的最后一條指令是條件分支指令或普通指令——即不是無(wú)條件跳轉(zhuǎn)指令、函數(shù)調(diào)用指令和函數(shù)返回指令,則在控制流圖中從當(dāng)前塊向其直接后繼基本塊劃一條有向邊;如果基本塊最后一條指令是函數(shù)調(diào)用指令,則在控制流圖中從當(dāng)前塊向被調(diào)用函數(shù)的入口基本塊劃一條有向邊,并且從被調(diào)用函數(shù)的退出基本塊向當(dāng)前塊在所屬函數(shù)基本塊列表中的下一個(gè)塊劃一條有向邊,表示函數(shù)返回的控制流轉(zhuǎn)移;
第三步,根據(jù)用戶對(duì)基本塊內(nèi)部控制流錯(cuò)誤檢測(cè)的需求和基本塊的構(gòu)成特征,設(shè)計(jì)基本塊標(biāo)簽,并為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽,采用可配置的方法進(jìn)行內(nèi)部控制流校驗(yàn),即當(dāng)基本塊內(nèi)部的指令計(jì)數(shù)每超過(guò)閾值Ω時(shí)才進(jìn)行一次內(nèi)部控制流校驗(yàn),Ω由用戶根據(jù)可靠性、性能的需求及程序運(yùn)行環(huán)境自定義,具體步驟為
3.1依次遍歷程序中所有基本塊,根據(jù)基本塊包含指令的條數(shù)對(duì)閾值Ω的比例∑,計(jì)算在該基本塊的內(nèi)部檢測(cè)指令計(jì)數(shù),該內(nèi)部檢測(cè)指令計(jì)數(shù)等于
再根據(jù)程序中每個(gè)基本塊的內(nèi)部檢測(cè)指令計(jì)數(shù)得到整個(gè)程序中所有基本塊最大的內(nèi)部檢測(cè)指令計(jì)數(shù);
3.2根據(jù)整個(gè)程序中所有基本塊最大的內(nèi)部檢測(cè)指令計(jì)數(shù),設(shè)計(jì)基本塊標(biāo)簽,基本塊標(biāo)簽由基本標(biāo)簽編碼和用于基本塊內(nèi)部控制流檢測(cè)的編碼兩部分組成,每個(gè)基本塊的基本標(biāo)簽編碼是該基本塊在程序總基本塊列表中的序列號(hào)的二進(jìn)制編碼,是唯一的,基本塊內(nèi)部控制流檢測(cè)的編碼是該塊所需的內(nèi)部控制流檢測(cè)指令計(jì)數(shù)的二進(jìn)制編碼,占整個(gè)基本塊標(biāo)簽的最末幾位;在基本塊標(biāo)簽的末端為塊內(nèi)部控制流檢測(cè)分配
位編碼,N為3.1步分析得出的整個(gè)程序中一個(gè)基本塊中最多需要的內(nèi)部檢測(cè)指令條數(shù);
3.3依次為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽,所有靜態(tài)標(biāo)簽中用于基本塊內(nèi)部控制流檢測(cè)的編碼都保持為0;
3.4從步驟2.1確定的空閑寄存器中選擇四個(gè)寄存器分別定義為DSR、ASR、SVR和RAR,分別保存程序運(yùn)行過(guò)程中產(chǎn)生的動(dòng)態(tài)標(biāo)簽DS、靜態(tài)標(biāo)簽AS、標(biāo)簽差異值SV和函數(shù)調(diào)用返回地址RA;其中,SV是兩個(gè)基本塊的靜態(tài)標(biāo)簽異或運(yùn)算的結(jié)果;如果程序沒有四個(gè)空閑寄存器可供使用,則通知用戶無(wú)法實(shí)現(xiàn)控制流錯(cuò)誤檢測(cè),用戶選擇采用編譯器的其它寄存器分派策略以重新生成匯編程序;
第四步,依次在程序每個(gè)基本塊的頭部、內(nèi)部和尾部分別插入相應(yīng)指令,具體步驟包括
4.1進(jìn)入一個(gè)函數(shù)后,首先針對(duì)函數(shù)入口基本塊Bentry和函數(shù)退出基本塊Bexit進(jìn)行特殊處理在調(diào)用函數(shù)的基本塊Bcaller把返回的目的基本塊Breturn的靜態(tài)標(biāo)簽通過(guò)寄存器RAR傳遞給被調(diào)用函數(shù),被調(diào)用函數(shù)的Bentry塊把RAR中的數(shù)據(jù)寫到分配給本函數(shù)的棧區(qū)間,最后被調(diào)用函數(shù)的Bexit塊把保存的Breturn靜態(tài)標(biāo)簽從棧區(qū)間重新讀出,實(shí)現(xiàn)對(duì)過(guò)程間控制流的跟蹤,所述Breturn是指在調(diào)用函數(shù)的基本塊列表中當(dāng)前基本塊的下一個(gè)塊,具體包括三個(gè)步驟
4.1.1首先確定分配給本函數(shù)的棧區(qū)間中是否有空閑單元可用于存放RAR中的數(shù)據(jù),如果確實(shí)沒有空閑區(qū)域,則修改Bentry塊入口處用于分配棧區(qū)間的指令,使得該函數(shù)的棧區(qū)間有一個(gè)機(jī)器字長(zhǎng)的空閑存儲(chǔ)單元可用于控制流檢測(cè)使用;然后從函數(shù)的??臻g的空閑區(qū)域中,選擇其中一個(gè)機(jī)器字長(zhǎng)的存儲(chǔ)單元,記為mem;
4.1.2在Bentry塊分配棧區(qū)間的指令后加入指令“store RAR,mem”,表示把RAR中的數(shù)據(jù)寫到分配給本函數(shù)棧區(qū)間的mem單元之中;
4.1.3如果Bentry塊入口處修改了分配棧區(qū)間的指令,則相應(yīng)修改Bexit塊入口處回收棧區(qū)間的指令,使得函數(shù)棧區(qū)間的分配和回收保持一致;
4.2在當(dāng)前基本塊頭部插入指令“xor DSR=DSR,SVR”,表示將動(dòng)態(tài)標(biāo)簽與標(biāo)簽差異值異或運(yùn)算生成新的動(dòng)態(tài)標(biāo)簽DS,所述當(dāng)前基本塊頭部是指基本塊第一條指令之前,對(duì)于函數(shù)入口基本塊來(lái)說(shuō)則在4.1.2步驟的指令“store RAR,mem”之后;
4.3按照設(shè)定的Ω值,在基本塊內(nèi)部插入將DSR減1的內(nèi)部控制流檢測(cè)指令,方法是依次遍歷基本塊的指令序列,每隔Ω大小的指令數(shù)就插入一條內(nèi)部控制流檢測(cè)指令“subDSR=DSR,1”,直到剩下的指令總數(shù)不大于Ω值;對(duì)于那些本身包含指令的數(shù)目小于Ω值的基本塊則不需要進(jìn)行內(nèi)部控制流檢測(cè),基本塊內(nèi)部保持不變;
4.4在基本塊的尾部按照基本塊的類型將DSR與后繼基本塊的靜態(tài)標(biāo)簽進(jìn)行異或運(yùn)算,產(chǎn)生新的標(biāo)簽差異值SV,所述基本塊的尾部是指基本塊最后一條指令之后,如果最后一條指令是程序控制指令,則在該程序控制指令之前;具體方法如下
4.4.1如果當(dāng)前基本塊既不是函數(shù)調(diào)用基本塊又不是函數(shù)退出基本塊,而且只有一個(gè)后繼基本塊,則在當(dāng)前基本塊的尾部插入指令“xor SVR=DSR,ASnext”,表示直接把后繼塊的靜態(tài)標(biāo)簽值A(chǔ)Snext與DSR進(jìn)行異或運(yùn)算,求得新的標(biāo)簽差異值后賦給SVR;如果后繼基本塊需要進(jìn)行塊內(nèi)控制流檢測(cè),ASnext等于后繼基本塊靜態(tài)標(biāo)簽加上相應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù);
4.4.2如果當(dāng)前基本塊的最后一條指令是分支指令,則采取分支預(yù)測(cè)方法提前判斷將要執(zhí)行哪條分支,然后把所預(yù)測(cè)分支對(duì)應(yīng)的后繼基本塊的靜態(tài)標(biāo)簽與DSR進(jìn)行異或運(yùn)算,求得新的標(biāo)簽差異值SV;具體方法是設(shè)ASthen和ASelse分別表示分支條件滿足和不滿足的目的基本塊靜態(tài)標(biāo)簽,首先在當(dāng)前基本塊的尾部插入指令“xor SVR=DSR,ASthen”,表示先假設(shè)分支條件滿足,將DSR與ASthen進(jìn)行異或運(yùn)算求SVR值;然后在“xor SVR=DSR,ASthen”之后插入分支預(yù)測(cè)指令“br L1′,brcond”,分支條件“brcond”與實(shí)際的分支指令相同,而分支的目標(biāo)“L1′”必須是一個(gè)沒有在程序中出現(xiàn)過(guò)的語(yǔ)句標(biāo)示符,具體指向4.5步即將插入的校驗(yàn)DSR數(shù)據(jù)的指令;最后在“br L1′,brcond”之后插入指令“xor SVR=DSR,ASelse”,表示將DSR與分支條件不滿足的目的基本塊的靜態(tài)標(biāo)簽進(jìn)行異或運(yùn)算求得SVR值;如果分支條件滿足,分支預(yù)測(cè)指令“br L1′,brcond”執(zhí)行結(jié)果將使得程序跳過(guò)指令“xor SVR=DSR,ASelse”,即SVR中的值是DSR與ASthen異或運(yùn)算的執(zhí)行結(jié)果,否則SVR中的值是DSR與ASelse異或運(yùn)算的運(yùn)算結(jié)果;如果后繼基本塊需要進(jìn)行內(nèi)部控制流檢測(cè),則ASthen或ASelse分別等于其靜態(tài)標(biāo)簽加上對(duì)應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù);
4.4.3如果當(dāng)前基本塊是函數(shù)調(diào)用基本塊,其后續(xù)執(zhí)行的基本塊是被調(diào)用函數(shù)的入口基本塊,先在當(dāng)前基本塊的尾部插入指令“xor SVR=DSR,AScallee”,實(shí)現(xiàn)DSR與被調(diào)用函數(shù)入口基本塊靜態(tài)標(biāo)簽AScallee的異或運(yùn)算,并把標(biāo)簽差異值賦予SVR;然后在“xor SVR=DSR,AScallee”之后插入指令“mov RAR=ASreturn”,表示把函數(shù)調(diào)用返回的目的基本塊的靜態(tài)標(biāo)簽ASreturn賦予寄存器RAR;如果后續(xù)執(zhí)行的被調(diào)用函數(shù)的入口基本塊或者函數(shù)返回的目的基本塊需要進(jìn)行基本塊內(nèi)部的控制流檢測(cè),則AScallee或ASreturn分別等于其靜態(tài)標(biāo)簽加上對(duì)應(yīng)的內(nèi)部控制流檢測(cè)指令計(jì)數(shù);所述函數(shù)調(diào)用返回的目的基本塊是指當(dāng)前基本塊在所屬函數(shù)的基本塊列表中的下一個(gè)塊;
4.4.4如果當(dāng)前基本塊是函數(shù)退出基本塊,先在當(dāng)前基本塊的尾部插入指令“l(fā)oad RAR,mem”,表示從mem中讀出數(shù)據(jù),寫回到寄存器RAR中;然后在“l(fā)oad RAR,mem”后插入指令“xor SVR=DSR,RAR”,表示將DSR與RAR進(jìn)行異或運(yùn)算求新標(biāo)簽差異值;最后在“xor SVR=DSR,RAR”后插入指令“clear mem”,表示將使用的內(nèi)存單元mem中的數(shù)據(jù)清除;
4.5在基本塊的尾部加入校驗(yàn)DSR數(shù)據(jù)的指令“br faultDet,DSR?。紸Scurrent”,其中AScurrent表示分派給當(dāng)前基本塊的靜態(tài)標(biāo)簽;如果基本塊的最后一條指令是程序控制指令,校驗(yàn)DSR數(shù)據(jù)的指令在程序控制指令之前插入;
第五步,通過(guò)編譯器,將插入了控制流檢測(cè)指令的匯編程序重新匯編并鏈接,生成可執(zhí)行的實(shí)現(xiàn)控制流錯(cuò)誤檢測(cè)的程序。
全文摘要
本發(fā)明公開了一種程序控制流錯(cuò)誤檢測(cè)方法,目的是克服已有方法提高控制流錯(cuò)誤的檢測(cè)率,解決基本塊內(nèi)部、過(guò)程間控制流檢測(cè)難點(diǎn)問題。技術(shù)方案是先標(biāo)識(shí)基本塊并確定基本塊之間的路由關(guān)系;然后根據(jù)基本塊內(nèi)部控制流檢測(cè)的需求和基本塊的構(gòu)成特征,確定單個(gè)基本塊最多需要多少條內(nèi)部控制流檢測(cè)指令,在此基礎(chǔ)上設(shè)計(jì)基本塊標(biāo)簽,并為每個(gè)基本塊分配唯一的靜態(tài)標(biāo)簽;然后在程序中的每個(gè)基本塊的頭部、內(nèi)部和尾部分別插入檢測(cè)指令,將插入了控制流檢測(cè)指令的匯編程序重新匯編鏈接,生成可執(zhí)行的實(shí)現(xiàn)控制流錯(cuò)誤檢測(cè)的程序。采用本發(fā)明能解決檢測(cè)盲點(diǎn)問題,檢測(cè)率很高;且能有效解決基本塊內(nèi)部、過(guò)程間控制流檢測(cè)的難點(diǎn)問題。
文檔編號(hào)G06F9/45GK101763291SQ200910226768
公開日2010年6月30日 申請(qǐng)日期2009年12月30日 優(yōu)先權(quán)日2009年12月30日
發(fā)明者譚慶平, 徐建軍, 寧洪, 周會(huì)平, 李建立, 李劍明, 羅宇, 鄧勝蘭 申請(qǐng)人:中國(guó)人民解放軍國(guó)防科學(xué)技術(shù)大學(xué)
網(wǎng)友詢問留言 已有0條留言
  • 還沒有人留言評(píng)論。精彩留言會(huì)獲得點(diǎn)贊!
1
临沂市| 牟定县| 岳阳县| 宜兰县| 富川| 青海省| 兴宁市| 泾川县| 邵阳市| 且末县| 紫云| 乌兰察布市| 桐梓县| 柯坪县| 陆丰市| 汕尾市| 五华县| 绥化市| 大庆市| 沙坪坝区| 富平县| 麻江县| 鹤岗市| 南汇区| 阿坝县| 防城港市| 安庆市| 旬邑县| 新宁县| 全州县| 辽源市| 桑植县| 仁寿县| 文安县| 陇南市| 巴马| 赣州市| 瓦房店市| 安溪县| 黔西| 连州市|