專利名稱:一種可執(zhí)行程序加殼保護(hù)方法
技術(shù)領(lǐng)域:
本發(fā)明屬于計(jì)算機(jī)軟件程序保護(hù)技術(shù)領(lǐng)域,具體涉及對(duì)可執(zhí)行程序加殼的軟件保護(hù)方法。
背景技術(shù):
軟件保護(hù)是軟件開發(fā)中一個(gè)不可忽視的環(huán)節(jié),由于軟件開發(fā)后要面對(duì)眾多逆向分析員的研究,要給發(fā)布的軟件加一層保護(hù)殼幾乎成了保護(hù)軟件的一個(gè)必要步驟。計(jì)算機(jī)軟件產(chǎn)品是一種知識(shí)密集的特殊產(chǎn)品,開發(fā)一個(gè)軟件產(chǎn)品需要大量的人力物力,成本很高。然而,軟件產(chǎn)品的復(fù)制卻是相當(dāng)?shù)娜菀?,這就導(dǎo)致了非法復(fù)制、盜版軟件之風(fēng)的泛濫。在這種形勢(shì)下,軟件的研制者和銷售商為了保護(hù)自己的利益不被侵犯,除了采用法律手段外,還必須使用技術(shù)手段來保護(hù)自己的產(chǎn)品不受侵犯。軟件加密是一種有效的保護(hù)方式。因此,如何解決軟件加密問題是業(yè)內(nèi)亟待解決的技術(shù)問題。
發(fā)明內(nèi)容
本發(fā)明的目的是提供一種可執(zhí)行程序加殼保護(hù)方法,解決現(xiàn)有技術(shù)中的傳統(tǒng)加殼保護(hù)后的軟件易于被攻擊者破解及非法篡改的問題。本發(fā)明采取的技術(shù)方案是一種可執(zhí)行程序加殼保護(hù)方法,包括以下步驟,步驟101 :將打好補(bǔ)丁的外殼目標(biāo)文件添加到可執(zhí)行程序文件的尾部形成目標(biāo)可執(zhí)行程序文件;步驟102 :對(duì)所述目標(biāo)可執(zhí)行程序文件的文件頭進(jìn)行修改形成修改后的目標(biāo)可執(zhí)行程序文件;所述修改包括在所述文件頭加入一條段命令來描述所述打好補(bǔ)丁的外殼目標(biāo)文件和密鑰設(shè)備驅(qū)動(dòng)程序模塊,以及修改在所述文件頭的命令項(xiàng)找到的線程狀態(tài)命令和預(yù)設(shè)段命令;步驟103 :遍歷所述修改后的目標(biāo)可執(zhí)行程序文件,找到執(zhí)行代碼段,用第一密鑰對(duì)所述執(zhí)行代碼段進(jìn)行第一次加密,并用加密結(jié)果替換所述修改后的目標(biāo)可執(zhí)行程序文件中的執(zhí)行代碼段,得到第一次加密后的目標(biāo)可執(zhí)行程序文件;步驟104 :將包含密鑰設(shè)備驅(qū)動(dòng)和加解密算法的密鑰設(shè)備驅(qū)動(dòng)程序模塊添加到所述第一次加密后的目標(biāo)可執(zhí)行程序文件的執(zhí)行代碼段的尾部形成新的第一次加密后的目標(biāo)可執(zhí)行程序文件;步驟105 :構(gòu)建一個(gè)外殼程序文件模型;步驟106 :根據(jù)所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件將所述外殼程序文件模型構(gòu)建形成外殼程序;步驟107 :調(diào)用所述密鑰設(shè)備驅(qū)動(dòng)程序模塊中的加密算法,利用第二密鑰對(duì)所述外殼程序中的所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件進(jìn)行第二次加密,用第二次加密后的目標(biāo)可執(zhí)行程序文件替換所述外殼程序中的所述新的第一加密后的目標(biāo)可執(zhí)行程序文件,構(gòu)成第二次加密后的外殼程序;步驟108 :修改所述第二次加密后的外殼程序的文件頭的內(nèi)容,獲得修改后的外殼程序;步驟109 :完成加殼,保存所述修改后的外殼程序。上述步驟101中,外殼目標(biāo)文件打補(bǔ)丁的過程包括,將所述外殼目標(biāo)文件載入內(nèi)存,將密鑰設(shè)備驅(qū)動(dòng)程序模塊的基本信息添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中,將第一隨機(jī)數(shù)作為種子碼添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中,將密鑰設(shè)備參數(shù)添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中。所述密鑰設(shè)備驅(qū)動(dòng)程序模塊的基本信息包含驅(qū)動(dòng)程序地址、驅(qū)動(dòng)程序大小,所述密鑰設(shè)備參數(shù)包含密鑰設(shè)備的硬件ID、用戶密碼和密鑰設(shè)備的輪詢間隔。上述步驟102中,所述修改在所述文件頭的命令項(xiàng)找到的線程狀態(tài)命令和預(yù)設(shè)段命令具體為,從所述線程狀態(tài)命令獲取程序原始入口點(diǎn),并將所述程序原始入口點(diǎn)寫入所述預(yù)設(shè)段命令;將所述預(yù)設(shè)段命令的入口點(diǎn)寫入所述線程狀態(tài)命令。上述步驟103中,所述第一密鑰是通過以下方式獲取的計(jì)算機(jī)向密鑰設(shè)備發(fā)送第一隨機(jī)數(shù),所述密鑰設(shè)備返回第一密鑰。上述步驟105中,所述外殼程序文件模型的文件頭的設(shè)置如下寫入段命令和線程狀態(tài)命令,標(biāo)志位設(shè)置為不需要附加動(dòng)態(tài)連接器,寫入的所述段命令的長(zhǎng)度設(shè)置為第一長(zhǎng)度,所述第一長(zhǎng)度等于所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件的長(zhǎng)度。上述步驟106中,構(gòu)建形成外殼程序的過程為從所述外殼程序文件模型中提取出代碼段進(jìn)行處理,然后將所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件添加到處理后的所述代碼段的尾部一起構(gòu)成所述外殼程序的代碼段;所述處理包括,將第二隨機(jī)數(shù)作為第二密鑰添加到代碼段的數(shù)據(jù)中,將待加密文件即所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件的文件偏移和文件長(zhǎng)度添加到代碼段的數(shù)據(jù)中,將代碼段中的數(shù)據(jù)與代碼之間的空隙用隨機(jī)數(shù)進(jìn)行填充。進(jìn)一步的,所述步驟108具體為,遍歷所述第二次加密后的外殼程序的文件頭,找到段命令,獲取所述第二次加密后的目標(biāo)可執(zhí)行程序文件的長(zhǎng)度并記為第二長(zhǎng)度,將所述外殼程序中的段命令的長(zhǎng)度設(shè)置為第二長(zhǎng)度。以上所述第一次加密和所述第二次加密可以采用同一對(duì)稱算法加密,或者采用不同的對(duì)稱算法加密。與現(xiàn)有技術(shù)相比,本發(fā)明的軟件加殼保護(hù)方法增加了攻擊者破解或者非法篡改軟件的難度,甚至無法找到真正的程序入口點(diǎn),能有效防止逆向分析人員對(duì)軟件的反匯編破解及非法篡改,增加了軟件的安全性。
圖I是一種可執(zhí)行文件加殼保護(hù)方法的流程圖;圖2是一種殼目標(biāo)文件的執(zhí)行過程示意圖。
具體實(shí)施方式
為使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚,下面將結(jié)合附圖對(duì)本發(fā)明實(shí)施方式作進(jìn)一步地詳細(xì)描述。本發(fā)明提供的一種可執(zhí)行程序加殼保護(hù)方法的基本原理是對(duì)可執(zhí)行程序文件的執(zhí)行代碼段加密,加密密鑰從密鑰設(shè)備中獲取;利用隨機(jī)數(shù)對(duì)可執(zhí)行程序文件整體加密; 將整體加密后的可執(zhí)行程序文件映射到殼模型的代碼段構(gòu)造殼文件結(jié)構(gòu),組裝生成殼程序。實(shí)施例I本實(shí)施例結(jié)合附圖詳細(xì)說明了對(duì)獲取的目標(biāo)文件進(jìn)行加密處理的過程。以下以基于Mac. OS平臺(tái)的實(shí)現(xiàn)方法為例對(duì)本發(fā)明提出的加殼保護(hù)方法進(jìn)行詳細(xì)描述,本實(shí)施例所提及的文件是以蘋果系統(tǒng)中通用的文件名來出現(xiàn)的。當(dāng)所述獲取的目標(biāo)文件是Flat格式文件,則先運(yùn)行吸脂程序Iipo對(duì)目標(biāo)文件進(jìn)行分離處理,再對(duì)分離出的i386或x64文件進(jìn)行加密處理。所述運(yùn)行Iipo對(duì)Flat文件進(jìn)行分離處理的過程具體為,根據(jù)Flat文件的文件頭判斷文件類型,并根據(jù)Flat文件頭中包含的待分離文件的結(jié)構(gòu)信息從指定位置將所述待分離文件分離出來。具體地,所述Flat文件的文件頭定義如下
struct fat—header { uint32_t magic; /* FAT—MAGIC */ uint32_t nfat arch; /* number of structs that follow */其中,nfat_arch可表示Flat文件包含的待分離文件的個(gè)數(shù),具體地,可以僅包含
多個(gè)x64文件或僅包含多個(gè)i386文件,還可以同時(shí)包含多個(gè)x64文件和i386文件。上述任意一個(gè)待分離文件的文件頭定義如下
struct fat—arch {
cpu type t cputype; /* cpu specifier (int) */ cpu subtype t cpusubtype; /* machine specifier (int) */ uint32」 offset; /* file offset to this object file */ uint32」 size; /* size of this object file */ uint32_t align; /* alignment as a power of 2 */其中,當(dāng)Cputype為7時(shí)是32位系統(tǒng),即表示該待分離文件是i386文件;當(dāng)Cputype為16777223時(shí)是64位系統(tǒng),即表示該待分離文件是x64文件。如果待分離文件是i386文件則Iipo程序發(fā)送i386分離命令給Flat文件,將i386 可執(zhí)行程序從Flat文件中分離出來;如果待分離文件是x64文件則Iipo程序發(fā)送x64分離命令給Flat文件,將x64可執(zhí)行程序從Flat文件中分離出來。本實(shí)施例中,具體用到的命令如下x64 分離命令 lipo-thin x86_64_output b a,用于將 x86_64mach_o 文件從 Flat 文件A中分離出來,存為文件c ;i386 分離命令 lipo-thin i386_output c a,用于將 i386mach_o 文件從 Flat 文件A中分尚出來,存為文件b。所述i386分離命令包含要分離出來的所述i386可執(zhí)行程序的文件名和所述Flat 文件的文件名,如上述示例,用a表示Flat文件的文件名,用b表示i386可執(zhí)行程序的文件名;所述x64文件分離命令包含要分離出來的所述x64可執(zhí)行程序的文件名和所述Flat 文件的文件名;如上述示例,用a表示Flat文件的文件名,用c表示x64可執(zhí)行程序的文件名。當(dāng)所述獲取的目標(biāo)文件是i386或x64格式文件則無需運(yùn)行Iipo程序,可以直接對(duì)所述目標(biāo)文件進(jìn)行如下處理。本實(shí)施例以對(duì)i386可執(zhí)行程序文件的加密處理為例進(jìn)行詳細(xì)介紹,如圖I所示, 一種可執(zhí)行程序加殼保護(hù)方法,包括以下步驟步驟101 :將i386可執(zhí)行程序文件加載到內(nèi)存,將打好補(bǔ)丁的外殼目標(biāo)文件添加到所述i386可執(zhí)行程序文件的尾部形成目標(biāo)可執(zhí)行程序文件;在本步驟前包括對(duì)所述外殼目標(biāo)文件打補(bǔ)丁的過程,具體如下將外殼目標(biāo)文件 core32載入內(nèi)存,將密鑰設(shè)備驅(qū)動(dòng)程序模塊的基本信息添加到所述外殼目標(biāo)文件core32 的數(shù)據(jù)段中,將第一隨機(jī)數(shù)作為種子碼添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中,將密鑰設(shè)備參數(shù)添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中,得到打好補(bǔ)丁的外殼目標(biāo)文件。Core32程序是第一層殼的引導(dǎo)程序,用C語言編寫,除了代碼段,還有數(shù)據(jù)段。數(shù)據(jù)段存放一些基本信息,比如密鑰設(shè)備的驅(qū)動(dòng)程序在文件里面的偏移、加載密鑰設(shè)備的驅(qū)動(dòng)程序所使用的系統(tǒng)函數(shù)地址、解密用的種子碼。本實(shí)施例中core32的數(shù)據(jù)段具體如下uint32_t_NSCreate0bjectFiIeImageFromFiIe = Oxff ;// 加載驅(qū)動(dòng)程序的系統(tǒng) APIuint32_t_NSCreate0bjectFiIeImageFromMemory = Oxff ;// 加載驅(qū)動(dòng)程序的系統(tǒng)APIuint32_t_NSLinkModule = Oxff ;// 加載驅(qū)動(dòng)程序的系統(tǒng) APIuint32_t_NSLookupSymbolInModule = Oxff -J/ 加載驅(qū)動(dòng)程序的系統(tǒng) APIuint32_t_NSAddress0fSymbol = Oxff ;// 加載驅(qū)動(dòng)程序的系統(tǒng) APIuint32_t_NSUnLinkModule = Oxff ;// 加載驅(qū)動(dòng)程序的系統(tǒng) APIuint32_t_NSDestroy0bjectFi IeImage = Oxff -J/ 加載驅(qū)動(dòng)程序的系統(tǒng) APIuint32_t_puts = Oxff -J/ 系統(tǒng) APIuint32_t_exit = Oxff -J/ 系統(tǒng) API
uint32—t—bundle—addr = Oxff ;// 驅(qū)動(dòng)程序地址uint32—t—bundle—size = Oxff ;// 驅(qū)動(dòng)程序大小uint32—t—seed—code = Oxff ;// 密鑰種子碼uint32—t—text—addr = Oxff ;// 原始程序代碼段段地址uint32—t—text—size = Oxff ;// 原始程序代碼段長(zhǎng)度uint32_t_hid = Oxff ;// 密鑰設(shè)備的硬件 IDuint32_t_pl = Oxff ;// 密碼第一個(gè)字節(jié)uint32_t_p2 = Oxff ;// 密碼第二個(gè)字節(jié)uint32—t—interval = Oxff ;// 密鑰設(shè)備的輪訓(xùn)間隔所述密鑰設(shè)備驅(qū)動(dòng)程序模塊的基本信息包含驅(qū)動(dòng)程序地址、驅(qū)動(dòng)程序大小;所述密鑰設(shè)備參數(shù)包含密鑰設(shè)備的硬件ID、用戶密碼和密鑰設(shè)備的輪詢間隔,即數(shù)據(jù)段中的 hid表示硬件ID,plp2表示用戶密碼,interval表示密鑰設(shè)備的輪詢間隔。步驟102 :在目標(biāo)可執(zhí)行程序文件的文件頭加入一條段命令來描述打好補(bǔ)丁的外殼目標(biāo)文件和密鑰設(shè)備驅(qū)動(dòng)程序模塊;本實(shí)施例中,在目標(biāo)可執(zhí)行程序文件的文件頭加入段命令LC—SEGMENT,并設(shè)置段名 segname 為—FTSAFE。具體地,加入的段命令如下#define LC SEGMENT Oxl /* segment of this file to be mapped 段命
Struct segment—command {/*for 32-bit architectures*/
uint32 tcmd;/*LC—SEGMENT*/uint32_tcmdsize;/*includes sizeof section structs*/charsegname[16];/^segment name*/uint32_tvmaddr;/*memory address of this segment*/uint32 tvmsize;/*memory size of this segment*/uint32 tfileoff;/*file offset of this segment*/uint32_tfilesize;/*amount to map from the file*/vm_prot_tmaxprot;/*maximum VM protection*/vm_prot_tinitprot;/*initia1 VM protection*/uint32 tnsects;/^number of sections in segment*/uint32_tflags;/*flags*/當(dāng)目標(biāo)文件為x64格式的文件時(shí)加入的段命令為L(zhǎng)C_SEGMENT64 ;則段名具體如
下; /* segment name*/uint64 tvmaddr;/*memory address of this segment*/uint64 tvmsize;/*memory size of this segment*/uint64 tfileoff;/*file offset of this segment*/uint32 tfilesize;/*amount to map from the file*/vm_prot_tmaxprot;/*maximum VM protection*/vm_prot_tinitprot;/*initial VM protection*/uint32 tnsects;/*number of sections in segment*/uint32 tflags;/*flags*/步驟103 :遍歷目標(biāo)可執(zhí)行程序文件的文件頭的命令項(xiàng),找到線程狀態(tài)命令和段名為_FTSAFE的段命令,從所述線程狀態(tài)命令獲取程序原始入口點(diǎn),并將所述程序原始入口點(diǎn)寫入段命令;將所述段命令的入口點(diǎn)寫入所述線程狀態(tài)命令;具體地,所述線程狀態(tài)命令定義如下
#define LC UNIXTHREAD 0x5 /* unix thread (includes a stack) 線程狀態(tài)命令(包含入口點(diǎn)) struct thread—command {
uint32_t cmd;/*LC—THREAD or LCUNIXTHREAD*/uint32_t cmdsize; /*uint32_t flavor /*uint32 t count
/*total size of this command*/ flavor of thread state*/ count of longs in thread state*/
/*struct XXX thread state state thread state for this flavor*/實(shí)際應(yīng)用中線程狀態(tài)命令thread_command的格式和上述示例有所不同,實(shí)際應(yīng)用中,如果是i386文件,cmd后面就是一個(gè)寄存器數(shù)組,我們用uint32_t*regslots表示, 且找到的原始入口點(diǎn)的入口地址為regslots[10];如果是x86_64文件,我們用uint64_ t*regslots表示,且找到的原始入口點(diǎn)的入口地址為regslots[16]。步驟104 :將第一隨機(jī)數(shù)發(fā)送給密鑰設(shè)備以獲取密鑰設(shè)備返回的第一密鑰;具體的,所述第一密鑰可以是一個(gè)DES密鑰。本實(shí)施例中,優(yōu)選采用發(fā)送第一隨機(jī)數(shù)獲取第一密鑰,除了采用隨機(jī)數(shù),還可以向密鑰設(shè)備發(fā)送其他數(shù)據(jù)來獲取第一密鑰,例如,計(jì)算機(jī)根據(jù)自身信息計(jì)算一個(gè)MD5值,將所述MD5值發(fā)送給密鑰設(shè)備以獲取密鑰設(shè)備返回的第一密鑰。步驟105 :遍歷目標(biāo)可執(zhí)行程序文件,找到執(zhí)行代碼段,用所述第一密鑰對(duì)所述執(zhí)行代碼段進(jìn)行第一次加密,并用加密結(jié)果替換所述目標(biāo)可執(zhí)行程序文件中的執(zhí)行代碼段, 得到第一次加密后的目標(biāo)可執(zhí)行程序文件;將包含密鑰設(shè)備驅(qū)動(dòng)和加解密算法的密鑰設(shè)備驅(qū)動(dòng)模塊添加到所述第一次加密后目標(biāo)可執(zhí)行程序文件的執(zhí)行代碼段的尾部,形成新的第一次加密后的目標(biāo)可執(zhí)行程序文件;步驟106 :將新的第一次加密后的目標(biāo)可執(zhí)行程序文件保存到磁盤;步驟107 :構(gòu)建一個(gè)外殼程序文件模型;本實(shí)施例中具體地,所述外殼程序文件模型的文件頭Mac-O的設(shè)置如下寫入兩條命令分別是段命令和線程狀態(tài)命令,將標(biāo)志位設(shè)置為MH_N0UNDEFS,即表示不需要附加動(dòng)態(tài)連接器,例如設(shè)置好的文件頭表示如下,mheader. magic = ΜΗ—MAGIC ;mheader. cputype = CPU—TYPE—1386 ;mheader. cpusubtype = CPU—SUBTYPE—386 ;mheader. filetype = MH—EXECUTE ;mheader. ncmds = 2 ;mheader. sizeofcmds = 0x88 ;mheader. flags = MH—N0UNDEFS ;將步驟106所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件加載到內(nèi)存,獲取所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件的長(zhǎng)度記為第一長(zhǎng)度,將所述外殼程序文件模型中所述段命令的長(zhǎng)度設(shè)置為第一長(zhǎng)度。步驟108 :將所述外殼程序文件模型加載到內(nèi)存,經(jīng)過構(gòu)建形成外殼程序;
構(gòu)建過程具體為從所述外殼程序文件模型中提取出代碼段進(jìn)行處理,然后將所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件添加到處理后的代碼段的尾部一起構(gòu)成所述外殼程序的代碼段。所述處理包括,將第二隨機(jī)數(shù)作為第二密鑰添加到代碼段的數(shù)據(jù)中,將待加密文件即新的第一次加密后的目標(biāo)可執(zhí)行程序文件的文件偏移和文件長(zhǎng)度添加到代碼段的數(shù)據(jù)中,將代碼段中的數(shù)據(jù)與代碼之間的空隙用隨機(jī)數(shù)進(jìn)行填充。步驟109 :調(diào)用密鑰設(shè)備驅(qū)動(dòng)模塊中的加密算法,利用第二密鑰對(duì)所述外殼程序中的新的第一次加密后的目標(biāo)可執(zhí)行程序文件進(jìn)行第二次加密,用第二次加密后的目標(biāo)可執(zhí)行程序文件替換所述外殼程序中的所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件,構(gòu)成第二次加密后的外殼程序,所述加密算法為對(duì)稱加密算法,可以采用與第一次加密采用的算法相同的DES算法,也可以采用RC4算法;步驟110 :修改所述第二次加密后的外殼程序的文件頭的內(nèi)容,獲得修改后的外殼程序;本步驟具體為,遍歷所述第二次加密后的外殼程序的文件頭,找到段命令,獲取所述第二次加密后的目標(biāo)可執(zhí)行程序文件的長(zhǎng)度并記為第二長(zhǎng)度,將外殼程序中的段命令的長(zhǎng)度設(shè)置為第二長(zhǎng)度。步驟111 :完成加殼,獲得殼目標(biāo)文件即修改后的外殼程序。實(shí)施例2執(zhí)行上述殼目標(biāo)文件的過程包括如下步驟步驟201 :將殼目標(biāo)文件加載到內(nèi)存,遍歷殼目標(biāo)文件獲取程序入口點(diǎn);具體地,遍歷殼目標(biāo)文件的文件頭,找到線程狀態(tài)命令LC_UNIXTHREAD,獲取程序入口點(diǎn)的入口地址。步驟202 :跳轉(zhuǎn)到程序入口點(diǎn),執(zhí)行外殼程序;執(zhí)行外殼程序具體為,從外殼程序的代碼段獲取第二密鑰,利用所述第二密鑰對(duì)外殼程序中的第二次加密后的外殼程序進(jìn)行解密得到新的第一次加密后的目標(biāo)可執(zhí)行程序文件,釋放掉所述外殼程序的代碼段的其他內(nèi)容;掃描所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件的執(zhí)行代碼段,將所有命令段都拷貝到指定的內(nèi)存地址。步驟203 :運(yùn)行動(dòng)態(tài)連接器,載入需要的動(dòng)態(tài)鏈接庫(kù);具體的,若所述動(dòng)態(tài)連接器程序文件是FLAT格式,則解析出其中的i386部分,并將動(dòng)態(tài)連接器程序中的i386文件載入內(nèi)存,掃描所述i386的執(zhí)行代碼段,將所有命令段都拷貝到指定的內(nèi)存地址。步驟204:在所述動(dòng)態(tài)鏈接庫(kù)的固定地址上掃描預(yù)設(shè)符號(hào),根據(jù)所述預(yù)設(shè)符號(hào)的地址指向找到所述動(dòng)態(tài)鏈接庫(kù)載入內(nèi)存的虛擬地址;所述虛擬地址是指動(dòng)態(tài)連接庫(kù)中的用于表不可載入密鑰設(shè)備驅(qū)動(dòng)模塊的符號(hào)載入內(nèi)存的地址。本實(shí)施例中具體地,所述固定地址為0x0x8fe00000,所述預(yù)設(shè)符號(hào)為_dyld_all_ image_infos。步驟205 :根據(jù)所述虛擬地址找到動(dòng)態(tài)鏈接庫(kù)的符號(hào)表,解析所述動(dòng)態(tài)鏈接庫(kù)的符號(hào)表,查找到表示預(yù)設(shè)函數(shù)符號(hào)的地址;所述預(yù)設(shè)函數(shù)是指用于表示可載入密鑰設(shè)備驅(qū)動(dòng)模塊函數(shù)。
12
例如,所述表示預(yù)設(shè)函數(shù)的符號(hào)如下,_NSCreateObjectFiIeImageFromFiIe_NSCreateObjectFiIeImageFromMemory_NSLinkModule_NSLookupSymbolInModule_NSAddressOfSymbol_NSUnLinkModule_NSDestroyObjectFiIeImage_puts_exit步驟206 :根據(jù)所述表示預(yù)設(shè)函數(shù)符號(hào)的地址指向調(diào)用相應(yīng)函數(shù),將包含設(shè)備驅(qū)動(dòng)和加解密算法的密鑰設(shè)備驅(qū)動(dòng)模塊載入內(nèi)存,連接在所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件所在的指定的內(nèi)存地址后面;步驟207 :解析所述密鑰設(shè)備驅(qū)動(dòng)模塊,查找到線程狀態(tài)命令,獲取目標(biāo)程序入口點(diǎn);獲取所述密鑰設(shè)備驅(qū)動(dòng)模塊中預(yù)存的第一隨機(jī)數(shù)發(fā)送給密鑰設(shè)備以得到第一密鑰;步驟208 :根據(jù)所述目標(biāo)程序入口點(diǎn)跳轉(zhuǎn)到所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件的執(zhí)行代碼段,利用所述第一密鑰對(duì)所述執(zhí)行代碼段進(jìn)行解密得到原始執(zhí)行代碼段。本發(fā)明提出的方法還可以適用于Unix、LinuxS平臺(tái),在具體實(shí)施過程中,只要將上述實(shí)施例中所述Mac系統(tǒng)中的文件名用相應(yīng)系統(tǒng)中可實(shí)現(xiàn)類似功能的文件進(jìn)行替換即可實(shí)施。以上所述,僅為本發(fā)明的具體實(shí)施方式
,但本發(fā)明的保護(hù)范圍并不局限于此,任何熟悉本技術(shù)領(lǐng)域的技術(shù)人員在本發(fā)明揭露的技術(shù)范圍內(nèi),可輕易想到變化或替換,都應(yīng)涵蓋在本發(fā)明的保護(hù)范圍之內(nèi)。因此,本發(fā)明的保護(hù)范圍應(yīng)所述以權(quán)利要求的保護(hù)范圍為準(zhǔn)。
權(quán)利要求
1.一種可執(zhí)行程序加殼保護(hù)方法,其特征是包括以下步驟,步驟101 :將打好補(bǔ)丁的外殼目標(biāo)文件添加到可執(zhí)行程序文件的尾部形成目標(biāo)可執(zhí)行程序文件;步驟102 :對(duì)所述目標(biāo)可執(zhí)行程序文件的文件頭進(jìn)行修改形成修改后的目標(biāo)可執(zhí)行程序文件;所述修改包括在所述文件頭加入一條段命令來描述所述打好補(bǔ)丁的外殼目標(biāo)文件和密鑰設(shè)備驅(qū)動(dòng)程序模塊,以及修改在所述文件頭的命令項(xiàng)找到的線程狀態(tài)命令和預(yù)設(shè)段命令;步驟103 :遍歷所述修改后的目標(biāo)可執(zhí)行程序文件,找到執(zhí)行代碼段,用第一密鑰對(duì)所述執(zhí)行代碼段進(jìn)行第一次加密,并用加密結(jié)果替換所述修改后的目標(biāo)可執(zhí)行程序文件中的執(zhí)行代碼段,得到第一次加密后的目標(biāo)可執(zhí)行程序文件;步驟104 :將包含密鑰設(shè)備驅(qū)動(dòng)和加解密算法的密鑰設(shè)備驅(qū)動(dòng)程序模塊添加到所述第一次加密后的目標(biāo)可執(zhí)行程序文件的執(zhí)行代碼段的尾部形成新的第一次加密后的目標(biāo)可執(zhí)行程序文件;步驟105 :構(gòu)建外殼程序文件模型,并根據(jù)所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件將所述外殼程序文件模型構(gòu)建形成外殼程序;步驟106 :調(diào)用所述密鑰設(shè)備驅(qū)動(dòng)程序模塊中的加密算法,利用第二密鑰對(duì)所述外殼程序中的所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件進(jìn)行第二次加密,用第二次加密后的目標(biāo)可執(zhí)行程序文件替換所述外殼程序中的所述新的第一加密后的目標(biāo)可執(zhí)行程序文件,構(gòu)成第二次加密后的外殼程序;步驟107 :修改所述第二次加密后的外殼程序的文件頭的內(nèi)容,獲得修改后的外殼程序;步驟108 :完成加殼,保存所述修改后的外殼程序。
2.根據(jù)權(quán)利要求I所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是步驟101所述外殼目標(biāo)文件打補(bǔ)丁的過程包括,將所述外殼目標(biāo)文件載入內(nèi)存,將密鑰設(shè)備驅(qū)動(dòng)程序模塊的基本信息添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中,將第一隨機(jī)數(shù)作為種子碼添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中,將密鑰設(shè)備參數(shù)添加到所述外殼目標(biāo)文件的數(shù)據(jù)段中。
3.根據(jù)權(quán)利要求2所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是所述密鑰設(shè)備驅(qū)動(dòng)程序模塊的基本信息包含驅(qū)動(dòng)程序地址、驅(qū)動(dòng)程序大小,所述密鑰設(shè)備參數(shù)包含密鑰設(shè)備的硬件ID、用戶密碼和密鑰設(shè)備的輪詢間隔。
4.根據(jù)權(quán)利要求I所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是步驟102所述修改在所述文件頭的命令項(xiàng)找到的線程狀態(tài)命令和預(yù)設(shè)段命令具體為,從所述線程狀態(tài)命令獲取程序原始入口點(diǎn),并將所述程序原始入口點(diǎn)寫入所述預(yù)設(shè)段命令;將所述預(yù)設(shè)段命令的入口點(diǎn)寫入所述線程狀態(tài)命令。
5.根據(jù)權(quán)利要求I所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是步驟103所述第一密鑰是通過以下方式獲取的計(jì)算機(jī)向密鑰設(shè)備發(fā)送第一隨機(jī)數(shù),所述密鑰設(shè)備返回第一密鑰。
6.根據(jù)權(quán)利要求I所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是步驟105所述外殼程序文件模型的文件頭的設(shè)置如下寫入段命令和線程狀態(tài)命令,標(biāo)志位設(shè)置為不需要附加動(dòng)態(tài)連接器,寫入的所述段命令的長(zhǎng)度設(shè)置為第一長(zhǎng)度,所述第一長(zhǎng)度等于所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件的長(zhǎng)度。
7.根據(jù)權(quán)利要求I所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是步驟105所述構(gòu)建形成外殼程序的過程為從所述外殼程序文件模型中提取出代碼段進(jìn)行處理,然后將所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件添加到處理后的所述代碼段的尾部一起構(gòu)成所述外殼程序的代碼段;所述處理包括,將第二隨機(jī)數(shù)作為第二密鑰添加到代碼段的數(shù)據(jù)中,將待加密文件即所述新的第一次加密后的目標(biāo)可執(zhí)行程序文件的文件偏移和文件長(zhǎng)度添加到代碼段的數(shù)據(jù)中,將代碼段中的數(shù)據(jù)與代碼之間的空隙用隨機(jī)數(shù)進(jìn)行填充。
8.根據(jù)權(quán)利要求7所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是所述步驟107具體為,遍歷所述第二次加密后的外殼程序的文件頭,找到段命令,獲取所述第二次加密后的目標(biāo)可執(zhí)行程序文件的長(zhǎng)度并記為第二長(zhǎng)度,將所述外殼程序中的段命令的長(zhǎng)度設(shè)置為第二長(zhǎng)度。
9.根據(jù)權(quán)利要求I所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是所述第一次加密和所述第二次加密采用同一對(duì)稱算法加密,或者采用不同的對(duì)稱算法加密。
10.根據(jù)權(quán)利要求I所述的一種可執(zhí)行程序加殼保護(hù)方法,其特征是所述可執(zhí)行程序文件是i386或X64格式文件。
全文摘要
本發(fā)明公開了一種可執(zhí)行程序加殼保護(hù)方法,計(jì)算機(jī)軟件程序保護(hù)技術(shù)領(lǐng)域。首先將打好補(bǔ)丁的外殼目標(biāo)文件添加到可執(zhí)行程序文件的尾部形成目標(biāo)可執(zhí)行程序文件,并相應(yīng)修改文件頭,并且對(duì)執(zhí)行代碼段進(jìn)行第一次加密,將密鑰設(shè)備驅(qū)動(dòng)程序模塊添加到第一次加密后的文件的尾部形成新的第一次加密后的目標(biāo)可執(zhí)行程序文件,構(gòu)建外殼程序,對(duì)所述外殼程序中的新的第一次加密后的目標(biāo)可執(zhí)行程序文件進(jìn)行第二次加密,并相應(yīng)的修改文件頭,完成加殼保存當(dāng)前外殼程序。本發(fā)明有效解決了現(xiàn)有技術(shù)中加殼保護(hù)后的軟件易于被攻擊者破解及非法篡改的問題。
文檔編號(hào)G06F21/22GK102609666SQ20121001932
公開日2012年7月25日 申請(qǐng)日期2012年1月20日 優(yōu)先權(quán)日2012年1月20日
發(fā)明者于華章, 陸舟 申請(qǐng)人:飛天誠(chéng)信科技股份有限公司