一種智能電表的軟件一致性檢測方法
【技術領域】
[0001] 本發明主要涉及計算機學科中的固件逆向工程技術、反匯編和反編譯技術、嵌入 式系統設計技術,特別是其中的反匯編和反編譯技術,具體涉及一種智能電表的軟件一致 性檢測方法。本發明是對逆向工程技術中軟件可靠性問題的合理剖析,可以有效解決智能 電表在生產過程中出現的樣品表與批量表的運行差異問題。
【背景技術】
[0002] 在智能電表的生產過程中,往往采用公開招標的方式選擇生產商為其制造預定規 格的電表。一旦競標成功,生產商便生產大批量電表用于投入使用。由于各種因素導致很 難保證大批量電表與樣品表的規格完全一致,因而在智能電表投入使用時經常出現工作狀 態異常、質量不合格的情況。因此對智能電能表進行軟件功能檢測工作迫在眉睫。由于在 智能電表測試中發現樣品表的質量和功能遠遠優于批量生產的電表。因此,需要提出一種 智能電表的軟件一致性檢測方法,并設計出一種智能電能表反匯編儀對兩種表型進行比較 鑒別,控制批量生產的智能電能表與樣品表的功能和質量誤差在一定范圍內。
【發明內容】
[0003] 本發明主要是解決現有技術所存在的技術問題;提供了一種用以實現兩個智能電 表之間的代碼功能比對情況。對比目前市場上出現的比較單一依靠反匯編或者反編譯的技 術實例,本發明提出的方法將反匯編與反編譯結合,系統地實現了智能電表從機器碼到高 級語言的處理,在語法和語義層次上均達到了最完整的蘊涵程度的一種智能電表的軟件一 致性檢測方法。
[0004] 本發明的上述技術問題主要是通過下述技術方案得以解決的:
[0005] -種智能電表的軟件一致性檢測方法,其特征在于,包括:
[0006] -個對智能電能表內部機器碼提取的步驟:提取智能電能表嵌入式主板的 EEPROM和MCU內部基于二進制表示的機器碼;
[0007] -個反匯編的步驟:將二進制表示的機器碼轉換為基于指定處理器的匯編指令; 依據處理器指令集的類型進行選擇靜態反匯編算法,具體是:
[0008] 選擇一:對于定長指令集,根據每條指令的長度將機器碼進行劃分,進而判斷指令 類型并進行處理;
[0009] 選擇二:對于變長指令集,從機器碼起始地址開始采取操作碼遍歷的方式獲取第 一個有效操作碼,根據該操作碼確定當前指令的長度,進而得到下一條指令的起始地址;然 后,使用遞歸的方法根據下一條指令的起始地址確定下下一條指令的長度……如此循環 下去,最終得到所有指令的操作碼長度和指令長度,根據這些信息判斷指令類型并進行處 理;
[0010] -個中間語言優化的步驟:將指定處理器的不同格式的匯編指令統一為一種中間 指令表示,以便于接下來反編譯流程的運作;將反匯編得到的匯編指令按照類別進行處理: 對于賦值類指令(如加、減、乘、除運算等),將其直接轉換為相應的運算表達式;對于無條 件轉移指令JMP,直接使用C語言中的GOTO語句替代;對于有條件轉移指令,保留其語句不 變,直接由程序流分析模塊進行處理;對于CALL過程調用,直接構造子函數進行抽象;對于 返回指令RET和堆棧指令PUSH和POP,保留其語句不變,直接由控制流分析模塊進行處理; 對于其它指令,由于沒有顯式的高級語言對應語句,故直接略去;
[0011] 一個反編譯的步驟:反編譯的目的是進行中間語言到C語言的轉換,分為前端, 數據流分析和后端;
[0012] -個代碼結構分析的步驟:完成對反編譯產生的高級語言(即由反編譯步驟7得 到的C語言)中的代碼結構的抽象化,即所謂的控制流分析;其實現過程包括:產生一組包 含各類信息的節點結構的中間文件解析模塊、在畫布特定位置繪制相應的圖形,矩形或者 菱形的函數繪制模塊、將函數繪制模塊繪制出來的圖形,按照特定的規則連接起來,從而形 成控制流圖函數連線模塊;具體方法是:
[0013] 步驟1 :由中間文件解析模塊產生一組包含各類信息的節點結構,詳細步驟如下:
[0014] 步驟I. 1 :打開輸入文件,獲取輸入文件流;通過調用C++中庫函數fopenO,并選 擇rt模式,即打開文本文件,允許讀與寫;
[0015] 步驟1. 2 :初始化節點信息;
[0016] 步驟1. 3 :解析文件的輸入流,以while語句進行遍歷,直至遍歷至文件結束標記 符;
[0017] 步驟1. 4 :在遍歷時,碰到換行符時將節點中funid屬性加一,并且記錄每一行的 起始的空格數目,并將結果作為節點的deep屬性;
[0018] 步驟1. 5 :調用私有函數GetName獲取每個節點的名字;在GetName函數中我們需 要特殊處理含有if, switch, while, else關鍵字的節點;在遍歷到此類節點的時候,我們去 除這些關鍵字,而只留下剩余的信息,即判斷條件;與此同時,修改節點中的type信息,根 據關鍵字的不同,修改為 IFTYPE, WHILETYPE, SWITCHTYPE, ELSETYPE ;
[0019] 步驟1. 6 :為ELSETYPE類型的節點找到與其配對的IFTYPE類型的節點;
[0020] 步驟1. 7 :為節點添加父節點和孩子節點信息;其中獲取孩子節點信息的方法為, 向下遍歷,直到碰到深度比本節點小于等于的節點則停止遍歷,否則將深度比自己大一的 節點加入孩子節點數組;獲取其父節點信息的方法為,向上遍歷,直到找到第一個深度小于 本節點的函數節點,則為雙親節點;
[0021] 步驟I. 8 :IF、WHILE、SWITCH模塊結束位置確定;中間文件解析后,產生的結果為 一組包含各類信息的節點結構;
[0022] 步驟2 :函數繪制模塊在畫布特定位置繪制相應的圖形,矩形或者菱形,詳細步驟 如下:
[0023] 步驟:2. 1 :遍歷經過中間文件解析模塊后的節點信息,當此節點擁有孩子節點并 且此節點的類型為FUNTYPE時,將此節點作為新的一行的起始節點;
[0024] 步驟2. 2 :計算每一行起始節點的Y軸方向的偏移量;這個偏移量由兩個方面的 因素所主導;其一,起始行節點的序列;其二,在此節點之前,若其他行中含有IFTYPE節點, ELSETYPE節點,WHILETYPE節點,SWITCHTYPE節點,那么需特別計算偏移量,因為以上這些 節點都會在Y軸方向存在增量;
[0025] 步驟2. 3 :計算新行首節點之后,繪制首節點圖像,即矩形;
[0026] 步驟2. 4 :將首節點位置信息,填入狀態信息結構體中;
[0027] 步驟2. 5 :在步驟三繪制的矩形框中間添加函數名稱信息;
[0028] 步驟2. 6 :遍歷新行的首節點的子孩子節點,繪制子孩子節點形狀;
[0029] 步驟2. 7 :繪制子孩子節點時,首先確定子孩子節點的位置信息,其次判斷子孩子 節點的類型信息;子孩子節點的位置信息也會由其之前的IFTYPE節點,ELSETYPE節點, WHILETYPE節點,SWITCHTYPE節點所影響,例如ELSETYPE類型的節點會出現在下面的一行 中,因此ELSETYPE類型節點的子孩子,不應該算在偏移量中;確定位置信息之后,為孩子節 點添加名稱;
[0030] 步驟3 :函數連線模塊將函數繪制模塊繪制出來的圖形,按照特定的規則連接起 來,從而形成控制流圖,詳細步驟如下:
[0031 ] 步驟:3. 1 :尋找每一行的起始節點,并將起始節點的出口坐標傳遞;
[0032] 步驟3. 2 :遍歷起始節點的孩子節點;子孩子節點可能有五種情況,分別是: IFTYPE,WHILETYPE,ELSETYPE,SWITCHTYPE,FUNCTYPE,具體是:
[0033] 條件情況一 =IFTYPE情況下分為兩部分,原因是IFTYPE和ELSETYPE不一定成對 出現;在IFTYPE情況下,首先將IFTYPE節點與傳遞進來的出口坐標相連,接下來對IFTYPE 節點的子孩子進行遍歷,遍歷之后獲取最后一個節點的橫坐標,并將該橫坐標值與IFTYPE 節點中標記的終止節點相連接;其次處理不含有ELSETYPE節點的IFTYPE節點;先計算此 IF塊中含有多少個IFTYPE,多少個WHILETYPE,以及多少個SWITCHTYPE ;將這作為轉折點的 縱坐標偏移量;并將此轉折點與IFTYPE節點菱形的下部節點相連,代表著不滿足IFTYPE節 點的路徑;
[0034] 條件情況二:WHILETYPE情況下,首先將WHILETYPE節點與傳遞進來的出口坐標相 連,接下來對WHILETYPE節點的子孩子進行遍歷,遍歷之后獲取最后一個節點的橫坐標,并 將該橫坐標值與WHILETYPE節點中標記的終止節點相連接;其次在WHILETYPE類型的菱形 節點的上部作為一個出口節點,接下來計算WHILETYPE類型節點函數域內是否包含有其他 WHILETYPE類型節點,以及這些節點的數目;將WHILETYPE節點的數目作為偏移量,從而在 菱形上部確定轉折點縱坐標位置,此條連線代表不滿足判斷條件所走路徑;在菱形下部的 頂點引出一條折線,代表在滿足條件之后返回WHILETYPE節點,再次進行判斷條件;
[0035] 條件情況三:ELSETYPE情況下,首先找到與其配對的IFTYPE節點,在找到與其配 對的IFTYPE節點之后,再次計算IFTYPE節點塊中含有多少個IFTYPE,多少個WHILETYPE, 以及多少個SWITCHTYPE,以這些作為偏移量在IFTYPE節點的下方確定ELSETYPE節點的坐 標;接下來將ELSETYPE節點與IFTYPE菱形節點的下部相連接;隨后遍歷ELSETYPE節點的 子孩子節點;
[0036] 條件情況四:SWITCHTYPE情況下,首先將SWITCHTYPE節點與傳遞進來的出口坐標 相連接,接下來對SWITCHTYPE節點的子孩子進行遍歷,遍歷之后,獲取最后一個節點的橫 坐標值,并將橫坐標值與S