999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于虛擬機的程序運行時監(jiān)控方法

2018-01-15 09:19:58王丹陳嘉趙文兵林九川
哈爾濱工程大學學報 2017年12期
關(guān)鍵詞:進程指令程序

王丹, 陳嘉, 趙文兵, 林九川

(1.北京工業(yè)大學 信息學部,北京 100124; 2.公安部第三研究所 信息網(wǎng)絡(luò)安全公安部重點實驗室,上海 201204)

為對程序運行時行為進行監(jiān)控和分析,通常是在運行時通過插樁、跟蹤調(diào)試等程序動態(tài)分析技術(shù)來完成。動態(tài)二進制插樁技術(shù)[1](dynamic binary instrument,DBI),是在不改變程序原有邏輯的基礎(chǔ)上,將一些探針插入到程序中,通過執(zhí)行探針得到程序運行的特征數(shù)據(jù),再分析這些特征數(shù)據(jù)完成對程序的分析[2-3]。DynamoRIO[4]、Valgrind[5]等是常用的動態(tài)二進制插樁工具,它們具有較完善的結(jié)構(gòu),但均是面向進程的,工作在用戶層,依靠動態(tài)插樁技術(shù)實現(xiàn)的,導致其難以實現(xiàn)對驅(qū)動、多進程、管道通信等的分析檢測,因此并不適合做與系統(tǒng)運行相關(guān)的內(nèi)核分析。

跟蹤調(diào)試技術(shù)使用調(diào)試器來加載程序,通過跟蹤程序運行時調(diào)用的函數(shù)及執(zhí)行的指令等來獲取相關(guān)信息。常用的跟蹤方法有兩種:一種是使用HOOK技術(shù)監(jiān)視程序運行調(diào)用的函數(shù)并進行分析;二是以較長的時間代價單步跟蹤程序的執(zhí)行過程并進行分析。但是,使用插樁技術(shù)會破壞程序運行現(xiàn)場和數(shù)據(jù)的完整性,也容易被惡意木馬反調(diào)試技術(shù)察覺和規(guī)避。

將程序置于虛擬機或虛擬機模擬器環(huán)境中運行以獲取其運行過程中的信息是另一種常用的程序運行時監(jiān)控方法,且該方法不受多態(tài)、變形和加密及程序中的間接跳轉(zhuǎn)和間接調(diào)用指令的影響。目前常用的虛擬機模擬分析工具有TEMU[6]、DECAF(dynamic executable code analysis framework)等,它們都基于QEMU平臺。QEMU是一個通用的開源模擬器和虛擬機。作為虛擬機使用時,QEMU可以在不同體系結(jié)構(gòu)的機器上運行同一個虛擬環(huán)境,安裝操作系統(tǒng)并運行程序,QEMU提供了多種接口供開發(fā)人員使用,采用動態(tài)翻譯技術(shù),將虛擬環(huán)境中的目標程序翻譯成宿主機器語言,先對基本塊進行翻譯,然后再執(zhí)行并加以緩存,后續(xù)可直接使用緩存的代碼,無需重復翻譯。TEMU是基于QEMU開發(fā)的全系統(tǒng)的動態(tài)二進制分析平臺,它定義了一組API,用于獲取和設(shè)置內(nèi)存及CPU寄存器的值,并增加了語義提取模塊和污點分析模塊,為用戶開發(fā)相關(guān)插件提供了接口。DECAF是在相關(guān)研究人員改進TEMU不足的基礎(chǔ)上生成的一個新的二進制框架,具有高效、污點信息分析完整等特性。DECAF也為開發(fā)人員提供了許多回調(diào)接口,通過這些回調(diào)接口開發(fā)人員可以開發(fā)出用于分析Guest操作系統(tǒng)執(zhí)行過程的強有力的插件。由于QEMU是面向系統(tǒng)的和基于事件驅(qū)動的,工作在系統(tǒng)層,能夠較為全面地對程序執(zhí)行流程實施監(jiān)控,避免插樁技術(shù)易被反調(diào)試的弊端。因此,本文基于虛擬機模擬技術(shù)的軟件行為監(jiān)控系統(tǒng),從系統(tǒng)視角獲取操作系統(tǒng)內(nèi)核狀態(tài)和多個進程的信息并進行分析。設(shè)計并實現(xiàn)了基于QEMU并配置DECAF的動態(tài)監(jiān)控平臺,被測程序在QEMU虛擬環(huán)境中運行,通過DECAF從外部監(jiān)視整個模擬器的運行情況,獲取系統(tǒng)級信息。

