專利名稱:保護.net軟件安全的方法和設(shè)備的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及計算機及通信技術(shù)領(lǐng)域,具體涉及一種保護.NET軟件安全的方法和設(shè)備,加強對可執(zhí)行文件與本地動態(tài)鏈接庫文件之間的接口的安全保護,防止被破壞。
背景技術(shù):
很多.NET軟件都包含一些可執(zhí)行程序(托管代碼的.exe文件)和本地動態(tài)鏈接庫文件(如.dll等格式的文件)。軟件在運行時可執(zhí)行程序調(diào)用動態(tài)庫中導出的接口以執(zhí)行只有本地代碼才能實現(xiàn)的功能。由于它們之間是動態(tài)鏈接,因此導出接口是通過函數(shù)名稱和函數(shù)原形(簽名)相關(guān)的機制來實現(xiàn),每一個導出函數(shù)都有一個對應(yīng)的本地(PInvoke)方法,在.NET托管代碼中通過調(diào)用本地方法來調(diào)用對應(yīng)的導出函數(shù)。由于.NET可執(zhí)行程序和動態(tài)鏈接庫之間的接口是以函數(shù)名稱和簽名來實現(xiàn)的,而目前的代碼保護主要都是單純保護.NET可執(zhí)行程序,或者單純保護動態(tài)鏈接庫中的本地代碼,對它們之間的接口的保護很少涉及,這些接口暴露出來的信息很可能被破解者用來探測和發(fā)現(xiàn)軟件的邏輯和流程,從而對軟件造成破壞。
發(fā)明內(nèi)容
為了解決上述技術(shù)問題,本發(fā)明所要解決的技術(shù)問題是提供一能對軟件的可執(zhí)行程序和動態(tài)鏈接庫之間的導出接口進行保護,提高.NET軟件安全性的方法和系統(tǒng)。為了解決上述技術(shù)問題,本發(fā)明提供了一種保護.NET軟件安全的方法,包括如下步驟:查找步驟:從所述.NET軟件中的動態(tài)鏈接庫文件中查找出所有導出函數(shù)并建立導出函數(shù)表;核對步驟:如果所述.NET軟件中的可執(zhí)行文件中有對本地方法的調(diào)用,則核對所述調(diào)用所對應(yīng)的導出函數(shù)的名稱是否在上述導出函數(shù)表中,如在,則將所述本地方法的相關(guān)參數(shù)存儲于所述導出函數(shù)表中,如果所述.NET軟件中的可執(zhí)行文件中沒有所述對本地方法的調(diào)用,則執(zhí)行下述替換步驟;改寫步驟:生成派遣代碼片段,替換所述可執(zhí)行文件中的對所述本地方法的調(diào)用的代碼,并返回所述核對步驟,其中所述派遣代碼片段用于調(diào)用統(tǒng)一導出函數(shù):替換步驟:生成所述統(tǒng)一導出函數(shù),并將所述動態(tài)鏈接庫文件中的所有導出函數(shù)的名稱替換為所述統(tǒng)一導出函數(shù)的名稱,所述統(tǒng)一導出函數(shù)用于跳轉(zhuǎn)到原導出函數(shù)。作為優(yōu)選,在所述查找步驟中:為每個導出函數(shù)分配一個索引值以建立所述導出函數(shù)表,并將導出函數(shù)的名稱與索引值對應(yīng)存儲,所述導出函數(shù)表以數(shù)據(jù)庫的表的形式或者以文件的形式存儲。作為優(yōu)選,在所述核對步驟中:如果核對所述調(diào)用所對應(yīng)的導出函數(shù)的名稱不在所述導出函數(shù)表中,則繼續(xù)查找所述.NET軟件中的可執(zhí)行文件中的下一個對本地方法的調(diào)用。
作為優(yōu)選,在所述核對步驟中:所述本地方法的相關(guān)參數(shù)包括簽名、返回值和參數(shù)類型,其中,根據(jù)可執(zhí)行文件的.NET元數(shù)據(jù)表中所記錄的所述本地方法的簽名獲得該本地方法的返回值和參數(shù)類型。作為優(yōu)選,在所述改寫步驟中:所述派遣代碼片段將所述統(tǒng)一導出函數(shù)所代替的原導出函數(shù)在所述導出函數(shù)表中的索引值及所傳入的參數(shù)封裝為一個字節(jié)數(shù)組作為所述統(tǒng)一導出函數(shù)的參數(shù)。作為優(yōu)選,在所述替換步驟中:所述統(tǒng)一導出函數(shù)從其參數(shù)中提取出原導出函數(shù)的索引值和原導出函數(shù)的參數(shù),然后跳轉(zhuǎn)到原導出函數(shù)。作為優(yōu)選,在所述替換步驟之后,執(zhí)行屬性修改步驟:將所述動態(tài)鏈接庫文件中的原導出函數(shù)的屬性修改為不可導出。作為優(yōu)選,在所述改寫步驟中,還包括將所述字節(jié)數(shù)組加密的步驟。作為優(yōu)選,在所述查找步驟或所述核對步驟中還包括對所述導出函數(shù)表加密的步驟。作為優(yōu)選,所述動態(tài)鏈接庫文件包括.dll格式的文件,所述可執(zhí)行文件包括.exe格式的文件。本發(fā)明還提供了一種保護.NET軟件安全的設(shè)備,包括:查找模塊,用于從所述.NET軟件中的動態(tài)鏈接庫文件中查找出所有導出函數(shù)并建立導出函數(shù)表;核對模塊,在確認所述.NET軟件中的可執(zhí)行文件中有對本地方法的調(diào)用時,所述核對模塊核對所述調(diào)用所對應(yīng)的導出函數(shù)的名稱是否在上述導出函數(shù)表中,如在,則將所述本地方法的相關(guān)參數(shù)存儲于所述導出函數(shù)表中;改寫模塊,用于生成派遣代碼片段,替換所述可執(zhí)行文件中的對所述本地方法的調(diào)用的代碼,其中所述派遣代碼片段用于調(diào)用統(tǒng)一導出函數(shù):替換模塊,當所述核對模塊確認所述.NET軟件中的可執(zhí)行文件中沒有所述對本地方法的調(diào)用時,所述替換模塊生成所述統(tǒng)一導出函數(shù),并將所述動態(tài)鏈接庫文件中的所有導出函數(shù)的名稱替換為所述統(tǒng)一導出函數(shù)的名稱,所述統(tǒng)一導出函數(shù)用于跳轉(zhuǎn)到原導出函數(shù)。作為優(yōu)選,所述保護.NET軟件安全的設(shè)備還包括加密模塊,用于對所述統(tǒng)一導出函數(shù)的參數(shù)進行加密。本發(fā)明的有益效果在于:本發(fā)明的保護.NET軟件安全的方法及系統(tǒng),通過在動態(tài)鏈接庫中插入一個統(tǒng)一導出函數(shù),并將動態(tài)鏈接庫中導出函數(shù)替換為統(tǒng)一導出函數(shù)名稱,將可執(zhí)行文件中調(diào)用本地方法代碼的部分替換為調(diào)用統(tǒng)一函數(shù),將要調(diào)用的導出函數(shù)的索引值和傳入的參數(shù)封裝為一個字節(jié)數(shù)組,作為統(tǒng)一導出函數(shù)的參數(shù)調(diào)用,使得軟件的接口暴露出的只有統(tǒng)一導出函數(shù),因此根據(jù)本發(fā)明提供的方法,可以提高軟件反編譯和調(diào)試的難度,增強軟件的安全性。
圖1為現(xiàn)有技術(shù)的.NET軟件的結(jié)構(gòu)框圖。圖2為采用本發(fā)明的實施例的保護.NET軟件安全的方法保護的.NET軟件的結(jié)構(gòu)框圖。圖3為本發(fā)明的一個實施例的保護.NET軟件安全的方法的流程圖。圖4為本發(fā)明的另一個實施例的保護.NET軟件安全的方法的流程。圖5為本發(fā)明的又一個實施例的保護.NET軟件安全的設(shè)備的結(jié)構(gòu)框圖。
具體實施例方式下面結(jié)合附圖和具體實施例對本發(fā)明作進一步詳細描述,但不作為對本發(fā)明的限定。本實施例中,受保護的軟件為某.NET軟件A的結(jié)構(gòu)如圖1所示,軟件A由.NET可執(zhí)行程序a.exe和動態(tài)鏈接庫文件b.dll組成,其中a.exe文件中存在兩處本地(PInvoke)方法調(diào)用;b.dll中導出兩個函數(shù)int funAbs (int)和int funMul (int, int),分別完成特定的功能,即完成取絕對值和乘法運算的功能。本發(fā)明所提供的保護.NET軟件安全的方法,包括如下步驟:查找步驟:從所述.NET軟件中的動態(tài)鏈接庫文件中查找出所有導出函數(shù)并建立導出函數(shù)表;核對步驟:如果所述.NET軟件中的可執(zhí)行文件中有對本地方法的調(diào)用,則核對所述調(diào)用所對應(yīng)的導出函數(shù)的名稱是否在上述導出函數(shù)表中,如在,則將所述本地方法的相關(guān)參數(shù)存儲于所述導出函數(shù)表中,如果所述.NET軟件中的可執(zhí)行文件中沒有所述對本地方法的調(diào)用,則執(zhí)行下述替換步驟;改寫步驟:生成派遣代碼片段,替換所述可執(zhí)行文件中的對所述本地方法的調(diào)用的代碼,并返回所述核對步驟,其中所述派遣代碼片段用于調(diào)用統(tǒng)一導出函數(shù):替換步驟:生成所述統(tǒng)一導出函數(shù),并將所述動態(tài)鏈接庫文件中的所有導出函數(shù)的名稱替換為所述統(tǒng)一導出函數(shù)的名稱,所述統(tǒng)一導出函數(shù)用于跳轉(zhuǎn)到原導出函數(shù)。具體地,請參考圖3所示的流程圖并參考圖2所示的框圖詳細說明發(fā)明的保護.NET軟件安全的方法的一個實施方式的詳細工作過程。如圖3所示,本發(fā)明的保護.NET軟件安全的方法一種實施方式,包括如下步驟:S1:枚舉所述.NET軟件中的動態(tài)鏈接庫文件,如果找到動態(tài)鏈接庫文件則執(zhí)行S2,如果該軟件中無動態(tài)鏈接庫文件,則結(jié)束;如果軟件中沒有動態(tài)鏈接庫文件,則不需要進行接口保護,這是顯然的。如果軟件中包括動態(tài)鏈接庫文件,就采用本發(fā)明的方法進行保護。S2:查找動態(tài)鏈接庫文件中所有導出函數(shù),為每個導出函數(shù)分配一個索引建立導出函數(shù)表,并將導出函數(shù)的名稱與索引對應(yīng)存儲,然后執(zhí)行S3。在S2步驟中,建立了導出函數(shù)表,在軟件執(zhí)行階段,通過從該導出函數(shù)表中按照導出函數(shù)的索引值找到相應(yīng)的導出函數(shù),還原到本來的導出函數(shù)。S3:在圖3所示的具體實施例的流程圖中,步驟S3被細分成兩個步驟:S31:枚舉所述.NET軟件中的可執(zhí)行文件,并查找其中一個所述可執(zhí)行文件中是否有對本地方法的調(diào)用,查找完畢時,執(zhí)行步驟S32的判斷步驟,S32如果有對本地方法的調(diào)用,則執(zhí)行步驟S4,如果無對本地方法的調(diào)用,執(zhí)行步驟S7。此步驟中,如果可執(zhí)行文件中無本地方法調(diào)用,顯然也不必再進行下面的步驟。
S4:檢查要調(diào)用的本地方法所對應(yīng)的導出函數(shù)的名稱是否在步驟S2中的導出函數(shù)表中,如果在,執(zhí)行步驟S5,否則執(zhí)行步驟S3,以繼續(xù)查找下一個對本地方法的調(diào)用。S5:根據(jù)可執(zhí)行文件.NET元數(shù)據(jù)表中所記錄的所述本地方法的簽名獲得該本地方法的返回值和參數(shù)類型,并將本地方法的相關(guān)參數(shù),包括簽名、返回值和參數(shù)類型對應(yīng)地存儲于步驟S2中的導出函數(shù)表中,然后執(zhí)行S6。通過步驟S4和S5,使得可執(zhí)行文件中記錄的所述本地方法與動態(tài)鏈接庫文件中的導出函數(shù)一一對應(yīng),并以數(shù)據(jù)庫的表的形式或者以文件的形式存儲,可插入動態(tài)鏈接庫中。S6:生成派遣代碼片段,替換所述可執(zhí)行文件中的對本地方法的調(diào)用的代碼,所述派遣代碼片段的功能是調(diào)用統(tǒng)一導出函數(shù),并將所述統(tǒng)一導出函數(shù)所代替的原導出函數(shù)在所述導出函數(shù)表中的索引及所傳入的參數(shù)封裝為一個字節(jié)數(shù)組作為所述統(tǒng)一導出函數(shù)的參數(shù),在步驟S6完成之后,返回執(zhí)行步驟S3,以繼續(xù)查找下一個對本地方法的調(diào)用。通過步驟S6,使可執(zhí)行文件中的對本地方法的調(diào)用的代碼被取消,派遣代碼片段的功能是調(diào)用統(tǒng)一導出函數(shù),該統(tǒng)一導出函數(shù)為統(tǒng)一的名稱,統(tǒng)一導出函數(shù)的參數(shù)是字節(jié)數(shù)組,從其名稱和參數(shù)上看不出其邏輯結(jié)構(gòu),也無從破解。S7:生成統(tǒng)一的統(tǒng)一導出函數(shù),并將所述動態(tài)鏈接庫文件中的所有導出函數(shù)的名稱替換為所述統(tǒng)一導出函數(shù)的名稱,所述統(tǒng)一導出函數(shù)的功能是從其參數(shù)中提取出原導出函數(shù)的索引和原導出函數(shù)的參數(shù),然后跳轉(zhuǎn)到原導出函數(shù)。步驟S7和步驟S6是對應(yīng)設(shè)置的,在動態(tài)鏈接庫文件中只保存統(tǒng)一的統(tǒng)一導出函數(shù),原有的導出函數(shù)的名稱全部被取代,破解者從動態(tài)鏈接庫文件和可執(zhí)行文件中均找不到導出函數(shù)的名稱和實際參數(shù),無從猜測其邏輯結(jié)構(gòu),從而增加了軟件反編譯和調(diào)試的難度,增強軟件的安全性。動態(tài)鏈接庫文件和可執(zhí)行文件中之間通過導出函數(shù)的索引值聯(lián)系。如圖3所示,為進一步增加其安全性,在步驟S7之后,執(zhí)行步驟S8:將所述動態(tài)鏈接庫文件中的原導出函數(shù)修改為不可導出。在圖3所示的實施例中,在步驟S8之后,增加步驟S9:判斷動態(tài)鏈接庫文件是否查找完畢的步驟,如果查找完畢,就結(jié)束,如果動態(tài)鏈接庫文件還未查找完畢,則繼續(xù)查找,并對回到步驟S2,對下一個動態(tài)鏈接庫文件執(zhí)行同樣的步驟。為了增強軟件的安全性,作為優(yōu)選,在步驟S6中還包括將所述字節(jié)數(shù)組加密的步驟。在步驟S2或S5中還包括對所述導出函數(shù)表加密的步驟。通過加密,增強軟件被破解的難度,即使第三方惡意軟件找到了所要保護軟件的導出函數(shù)表,也無從下手。以下結(jié)合圖1、圖2和圖3,詳細說明采用發(fā)明的保護.NET軟件安全的方法進行保護后的.NET軟件的詳細運行過程。如圖1所示,該.NET軟件中,可執(zhí)行文件a.exe中存在兩處本地方法調(diào)用,其功能是分別調(diào)用從動態(tài)鏈接庫文件b.dll中導出兩個函數(shù)funAbs(int),和funMul (int, int),以執(zhí)行求絕對值和乘法的功能。顯然,取絕對值的函數(shù)包括一個參數(shù),其數(shù)據(jù)類型為int,乘法函數(shù)包括兩個int參數(shù)。在動態(tài)鏈接庫文件b.dll中包括兩個導出函數(shù),分別用于導出函數(shù)int funAbs (int)和int funMul (int, int),分別完成特定的功能(取絕對值和乘法)。如圖2所示,采用本發(fā)明的保護.NET軟件安全的方法的進行保護后,圖1所示的.NET程序中的可執(zhí)行文件a.exe文件中對本地方法調(diào)用的代碼被一段派遣代碼代替,該派遣代碼的功能是調(diào)用統(tǒng)一導出函數(shù),并將所述統(tǒng)一導出函數(shù)所代替的原導出函數(shù)在所述導出函數(shù)表中的索引及所傳入的參數(shù)封裝為一個字節(jié)數(shù)組作為所述統(tǒng)一導出函數(shù)的參數(shù)。在本地動態(tài)鏈接庫文件b.dll中,增加有導出函數(shù)表,導出函數(shù)表的形式如表I所示,為每個導出的函數(shù)分配一個索引值,并與本地方法對應(yīng)。每個索引值對應(yīng)于相應(yīng)的本地方法的簽名和返回值,即表I還可以再增加兩列,分別存儲每個索引值對應(yīng)于相應(yīng)的本地方法的簽名和返回值。表I導出函數(shù)表
權(quán)利要求
1.一種保護.NET軟件安全的方法,其特征在于,包括如下步驟: 查找步驟:從所述.NET軟件中的動態(tài)鏈接庫文件中查找出所有導出函數(shù)并建立導出函數(shù)表; 核對步驟:如果所述.NET軟件中的可執(zhí)行文件中有對本地方法的調(diào)用,則核對所述調(diào)用所對應(yīng)的導出函數(shù)的名稱是否在上述導出函數(shù)表中,如在,則將所述本地方法的相關(guān)參數(shù)存儲于所述導出函數(shù)表中,如果所述.NET軟件中的可執(zhí)行文件中沒有所述對本地方法的調(diào)用,則執(zhí)行下述替換步驟; 改寫步驟:生成派遣代碼片段,替換所述可執(zhí)行文件中的對所述本地方法的調(diào)用的代碼,并返回所述核對步驟,其中所述派遣代碼片段用于調(diào)用統(tǒng)一導出函數(shù): 替換步驟:生成所述統(tǒng)一導出函數(shù),并將所述動態(tài)鏈接庫文件中的所有導出函數(shù)的名稱替換為所述統(tǒng)一導出函數(shù)的名稱,所述統(tǒng)一導出函數(shù)用于跳轉(zhuǎn)到原導出函數(shù)。
2.如權(quán)利要求1所述的保護·.NET軟件安全的方法,其特征在于,在所述查找步驟中: 為每個導出函數(shù)分配一個索引值以建立所述導出函數(shù)表,并將導出函數(shù)的名稱與索引值對應(yīng)存儲,所述導出函數(shù)表以數(shù)據(jù)庫的表的形式或者以文件的形式存儲。
3.如權(quán)利要求1所述的保護.NET軟件安全的方法,其特征在于,在所述核對步驟中: 如果核對所述調(diào)用所對應(yīng)的導出函數(shù)的名稱不在所述導出函數(shù)表中,則繼續(xù)查找所述.NET軟件中的可執(zhí)行文件中的下一個對本地方法的調(diào)用。
4.如權(quán)利要求1所述的保護.NET軟件安全的方法,其特征在于,在所述核對步驟中: 所述本地方法的相關(guān)參數(shù)包括簽名、返回值和參數(shù)類型,其中,根據(jù)可執(zhí)行文件的.NET元數(shù)據(jù)表中所記錄的所述本地方法的簽名獲得該本地方法的返回值和參數(shù)類型。
5.如權(quán)利要求1所述的保護.NET軟件安全的方法,其特征在于,在所述改寫步驟中: 所述派遣代碼片段將所述統(tǒng)一導出函數(shù)所代替的原導出函數(shù)在所述導出函數(shù)表中的索引值及所傳入的參數(shù)封裝為一個字節(jié)數(shù)組作為所述統(tǒng)一導出函數(shù)的參數(shù)。
6.如權(quán)利要求1所述的保護.NET軟件安全的方法,其特征在于,在所述替換步驟中: 所述統(tǒng)一導出函數(shù)從其參數(shù)中提取出原導出函數(shù)的索引值和原導出函數(shù)的參數(shù),然后跳轉(zhuǎn)到原導出函數(shù)。
7.如權(quán)利要求1所述的保護.NET軟件安全的方法,其特征在于, 在所述替換步驟之后,執(zhí)行屬性修改步驟:將所述動態(tài)鏈接庫文件中的原導出函數(shù)的屬性修改為不可導出。
8.如權(quán)利要求5所述的保護.NET軟件安全的方法,其特征在于,在所述改寫步驟中,還包括將所述字節(jié)數(shù)組加密的步驟。
9.如權(quán)利要求2或3所述的保護.NET軟件安全的方法,其特征在于,在所述查找步驟或所述核對步驟中還包括對所述導出函數(shù)表加密的步驟。
10.如權(quán)利要求1所述的保護.NET軟件安全的方法,其特征在于,所述動態(tài)鏈接庫文件包括.dll格式的文件,所述可執(zhí)行文件包括.exe格式的文件。
11.一種保護.NET軟件安全的設(shè)備,其特征在于,包括: 查找模塊,用于從所述.NET軟件中的動態(tài)鏈接庫文件中查找出所有導出函數(shù)并建立導出函數(shù)表; 核對模塊,在確認所述.NET軟件中的可執(zhí)行文件中有對本地方法的調(diào)用時,所述核對模塊核對所述調(diào)用所對應(yīng)的導出函數(shù)的名稱是否在上述導出函數(shù)表中,如在,則將所述本地方法的相關(guān)參數(shù)存儲于所述導出函數(shù)表中; 改寫模塊,用于生成派遣代碼片段,替換所述可執(zhí)行文件中的對所述本地方法的調(diào)用的代碼,其中所述派遣代碼片段用于調(diào)用統(tǒng)一導出函數(shù): 替換模塊,當所述核對模塊確認所述.NET軟件中的可執(zhí)行文件中沒有所述對本地方法的調(diào)用時,所述替換模塊生成所述統(tǒng)一導出函數(shù),并將所述動態(tài)鏈接庫文件中的所有導出函數(shù)的名稱替換為所述統(tǒng)一導出函數(shù)的名稱,所述統(tǒng)一導出函數(shù)用于跳轉(zhuǎn)到原導出函數(shù)。
12.如權(quán)利要求11所述的保護.NET軟件安全的設(shè)備,其特征在于,還包括加密模塊,用于對所述統(tǒng)一導出函數(shù)的 參數(shù)進行加密。
全文摘要
本發(fā)明公開了一種保護.NET軟件安全的方法,包括如下步驟查找步驟從軟件中的動態(tài)鏈接庫文件中查找出所有導出函數(shù)并建立導出函數(shù)表;核對步驟核對調(diào)用所對應(yīng)的導出函數(shù)的名稱是否在上述導出函數(shù)表中,如在,則將本地方法的相關(guān)參數(shù)存儲于導出函數(shù)表中,如果沒有對本地方法的調(diào)用,則執(zhí)行替換步驟;改寫步驟生成派遣代碼片段,替換可執(zhí)行文件中的對本地方法的調(diào)用的代碼替換步驟生成統(tǒng)一導出函數(shù),并將所有導出函數(shù)的名稱替換為統(tǒng)一導出函數(shù)的名稱,統(tǒng)一導出函數(shù)用于跳轉(zhuǎn)到原導出函數(shù)。本發(fā)明的保護.NET軟件安全的方法及系統(tǒng)使軟件的接口暴露出的只有統(tǒng)一導出函數(shù),可提高軟件反編譯和調(diào)試的難度,增強軟件的安全性。
文檔編號G06F21/14GK103186730SQ20131010025
公開日2013年7月3日 申請日期2013年3月26日 優(yōu)先權(quán)日2013年3月26日
發(fā)明者孫吉平, 韓勇 申請人:北京深思數(shù)盾科技有限公司