:直接使用Debugger加載Cry stalLoader的時(shí)候,會(huì)檢查到當(dāng)前進(jìn)程是由 Debugger啟動(dòng)的。
[0185] 圖8為:被線(xiàn)程注入之后的結(jié)果。
[0186] 圖9為:在保護(hù)線(xiàn)程中啟動(dòng)子進(jìn)程。
[0187] 圖10為:保護(hù)進(jìn)程主動(dòng)加載一個(gè)IAT被Hook過(guò)的Dl 1動(dòng)態(tài)鏈接庫(kù)。
[0188]圖11為:在保護(hù)進(jìn)程運(yùn)行中,植入Debugger后的結(jié)果。
[0189] 圖12為:保護(hù)程序在windows 10中運(yùn)行。
[0190] 圖13為:保護(hù)程序在windows 8.1中運(yùn)行。
[0191 ] 圖14為:保護(hù)程序在windows xp中運(yùn)行。
[0192] 圖15為:保護(hù)程序在windows 2003中運(yùn)行。
[0193] 圖16為:保護(hù)前和保護(hù)后程序運(yùn)行速度。
【具體實(shí)施方式】
[0194] 下面結(jié)合實(shí)例對(duì)本發(fā)明做進(jìn)一步說(shuō)明:
[0195] 實(shí)施例:
[0196] 使用的平臺(tái)為Wind〇ws764bit版本,使用的調(diào)試器為OllyDbg V2.01版本。
[0197] 測(cè)試的步驟如下:
[0?98] 使用01 lyDbg加載AppTestWin32 · vpe這個(gè)保護(hù)鏡像:
[0199] 如圖4所示,反匯編器無(wú)法分析這個(gè)鏡像文件,在打開(kāi)的16進(jìn)制編輯器中,也無(wú)法 看見(jiàn)熟悉的PE鏡像格式。
[0200] 去掉Debugger檢測(cè)保護(hù),在已經(jīng)加載的鏡像模塊中,如圖5所示,找不到受保護(hù)的 鏡像模塊,所以Dumper也無(wú)法準(zhǔn)確抓去內(nèi)存鏡像文件。打開(kāi)本進(jìn)程的內(nèi)存Map,也找不到可 疑的區(qū)段。受保護(hù)的模塊對(duì)于操作系統(tǒng)是隱藏的。
[0201 ] 加上全部的保護(hù),再次使用01 lyDbg加載CrystalLoader.exe,發(fā)現(xiàn)會(huì)直接如圖7的 錯(cuò)誤,當(dāng)前系統(tǒng)已經(jīng)發(fā)現(xiàn)自己是由一個(gè)Debugger加載的,就提示錯(cuò)誤并且拒絕執(zhí)行。
[0202] 測(cè)試線(xiàn)程注入:
[0203] 運(yùn)行CrystalLoader.exe使用loader的形式注入一個(gè)dll,如圖8所示。
[0204 ]當(dāng)保護(hù)d 11檢測(cè)到一個(gè)未記錄的線(xiàn)程被添加進(jìn)來(lái)的時(shí)候,會(huì)直接報(bào)錯(cuò)。
[0205]測(cè)試子進(jìn)程保護(hù):
[0206] 關(guān)閉防止線(xiàn)程注入保護(hù),在受保護(hù)的進(jìn)程中,創(chuàng)建一個(gè)新的進(jìn)程。
[0207] 如圖9所示,可以看見(jiàn)CrystalProtector.dll成果注入子進(jìn)程空間中,對(duì)子進(jìn)程開(kāi) 始執(zhí)行保護(hù)代碼。
[0208] 測(cè)試dll保護(hù)驗(yàn)證:
[0209] 在受保護(hù)的鏡像代碼中,主動(dòng)加載一個(gè)IAT被修改的dll。
[0210] 如圖10所示,進(jìn)程主動(dòng)提示dll是被修改過(guò)的,是不合法的。
[0211] 在受保護(hù)鏡像運(yùn)行的時(shí)候,植入Debugger進(jìn)程,如圖11所示,會(huì)同時(shí)提示系統(tǒng)被 Debugger注入和系統(tǒng)檢測(cè)到線(xiàn)程注入。
[0212] 圖 12到圖 15,分別給出 了保護(hù)程序在windowslO,windows 8 · 1,windows xp, windows2003這幾個(gè)主流平臺(tái)上運(yùn)行的例子。
[0213]圖16給出了對(duì)比測(cè)試。圖片上面是未經(jīng)過(guò)保護(hù)的原始程序運(yùn)行的結(jié)果,圖片下面 是進(jìn)過(guò)保護(hù)后,程序執(zhí)行的結(jié)果。兩段程序都執(zhí)行的是蒙特卡洛算法求圓周率,枚舉的范圍 從0到OxFFFFFF,為了防止CPU Cache對(duì)時(shí)間的準(zhǔn)確性的影響,先將程序預(yù)先加載一次,然后 在依次執(zhí)行保護(hù)和未保護(hù)的程序??梢钥吹剑捎诩虞d器對(duì)做了足夠的優(yōu)化并且選擇性模 擬cruntime library的功能,使得程序能在受保護(hù)情況下,得到更加高效的執(zhí)行結(jié)果。
【主權(quán)項(xiàng)】
1. 基于隱藏可執(zhí)行鏡像并注入dl 1保護(hù)鏡像代碼的方法,該方法包括以下步驟: 1) 將目標(biāo)鏡像在內(nèi)存中解密: 將加密鏡像讀取到內(nèi)存,讀取文件首部的文件頭(例如文件前16字節(jié))來(lái)判斷判斷目標(biāo) 鏡像是否是加密鏡像(例如判斷Magic值是否和預(yù)設(shè)值相同),1.1)如果不是指定的加密鏡 像,則放棄加載;1.2)如果是指定的加密鏡像,則執(zhí)行對(duì)應(yīng)的解密,然后判斷解密后的數(shù)據(jù) 是否是一個(gè)合法PE鏡像,1.2.1)如果不是一個(gè)合法PE鏡像,則退回到待解密狀態(tài),1.2.2)如 果是一個(gè)合法PE鏡像,則執(zhí)行第2步; 2. PE鏡像的加載: 裝載程序所需要的dll文件,執(zhí)行鏡像重定位,最后執(zhí)行OEP,如果上面的過(guò)程有出錯(cuò), 則返回到本步驟2的待裝載狀態(tài)(即PE鏡像的待加載狀態(tài)),如果上面的過(guò)程都沒(méi)有出錯(cuò),就 執(zhí)行第3步; 3) 檢查exe模塊的IAT是否被劫持: 該步驟包括以下兩個(gè)子步驟:3.1)獲取IAT中的dl 1帶入列表,對(duì)其中每一個(gè)API地址做 一次檢查,看記錄的API地址和實(shí)際的API是否一致,如果有不同的,則可以認(rèn)為該exe模塊 的IAT被做了改動(dòng)(例如,可能是被Hook過(guò)的),接著,3.2)對(duì)每個(gè)導(dǎo)入的系統(tǒng)dl 1做一次鏡像 Hash檢查,使用的Hash函數(shù)是zlib中的Adler32函數(shù),如果內(nèi)存鏡像的Hash值和本地文件的 Hash不同,則可以認(rèn)為這個(gè)dl 1的內(nèi)存鏡像被修改過(guò), 如果發(fā)現(xiàn)上面幾個(gè)子步驟存在問(wèn)題,則返回至步驟3.1)的初始狀態(tài)或返回到步驟2,如 果上面子步驟都沒(méi)問(wèn)題,則執(zhí)行第4步; 4) 主動(dòng)劫持 LoadLibrary 和 LoadLibraryEx: 劫持LoadLibrary和LoadLibraryEx,它們分別包含多字節(jié)版本和Unicode版本,所以需 要劫持的API實(shí)際上有4個(gè),對(duì)加載成果的dll鏡像執(zhí)行上述步驟3中的操作,如果判定有異 常,則返回步驟2或步驟3,如果判定沒(méi)有異常,則執(zhí)行第5步;和 5) 劫持 CreateProcess 函數(shù): 劫持CreateProcess函數(shù),并且在創(chuàng)建子進(jìn)程同時(shí),注入本保護(hù)dll。2. 根據(jù)權(quán)利要求1所述的方法,其中所述方法進(jìn)一步包括以下步驟 6) 防止線(xiàn)程注入: 通過(guò)遠(yuǎn)程線(xiàn)程注入,在Ring3環(huán)境下注入被保護(hù)的目標(biāo)進(jìn)程,防止惡意加載器的線(xiàn)程注 入; 7) 建立保護(hù)線(xiàn)程: 建立一個(gè)優(yōu)先度比較底的線(xiàn)程(THREAD_PRIORITY_BEL0W_N0RMAL),做死循環(huán)檢查,其 中檢查的內(nèi)容包括或是:是否是Debugger加載;優(yōu)選的是,每一秒檢查一次。3. 根據(jù)權(quán)利要求1所述的方法,其中在步驟1中加密鏡像的擴(kuò)展名使用*.vpe,和/或, 執(zhí)行對(duì)應(yīng)的解密是指:解密的算法基于快速的xor算法,將文件頭Null作為解密Key,對(duì) 文件進(jìn)行解密。4. 根據(jù)權(quán)利要求1、2或3所述的方法,其中步驟2包括以下子步驟:2.1)加載器會(huì)模擬操 作系統(tǒng)的加載器,依次修改PE鏡像的區(qū)段的屬性,并且對(duì)齊區(qū)段,2.2)執(zhí)行預(yù)加載函數(shù)(比 如TLS回調(diào)函數(shù)),加載IAT中對(duì)應(yīng)的dl 1動(dòng)態(tài)鏈接庫(kù),然后獲取到0EP,和2.3)注入保護(hù)dl 1, 執(zhí)行入口點(diǎn)函數(shù),從而完成PE鏡像的加載。5. 根據(jù)權(quán)利要求4所述的方法,其中所加載的受保護(hù)的PE鏡像是基于加載器進(jìn)程執(zhí)行 的,即,受保護(hù)的PE鏡像對(duì)于操作系統(tǒng)來(lái)說(shuō)是不可見(jiàn)的;優(yōu)選的是,在受保護(hù)的PE鏡像執(zhí)行 時(shí)既不是加載器的子進(jìn)程,又不是加載器的代碼段,只是堆上一塊可執(zhí)行區(qū)段,dumper無(wú)法 將這個(gè)區(qū)段準(zhǔn)確提取出來(lái)。6. 根據(jù)權(quán)利要求1-5中任何一項(xiàng)所述的方法,其中在步驟4中,每當(dāng)Exe模塊主動(dòng)調(diào)用一 個(gè)dll時(shí),必定會(huì)使用到LoadLibrary或者是LoadLibraryEx,對(duì)這兩個(gè)API做劫持,每當(dāng)加載 一個(gè)dl 1鏡像時(shí),使用步驟3中的方法,對(duì)dl 1的IAT做一次檢查,如果有導(dǎo)入函數(shù)的地址和原 本的地址不同,就認(rèn)為這個(gè)dll的IAT被做了修改。7. 根據(jù)權(quán)利要求1-6中任何一項(xiàng)所述的方法,其中在步驟5中,主要的方式是在創(chuàng)建進(jìn) 程的時(shí)候,先保存原來(lái)的創(chuàng)建f lag,為創(chuàng)建f lag中添加 CREATE_SUSPEND的f lag進(jìn)行創(chuàng)建;優(yōu) 選的是,在建立子進(jìn)程的時(shí)候,劫持EIP,保存CPU的Context,注入ShellCode來(lái)加載內(nèi)存保 護(hù)dll,最后釋放ShellCode的內(nèi)存,并且恢復(fù)CPU的Context。8. 根據(jù)權(quán)利要求2-7中任何一項(xiàng)所述的方法,其中在步驟6中,需要防止的線(xiàn)程注入是: 惡意加載器在遠(yuǎn)程調(diào)用以下三種CreateRemoteThreacUVirtualAlloc和LoadLibrary相關(guān) 的API (如LoadLibraryEx)完成線(xiàn)程注入。9. 根據(jù)權(quán)利要求2-8中任何一項(xiàng)所述的方法,其中在步驟7中,直接從BYTE Ptr fs: [3 0 ] + 2處獲取到一個(gè)B Y T E長(zhǎng)度的數(shù)據(jù),如果檢測(cè)到F 1 a g為1,則使用 SetUnhandledExceptionFilter設(shè)置一個(gè)Filter函數(shù),函數(shù)中輸出一些出錯(cuò)信息,然后返回 EXCEPT I0N_EXE⑶TE_HANDLER,表明當(dāng)前的異常已經(jīng)處理,程序直接退出。
【專(zhuān)利摘要】基于隱藏可執(zhí)行鏡像并注入dll保護(hù)鏡像代碼的方法,該方法包括以下步驟:1)將目標(biāo)鏡像在內(nèi)存中解密;2)PE鏡像的加載:裝載程序所需要的dll文件,執(zhí)行鏡像重定位,最后執(zhí)行OEP;3)檢查exe模塊的IAT是否被劫持;4)主動(dòng)劫持LoadLibrary和LoadLibraryEx,對(duì)加載成果的dll鏡像執(zhí)行上述步驟3中的操作,如果判定沒(méi)有異常,則執(zhí)行第5步;5)劫持CreateProcess函數(shù),并且在創(chuàng)建子進(jìn)程同時(shí),注入本保護(hù)dll;6)通過(guò)遠(yuǎn)程線(xiàn)程注入,在Ring3環(huán)境下注入被保護(hù)的目標(biāo)進(jìn)程,防止惡意加載器的線(xiàn)程注入;和7)建立一個(gè)優(yōu)先度比較底的線(xiàn)程(THREAD_PRIORITY_BELOW_NORMAL),做死循環(huán)檢查,檢查它是否屬于Debugger加載,每一秒檢查一次。
【IPC分類(lèi)】G06F21/51
【公開(kāi)號(hào)】CN105512548
【申請(qǐng)?zhí)枴緾N201510873591
【發(fā)明人】歐陽(yáng)建權(quán), 陳靈鋒, 劉任任, 唐歡容
【申請(qǐng)人】湘潭大學(xué)
【公開(kāi)日】2016年4月20日
【申請(qǐng)日】2015年12月2日