1 監(jiān)控框架及關(guān)鍵技術(shù)

1.1 監(jiān)控框架

圖1是總體的監(jiān)控系統(tǒng)架構(gòu)。首先在宿主機器上安裝QEMU并配置DECAF平臺,然后在全系統(tǒng)模擬器QEMU上安裝Windows XP操作系統(tǒng),再在虛擬環(huán)境的操作系統(tǒng)中執(zhí)行被監(jiān)控對象(如圖1中所示的PE文件)。DECAF從外部監(jiān)視整個模擬器的運行情況,獲取QEMU系統(tǒng)級語義信息。

如圖2所示,被測程序在QEMU虛擬環(huán)境中運行時,QEMU通過微指令生成器將多種不同結(jié)構(gòu)的程序代碼,如x86上的Windows、x86上的Linux、MIPS上的Linux等,翻譯為統(tǒng)一的中間語言。然后,QEMU再根據(jù)宿主系統(tǒng)不同的結(jié)構(gòu),將中間語言翻譯為宿主操作系統(tǒng)可識別的機器碼,進而運行程序。這一系列操作對用戶來說都是透明的。與此同時,DECAF在QEMU翻譯的基礎(chǔ)之上,獲取用戶分析所需的相關(guān)信息,如當前進程名稱、程序計數(shù)器、當前系統(tǒng)環(huán)境等信息并進行處理。另外,通過事件處理機制,可處理用戶注冊的感興趣的事件。當DECAF檢測到用戶注冊的事件在模擬系統(tǒng)中發(fā)生時,會觸發(fā)DECAF調(diào)用用戶注冊的響應(yīng)函數(shù),獲取當前系統(tǒng)環(huán)境數(shù)據(jù)和被監(jiān)控程序的信息并進行處理。

圖1 基于虛擬機的監(jiān)控系統(tǒng)架構(gòu)Fig.1 Monitoring framework based on virtual machine

圖2 平臺對照Fig.2 Platform contrast

1.2 動態(tài)二進制翻譯

基于虛擬機的動態(tài)二進制分析技術(shù),首先會對程序進行動態(tài)二進制翻譯,然后再去執(zhí)行翻譯的結(jié)果。這一功能主要依賴它的動態(tài)代碼生成器(TCG)。TCG采用動態(tài)的翻譯方式,主要負責分析并優(yōu)化目標代碼,然后將其翻譯為主機代碼,遵循從目標代碼、到TCG代碼、再到主機可識別代碼這樣的流程。具體翻譯過程如下:首先,將每一條目標代碼指令切分為若干個單元操作,每個單元操作由一段簡單的C語言代碼實現(xiàn),作為一個翻譯塊(TB)。TB是QEMU指令翻譯的基本單位,對應(yīng)目標代碼的一條指令。在程序運行時,利用動態(tài)代碼生成器將以上單元組合操作,以函數(shù)形式展現(xiàn)。系統(tǒng)調(diào)用這個函數(shù),就相當于執(zhí)行了一條目標代碼的指令。在翻譯過程中會涉及很多事件,如塊開始執(zhí)行/結(jié)束事件、內(nèi)存讀寫、被修改的內(nèi)存位置讀寫等。這些事件會在事件驅(qū)動中觸發(fā)函數(shù)調(diào)用。通過QEMU,目標代碼以翻譯塊為單位翻譯并生成中間代碼后放入翻譯緩存中,執(zhí)行過程如圖3所示。

1.3 事件驅(qū)動

DECAF提供了簡單易用的事件驅(qū)動程序接口,當監(jiān)測到被注冊的事件發(fā)生時,它會調(diào)用事先定義的相應(yīng)的事件處理函數(shù)。利用這一接口,分析人員根據(jù)自己的需求選擇注冊事件,并在事件發(fā)生時,進行相應(yīng)信息的提取和處理工作。因為要在事件發(fā)生時進行實時信息獲取,即注冊的事件在QEMU中發(fā)生后,會觸發(fā)所對應(yīng)的回調(diào)函數(shù),所以QEMU暫停客戶操作系統(tǒng)的運行,將DECAF的回調(diào)函數(shù)作為輔助函數(shù)插入到QEMU中,然后恢復QEMU的運行,這時回調(diào)函數(shù)就會被運行,如圖4所示。

圖3 翻譯過程Fig.3 Translation process

圖4 回調(diào)函數(shù)觸發(fā)過程Fig.4 Trigger process of callback function

