陳炎明,李旺林,陳 希,3,關(guān)靜雅,3
(1湖北省計(jì)量測試技術(shù)研究院,湖北 武漢430223;2湖北省產(chǎn)品質(zhì)量監(jiān)督檢驗(yàn)研究院,湖北 武漢430061;3武漢大學(xué)計(jì)算機(jī)學(xué)院,湖北 武漢430072)
現(xiàn)代計(jì)量器具仍存在計(jì)量作弊現(xiàn)象,并且不僅有一般的硬件設(shè)備改裝、加裝多余脈沖發(fā)生設(shè)備等作弊手段,有些不法商家更改計(jì)量軟件的程序代碼[1],利用嵌入式計(jì)量軟件本身存在的設(shè)計(jì)漏洞修改計(jì)量程序,甚至直接更換計(jì)量主板以達(dá)到作弊的目的。在嵌入式計(jì)量軟件中,后門程序是指生產(chǎn)廠家預(yù)留或者經(jīng)營者刻意設(shè)計(jì)的作弊方式,通過遙控器或者設(shè)置鍵盤組合鍵等方式觸發(fā)作弊后門來篡改計(jì)量程序中的計(jì)量參數(shù)或其他計(jì)量數(shù)據(jù)[2]。趨于高科技化的作弊方式為人工檢測計(jì)量軟件后門帶來了困難,因此急需一種自動檢測方法來方便高效地檢測嵌入式計(jì)量軟件中的作弊后門。
本文在研究分析了一般軟件的后門檢測方法和二進(jìn)制可執(zhí)行程序檢測方法的基礎(chǔ)上,針對其不足,提出了基于執(zhí)行路徑分析的嵌入式計(jì)量軟件的后門檢測方法。該檢測方法以二進(jìn)制可執(zhí)行程序?yàn)闄z測對象,跟蹤和分析二進(jìn)制程序的執(zhí)行路徑,判斷是否存在作弊后門,為嵌入式軟件后門的自動化檢測提供了新的借鑒。
靜態(tài)分析法是在不實(shí)際執(zhí)行程序的條件下,利用分析工具對程序代碼進(jìn)行分析,對可執(zhí)行程序進(jìn)行反匯編,在此基礎(chǔ)上找出惡意代碼的特征值或可疑語義特征[3]。靜態(tài)分析的優(yōu)點(diǎn)是可以避免執(zhí)行惡意代碼對被分析系統(tǒng)的破壞;但同時(shí)因?yàn)椴粓?zhí)行代碼,所分析的代碼不全是最終執(zhí)行的代碼,在無用代碼上浪費(fèi)了分析時(shí)間,且對反匯編技術(shù)的依賴也使靜態(tài)分析存在局限性。靜態(tài)分析方法包括基于代碼語義的方法,通過分析惡意代碼的行為和代碼意義來識別和判定惡意代碼[4],和不分析語義而是通過提取惡意行為和代碼的特征來標(biāo)識惡意代碼的基于代碼特征的分析方法[5]。
動態(tài)檢測方法[6]是通過動態(tài)跟蹤并觀察惡意代碼的執(zhí)行情況來理解惡意代碼的行為,所研究的代碼部分即實(shí)際執(zhí)行到的代碼。該方法獲得運(yùn)行時(shí)信息,分析過程簡單且結(jié)果清晰。動態(tài)檢測方法包括外部觀察法,即通過觀察惡意代碼執(zhí)行時(shí)系統(tǒng)發(fā)生的調(diào)用函數(shù)行為來研究惡意代碼的功能,這種方法不對惡意代碼本身的語義特性作分析。另一種方法是跟蹤調(diào)試法,通過跟蹤目標(biāo)程序執(zhí)行情況,對惡意代碼的語義進(jìn)行分析,進(jìn)而判別惡意代碼的惡意行為。
程序執(zhí)行路徑(execution path)是程序在一次運(yùn)行中所執(zhí)行的有序語句序列。跟蹤程序執(zhí)行路徑是程序在測試、糾錯(cuò)、排查和理解等方面重要的輔助手段。
對嵌入式計(jì)量軟件的二進(jìn)制可執(zhí)行程序進(jìn)行分析時(shí),執(zhí)行路徑是程序執(zhí)行一次命令的指令序列,記錄所執(zhí)行過的指令流。跟蹤程序的執(zhí)行路徑,需要監(jiān)視相關(guān)寄存器內(nèi)容、堆棧信息、狀態(tài)轉(zhuǎn)移規(guī)律及整個(gè)地址空間的動態(tài)運(yùn)行狀態(tài),通過獲取當(dāng)前二進(jìn)制可執(zhí)行程序所執(zhí)行的指令地址,取出指令并譯碼后計(jì)算下一指令的地址。
關(guān)于程序執(zhí)行路徑,有如下幾個(gè)定義。
1)路徑P = {I1,I2,I3,…,Ij…,|j≤N},其中語句I可以是細(xì)粒度的指令,或者基本塊、函數(shù)等。執(zhí)行語句按照執(zhí)行順序組成的語句序列稱為路徑。在本文的檢測方法中,記錄執(zhí)行路徑以條件轉(zhuǎn)移指令劃分的基本塊為記錄單位,基本塊內(nèi)為順序執(zhí)行的不可分割的指令序列。
2)起始路徑。起始于語句I1的執(zhí)行路徑為起始路徑。本文檢測方法中的起始路徑為二進(jìn)制可執(zhí)行程序加載執(zhí)行后的初始化執(zhí)行過程,每一條執(zhí)行路徑都以程序初始化為起點(diǎn),由于初始化過程相同,本文從初始化完成后的執(zhí)行路徑開始記錄。
3)原子路徑。如果執(zhí)行路徑P由連續(xù)執(zhí)行不可分的語句序列P0組成,那么P0為路徑P的原子路徑。本文檢測方法以基本塊為路徑節(jié)點(diǎn),基本塊內(nèi)的指令流為連續(xù)執(zhí)行不可分割的指令流組成,每一個(gè)基本塊即原子路徑。通過記錄基本塊的地址可以降低記錄的路徑節(jié)點(diǎn)數(shù)量,提高處理速度。
4)路徑執(zhí)行條件。對于執(zhí)行路徑P={Ij|j≤N},其中有k條判斷語句(0<k≤N),JD為判斷語句的集合,JD = {Ij|Ij為判斷語句}。P,Ij,JD對應(yīng)于一個(gè)判斷條件Cj,Cj是一個(gè)布爾表達(dá)式,由若干原子謂詞和and,or,not等邏輯連接詞組成。集合Var由所有與Cj有關(guān)的變量的組成。當(dāng)且僅當(dāng)C1,C2,…,Ck為真時(shí),路徑P 執(zhí)行。因此記 <C1,C2,…,Ck,Var> 為真時(shí)路徑P的執(zhí)行條件。
本文對執(zhí)行路徑的路徑節(jié)點(diǎn)定義為條件轉(zhuǎn)移分支點(diǎn),即以轉(zhuǎn)移語句作為路徑節(jié)點(diǎn)來組成執(zhí)行路徑。輸入一條命令的過程中,每輸入一個(gè)命令字,在二進(jìn)制程序中都將對應(yīng)一個(gè)條件分支,即一條控制轉(zhuǎn)移指令,形成一個(gè)路徑節(jié)點(diǎn)。根據(jù)不同命令值與命令樹中命令值的匹配,跳轉(zhuǎn)到不同的執(zhí)行指令或入口函數(shù)。每一命令字對應(yīng)的路徑節(jié)點(diǎn)之間,對應(yīng)的二進(jìn)制執(zhí)行程序中也可能存在其他控制轉(zhuǎn)移指令,不作為路徑節(jié)點(diǎn)來跟蹤和處理。
執(zhí)行路徑跟蹤算法記錄每一個(gè)路徑節(jié)點(diǎn)的首地址和末地址,記錄一條執(zhí)行路徑所執(zhí)行過的代碼的地址。條件轉(zhuǎn)移指令由JZ,JNZ,JB,JC等幾種指令組成。執(zhí)行路徑跟蹤算法記錄以條件轉(zhuǎn)移指令開始的路徑節(jié)點(diǎn),首地址即當(dāng)前跳轉(zhuǎn)指令的跳轉(zhuǎn)目的地址,即跳轉(zhuǎn)指令地址與偏移量的和,末地址為下一跳轉(zhuǎn)指令所在的地址。路徑節(jié)點(diǎn)用該節(jié)點(diǎn)執(zhí)行代碼的首末指令地址來標(biāo)識,記為 Ni(begini,endi)。執(zhí)行路徑存儲為 path{N0(begin0,end0),N1(begin1,end1),…,Ni(begini,endi),…,Nn-1(beginn-1,endn-1)}(i≥0,n≥1)。單片機(jī)程序從0000 H 地址開始自動執(zhí)行,這部分代碼對于每次執(zhí)行都相同,因此執(zhí)行路徑從接收第一個(gè)命令字輸入后產(chǎn)生的路徑節(jié)點(diǎn)開始計(jì)算,到輸入最后一個(gè)命令字程序執(zhí)行相關(guān)操作后執(zhí)行路徑截止。
執(zhí)行路徑跟蹤分為兩個(gè)步驟:1)對有關(guān)計(jì)量參數(shù)(如計(jì)量系數(shù)、計(jì)量單價(jià)、計(jì)量密度等)正常的系統(tǒng)命令做預(yù)處理路徑跟蹤,計(jì)量程序逐條執(zhí)行這些系統(tǒng)命令,路徑跟蹤模塊保存執(zhí)行路徑的節(jié)點(diǎn),得到計(jì)量程序執(zhí)行正常操作指令所執(zhí)行到的代碼地址,此部分地址的代碼的功能為計(jì)量系數(shù)操作,為敏感區(qū)域代碼,存儲為path{N0(begin0,end0),N1(begin1,end1),…,Ni(begini,endi),…,Nn-1(beginn-1,endn-1)}(i≥0,n≥1);2)對計(jì)量程序執(zhí)行測試命令所得的執(zhí)行路徑進(jìn)行路徑跟蹤處理,得到計(jì)量程序執(zhí)行測試命令所執(zhí)行到的代碼地址,即該條測試命令所運(yùn)行的代碼部分,存儲為pat hk{N0(begin0,end0),N1(begin1,end1),…,Nj(beginj,endj),…,Nm-1(beginm-1,endm-1)}(k,j≥0,m ≥1)。
執(zhí)行路徑跟蹤是系統(tǒng)檢測后門的關(guān)鍵部分,通過執(zhí)行自動生成的測試命令,逐條跟蹤并記錄執(zhí)行被測命令時(shí)的執(zhí)行路徑。執(zhí)行路徑由執(zhí)行結(jié)點(diǎn)組成,記錄執(zhí)行路徑首先要對執(zhí)行結(jié)點(diǎn)進(jìn)行處理。
嵌入式計(jì)量器具通過外部連接設(shè)備(如鍵盤等)輸入功能指令、計(jì)量命令等,計(jì)量軟件接受這些指令并且匹配、解析指令并執(zhí)行相應(yīng)功能操作。通常在嵌入式軟件的指令系統(tǒng)中,對于指令的存儲和匹配采用簡單的狀態(tài)轉(zhuǎn)移和命令樹法。狀態(tài)轉(zhuǎn)移適用于簡單且指令數(shù)量少的嵌入式指令系統(tǒng),復(fù)雜的指令系統(tǒng)采用命令樹來存儲指令,指令的查找和匹配操作通過遍歷命令樹來實(shí)現(xiàn)。
3.1.1 簡單的狀態(tài)轉(zhuǎn)移 對于指令數(shù)少、功能簡單的指令系統(tǒng),采用簡單的狀態(tài)轉(zhuǎn)移來對輸入的操作指令進(jìn)行匹配和執(zhí)行。其過程可視為有限狀態(tài)機(jī)(FSM)。每輸入一個(gè)命令字,程序相應(yīng)地做出反應(yīng),跳轉(zhuǎn)到不同的執(zhí)行指令處。每一個(gè)轉(zhuǎn)移的狀態(tài)都在程序中對應(yīng)一條控制轉(zhuǎn)移指令。
3.1.2 命令樹 計(jì)量器具中復(fù)雜的指令系統(tǒng)按命令樹對命令進(jìn)行存儲。命令格式為樹狀層次結(jié)構(gòu),具有多個(gè)命令子系統(tǒng),每個(gè)命令子系統(tǒng)又具有多個(gè)子命令。
1)命令樹存儲 命令樹結(jié)構(gòu)為多棵二叉樹的形式,常見的方法為將命令樹存儲為多叉樹結(jié)構(gòu),并將多叉樹轉(zhuǎn)化為鏈?zhǔn)蕉鏄湫问?,簡化了命令樹的存儲和遍歷操作。采用孩子兄弟法用來存儲命令樹,將每一個(gè)命令子系統(tǒng)存儲為一棵二叉樹,公用命令則是一棵只有根結(jié)點(diǎn)的二叉樹。一棵完整的命令樹由每一個(gè)子系統(tǒng)根結(jié)點(diǎn)和公用命令結(jié)點(diǎn)組成命令樹的右鏈,各個(gè)子系統(tǒng)下的孩子結(jié)點(diǎn)組成左鏈。
2)命令樹查找 命令查找過程是程序根據(jù)用戶輸入的指令,遍歷命令樹,跳轉(zhuǎn)到相應(yīng)的處理指令。具體過程如下:根據(jù)用戶輸入的命令字符串,分離命令字和參數(shù),并將參數(shù)保存至參數(shù)表。取第一個(gè)命令字,從命令樹的右分支開始查找,若匹配則在此結(jié)點(diǎn)的左分支進(jìn)行下一等級結(jié)點(diǎn)的匹配和查找;若不匹配則在此結(jié)點(diǎn)同一等級的右分支查找。對于不匹配的命令,報(bào)告輸入錯(cuò)誤信息,對于匹配的命令,則執(zhí)行相應(yīng)地址處的控制轉(zhuǎn)移指令。
在計(jì)量程序中,對輸入的命令進(jìn)行查找、匹配、執(zhí)行的過程都伴隨著程序指令的轉(zhuǎn)移和執(zhí)行,通過記錄計(jì)量程序執(zhí)行指令流可以得到計(jì)量程序的執(zhí)行軌跡。
執(zhí)行路徑跟蹤算法要對程序執(zhí)行系統(tǒng)級測試命令的匹配和執(zhí)行過程中的狀態(tài)轉(zhuǎn)移路徑進(jìn)行跟蹤,并記錄為執(zhí)行路徑。具體動態(tài)跟蹤方法為:以8052系列單片機(jī)仿真平臺執(zhí)行目標(biāo)二進(jìn)制可執(zhí)行程序?yàn)榛A(chǔ),通過在路徑跟蹤過程中對代碼指令進(jìn)行解碼,以基本塊為處理單位,判斷指令的類型,若指令為條件轉(zhuǎn)移指令,則作為路徑節(jié)點(diǎn)進(jìn)行處理?;緣K劃分示意圖如圖1所示。
圖1 基本塊劃分示意圖
具體實(shí)現(xiàn)如下:執(zhí)行路徑跟蹤采用記錄以條件轉(zhuǎn)移指令為界劃分的基本塊的首末指令地址?;緣K內(nèi)為順序執(zhí)行的指令流,除末尾一條指令為條件轉(zhuǎn)移指令外,塊內(nèi)無多余的條件轉(zhuǎn)移指令。條件轉(zhuǎn)移指令和無條件轉(zhuǎn)移指令共同構(gòu)成二進(jìn)制程序中的控制轉(zhuǎn)移指令,其中程序執(zhí)行無條件轉(zhuǎn)移指令后將自動跳轉(zhuǎn)并執(zhí)行下一條指令,不會改變基本塊內(nèi)指令流執(zhí)行順序;只有執(zhí)行條件轉(zhuǎn)移指令時(shí),程序根據(jù)判定條件會出現(xiàn)不同轉(zhuǎn)移分支,此時(shí)基本塊發(fā)生分割。條件轉(zhuǎn)移指令位于基本塊的末尾,將當(dāng)前條件轉(zhuǎn)移指令歸為上一基本塊,指令地址為上一基本塊的末地址;通過計(jì)算條件轉(zhuǎn)移指令的地址可得到將要執(zhí)行的基本塊的首指令地址,按照取得末指令地址的方法,在下一個(gè)條件轉(zhuǎn)移指令處可得到該基本塊的最后一條指令地址。其中轉(zhuǎn)移地址為入口函數(shù)地址的條件轉(zhuǎn)移指令的首指令地址處理同上。執(zhí)行路徑跟蹤算法流程如圖2所示。
圖2 執(zhí)行路徑跟蹤算法
在8052系列單片機(jī)指令集中,控制轉(zhuǎn)移指令包括條件轉(zhuǎn)移指令JZ,JNZ,JC,JB,JNE,以及無條件轉(zhuǎn)移指令JMP,CALL。單片機(jī)仿真平臺執(zhí)行指令時(shí)定義一個(gè)變量保存當(dāng)前執(zhí)行指令的地址,根據(jù)地址取出第一個(gè)指令字解碼判斷指令功能,并計(jì)算要取的操作數(shù)字長。若當(dāng)前指令判斷為控制轉(zhuǎn)移指令,根據(jù)取出的操作數(shù)可算出跳轉(zhuǎn)指令地址。每執(zhí)行一條指令都判斷是否為控制轉(zhuǎn)移指令,若是條件轉(zhuǎn)移指令,則后門跟蹤模塊對其做存儲基本塊首尾指令地址的處理。下面的代碼片段以JNZ指令處理為例,說明路徑跟蹤的方法:
vector<unsigned>copy_PC0;//定義vector變量copy_PC0,記錄基本塊的首地址
vector<unsigned>copy_PC1;//定義vector變量copy_PC1,記錄基本塊的首地址
unsigned i8052_PC;//i8052_PC保存仿真平臺當(dāng)前執(zhí)行的指令地址
……
以上基本塊首末指令地址的處理方法以條件跳轉(zhuǎn)指令JNZ指令的處理為例,記錄執(zhí)行路徑經(jīng)過的基本塊。本模塊采用跟蹤條件轉(zhuǎn)移指令為執(zhí)行路徑,不同于全路徑跟蹤。所跟蹤到的路徑指令為非連續(xù)地址的指令流,將跟蹤到的條件轉(zhuǎn)移指令串聯(lián)起來就是一次執(zhí)行的一條完整路徑。
[1]王林波,沈春磊,趙書展,等.如何治理加油機(jī)高科技計(jì)量作弊[J].上海計(jì)量測試,2007,34(03):47-49.
[2]王鳳翔.淺析燃油加油機(jī)的防作弊措施[J].科技信息,2012(23):103-103.
[3]Rieck K,Holz T,Willems C,etal.Lear ning and classification of mal ware behavior[M].Detection of Intr usions and Mal ware,and Vulnerability Assessment.Springer Berlin Heidelber g,2008:108-125.
[4]Rieck K,Trinius P,Willems C,etal.Automatic analysis of mal ware behavior using machine lear ning[J].Journal of Computer Security,2011,19(04):639-668.
[5]Roberto B,Matthien C,Roberta G,etal.Sy mbolic Path-Oriented Test Data Generation for Floating-Point Programs[C].Proc of the 6th IEEE Int.Conf.on Soft ware Testing, Verification and Validation(ICST13),2013.
[6]Panchapakesan A,Abiel mona R,Petriu E,etal.Dynamic white-box soft ware testing using a recursive hybrid evolutionary strategy/genetic algorithm[C].Evolutionary Computation (CEC),2013 IEEE Congress on.IEEE,2013:2 525-2 532.