本發(fā)明申請屬于計(jì)算機(jī)操作系統(tǒng)中DLL注入技術(shù),更為具體來說是一種將多DLL注入目標(biāo)進(jìn)程的優(yōu)化管理方法,以實(shí)現(xiàn)目標(biāo)進(jìn)程注入的高穩(wěn)定性和高效率。
背景技術(shù):
隨著WINDOWS應(yīng)用的飛速發(fā)展,WINDOWSAPI編程得到了普及和應(yīng)用,為了更好地收集一些系統(tǒng)運(yùn)行時(shí)的數(shù)據(jù),可以通過HOOKAPI(HOOK Application Programming Interface,具有鉤子功能的應(yīng)用程序編程接口)的方式對系統(tǒng)在應(yīng)用層的程序進(jìn)行HOOK(鉤子)處理以攔截需要的數(shù)據(jù),或者對已有功能進(jìn)行增強(qiáng)。目前,通過HOOK API攔截需要的數(shù)據(jù)時(shí),首先需要將編寫有可實(shí)現(xiàn)功能的DLL(DynamicLinkLibrary,動態(tài)鏈接庫)注入到被HOOK的目標(biāo)進(jìn)程中。
DLL注入技術(shù)的目的是實(shí)現(xiàn)應(yīng)用程序主動跨越進(jìn)程邊界訪問其他進(jìn)程的數(shù)據(jù),從而控制目標(biāo)進(jìn)程的行為。它的用途很廣泛,這主要體現(xiàn)在:(1)你要操縱的對象涉及的數(shù)據(jù)不在自身進(jìn)程內(nèi);(2)你想對目標(biāo)進(jìn)程中的系統(tǒng)函數(shù)進(jìn)行攔截;(3)你想編寫一些函數(shù)用于增強(qiáng)或增加目標(biāo)進(jìn)程功能;(4)隱藏自己的程序(將自己程序的主要功能注入到其他進(jìn)程運(yùn)行,本身的進(jìn)程退出);從以上列舉的用途不難看出,DLL注入技術(shù)不僅可以用來搞破壞,如果我們使用得當(dāng),它將成為我們控制目標(biāo)進(jìn)程的一個(gè)強(qiáng)大的武器。
目前各大安全廠商所使用的主流DLL注入技術(shù)主要分為以下幾類:(1)通過DLL劫持,缺點(diǎn)是重啟電腦以后才能生效;(2)使用注冊表注入DLL,缺點(diǎn)是只能注入那些使用了user32.dll的進(jìn)程,并且不能動態(tài)撤銷,只能跟隨系統(tǒng)啟動和關(guān)閉;(3)使用windows掛鉤來注入DLL,缺點(diǎn)是只能控制窗口類消息;(4)使用木馬DLL來注入DLL,缺點(diǎn)是編程難度大、工作量大;(5)使用導(dǎo)入表注入DLL,缺點(diǎn)是不夠靈活,必須先定好注入DLL的名稱,寫入導(dǎo)入表中;(6)在內(nèi)核空間中利用APC機(jī)制(Asynchronous Procedure Calls,異步過程調(diào)用)插入一個(gè)APC函數(shù),將注入執(zhí)行DLL注入到目標(biāo)進(jìn)程中,缺點(diǎn)是缺少對多注入DLL注入管理,當(dāng)存在多個(gè)注入DLL,同時(shí)需要注入目標(biāo)進(jìn)程的情況下,目標(biāo)進(jìn)程的穩(wěn)定性和效率受影響較大。當(dāng)注入目標(biāo)進(jìn)程存在多個(gè)注入DLL,而且同時(shí)攔截相同API的時(shí)候,每個(gè)DLL都會攔截目標(biāo)進(jìn)程的此個(gè)API,增加了系統(tǒng)執(zhí)行地址的多次跳轉(zhuǎn),多次攔截嚴(yán)重影響目標(biāo)進(jìn)程的執(zhí)行效率,另外多次的攔截極有可能導(dǎo)致目標(biāo)進(jìn)程崩潰。
技術(shù)實(shí)現(xiàn)要素:
本申請的技術(shù)方案要解決的技術(shù)問題是提供一種能夠及時(shí)生效、不受進(jìn)程類型限制、可以動態(tài)加載和撤銷、控制全面、注入靈活、且工作量小的將任意數(shù)目的DLL注入目標(biāo)進(jìn)程的方法和系統(tǒng)。另外高效地管理目標(biāo)進(jìn)程中注入DLL的管理,特別提高了注入多DLL的時(shí)候,目標(biāo)進(jìn)程的穩(wěn)定性和效率,增加對多注入DLL的統(tǒng)一管理,優(yōu)化和節(jié)省目標(biāo)進(jìn)程資源。針對多注入DLL的情況,將攔截動作進(jìn)行統(tǒng)一的封裝和管理,提高目標(biāo)進(jìn)程的穩(wěn)定性和效率,靈活高效。
實(shí)現(xiàn)上述發(fā)明目的技術(shù)方案為:一種將多DLL注入目標(biāo)進(jìn)程的優(yōu)化管理方法,該方法包括步驟如下:(1)設(shè)置用于監(jiān)測操作系統(tǒng)中程序啟動的內(nèi)核DLL注入模塊(SysDLL模塊),將SysDLL注入模塊注冊到操作系統(tǒng)中,當(dāng)有需要注入的目標(biāo)進(jìn)程向操作系統(tǒng)請求啟動時(shí),操作系統(tǒng)將該請求通知SysDLL注入模塊,SysDLL模塊獲取目標(biāo)進(jìn)程的基地址,通過基地址找到保存ShellCode的地址空間,將ShellCode的執(zhí)行體寫入地址空間,這里的操作系統(tǒng)主要是視窗操作系統(tǒng),目標(biāo)進(jìn)程的啟動和注入請求的通知采用同步機(jī)制實(shí)現(xiàn);(2)通過QueueUserAPC函數(shù),向目標(biāo)進(jìn)程的每一個(gè)線程都插入APC函數(shù)(Asynchronous Procedure Calls,異步過程調(diào)用),該APC函數(shù)的過程函數(shù)是ShellCode的執(zhí)行體,該過程函數(shù)的參數(shù)是注入執(zhí)行DLL模塊(InjectDLL模塊)的路徑字符串,將InjectDLL模塊注入到目標(biāo)進(jìn)程導(dǎo)入表中,這里在將InjectDLL模塊注入到目標(biāo)進(jìn)程導(dǎo)入表之前,目標(biāo)進(jìn)程中的線程產(chǎn)生異步中斷時(shí),注冊的APC函數(shù)得到調(diào)用,InjectDLL模塊被目標(biāo)進(jìn)程加載(3)用戶通過注入控制DLL模塊(ControlDLL模塊)向InjectDLL發(fā)送要注入目標(biāo)DLL(HookDLL)的注入和卸載消息,這里的注入目標(biāo)DLL是多個(gè)DLL,InjectDLL模塊收到消息后進(jìn)行統(tǒng)一決策,最終決定加載或者卸載用戶要求操作的HookDLL;(4)用戶注入的HookDLL模塊開始啟動攔截操作時(shí),通過調(diào)用ControlDLL模塊,向InjectDLL模塊通知需要攔截的API及針對此API的控制類型;(5)InjectDLL模塊根據(jù)此HookDLL模塊攔截API信息內(nèi)容,并根據(jù)ControlDLL模塊對控制類型的優(yōu)先級別,將HookDLL模塊對API的攔截返回地址保存到數(shù)據(jù)結(jié)構(gòu)表中,并更新到此攔截API的Hook處理表模塊中;(6)當(dāng)目標(biāo)進(jìn)程發(fā)生了API動作時(shí),InjectDLL模塊根據(jù)數(shù)據(jù)結(jié)構(gòu)表,通過攔截API的Hook處理表模塊分別將攔截地址信息,根據(jù)保存的數(shù)據(jù)結(jié)構(gòu)表分別傳遞給各個(gè)HookDLL模塊進(jìn)行分析處理;(7)攔截API地址的操作結(jié)束后,統(tǒng)一由InjectDLL根據(jù)返回系統(tǒng)的API函數(shù)執(zhí)行;上述內(nèi)核DLL注入模塊(SysDLL模塊)為內(nèi)核驅(qū)動程序,注入目標(biāo)DLL模塊(HookDLL模塊)、注入執(zhí)行DLL模塊(InjectDLL模塊)及注入控制DLL模塊(ControlDLL模塊)均為用戶態(tài)下的DLL程序。
上述步驟(6)中的Hook處理表模塊的形成過程是:針對每個(gè)要攔截的API函數(shù),InjectDLL只攔截一次,后面多個(gè)其他HookDLL需要攔截此同一個(gè)API的時(shí)候,InjectDLL通過一個(gè)數(shù)據(jù)結(jié)構(gòu)順序保存多個(gè)HookDLL對此API攔截的返回地址從而形成每個(gè)攔截API的Hook處理表模塊,在InjectDLL模塊根據(jù)數(shù)據(jù)結(jié)構(gòu)表通過攔截API的Hook處理表模塊分別將攔截地址信息后,還將地址返回原來的API1Function執(zhí)行,各個(gè)HookDLL模塊進(jìn)行分析處理是HookDLL異步處理,各自的邏輯不受影響。
在完成注入操作實(shí)現(xiàn)目的后,如果用戶需要卸載某個(gè)HookDLL時(shí),用戶進(jìn)程通過ControlDLL模塊通知InjectDLL模塊卸載某個(gè)HookDLL,InjectDLL模塊收到后執(zhí)行卸載操作,并刷新每個(gè)API攔截的數(shù)據(jù)結(jié)構(gòu)表,將此HookDLL從數(shù)據(jù)結(jié)構(gòu)表中清除。
上述注入、寫在管理過程中,ControlDLL模塊與InjectDLL模塊間通信方式采用的是全局共享內(nèi)存的方法;被InjectDLL模塊注入的目標(biāo)進(jìn)程默認(rèn)為所有非系統(tǒng)關(guān)鍵進(jìn)程,以防止影響系統(tǒng)正常運(yùn)行。
本發(fā)明的技術(shù)方案具有以下優(yōu)點(diǎn):首先是具有控制全面、靈活性高等優(yōu)點(diǎn),可以注入任意個(gè)數(shù)的DLL;其次,采用注入執(zhí)行DLL模塊(InjectDLL模塊)來攔截目標(biāo)進(jìn)程的API函數(shù),相比其他由各個(gè)Hook去攔截的方法,在存在多注入HookDLL的情況下,可以明顯提高目標(biāo)進(jìn)程的穩(wěn)定性和效率;再次,采用注入控制DLL模塊(ControlDLL模塊),有效地管理了多HookDLL的執(zhí)行順序,靈活多變,可以適應(yīng)多種場所;另外,此方案可應(yīng)用于安全桌面技術(shù),能夠適應(yīng)多種常用的操作系統(tǒng),包括WindowsXP、WindowsServer2003、Windows7、Windows8、Windows10等。極大地提高了目標(biāo)進(jìn)程的穩(wěn)定性和攔截函數(shù)執(zhí)行的效率,應(yīng)用前景十分廣泛。
附圖說明
圖1是SysDLL模塊、InjectDLL模塊、ControlDLL模塊實(shí)現(xiàn)加載多個(gè)HookDLL的原理圖;
圖2是本發(fā)明的技術(shù)方案實(shí)現(xiàn)函數(shù)攔截的原理圖。
具體實(shí)施方式
為更清楚說明本發(fā)明技術(shù)方案,下面具體進(jìn)行介紹。
首先設(shè)置用于監(jiān)測操作系統(tǒng)中程序啟動的內(nèi)核DLL注入模塊(SysDLL模塊),將SysDLL模塊注冊到操作系統(tǒng)中,當(dāng)有需要注入的目標(biāo)進(jìn)程向操作系統(tǒng)請求啟動時(shí),操作系統(tǒng)將該請求通知SysDLL模塊,SysDLL模塊獲取目標(biāo)進(jìn)程的基地址,通過基地址找到保存ShellCode的地址空間,將ShellCode的執(zhí)行體寫入地址空間,通過QueueUserAPC函數(shù),向該進(jìn)程的每一個(gè)線程都插入一個(gè)APC,每個(gè)線程都插入APC可以保證每個(gè)進(jìn)程都可以順利執(zhí)行,然后把ShellCode的執(zhí)行體作為APC函數(shù)的過程函數(shù),把注入執(zhí)行DLL模塊(InjectDLL模塊)的路徑字符串作為過程函數(shù)的參數(shù),將InjectDLL模塊注入到目標(biāo)進(jìn)程導(dǎo)入表中。
用戶通過統(tǒng)一提供的注入控制DLL模塊(ControlDLL模塊)向InjectDLL發(fā)送要注入目標(biāo)DLL(HookDLL)的注入和卸載消息,InjectDLL模塊收到消息后進(jìn)行統(tǒng)一決策,最終決定加載或者卸載用戶要求操作的HookDLL。
HookDLL注入目標(biāo)進(jìn)程后,對目標(biāo)進(jìn)程API函數(shù)的攔截,并不分別攔截目標(biāo)進(jìn)程的攔截API,而是調(diào)用ControlDLL,通知InjectDLL需要攔截目標(biāo)進(jìn)程的那個(gè)API,由InjectDLL一個(gè)模塊來攔截,針對每個(gè)要攔截的API函數(shù),InjectDLL只攔截一次,后面多個(gè)其他HookDLL需要攔截此同一個(gè)API的時(shí)候,InjectDLL通過一個(gè)數(shù)據(jù)結(jié)構(gòu)順序保存多個(gè)HookDLL對此API攔截的返回地址,形成每個(gè)攔截API的Hook處理表模塊。
攔截操作功能過程中,InjectDLL模塊負(fù)責(zé)對目標(biāo)API的攔截,攔截到信息后傳遞給每個(gè)攔截API的Hook處理表模塊,API的Hook處理表模塊負(fù)責(zé)傳遞給每個(gè)HookDLL的函數(shù)處理地址進(jìn)行處理。每個(gè)HookDLL不進(jìn)行函數(shù)地址的傳遞,由InjectDLL模塊統(tǒng)一傳遞。
另外,每個(gè)HookDLL,將對每個(gè)API攔截請求類型,通過ControlDLL模塊通知InjectDLL模塊,InjectDLL模塊根據(jù)ControlDLL模塊的要求,調(diào)整對每個(gè)HookDLL對API攔截返回地址的順序,優(yōu)化每個(gè)攔截API的Hook處理表模塊,傳遞給每個(gè)HookDLL函數(shù)地址的順序,提高處理效率。
其具體過程可以細(xì)分為如下步驟:
(1)進(jìn)程向操作系統(tǒng)請求啟動;
(2)操作系統(tǒng)收到目標(biāo)進(jìn)程啟動請求,將該啟動請求通知SysDLL模塊;
(3)SysDLL模塊獲取目標(biāo)進(jìn)程的基地址,找到可保存ShellCode的地址空間,將ShellCode和相關(guān)參數(shù)寫入該地址空間中;
(4)SysDLL模塊通過QueueUserAPC函數(shù)插入一個(gè)APC,將寫入的ShellCode函數(shù)作為APC函數(shù)的過程函數(shù);
(5)當(dāng)目標(biāo)進(jìn)程中的線程產(chǎn)生異步中斷時(shí),注冊的APC函數(shù)得到調(diào)用,InjectDLL模塊被加載進(jìn)入該進(jìn)程中,完成了InjectDLL的加載注入工作;
(6)用戶需要注入自己的HookDLL模塊時(shí),通過調(diào)用ControlDLL模塊,向InjectDLL模塊通知用戶要注入的HookDLL模塊的注入信息;
(7)InjectDLL模塊比對此個(gè)HookDLL模塊的注入信息內(nèi)容及請求,執(zhí)行相應(yīng)的加載或卸載動作;
(8)用戶注入的HookDLL模塊開始啟動攔截操作時(shí),通過調(diào)用ControlDLL模塊,向InjectDLL模塊通知需要攔截的API及針對此API的控制類型;
(9)InjectDLL模塊根據(jù)此HookDLL模塊攔截API信息內(nèi)容,并且根據(jù)ControlDLL模塊對控制類型的優(yōu)先級別,將此HookDLL模塊對此API的攔截返回地址保存到一個(gè)數(shù)據(jù)結(jié)構(gòu)表中,更新到此攔截API的Hook處理表模塊中;
(10)當(dāng)目標(biāo)進(jìn)程發(fā)生了此API動作的時(shí)候,InjectDLL模塊根據(jù)數(shù)據(jù)結(jié)構(gòu)表,通過此攔截API的Hook處理表模塊分別將攔截地址信息,根據(jù)保存的數(shù)據(jù)結(jié)構(gòu)表分別傳遞給各個(gè)HookDLL模塊進(jìn)行分析處理。
(11)攔截API地址的操作結(jié)束后,統(tǒng)一由InjectDLL根據(jù)返回系統(tǒng)的API函數(shù)執(zhí)行。
如圖1是SysDLL模塊、InjectDLL模塊、ControlDLL模塊實(shí)現(xiàn)加載多個(gè)HookDLL的原理圖;在內(nèi)核空間中利用APC機(jī)制插入一個(gè)APC函數(shù),將InjectDLL模塊注入到目標(biāo)進(jìn)程中,用戶需要注入各自的HookDLL模塊時(shí),不需要各自注入HookDLL模塊,而是通過ControlDLL模塊通知InjectDLL模塊加載各自的HookDLL模塊信息,InjectDLL模塊將HookDLL加載到目標(biāo)進(jìn)程中。InjectDLL已經(jīng)存在于目標(biāo)進(jìn)程中,InjectDLL可以加載任何HookDLL到目標(biāo)進(jìn)程中,靈活性高、穩(wěn)定度高。
圖2是本發(fā)明的技術(shù)方案實(shí)現(xiàn)函數(shù)攔截的原理圖。當(dāng)用戶需要HookDLL模塊去攔截某個(gè)目標(biāo)進(jìn)程的API函數(shù)時(shí),不需要各自的HoolDLL模塊執(zhí)行攔截動作,而是通過ControlDLL模塊將需要攔截的API函數(shù)及控制類型通知InjectDLL模塊,對函數(shù)的攔截只有InjectDLL去攔截,常規(guī)攔截方式分別有各個(gè)HookDLL模塊分別攔截,對于多DLL注入的情況,多個(gè)DLL分別攔截,嚴(yán)重影響了目標(biāo)函數(shù)執(zhí)行的效率。InjectDLL攔截到API1Function函數(shù)執(zhí)行地址及參數(shù),將攔截到的參數(shù)信息傳遞給HookDLL處理函數(shù)地址數(shù)據(jù)結(jié)構(gòu)表模塊,進(jìn)行處理,根據(jù)ControlDLL要求返回執(zhí)行結(jié)果后,根據(jù)執(zhí)行結(jié)果決定是攔截此操作、還是傳遞給API1Function繼續(xù)執(zhí)行。
常見的安全廠商攔截常規(guī)API信息,并不對結(jié)果進(jìn)行攔截,阻止函數(shù)執(zhí)行。對于這種情況,InjectDLL將獲取函數(shù)的信息傳遞給HookDLL攔截的API處理函數(shù)地址數(shù)據(jù)結(jié)構(gòu)表后,及時(shí)將地址返回原來的API1Function執(zhí)行,極大地提高了目標(biāo)進(jìn)程執(zhí)行的效率。InjectDLL將獲取函數(shù)的信息傳遞給HookDLL攔截的API處理函數(shù)地址數(shù)據(jù)結(jié)構(gòu)表,順序地將信息傳遞給每個(gè)HookDLL的處理函數(shù),各個(gè)HookDLL異步處理各自的邏輯互不影響。
對于多個(gè)HookDLL中,存在攔截到目標(biāo)進(jìn)程的某個(gè)API,根據(jù)自己的檢測邏輯,有可能要禁止此API的動作,例如U盤拷貝禁止,如果存在拷貝動作,HookDLL檢測到拷貝的路徑是U盤,則阻止拷貝。對于這種情況,InjectDLL將獲取函數(shù)的信息傳遞給HookDLL攔截的API處理函數(shù)地址數(shù)據(jù)結(jié)構(gòu)表,首先順序地將信息傳遞給那些不需要禁止此API的每個(gè)HookDLL的處理函數(shù),這部分HookDLL處理各自的邏輯互不影響。然后將此部分信息傳遞給有可能要禁止此API的各個(gè)HookDLL,這部分HookDLL處理各自的邏輯互不影響,并將判斷結(jié)果反饋給InjectDLL模塊,如果存在需要禁止此API的行為,則InjectDLL模塊將禁止目標(biāo)進(jìn)程繼續(xù)執(zhí)行此API,如果沒有需要禁止此API的行為,InjectDLL模塊將地址返回原來API繼續(xù)執(zhí)行。
以上所述僅為本發(fā)明的較佳實(shí)施例而已,并不用以限制本發(fā)明,凡在本發(fā)明實(shí)質(zhì)內(nèi)容上所作的任何修改、等同替換和簡單改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。