當“翻譯塊開始/結(jié)束”,“讀取/寫入被污染的內(nèi)存位置”這樣的事件發(fā)生時,相應(yīng)的回調(diào)函數(shù)就會開始工作。DECAF通過接口將事件處理函數(shù)與事件相關(guān)聯(lián)。接收到事件的信號后,DECAF會在某個翻譯塊中插入一個輔助函數(shù),使客戶操作系統(tǒng)暫停運行,將輔助函數(shù)中的指令兩次翻譯到翻譯塊中,并覆蓋原有指令,然后恢復客戶系統(tǒng)的運行。為這些事件注冊的回調(diào)函數(shù)就會利用這些數(shù)據(jù)開始分析處理工作。因為回調(diào)函數(shù)的觸發(fā)和客戶系統(tǒng)的執(zhí)行是內(nèi)聯(lián)的,所以當事件發(fā)生時,回調(diào)函數(shù)的觸發(fā)和客戶系統(tǒng)的執(zhí)行也會同時發(fā)生。

// 開始翻譯塊

// 觸發(fā)DECAF_BLOCK_BEGIN回調(diào)

movi_i32 tmp21, $

movi_i32 tmp22, $DECAF_invoke_block_begin_callback

call tmp22, $0x0, $0, env, tmp21

// 初始化指令: orl %ebx, %eax

// 觸發(fā)DECAF_INSN_BEGIN回調(diào)

movi_i32 tmp23, $DECAF_invoke_insn_begin_callback

call tmp23, $0x0, $0, env

mov_i32 tmp11, ebx

mov_i32 tmp12, eax

or_i32 tmp13, tmp12, tmp11

// 觸發(fā)DECAF_INSN_END回調(diào)

movi_i32 tmp24, $DECAF_invoke_insn_end_callback

call tmp24, $0x0, $0, env

// 初始化指令: addl $0x01, %eax

// Insert DECAF_INSN_BEGIN callback

movi_i32 tmp25, $DECAF_invoke_insn_begin_callback

call tmp25, $0x0, $0, env

movi_i32 tmp14, $0x01

add_i32 tmp15, tmp14, tmp13

mov_i32 eax, tmp15

// 觸發(fā) DECAF_INSN_END 回調(diào)

movi_i32 tmp26, $DECAF_invoke_insn_end_callback

call tmp26, $0x0, $0, env

// 翻譯塊結(jié)束

// 觸發(fā) DECAF_BLOCK_END 回調(diào)

movi_i32 tmp27, $DECAF_invoke_block_end_callback

call tmp27, $0x0, $0, env

goto_tb $0x0

上面的代碼展示了輔助函數(shù)DECAF_invoke_insn_begin_callback 和 DECAF_invoke_insn_end_callback的使用,即在相應(yīng)的事件發(fā)生時,這兩個函數(shù)會被插入到客戶指令的開頭和結(jié)尾。

這里需要說明:事件對應(yīng)的回調(diào)函數(shù)調(diào)度機制的設(shè)計,即對于每一個事件,例如翻譯塊開始,只能插入一個輔助函數(shù),而不能在一個事件發(fā)生時,同時調(diào)用多個函數(shù)對數(shù)據(jù)進行處理,且在輔助函數(shù)內(nèi),會遍歷為該事件注冊的所有回調(diào)函數(shù),并且決定觸發(fā)哪個。該設(shè)計有兩個理由:1)各種插件和平臺自身對于同一個事件會注冊很多回調(diào)函數(shù),重復調(diào)用這些輔助函數(shù)會對系統(tǒng)的性能產(chǎn)生負面影響。而上面設(shè)計的調(diào)度機制可以避免輔助函數(shù)的內(nèi)聯(lián)重復調(diào)用這一問題。2)在全系統(tǒng)仿真模擬器中,插入到代碼流中的回調(diào)函數(shù)會在整個客戶操作系統(tǒng)環(huán)境中執(zhí)行,例如,指令碼被插入到一個共享庫中,就會被所有使用這個庫的程序執(zhí)行。所以需要調(diào)度機制來確保當前的執(zhí)行環(huán)境是否對每一個注冊的回調(diào)函數(shù)都是正確的,之后才可以決定執(zhí)行。

2 實例分析

