Linux系統(tǒng)軟件加殼保護(hù)技術(shù)的改進(jìn)設(shè)計(jì)
加殼是對軟件內(nèi)核一種很有效的保護(hù)方式。目前Linux系統(tǒng)下的加殼方法,多是直接繼承Windows 程序的加殼理論和方法,在傳統(tǒng)加殼工具上進(jìn)行了有限的擴(kuò)展, 單純在LINUX 系統(tǒng)下實(shí)現(xiàn)的加殼工具還是很少的。如何在Linux 系統(tǒng)下盡量減少內(nèi)核信息的暴露,增加有難度的反逆向手段來提升破解難度,對加殼保護(hù)程序進(jìn)行很好的隱藏,都是目前主要攻克的難題。
本文引用地址:http://butianyuan.cn/article/148245.htm根據(jù)加載外殼程序方式的不同將現(xiàn)有軟件加殼技術(shù)分為:嵌入式、附加式和包含式。嵌入式中最經(jīng)典的是Upx,支持多種文件類型加殼,且壓縮算法先進(jìn)。但該方法缺少反動態(tài)跟蹤功能,破解者可用動態(tài)跟蹤調(diào)試方法對Upx 進(jìn)行破解[1]。文獻(xiàn)[2]中描述了附加式加殼(SELF 加殼):在原elf 文件格式中添加處理安全操作的代碼段,但不內(nèi)置解壓縮,容易暴漏殼的位置。包含式結(jié)合了壓縮和保護(hù)兩種類型的殼,但殼加載的過程中會改變?nèi)肟诘刂?。結(jié)合上述三種加殼方法的優(yōu)缺點(diǎn),文章提出了在Linux 系統(tǒng)下一種改進(jìn)的加殼保護(hù)方法—加殼并重構(gòu)可執(zhí)行文件———SRELF[3]。改進(jìn)后的算法將殼程序和目標(biāo)可執(zhí)行文件中代碼段,數(shù)據(jù)段等關(guān)鍵部分相結(jié)合,引入多態(tài)變形技術(shù),使程序呈現(xiàn)出多態(tài)性,提高了殼程序的反破解能力,同時(shí)還很好的隱藏了加殼的信息。通過實(shí)驗(yàn)證明,改進(jìn)后的方法解決了加殼中入口地址易被改變的問題,使得加殼的程序以多態(tài)的形式出現(xiàn),很大程度上提高了反破解的難度。
1 加殼原理
加殼實(shí)質(zhì)上就是把一段特殊程序附加到應(yīng)用程序中,并把程序的執(zhí)行入口指向附加的特殊殼程序。殼的加載過程如圖1 所示,首先殼程序需要獲得應(yīng)用程序編程接口———即API 地址。在加殼程序的代碼中用顯示鏈接方式動態(tài)的加載所需的API 地址。通過殼程序后,對各個區(qū)塊的數(shù)據(jù)按照定義進(jìn)行解密;若加殼時(shí)用到了壓縮技術(shù),那么在解密之前先要進(jìn)行解壓縮,然后將解壓文件映像到指定內(nèi)存地址中。修改原程序文件的輸入表后填充HOOK—API 表中的代碼地址,間接的獲得程序的控制權(quán),進(jìn)行校驗(yàn)和測試完后跳轉(zhuǎn)到原入口點(diǎn)(OEP)[3]。
現(xiàn)有的軟件加殼技術(shù)方法大多都改變了原有文件結(jié)構(gòu),在重定位的過程中改變程序的入口地址,加載的過程中把部分程序映射到地址空間中,若破解者知道如何在一個加殼程序中尋址,那么當(dāng)文件被加載進(jìn)內(nèi)存時(shí)就可以找到加殼程序的信息。文章針對上述問題,提出了一種改進(jìn)的加殼方法SRELF。
2 SRELF 加殼方法
2.1 SRELF 方法原理
SRELF———加殼并重構(gòu)可執(zhí)行文件,最大特點(diǎn)是重構(gòu)變形使得重構(gòu)的程序呈現(xiàn)多態(tài)性。首先將目標(biāo)elf 文件中的核心部分提取出來,然后與準(zhǔn)備好的解密或解壓縮程序,反靜態(tài)分析和反動態(tài)跟蹤程序結(jié)合在一起,讓加殼程序呈現(xiàn)出多態(tài)變形性,最后遍歷整合程序,按照elf 文件標(biāo)準(zhǔn)格式重新構(gòu)造一個全新的elf 可執(zhí)行文件。
2.2 SRELF 方法實(shí)現(xiàn)
如圖2 所示:SRELF 加殼方法實(shí)現(xiàn)的基本程序框圖。首先了解應(yīng)用程序二進(jìn)制接口文件(即擴(kuò)展名為elf 文件)結(jié)構(gòu)。圖3 所示為標(biāo)準(zhǔn)elf 文件的結(jié)構(gòu)圖。從圖中可以看到:一個ELF 頭在文件的開始,保存了路線圖描述了文件組織情況。隨后是一些段(segments)或者一些區(qū)段(sections)。段中包含文件運(yùn)行所需的信息,而保存著object 文件的信息,用于鏈接和重定位。
第一步:提取目標(biāo)文件中的核心部分
提取核心部分的可執(zhí)行指令、動態(tài)鏈接表、段或節(jié)等信息。由于匯編程序中存在間接跳轉(zhuǎn)使得反匯編生成控制流圖中斷,影響了提取核心代碼的準(zhǔn)確性,這里引入了一種間接跳轉(zhuǎn)程序方式[4]。
1)從殼運(yùn)行到原始程序的OEP 進(jìn)行單步向下跟蹤,遇到拋出異常后,修改溢出標(biāo)志;
2)分析操作數(shù)的類型。若是直接尋址類型,進(jìn)入4);否則進(jìn)入3);
3)找到定義的語句或函數(shù)入口,設(shè)置CREAT_SUSPENDED計(jì)數(shù)器,若計(jì)數(shù)器加一,則將宿主進(jìn)程作為一個掛起的子進(jìn)程打開,調(diào)用GetThreadContext()獲取子進(jìn)程初始化線程的上下文;
4)判斷后的程序進(jìn)行輸入鎖定,在語句序列上模擬執(zhí)定義位置與目標(biāo)間接跳轉(zhuǎn)運(yùn)算,對獲取寄存器內(nèi)容進(jìn)行復(fù)制。使用間接跳轉(zhuǎn)語句獲取elf 頭文件中的信息后, 定位到GetElfCore 的頭表,然后定位到所需代碼段的核心位置,將其中的數(shù)據(jù)復(fù)制出來。
評論