余彥 萬(wàn)毅
摘 要: 作為最常用的軟件保護(hù)方式之一,序列號(hào)保護(hù)面臨著最多的攻擊者的研究。破解者主要的攻擊過(guò)程分為黑盒階段,動(dòng)態(tài)分析階段,靜態(tài)分析階段和編輯階段。動(dòng)態(tài)分析可以理解成一個(gè)遵循“定位保護(hù)代碼-修改二進(jìn)制代碼-測(cè)試”的破解循環(huán)。從該破解循環(huán)入手,提出一種新的程序架構(gòu),在校驗(yàn)代碼之前加入某種規(guī)則決定是否進(jìn)行校驗(yàn),并將其嵌入主程序的不同位置,形成的對(duì)主程序的校驗(yàn)位置的組合有2N種,這可為軟件提供更有效的保護(hù)措施。
關(guān)鍵詞: 軟件保護(hù); 序列號(hào); 動(dòng)態(tài)分析; 軟件破解
中圖分類號(hào):TP311.1 文獻(xiàn)標(biāo)志碼:A 文章編號(hào):1006-8228(2015)05-22-04
Abstract: As one of the most commonly used method of software protection, serial number protection is facing up to the crackers' research. The main process of software attacking is divided into black box stage, dynamic analysis stage, static analysis stage and editing stage. Dynamic analysis stage can be understood as a follow "positioning the protection code-modify the binary code-test" of the work cycle. From the work cycle of dynamic analysis stage, we put forward a new program architecture, by adding certain rules before deciding whether to execute the code for checking serial number, and to embed them into the main program for n times, so there are 2n different kinds of combinations of the code for checking serial number to form. Thus the software can be protected more effectively.
Key words: software protection; serial number; dynamic analysis; software cracking
0 引言
在計(jì)算機(jī)軟件技術(shù)高速發(fā)展的今天,軟件產(chǎn)品早已作為知識(shí)產(chǎn)權(quán)受到法律保護(hù)??墒窃谖覈?guó),即使有各種各樣的法律,軟件被盜版問(wèn)題依然很嚴(yán)重。根據(jù)商業(yè)軟件聯(lián)盟(Business Software Alliance)公布的調(diào)查報(bào)告[1]顯示,2013年的盜版軟件安裝率為74%,雖然較前幾年(2011:77%,2009:79%,2007:84%)有所下降,但依然處于非常高的比例,據(jù)該調(diào)查報(bào)告顯示,盜版軟件的商業(yè)價(jià)值達(dá)到87億美元。因此,軟件保護(hù)技術(shù)的研究依然是熱點(diǎn)課題。
軟件保護(hù)技術(shù)中最常見的是序列號(hào)保護(hù)技術(shù)。針對(duì)序列號(hào)保護(hù),本文提出了一種新的程序架構(gòu),其關(guān)鍵是將校驗(yàn)的代碼隨機(jī)多次嵌入主程序的不同位置,而校驗(yàn)代碼之前加入某種規(guī)則決定是否進(jìn)行授權(quán)校驗(yàn),使得程序可以根據(jù)不同運(yùn)行狀態(tài)而進(jìn)入不同位置的校驗(yàn)代碼段,從而增加盜版者的破解難度。
1 序列號(hào)保護(hù)機(jī)制原理
作為最常見的軟件保護(hù)模型,序列號(hào)保護(hù)[2]的結(jié)構(gòu)如圖1所示。每次程序開始運(yùn)行時(shí),需要先校驗(yàn)保存在本地的序列號(hào)。如果校驗(yàn)未通過(guò),如序列號(hào)不正確或序列號(hào)有效期已過(guò),則要求用戶輸入合法的序列號(hào),否則不允許進(jìn)入受保護(hù)的主程序。當(dāng)校驗(yàn)通過(guò),程序便處于合法運(yùn)行狀態(tài),可以使用受保護(hù)的功能或算法等。
[啟動(dòng)程序][用戶程序][校驗(yàn)序列號(hào)] [進(jìn)入主程序][程序結(jié)束][輸入序列號(hào)] [T][F]
圖1 序列號(hào)校驗(yàn)流程
對(duì)于獲得了序列號(hào)的用戶來(lái)說(shuō),校驗(yàn)過(guò)程是透明的,用戶只需要輸入從軟件廠商購(gòu)買的序列號(hào),校驗(yàn)過(guò)程由本地程序自動(dòng)完成[3]。校驗(yàn)過(guò)程可用如下公式表示。
⑴ 軟件廠商獲得用戶信息后計(jì)算序列號(hào):
序列號(hào)=F(用戶信息)
⑵ 用戶獲得序列號(hào)后在本地進(jìn)行校驗(yàn):
用戶信息=G(序列號(hào))
購(gòu)買者如果隨意將用戶信息和對(duì)應(yīng)的序列號(hào)非法分發(fā)給其他未授權(quán)使用者,軟件廠商無(wú)法禁止其使用。因此本文采取硬件信息作為用戶信息,如此,即使序列號(hào)被非法分發(fā),也因?yàn)橛布煌鵁o(wú)法在不同的機(jī)器上使用,從而可以更好的保護(hù)軟件。
2 破解者的主要攻擊方法
整個(gè)破解的過(guò)程可以分為若干個(gè)階段,在最初的幾個(gè)階段中,破解者的任務(wù)主要是分析程序,試圖弄明白程序的內(nèi)部結(jié)構(gòu)及其行為模式。而在后面幾個(gè)階段,破解者則會(huì)使用前幾個(gè)階段中獲得的信息,按具體需要對(duì)程序進(jìn)行修改。我們把破解過(guò)程大致分為四個(gè)階段[4]。
⑴ 黑盒階段
在黑盒分析階段,破解者并不了解程序的內(nèi)部構(gòu)造,對(duì)其而言,程序就是一個(gè)“黑盒”。破解者會(huì)試圖給程序輸入一些數(shù)據(jù),并觀察程序的輸出,然后根據(jù)程序的行為做出某些推斷。
⑵ 動(dòng)態(tài)分析階段
在動(dòng)態(tài)分析階段,破解者開始分析程序的內(nèi)部行為,雖然這時(shí)他仍然會(huì)執(zhí)行程序,但是他這時(shí)會(huì)記錄在輸入不同的數(shù)據(jù)后,程序會(huì)執(zhí)行哪些不同的部分。
⑶ 靜態(tài)分析階段
為了更好的理解程序的作用,破解者在動(dòng)態(tài)分析過(guò)后會(huì)直接分析代碼本身,這就是靜態(tài)分析。
⑷ 編輯階段
前三個(gè)階段的工作使得破解者可以弄清楚他所關(guān)心的算法,找到了秘鑰所在。但如果破解者還需要對(duì)程序進(jìn)行修改,例如刪除檢查軟件序列號(hào)部分的代碼,或者是抹除程序中用來(lái)標(biāo)識(shí)用戶信息的指紋水印等,則需要驚醒這個(gè)步驟對(duì)原程序進(jìn)行編輯。
動(dòng)態(tài)分析中的破解循環(huán),對(duì)于破解者來(lái)說(shuō),對(duì)一個(gè)程序進(jìn)行動(dòng)態(tài)分析是需要遵循“定位保護(hù)代碼-修改二進(jìn)制代碼-測(cè)試”的破解循環(huán)來(lái)工作。如圖2所示,在定位保護(hù)代碼的階段,破解者需要找到程序的保護(hù)代碼(比如校驗(yàn)序列號(hào)的代碼段)在程序中的位置,并且在接下來(lái)的修改階段對(duì)其進(jìn)行一系列的修改使程序能按其方式來(lái)運(yùn)行。對(duì)二進(jìn)制代碼進(jìn)行的修改包括去除舊的指令,增加新的指令以及對(duì)原有指令進(jìn)行修改。最后,破解者還要測(cè)試經(jīng)過(guò)修改后的程序是否能按照其意愿進(jìn)行工作,否則將進(jìn)行下一次破解循環(huán)。本文提出的程序結(jié)構(gòu)就是從破解循環(huán)入手,增加其動(dòng)態(tài)分析程序的阻力,通過(guò)增加程序運(yùn)行時(shí)的不確定性讓程序在每次獨(dú)立運(yùn)行時(shí)都會(huì)動(dòng)態(tài)的選擇不同的執(zhí)行路徑,讓破解者無(wú)法輕易找到序列號(hào)的校驗(yàn)代碼所在。
圖3是采用objdump工具對(duì)作者的程序進(jìn)行反匯編得到的結(jié)果。圖3左側(cè)是未經(jīng)過(guò)修改的程序,MainWindow::core()是一個(gè)函數(shù),用于代表程序的主體部分,其地址為0x00405040。圖片左側(cè)下方的內(nèi)容是軟件的序列號(hào)校驗(yàn)?zāi)K其中的一段。進(jìn)入程序主體部分之前,需要經(jīng)過(guò)序列號(hào)的校驗(yàn)。這段匯編代碼中有一條判斷語(yǔ)句:test %al,%al,其功能是如果用戶輸入的序列號(hào)通過(guò)了校驗(yàn),那么就進(jìn)入主程序部分(地址0x00405040)繼續(xù)執(zhí)行,否則就跳轉(zhuǎn)至程序的結(jié)束部分的地址(0x004059b0)。可以看出,對(duì)軟件的保護(hù)依賴于序列號(hào)的校驗(yàn)是否成功。如果攻擊者對(duì)程序先進(jìn)行反匯編,然后找到這段控制序列號(hào)校驗(yàn)邏輯的代碼,將其的跳轉(zhuǎn)邏輯修改成無(wú)論序列號(hào)校驗(yàn)是否成功都跳轉(zhuǎn)至程序的主體部分繼續(xù)執(zhí)行,那么序列號(hào)的校驗(yàn)?zāi)K也就無(wú)法對(duì)軟件提供保護(hù)了。如圖3右下方代碼段所示,將匯編程序跳轉(zhuǎn)邏輯修改后,無(wú)論序列號(hào)校驗(yàn)的結(jié)果如何,程序始終都會(huì)執(zhí)行MainWindow::core()(在修改過(guò)的程序中該函數(shù)的地址為0x00404fd0)。也就是說(shuō),如果通過(guò)動(dòng)態(tài)分析的手段找出了軟件的序列號(hào)校驗(yàn)的代碼并對(duì)其功能進(jìn)行修改,那么即使不知道序列號(hào)校驗(yàn)的算法,也可以直接繞過(guò)序列號(hào)校驗(yàn)的部分直接非法的使用該軟件。
3 一種新的抵抗動(dòng)態(tài)分析的軟件模式
如前文所述,破解者在動(dòng)態(tài)分析階段會(huì)試圖找出程序的序列號(hào)校驗(yàn)?zāi)K,并修改其邏輯已獲得非法使用程序的目的。動(dòng)態(tài)分析主要是遵循“定位保護(hù)代碼-修改二進(jìn)制代碼-測(cè)試”的破解循環(huán)來(lái)工作的,其中最重要的環(huán)節(jié)就是定位二進(jìn)制代碼,如果破解者無(wú)法順利定位序列號(hào)校驗(yàn)部分的代碼,也就無(wú)法針對(duì)其進(jìn)行攻擊。傳統(tǒng)的商業(yè)軟件對(duì)于程序的保護(hù)一般是將程序的序列號(hào)校驗(yàn)部分放在程序的最開始,這樣,攻擊者跟蹤程序的運(yùn)行步驟不久后比較容易找出程序的校驗(yàn)?zāi)K。本系統(tǒng)的設(shè)計(jì)主要目的是提高破解者對(duì)代碼動(dòng)態(tài)分析的難度,并且輔助以注冊(cè)碼的安全生成機(jī)制而提高軟件的安全性。
防止動(dòng)態(tài)分析的手段,從動(dòng)態(tài)分析階段入手,我們提出了以下更具復(fù)雜性和隨機(jī)性的機(jī)制來(lái)保護(hù)軟件。
⑴ 增加程序中校驗(yàn)序列號(hào)的次數(shù),也就是說(shuō),不僅僅在軟件安裝時(shí)校驗(yàn)序列號(hào),而在軟件的使用過(guò)程中可以嵌入多段校驗(yàn)序列號(hào)的代碼。
⑵ 校驗(yàn)序列號(hào)時(shí)不采用函數(shù)調(diào)用的方式,而是直接將代碼嵌入到需要校驗(yàn)序列號(hào)的位置,這樣一來(lái),攻擊者無(wú)法通過(guò)函數(shù)的調(diào)用頻率來(lái)分析該函數(shù)是否是校驗(yàn)序列號(hào)的函數(shù)。
⑶ 在校驗(yàn)的代碼段前增加一個(gè)開關(guān),這個(gè)開關(guān)的狀態(tài)決定了是否進(jìn)入校驗(yàn)代碼段。如果開關(guān)的狀態(tài)可以隨機(jī)化,那么對(duì)于整個(gè)程序來(lái)說(shuō),不同位置的校驗(yàn)狀態(tài)組合結(jié)果也就是隨機(jī)的。開關(guān)的狀態(tài)可以由開發(fā)人員自己決定,例如使用主程序的某個(gè)變量來(lái)決定,或者使用當(dāng)前的時(shí)間,還可以將二者結(jié)合某個(gè)隨機(jī)值運(yùn)算而成。加入這種機(jī)制后,如果在主程序代碼段內(nèi)嵌入了N段校驗(yàn)代碼,對(duì)于整個(gè)程序的校驗(yàn)位置的組合來(lái)說(shuō)理論上有2N種狀態(tài)。這種隨機(jī)性的加入使得代碼的破解難度呈指數(shù)級(jí)增加。
在設(shè)計(jì)開關(guān)時(shí),我們提出三種方法。第一種是取系統(tǒng)的時(shí)間,根據(jù)其奇偶性作為開關(guān)的值;第二種是取系統(tǒng)中一個(gè)叫做State_Output_Counts的全局變量的值,State_Output_Counts是軟件中用于記錄程序運(yùn)行狀態(tài)語(yǔ)句輸出次數(shù)的變量,根據(jù)其奇偶性作為開關(guān)的值;第三種是將系統(tǒng)當(dāng)前時(shí)間和上述State_Output_Counts變量結(jié)合起來(lái)進(jìn)行異或計(jì)算,根據(jù)得到的結(jié)果的奇偶性作為開關(guān)變量的值。每次決定具體使用哪一種方法之前取隨機(jī)數(shù),根據(jù)隨機(jī)數(shù)的值對(duì)3求模,根據(jù)其結(jié)果決定使用哪一種開關(guān)。具體代碼如下:
r=rand();
seconds=time(NULL);
r=r%3;
switch (r)
{ case 0:Check_Switch=seconds;break;
case 1: Check_Switch=State_Output_counts; break;
case 2: Check_Switch=seconds^State_Output_Counts; bresk;
}
⑷ 將校驗(yàn)序列號(hào)的代碼和程序的運(yùn)算模塊結(jié)合起來(lái),將校驗(yàn)序列號(hào)的代碼段嵌入程序的運(yùn)算模塊內(nèi),并且根據(jù)序列號(hào)校驗(yàn)的結(jié)果決定運(yùn)算模塊的結(jié)果是否正確,如果通過(guò)校驗(yàn)代碼的驗(yàn)證后,運(yùn)算模塊可以正常使用。如果序列號(hào)校驗(yàn)不通過(guò),則可以通過(guò)校驗(yàn)?zāi)K傳遞給運(yùn)算模塊一個(gè)錯(cuò)誤的變量值使運(yùn)算模塊失效或者輸出錯(cuò)誤的結(jié)果。攻擊者很難發(fā)現(xiàn)運(yùn)算模塊發(fā)生錯(cuò)誤,而攻擊者如果采用修改二進(jìn)制代碼的方式繞過(guò)校驗(yàn)代碼部分,運(yùn)算模塊也無(wú)法使用,也就起到了保護(hù)程序的作用。如果再結(jié)合第⑶步所描述的方法,運(yùn)算模塊中的序列號(hào)校驗(yàn)代碼不一定每次都會(huì)執(zhí)行,因此在序列號(hào)不合法時(shí)運(yùn)算模塊的功能有時(shí)會(huì)產(chǎn)生正確的結(jié)果而有時(shí)又會(huì)產(chǎn)生錯(cuò)誤的結(jié)果,更加迷惑攻擊者。當(dāng)序列號(hào)不正確時(shí),程序并不會(huì)提示用戶序列號(hào)錯(cuò)誤,而是直接給出錯(cuò)誤的運(yùn)算結(jié)果,因此攻擊者很難分析出序列號(hào)校驗(yàn)代碼段的位置。
例如,原始代碼在主程序中完成一個(gè)加法功能的語(yǔ)句a+b,我們將其更改成為一個(gè)函數(shù)int Add(int a,int b),并且將序列號(hào)校驗(yàn)的代碼嵌入其中,如果序列號(hào)校驗(yàn)通過(guò)就正常的返回兩個(gè)參數(shù)的和,如果序列號(hào)校驗(yàn)不通過(guò),并不會(huì)有錯(cuò)誤提示,但是返回值會(huì)是兩個(gè)參數(shù)的乘積,如此一來(lái),攻擊者無(wú)法找到校驗(yàn)的位置,也無(wú)法發(fā)現(xiàn)最終的運(yùn)算結(jié)果是一個(gè)錯(cuò)誤的答案。具體代碼如下:
int Add(int a,int b)
{ switch (Prog_State)
{ case true: return a+b;break;
case false: return a*b;break;
}
}
具體實(shí)現(xiàn)中,本文在主程序代碼中嵌入了5次校驗(yàn)序列號(hào)的代碼,理論上應(yīng)該有25種校驗(yàn)狀態(tài)的組合。當(dāng)校驗(yàn)不通過(guò)時(shí),計(jì)算結(jié)果產(chǎn)生了錯(cuò)誤,也從另一個(gè)方面阻止了軟件的非法使用。
4 系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)
如圖4所示,該架構(gòu)中客戶在程序開始時(shí)先獲得用戶ID,本系統(tǒng)中的用戶ID采用CPUID與MAC地址組合的方式生成。得到用戶ID后進(jìn)入客戶端的序列號(hào)校驗(yàn)?zāi)K。校驗(yàn)通過(guò)以后,可以進(jìn)入主程序,序列號(hào)的校驗(yàn)部分是由開發(fā)人員無(wú)規(guī)律隨機(jī)的分散在主程序代碼中的,校驗(yàn)代碼段之前會(huì)有一個(gè)開關(guān)決定進(jìn)入或是跳過(guò)校驗(yàn)代碼,開關(guān)的狀態(tài)可以由多種變量的狀態(tài)決定。
對(duì)于服務(wù)器端,在用戶需要注冊(cè)時(shí)可以通過(guò)通信模塊接收用戶ID并通過(guò)序列號(hào)生成模塊計(jì)算出序列號(hào)并返回給用戶,并將用戶ID和生成的序列號(hào)保存在服務(wù)器本身的數(shù)據(jù)庫(kù)中。
4.1 序列號(hào)申請(qǐng)模塊
服務(wù)器計(jì)算出序列號(hào)的過(guò)程可用公式:序列號(hào)=F(用戶ID)來(lái)表示。其中用戶ID代表了用戶的個(gè)人信息,可以是電話號(hào)碼或者是銀行卡號(hào)等信息。但這些信息很容易被重復(fù)使用并且無(wú)法保證是否是用戶本人,本文采取提取用戶機(jī)器的硬件序列號(hào)(CPU ID和MAC地址)作為用戶ID來(lái)保證其惟一性和不可傳播性。由于用戶的硬件基本上不會(huì)隨便更換,因此可以保證用戶在使用軟件的過(guò)程中不會(huì)因此產(chǎn)生麻煩。公式中F代表的是根據(jù)用戶ID生成序列號(hào)所使用的算法,本文中使用的是MD5消息摘要算法。
序列號(hào)申請(qǐng)模塊主要分為生成用戶ID和序列號(hào)的生成與驗(yàn)證兩個(gè)部分。
4.1.1 生成用戶ID的方式
本文采用了CPU ID和MAC地址共同作為用戶ID,但是在獲得了CPU ID和網(wǎng)卡MAC地址后需要構(gòu)造一個(gè)可靠的用戶ID,若是簡(jiǎn)單的將其連接必然會(huì)造成安全性上的欠缺,又因?yàn)橥ㄓ玫腗D5算法是公開的,因此如果對(duì)用戶ID 的構(gòu)成方式進(jìn)行復(fù)雜化則可以迷惑攻擊者無(wú)法輕易的推測(cè)出用戶ID 的構(gòu)造方式。本文通過(guò)采取將CPU ID和MAC地址交叉組合的方式,并在其后添加一個(gè)附加的自定義字串。例如CPU ID為abcdefgh而MAC地址為12345678則構(gòu)成的用戶ID為a1b2c3d4e5f6g7h803914256。
4.1.2 序列號(hào)的生成與驗(yàn)證
本文采用MD5消息摘要算法來(lái)生成序列號(hào)。MD5算法的特點(diǎn)[5]包括:易于從原始信息計(jì)算出MD5值,而從MD5值無(wú)法逆推算出原始數(shù)據(jù),任意長(zhǎng)的數(shù)據(jù)計(jì)算后得出的MD5值都是固定長(zhǎng)度的。對(duì)于序列號(hào)的生成過(guò)程和校驗(yàn)過(guò)程在計(jì)算上是同一個(gè)過(guò)程。客戶端機(jī)器先在機(jī)器內(nèi)計(jì)算出自己的用戶ID并將其發(fā)送給服務(wù)器端,當(dāng)服務(wù)器端收到了用戶ID后根據(jù)收到的用戶ID計(jì)算其MD5值,并以此作為合法的序列號(hào)返回給用戶。如果用戶收到了序列號(hào)后,再在本地重復(fù)這一過(guò)程,根據(jù)同一個(gè)公式去計(jì)算本地的用戶ID是否與所得到的序列號(hào)相同。
4.2 程序運(yùn)行結(jié)果
程序運(yùn)行結(jié)果如圖5所示。程序左側(cè)的文本框采用獨(dú)立線程每隔三秒會(huì)顯示程序是否運(yùn)行在合法狀態(tài),即使破解者找到了注冊(cè)序列號(hào)的位置繞過(guò)了最初注冊(cè)時(shí)的驗(yàn)證,但是每次運(yùn)行程序時(shí),隨機(jī)出現(xiàn)的校驗(yàn)位置的狀態(tài)組合都不一樣,如果攻擊者并不知曉序列號(hào)而只是繞過(guò)了驗(yàn)證部分,則在此處無(wú)法再次通過(guò)驗(yàn)證因此程序提示用戶使用的是未注冊(cè)版本,進(jìn)而可以保護(hù)主程序無(wú)法輕易的被破解和非法使用。程序下方還顯示了當(dāng)前五個(gè)開關(guān)的狀態(tài),可以看出,當(dāng)前的開關(guān)狀態(tài)為“10110”,也就是說(shuō),主程序中的有五個(gè)位置需要進(jìn)行序列號(hào)校驗(yàn),而在程序運(yùn)行完一次后只有第一個(gè)、第三個(gè)和第四個(gè)位置發(fā)生了校驗(yàn),而第二個(gè)和第五個(gè)位置的校驗(yàn)代碼并沒有運(yùn)行。多次運(yùn)行得到的開關(guān)狀態(tài)并不相同,具有隨機(jī)性。
5 結(jié)束語(yǔ)
本文提出了一種新的抵抗動(dòng)態(tài)分析的軟件保護(hù)模型,并在LINXU平臺(tái)下采用QT和C++編程實(shí)現(xiàn)了該系統(tǒng),經(jīng)過(guò)實(shí)驗(yàn)驗(yàn)證能完整地提供序列號(hào)保護(hù)所需的功能,并較傳統(tǒng)序列號(hào)保護(hù)方式更具有復(fù)雜性和隨機(jī)性。該系統(tǒng)可以較好地抵御攻擊者對(duì)程序的動(dòng)態(tài)分析過(guò)程。該程序結(jié)構(gòu)簡(jiǎn)單,卻能大大增加攻擊者的破解難度和破解代價(jià),并且其結(jié)構(gòu)的復(fù)雜度可以自己控制。因此,該系統(tǒng)具有較好的實(shí)用性和應(yīng)用前景。本系統(tǒng)還有需要改進(jìn)的地方,如太過(guò)于頻繁的驗(yàn)證可能影響計(jì)算的性能,用戶如果更換硬件則需要更換序列號(hào)等問(wèn)題,這些將是下一步需要研究的問(wèn)題。
參考文獻(xiàn):
[1] Business Software Alliance. The Compliance Gap BSA GLOBAL SOFTWARE SURVEY[R/OL].Washington, DC: Business Software Alliance, 2014. [2014-06].http://globalstudy.bsa.org/2013/downloads/studies/2013GlobalSurvey_Study_en.pdf
[2] 許旭,潘志剛.一種基于一機(jī)一碼的軟件激活序列號(hào)生成方案[J].浙江科技學(xué)院學(xué)報(bào),2010.4.
[3] 龐啟寧.一種基于注冊(cè)碼的軟件加密算法[J].通信與廣播電視,2008.2.
[4] Christian Collberg,Jasvir Nagra,Surreption Software[M].人民郵電出版社,2012.
[5] 許琪.MD5加密算法的研究[J].福建電腦,2014.3.