目前的基于軟件行為的可疑軟件的分析和監(jiān)控可通過靜態(tài)分析或者動態(tài)學習,建立軟件的控制流行為模型來實現(xiàn),如統(tǒng)調(diào)用模型和函數(shù)調(diào)用模型[7-9]。控制流行為度量模型已被證明可以有效地檢測對于控制數(shù)據(jù)的攻擊[10-11],如惡意代碼注入攻擊、返回庫函數(shù)攻擊等常見的攻擊類型。在此背景下,本文從控制流的角度出發(fā),通過使用本文的監(jiān)控框架對程序的可疑性進行分析判斷。以圖5為例,這是一個簡單的判斷輸入信息是否為數(shù)字的程序。當程序正常運行時,即用戶從終端輸入數(shù)字的情況下,將susData賦值給memData,但是當用戶輸入的信息不是數(shù)字時,即視為程序異常,將會彈出對話框并對用戶進行提示。

//判斷輸入是否為數(shù)字

1)if(susData < ‘0’ || susData > ‘9’)

2)MessageBox(NULL, TEXT(“WRONG”), TEXT(“NOT A NUMBER”), MB_OK);

3)else

4)memData=susData;

5)cout 《susData;

圖5 程序正常運行路徑Fig.5 Normal runtime path

正常的運行流程的執(zhí)行順序應(yīng)為1→3→4→5,但是當程序異常時,執(zhí)行順序則為1→2→5,造成了程序的行為異常。這是由于在節(jié)點1的控制信息不同引發(fā)的。因此,可以通過監(jiān)測程序的控制流信息,了解到程序是否在預期的軌跡上正常運行,并以此為依據(jù),判斷程序的行為是否可疑。

2.1 基于標志寄存器的控制流信息搜集

在執(zhí)行條件跳轉(zhuǎn)指令時,匯編語言通過判斷標志位寄存器的情況來判斷是否進行跳轉(zhuǎn)。如匯編語言的JE指令在執(zhí)行的時候,系統(tǒng)會查詢標志寄存器中的ZF標志位的內(nèi)容。如果ZF=1,符合跳轉(zhuǎn)條件,則程序計數(shù)器會跳轉(zhuǎn)到目標地址;如果ZF=0,則說明跳轉(zhuǎn)條件不成立,程序計數(shù)器將會指向緊接著的下一條指令地址,順序執(zhí)行。通過獲取在每次跳轉(zhuǎn)時的標志位寄存器信息,加以處理整合,就可以得到程序運行過程中的控制流信息,并確定跳轉(zhuǎn)的目的地址。這里不考慮CALL指令和JMP指令這兩個跳轉(zhuǎn)指令,因為跳轉(zhuǎn)的目的地址在程序編寫時已經(jīng)確定,不受控制流信息影響。

2.2 事件驅(qū)動與回調(diào)函數(shù)的設(shè)計

基于事件驅(qū)動機制,本文設(shè)計了回調(diào)函數(shù)來收集控制流信息。由于QEMU中每一個翻譯塊對應(yīng)進程的一條指令,因此為了獲取條件跳轉(zhuǎn)指令,對代碼塊執(zhí)行結(jié)束事件(VM_BLOCK_END_CB)進行注冊。在事件發(fā)生時,調(diào)用回調(diào)函數(shù),該函數(shù)根據(jù)DECAF提供的用戶接口,對數(shù)據(jù)進行分析處理,完成控制流信息收集工作。

在回調(diào)函數(shù)中,需要獲取翻譯執(zhí)行結(jié)束時的系統(tǒng)狀態(tài)、翻譯塊的信息、當前程序計數(shù)器及下一條指令的程序計數(shù)器值。DECAF提供了DECAF_Block_End_Params數(shù)據(jù)結(jié)構(gòu),且將對這些變量的賦值過程進行了封裝,可直接使用。

typedef struct _DECAF_Block_End_Params

{

CPUState* env; //CPU環(huán)境

TranslationBlock* tb; //翻譯塊

gva_t cur_pc; //當前PE值

gva_t next_pc; //下一個PC值

} DECAF_Block_End_Params;

本文首先通過當前的PC值獲取當前指令,然后通過操作碼判斷指令類型。對于指令JE/JZ (ZF=1),其操作碼為01111110。可以通過操作碼判斷當前指令是否為條件跳轉(zhuǎn)指令,如果是,繼續(xù)進行下一步處理。由于DECAF通過QEMU提供的接口獲取CPU狀態(tài),并將CPU信息存儲在結(jié)構(gòu)體CPUState中,所以本文將該結(jié)構(gòu)體中的eflag的信息提取出來,并保存在記錄文件中。

在回調(diào)函數(shù)中,首先要初始化插件,然后獲取要檢測的程序名稱和保存結(jié)果的記錄文件名稱。根據(jù)事件驅(qū)動原理,當有新的程序被調(diào)用的時候,判斷是否為被測程序,如果是,則開始信息獲取工作,再根據(jù)指令的操作碼判斷當前指令是否為條件跳轉(zhuǎn)指令。如果否,則獲取虛擬機當前的操作系統(tǒng)狀態(tài),并且保存在記錄文件中。然后,繼續(xù)按照此判斷和記錄原則監(jiān)控和跟蹤程序的動態(tài)運行。當程序結(jié)束時,注銷翻譯塊結(jié)束事件發(fā)生時要調(diào)用的相關(guān)函數(shù),最后清理插件資源。

3 測試平臺部署與運行

3.1 測試環(huán)境構(gòu)建

本文選用虛擬機QEMU,可以直接使用如下命令進行QEMU安裝。

$ sudo apt-get install qemu sudo apt-get build-dep qemu

對于DECAF,需要安裝BFD庫和boost庫,命令如下:

$ sudo apt-get install binutils-dev

$ sudo apt-get install libboost-all-dev

在準備好庫后,開始進行配置和編譯工作。DECAF有三個基本的功能設(shè)置:TCG污點傳播、VMI和TCG IR日志。因本文只涉及到虛擬機自省技術(shù)(virtual machine instropection,VMI),所以只啟用這一功能。然后進行編譯,QEMU就可以運行了,指令如下:

$ sudo config make install

完成QEMU的安裝之后,就可以開始在其上安裝操作系統(tǒng)鏡像,創(chuàng)建所需使用的虛擬機。雖然QEMU本身已經(jīng)幾乎和任何運行x86體系結(jié)構(gòu)的客戶操作系統(tǒng)兼容,然而DECAF需要更多關(guān)于操作系統(tǒng)的信息,進行語義翻譯,提供更多諸如進程的操作系統(tǒng)抽象信息,所以從打開虛擬機開始,使用DECAF控制QEMU運行。

鏡像準備好之后,可以加載QCOW格式的鏡像到QEMU中,完成虛擬機的創(chuàng)建。接下來,通過終端啟動QEMU并運行虛擬機,QEMU窗口就會彈出,可以看到虛擬機啟動情況。

3.2 控制流信息獲取過程

3.2.1 注冊關(guān)注事件

根據(jù)DECAF的事件驅(qū)動機制,用戶可選擇所關(guān)注的事件進行注冊,并根據(jù)這個事件的發(fā)生,獲取系統(tǒng)信息,進行相應(yīng)的處理與分析。首先通過如下命令注冊新進程開始事件:handle_load_mainmodule=VMI_register_callback(VMI_CREATEPROC_CB,ProcessTrace_loadmainmodule_notify,&should_monitor);

同樣地,在被測程序關(guān)閉后,監(jiān)控工作也應(yīng)該自動結(jié)束,并且對注冊的時間關(guān)聯(lián)函數(shù)進行注銷,實現(xiàn)代碼如下:

handle_remov_process=VMI_register_callback(VMI_REMOVEPROC_CB,ProcessTrace_procexit,&should_monitor);

當新的進程開始運行這一事件發(fā)生后,所需要進行的操作如下。首先需要判斷新開始運行的這個進程是否為被測進程,這可以通過獲取QEMU當前系統(tǒng)環(huán)境信息實現(xiàn)。具體數(shù)據(jù)結(jié)構(gòu)設(shè)計如下:

typedef struct _VMI_CreateProc_Params {

uint32_t pid; //新進程PID

uint32_t cr3; //新進程CR3

char *name; //新進程名稱

}VMI_CreateProc_Params;

將當前程序的名稱與被檢測的進程名稱進行對比,如calc.exe。判斷當前程序的名稱是否與用戶輸入的要監(jiān)控的進程名稱一致。如果不一致,繼續(xù)等待下一個新進程被運行;如果一致,首先在終端輸出,告知用戶被監(jiān)控程序已經(jīng)開始。

程序運行后,系統(tǒng)會為程序分配一個進程PID,并根據(jù)當前程序運行情況,將被測程序的PID存入到被測程序的數(shù)據(jù)結(jié)構(gòu)中。同樣,將CR3寄存器的內(nèi)容進行保存。根據(jù)以上需求,被監(jiān)控程序需要采用如下數(shù)據(jù)結(jié)構(gòu)來保存相關(guān)信息。

struct monitored_proc {

char name[512]; //被測進程名稱

char configfile[512];//編譯文件

uint32_t cr3; //被測進程CR3

uint32_t pid; //被測進程PID

FILE *tracefile; //記錄文件地址

};

接下來,注冊事件發(fā)生時要調(diào)用的相關(guān)函數(shù),DECAF_registerOptimizedBlockEndCallback,具體實現(xiàn)方法如下:

static void

ProcessTrace_loadmainmodule_notify(VMI_Callback_Params *pcp)

{ char *errorstring;

int i;

uint32_t pid=pcp->cp.pid; //獲取進程的id

char *name=pcp->cp.name; //獲取進程的名稱

if(strlen(mon_proc.name) > 0)

{ //檢查目標進程的名稱是否有效

if(strcmp(mon_proc.name, name)==0)

{ //創(chuàng)建的進程名稱與目標進程名稱一致

printf("%s is starting! ",mon_proc.name);

//輸出目標進程開始執(zhí)行的信息

mon_proc.pid=pid; //設(shè)置目標進程的id

mon_proc.cr3=VMI_find_cr3_by_pid_c(pid);

//設(shè)置目標進程的cr3

/ / 進行開始執(zhí)行, 注冊回調(diào)函數(shù)

if (!handle_block_end)

//注冊block end事件,開始對進程的控制流進行監(jiān)控和收集

handle_block_end=

DECAF_registerOptimizedBlockEndCallback(do_block_end, NULL, INV_ADDR,INV_ADDR);

}

}

}

相應(yīng)地,在被測程序關(guān)閉后,需要注銷已經(jīng)注冊的事件。首先,在終端提示用戶被監(jiān)控進程已關(guān)閉,監(jiān)控任務(wù)結(jié)束后,關(guān)閉記錄文件;然后清空被監(jiān)控程序的數(shù)據(jù)結(jié)構(gòu)中對應(yīng)的相應(yīng)數(shù)據(jù),最后利用DECAF提供的指令完成事件注銷。具體代碼如下:

int i=0;

uint32_t pid=pcp->rp.pid; //被刪除進程Pid

if(pid==mon_proc.pid) { //如果是被測進程

//輸出相關(guān)信息

printf("%s is closed. ", mon_proc.name);

printf("%d kernel calls found. ", kcount);

//關(guān)閉文件

fclose(mon_proc.tracefile);

mon_proc.tracefile=NULL;

if (handle_block_end) //如果有回調(diào)函數(shù)

DECAF_unregisterOptimizedBlockEndCallback(handle_block_end); //注銷

}

3.2.2 判斷獲取時機

確定被監(jiān)測程序之后,可以開始控制流信息的獲取。當翻譯塊執(zhí)行結(jié)束這一事件發(fā)生時,可以獲取到當前指令內(nèi)容。首先通過當前系統(tǒng)的環(huán)境變量參數(shù)來判斷系統(tǒng)是否處于內(nèi)核態(tài),如果是內(nèi)核態(tài),則說明正在執(zhí)行內(nèi)核相關(guān)的系統(tǒng)調(diào)用指令,不需要進行分析處理,直接返回,等待下一個關(guān)注事件發(fā)生。 DECAF提供了一個回調(diào)函數(shù)聯(lián)合體,根據(jù)不同的事件,提供不同的參數(shù)。聯(lián)合體的數(shù)據(jù)結(jié)構(gòu)如下:

typedef struct _DECAF_Callback_Params

{

DECAF_Handle cbhandle;

union{

DECAF_Block_Begin_Params bb;

DECAF_Block_End_Params be;

DECAF_Insn_Begin_Params ib;

DECAF_Insn_End_Params ie;

DECAF_Mem_Read_Params mr;

DECAF_Mem_Write_Params mw;

DECAF_EIP_Check_Params ec;

DECAF_Keystroke_Params ks;

DECAF_Nic_Rec_Params nr;

DECAF_Nic_Send_Params ns;

DECAF_Opcode_Range_Params op;

DECAF_Tlb_Exec_Params tx;

DECAF_Read_Taint_Mem rt;

DECAF_Write_Taint_Mem wt;

#ifdef CONFIG_TCG_LLVM

DECAF_Block_Trans_Params bt;

#endif /* CONFIG_TCG_LLVM */

};

} DECAF_Callback_Params;

在這部分,本文關(guān)注翻譯塊執(zhí)行結(jié)束事件,即“DECAF_Block_End_Params”這一類型。這一類型中有四個變量:當前CPU狀態(tài)、翻譯塊指針、當前程序PC值和下一個PC值,數(shù)據(jù)結(jié)構(gòu)如下:

typedef struct _DECAF_Block_End_Params

{

CPUState* env; //CPU狀態(tài)

TranslationBlock* tb; //翻譯塊

gva_t cur_pc; //當前PC

gva_t next_pc; //下一個PC

} DECAF_Block_End_Params;

通過傳入第一個變量env可以利用DECAF的判斷函數(shù)判斷當前系統(tǒng)是否處于內(nèi)核狀態(tài)。若系統(tǒng)不處于內(nèi)核態(tài),則意味著當前指令屬于被測進程,通過當前PC值,獲取匯編指令對應(yīng)的指令編碼。由于本文主要關(guān)注條件跳轉(zhuǎn)指令,通過其獲取控制流信息內(nèi)容,而在Windows_x86系統(tǒng)中,編碼第一字節(jié)的內(nèi)容為指令的操作碼,可以根據(jù)操作碼判斷當前指令是否為條件跳轉(zhuǎn)指令。

然后,判斷當前指令所屬的進程是否為監(jiān)視進程。可通過DECAF提供的宏,獲取當前CR3寄存器的值。因為每一個進程都有自己的CR3寄存器內(nèi)容,所以可以根據(jù)這個值進行判斷。如果指令不屬于被監(jiān)控程序,則直接返回,等待下一個翻譯塊執(zhí)行事件的發(fā)生。如果是被監(jiān)控進程,則繼續(xù)下面的相關(guān)信息的提取工作。

3.2.3 提取相關(guān)信息

確定當前指令是屬于被監(jiān)控程序的一條跳轉(zhuǎn)指令后,開始獲取當前系統(tǒng)標志位寄存器狀態(tài)的工作。在x86系統(tǒng)中,有一個32位的標志寄存器。在初始化時,x86的標志寄存器狀態(tài)為00000002H,第1、3、5、15以及22~31位被系統(tǒng)預留,內(nèi)容固定,不表示任何具體信息,程序的運行也不會以這些位的內(nèi)容為依據(jù)。標志位寄存器的值不能被整體復制或修改,因為它們都是根據(jù)特定指令,由系統(tǒng)進行修改,例如cmp指令,執(zhí)行后不保留運算結(jié)果,只對標志寄存器產(chǎn)生影響,然后通過其他相關(guān)指令訪問這些被影響的標志寄存器,來產(chǎn)生對整個程序的影響。但是,通過DECAF提供的接口,可以直接將標志寄存器的信息賦值給特定類型的變量,然后將其輸出到記錄文件中。

本文設(shè)計的獲取eflags的變量類型定義如下。因為DECAF支持多種體系結(jié)構(gòu)和操作系統(tǒng)的虛擬機,所以根據(jù)不同的虛擬機類型,有一套對應(yīng)機制。如果是32位系統(tǒng),則將獲取eflags的變量類型定位為32位,對于64位的操作系統(tǒng)也進行相應(yīng)的定義。

#if TARGET_LONG_SIZE==4

//如果目標代碼長4字節(jié),按如下方式進行定義

//定義long型

typedef int32_t target_long

__attribute__((aligned(TARGET_LONG_ALIGNMENT)));

//定義無符號long型

typedef uint32_t target_ulong

__attribute__((aligned(TARGET_LONG_ALIGNMENT)));

//定義lx

#define TARGET_FMT_lx "%08x"

//定義ld

#define TARGET_FMT_ld "%d"

//定義lu

#define TARGET_FMT_lu "%u"

#elif TARGET_LONG_SIZE==8

//如果目標代碼長8字節(jié),按如下方式進行定義

typedef int64_t target_long

__attribute__((aligned(TARGET_LONG_ALIGNMENT)));

typedef uint64_t target_ulong

__attribute__((aligned(TARGET_LONG_ALIGNMENT)));

#define TARGET_FMT_lx "%016" /*PRIx64*/

#define TARGET_FMT_ld "%" PRId64

#define TARGET_FMT_lu "%" PRIu64

#else

#error TARGET_LONG_SIZE undefined

#endif

3.3 封裝功能

通過以上過程得到了程序動態(tài)運行過程中的控制流信息。下面需要對功能進行封裝,完成與DECAF平臺接口的連接工作和用戶交互的實現(xiàn)。

用戶使用本項目所提供的功能時,需要在命令行輸入如下命令:

trace_process process_name trace_file_name

其中,包含兩個參數(shù):進程名和記錄文件名稱。

在Linux中,通過定義命令配置文件,將實現(xiàn)功能的函數(shù)與命令綁定。具體來說,當用戶在終端輸入trace_process命令時,調(diào)用do_trace_process()函數(shù)。實現(xiàn)代碼如下:

{//命令名稱

.name=“trace_process”,

//命令類型

.args_type="proc_name:s,tracefile:F",

//命令處理函數(shù)

.mhandler.cmd=do_trace_process,

//記錄文件

.params=“process_name trace_file_name”,

//使用說明

.help="Trace by name of the process. The process must not have started yet. The trace is saved to the said file.",

}

然后,do_trace_process()函數(shù)從命令行提取參數(shù),具體實現(xiàn)代碼如下:

//獲取進程名稱

const char *procname=qdict_get_str(qdict,

“proc_name”);

//獲取記錄文件路徑

const char *tracefile_path=qdict_get_str(qdict, “tracefile”);

存放被監(jiān)測程序信息的結(jié)構(gòu)體設(shè)計如下。

struct monitored_proc {

char name[512]; //進程名稱

char configfile[512]; //配置文件

uint32_t cr3; //CR3寄存器

uint32_t pid; //進程ID

FILE *tracefile; } //記錄文件

首先,命令的參數(shù)中,用戶輸入的被測程序的名字記錄到結(jié)構(gòu)體對應(yīng)的變量中;然后,根據(jù)用戶輸入的記錄文件路徑嘗試打開文件,如果路徑無效或者文件無法打開,則在終端給用戶提示,不進行后續(xù)工作。該處理可以增強程序的健壯性。如果文件可以成功打開,則將記錄文件路徑寫入結(jié)構(gòu)體,然后等待被測程序運行,并通過終端告知用戶程序開始運行。

下面是Linux命令處理模塊的部分代碼。模塊的輸入信息為被測程序和記錄文件。

int i;

FILE *tracefile;

//新建進程如果是被測進程

if(strcmp(mon_proc.name, procname)==0) {

printf("Process %s already being traced. ", procname);

return;

}

//保存被測進程名稱

strncpy(mon_proc.name, procname, 512);

mon_proc.name[511]='

主站蜘蛛池模板: 精品国产网| 亚洲高清国产拍精品26u| 国产97区一区二区三区无码| 欧美午夜在线观看| 四虎精品免费久久| 黄片一区二区三区| 免费在线观看av| 被公侵犯人妻少妇一区二区三区| 亚洲91在线精品| 国产精品无码翘臀在线看纯欲| 二级特黄绝大片免费视频大片| 亚洲香蕉在线| 国产最新无码专区在线| 五月综合色婷婷| 久久精品电影| 国产成人91精品免费网址在线| 国产日韩欧美视频| 亚洲区第一页| 四虎国产精品永久一区| 久久人体视频| 97在线公开视频| 中国精品自拍| 久久99热66这里只有精品一| 无码日韩人妻精品久久蜜桃| 国产精品男人的天堂| 58av国产精品| 一本久道热中字伊人| 亚洲国产AV无码综合原创| 国产成人亚洲欧美激情| 亚洲精品无码高潮喷水A| 伊人中文网| 欧美日韩福利| 久久91精品牛牛| 亚洲人成在线精品| 国产自在自线午夜精品视频| 中文国产成人精品久久| 日韩毛片免费| 六月婷婷综合| 波多野结衣一区二区三区AV| 亚洲欧洲日本在线| 久久情精品国产品免费| 98超碰在线观看| 欧美在线综合视频| 欧美日韩专区| 国产极品嫩模在线观看91| 91在线国内在线播放老师| 自拍偷拍一区| 亚洲一区波多野结衣二区三区| 伊人激情综合| 亚洲高清无码精品| 免费人欧美成又黄又爽的视频| 免费一级毛片| 久久天天躁狠狠躁夜夜2020一| 亚洲国产成人精品青青草原| 日本久久网站| 国产亚洲男人的天堂在线观看| 国模粉嫩小泬视频在线观看| 色婷婷色丁香| 鲁鲁鲁爽爽爽在线视频观看| 日本三级精品| 亚洲精品成人片在线观看| 成人综合在线观看| 亚洲人成人伊人成综合网无码| 国产乱子伦精品视频| 国产男人的天堂| 九九热视频在线免费观看| 久久a毛片| 欧美精品伊人久久| 成人免费网站久久久| 国产高清在线观看91精品| 99这里只有精品在线| 韩国v欧美v亚洲v日本v| 亚洲最新在线| 成人在线不卡视频| 久久99精品久久久大学生| 日韩国产欧美精品在线| 欧美成人精品一级在线观看| 福利小视频在线播放| 无码 在线 在线| 亚洲视频黄| 成人韩免费网站| 国产成人精品一区二区三区|