對可執行文件進行保護的方法和裝置與流程
2023-09-12 02:03:10 1

本發明涉及信息安全技術領域,特別涉及一種對可執行文件進行保護的方法和裝置。
背景技術:
在信息安全領域中,軟體作為一種寶貴的財富,軟體的安全性越來越受到單位、企業和個人的關注。軟體作為一種特殊的產品,由於其數位化的特徵,從問世起就一直遭受盜版的困擾。盜版的存在不僅給軟體開發者造成了巨大的損失,也極大的阻礙了整個軟體行業的發展。
目前對於軟體中代碼的保護主要是基於應用層的軟體保護技術和基於硬體的保護方法。
常見的應用層的保護軟體有VMProtect虛擬機保護軟體等各種混淆器,對這種保護軟體的保護方式的分析完全可以在應用層進行,目前已經有各種破解插件可以利用,因此這種軟體保護技術的抗分析性較差。
基於硬體的保護方法主要是從程序文件中提取部分代碼到硬體保護裝置中,這樣軟體的一部分代碼在計算機中執行,另外一部分在保護裝置中模擬執行。基於硬體的保護方法可以移植的代碼指令有限,受限於硬體的保護裝置的空間限制,移植的代碼的數量也有限。
技術實現要素:
有鑑於此,本發明的一個目的在於提供一種對可執行文件的有效保護手段,以進一步提高軟體的安全性。
為此,本發明提供了一種對可執行文件進行保護的方法,其包括:在運行可執行文件時,所述可執行文件中的預定代碼段的執行過程中的至少部分過程不在應用層執行而是在驅動層進行模擬執行。
作為優選,所述可執行文件中預定位置處包括與實現所述預定代碼段的指令中的至少部分指令的功能對應的驅動層指令。
作為優選,所述預定位置為所述可執行文件中的預定數組或預定行。
作為優選,所述至少部分指令中每條指令對應至少一條所述驅動層指令。
作為優選,在所述可執行文件中,所述至少部分指令被替換為包括與所述驅動層指令的調用相關的指令和/或函數在內的第一代碼段。
作為優選,在運行所述可執行文件時,應用層將所述驅動層指令發送至驅動層,並從驅動層接收相應的執行結果。
作為優選,通過以下步驟確定所述預定代碼段:分析所述可執行文件中的多個函數,根據如下條件在所述多個函數中確定目標函數:對於實現所述目標函數的指令中的至少部分指令,存在功能對應的驅動層指令;將至少一個所述目標函數對應的代碼段確定為所述預定代碼段。
作為優選,通過以下步驟確定所述預定代碼段:分析所述可執行文件中的多個函數,在所述多個函數中將具有參數和返回值的函數確定為目標函數:將至少一個所述目標函數對應的代碼段確定為所述預定代碼段。
作為優選,通過以下步驟確定所述預定代碼段:分析所述可執行文件中的多個函數,在所述多個函數中將具有同一類型的參數和返回值的函數確定為目標函數:將至少一個所述目標函數對應的代碼段確定為所述預定代碼段。
本發明同時提供了一種對可執行文件進行保護的裝置,包括:應用程式端,其配置為運行可執行文件;驅動層模擬器,其配置為在可執行文件運行時,對所述可執行文件中的預定代碼段的執行過程中的至少部分過程進行模擬執行,其中,所述至少部分過程不在應用程式端執行。
作為優選,所述裝置還包括:處理單元,其配置為將與實現所述預定代碼段的指令中的至少部分指令的功能對應的驅動層指令寫入所述可執行文件中預定位置處。
作為優選,所述處理單元配置為將所述驅動層指令寫入所述可執行文件中的預定數組或預定行處。
作為優選,所述處理單元配置為,對於所述至少部分指令的每條指令,在所述預定位置寫入至少一條所述驅動層指令。
作為優選,所述處理單元進一步配置為將所述可執行文件中的所述至少部分指令替換為包括與所述驅動層指令的調用相關的指令和/或函數在內的第一代碼段。
作為優選,所述處理單元進一步配置為在所述可執行文件運行時將所述驅動層指令發送至所述驅動層模擬器,並從所述驅動層模擬器接收相應的執行結果。
作為優選,所述裝置還包括分析單元,其配置為分析所述可執行文件中的多個函數,並將所述多個函數中的至少一個目標函數對應的代碼段確定為所述預定代碼段,其中,所述分析單元配置為根據如下條件確定所述目標函數:對於實現所述目標函數的指令中的至少部分指令,存在功能對應的驅動層指令。
作為優選,所述裝置還包括分析單元,其配置為分析所述可執行文件中的多個函數,並將所述多個函數中的至少一個目標函數對應的代碼段確定為所述預定代碼段,其中,所述分析單元配置為將具有參數和返回值的函數確定為所述目標函數。
作為優選,所述裝置還包括分析單元,其配置為分析所述可執行文件中的多個函數,並將所述多個函數中的至少一個目標函數對應的代碼段確定為所述預定代碼段,其中,所述分析單元配置為將具有同一類型的參數和返回值的函數確定為所述目標函數。
本發明在對可執行文件進行保護時,將部分代碼或指令的執行過程轉移至驅動層模擬執行,這樣對軟體中代碼或指令的保護的對抗從應用層轉移到驅動層,進一步增加了調試難度,從而達到了保護軟體的目的。
附圖說明
圖1為本發明的對可執行文件進行保護的方法的一個實施例的示意性流程圖;
圖2為本發明的對可執行文件進行保護的方法的另一個實施例的部分示意性流程圖;
圖3為本發明的對可執行文件進行保護的方法的又一個實施例的部分示意性流程圖;
圖4為本發明的對可執行文件進行保護的方法的再一個實施例的部分示意性流程圖;
圖5為本發明的對可執行文件進行保護的裝置的一個實施例的示意性框圖;
圖6為本發明的對可執行文件進行保護的裝置的另一個實施例的示意性框圖;
圖7為本發明的對可執行文件進行保護的裝置的又一個實施例的示意性框圖。
具體實施方式
下面參照附圖對本發明的具體實施方式進行詳細說明。本發明的對可執行文件進行保護的方法可以支持例如.NET可執行文件以及由C/C++編譯生成的32位或者64位的可執行文件等。
圖1為本發明的對可執行文件進行保護的方法的一個實施例的示意性流程圖。如圖1所示,本實施例的方法包括以下步驟:運行可執行文件;在運行至所述可執行文件的預定代碼段時,將預定代碼段的執行過程中的至少一部分過程不在應用層執行而是在驅動層進行模擬執行;繼續運行所述可執行文件。
預定代碼段為可執行文件中待保護的代碼段,其可包括代碼或指令。預定代碼段可由用戶自行分析確定,也可以由客戶端軟體自動分析確定,或者由客戶端軟體對可執行文件進行分析後向用戶提供能夠進行保護的多個代碼段以供用戶選定,用戶根據實際需要從中選定所需進行保護的代碼段作為預定代碼段。
在可執行文件常規運行時,所有的代碼或指令均在應用層執行。本發明的創新之處在於,將可執行文件中預定代碼段的至少部分執行過程不在應用層執行,而是轉移至驅動層進行模擬執行,驅動層在模擬執行後可將執行結果返回給應用層,如此可將可執行文件中的預定執行過程「隱藏」在驅動層執行,要想破解可執行文件中預定代碼的內容將變得十分困難。
本發明實施例的方法在運行可執行文件時,將可執行文件的預定代碼段(部分代碼或指令)的至少部分執行過程轉移至驅動層進行模擬執行,這樣對軟體中預定代碼或指令的保護的對抗從應用層轉移到驅動層,進一步增加了調試難度,能夠同時應對應用層保護軟體抗分析性差的問題和硬體保護方法容易受限的問題。應當理解的是,可執行文件中可以包括多個上述的預定代碼段,從而在運行到每個預定代碼段處時均執行上述過程。
在本發明一個實施例中,可將與可執行文件中預定代碼段的指令中的至少部分指令的功能對應的驅動層指令寫入可執行文件中的預定位置處。在該實施例中,預定代碼段可對應於與其實現相關的多個指令(或代碼),可將與其中的部分指令的功能對應的驅動層指令寫入可執行文件中預定位置處,該預定位置可以是該部分指令原先所在行或其他行,或者也可以是可執行文件中的預定數組處,例如一個新增的全局數組。
在本發明另一個實施例中,對於用於實現預定代碼段的指令中的至少部分指令中的每條指令,可能通過一條驅動層指令就能實現其功能,也可能通過兩條驅動層指令實現其功能。這裡需要說明的是,驅動層指令可包括多種類型,對於某一類型的驅動層指令,可能一條驅動層指令的功能就能夠對應實現預定代碼段的部分指令中的一條指令,而對於另一類型的驅動層指令,可能需要兩條驅動層指令的功能才能對應實現預定代碼段的部分指令中的一條指令,具體對應關係由所選用的驅動層指令的類型而確定。
在本發明一個實施例中,可將實現上述預定代碼段的指令中的上述部分指令替換為包括與驅動層指令的調用相關的指令和/或函數在內的第一代碼段。如此可將與預定代碼段的執行相關的指令中的至少部分指令完全隱藏,並且在可執行文件運行時,通過與驅動層指令的調用相關的指令和/或函數來對驅動層指令進行調度,能夠例如將驅動層指令從應用層發送至驅動層,並從驅動層接收返回的執行結果,從而在將上述的部分指令隱藏的同時能夠確保可執行文件的順利執行。
圖2為本發明的對可執行文件進行保護的方法的另一個實施例的部分示意性流程圖。
如圖2所示,本發明的對可執行文件進行保護的方法的另一個實施例中在運行可執行文件前,包括:分析所述可執行文件中的多個函數,根據如下條件在所述多個函數中確定目標函數:對於實現所述目標函數的指令中的至少部分指令,存在功能對應的驅動層指令;將至少一個所述目標函數對應的代碼段確定為所述預定代碼段。
在本發明的實施例中,首先對可執行文件中的多個函數進行分析,在多個函數中確定目標函數。目標函數的確定條件為,實現該目標函數的指令中的至少部分指令有驅動層指令的功能與之對應,即確定包括了能夠在驅動層模擬的指令的函數為目標函數,再將該目標函數對應的代碼段確定為待保護的預定代碼段。在確定了預定代碼段後,可執行文件的運行過程與圖1所示相同。
圖3為本發明的對可執行文件進行保護的方法的又一個實施例的部分示意性流程圖。
如圖3所示,本發明的對可執行文件進行保護的方法的又一個實施例中在運行可執行文件之前,包括:分析可執行文件中的多個函數;在多個函數中將具有參數和返回值的函數確定為目標函數:將至少一個所述目標函數對應的代碼段確定為所述預定代碼段。
在本發明的實施例中,首先對可執行文件中的多個函數進行分析,在多個函數中確定目標函數。目標函數的確定條件為,該目標函數具有參數、對參數的處理過程以及返回值,返回值即對參數的處理結果。即,確定了具備參數和返回值的函數為目標函數,再將該目標函數對應的代碼段確定為待保護的預定代碼段。在確定了預定代碼段後,可執行文件的運行過程與圖1所示相同。
圖4為本發明的對可執行文件進行保護的方法的再一個實施例的部分示意性流程圖。
如圖4所示,本發明的對可執行文件進行保護的方法的又一個實施例中在運行可執行文件之前,包括:分析可執行文件中的多個函數,在所述多個函數中將具有同一類型的參數和返回值的函數確定為目標函數:將至少一個所述目標函數對應的代碼段確定為所述預定代碼段。
在本發明的實施例中,首先對可執行文件中的多個函數進行分析,在多個函數中確定目標函數。目標函數的確定條件為,該目標函數具有參數、對參數的處理過程以及返回值,返回值即對參數的處理結果,並且參數和返回值為同一類型。即,確定了具備相同類型的參數和返回值的函數為目標函數,再將該目標函數對應的代碼段確定為待保護的預定代碼段。在確定了預定代碼段後,可執行文件的運行過程與圖1所示相同。
下面結合一個示例性的.NET可執行文件來說明本發明實施例對可執行文件進行保護的方法的實現過程,該實施例以保護安裝有微軟Windows XP32位作業系統的系統環境為例,該示例性的.NET可執行文件具體如下所示:
在所給出的示例性的.NET可執行文件中包含Program類,Program中包含.ctor、Main、test_add、test_sub和test_mul等函數(或方法)。其中.ctor函數和Main函數中的返回值為void類型,兩者參數個數為0;test_add函數、test_sub函數和test_mul函數均包含2個int類型的參數,其對參數進行操作後得到的返回值也為int類型。經過分析,確定test_add函數、test_sub函數和test_mul函數可以在驅動層進行模擬。
下面以IL指令為例對實現test_add函數的指令進行說明:
{
IL_0000:nop
IL_0001:ldarg.0
IL_0002:ldarg.1
IL_0003:add
IL_0004:stloc.0
IL_0005:br.s IL_0007
IL_0007:ldloc.0
IL_0008:ret
}
上述用於實現test_add函數的IL指令中可以在驅動層模擬的指令為:
IL_0001:ldarg.0
IL_0002:ldarg.1
IL_0003:add
IL_0004:stloc.0
當用戶選定Program類中的test_add函數為目標函數時,將與上述四條IL指令的功能對應的驅動層指令(在本實施例中也稱為自定義指令)保存到可執行文件中的預定位置處。這裡給出所採用的驅動層指令的兩個例子。
驅動層指令的第一個例子可以包括:
vm_read_mem //讀取第一個參數
vm_push_imm //將參數入棧
vm_read_mem //讀取第二個參數
vm_push_imm //將參熟入棧
vm_add //相加
vm_pop //彈出棧頂垃圾數據
vm_write_mem //將結果保存
驅動層指令的第二個例子可以包括:
vm_get_context(相當於第一個例子中的vm_read_mem,vm_push_imm兩條指令)
vm_get_context
vm_add
vm_set_context(相當於第一個例子中的vm_pop,vm_write_mem兩條指令)
然後將上述的四條IL指令,即:
IL_0001:ldarg.0
IL_0002:ldarg.1
IL_0003:add
IL_0004:stloc.0
替換成包括了與驅動層指令的調用相關的代碼、指令和/或函數在內的以下代碼段:
System.Byte[]ab=new System.Byte[size];
System.Init(ab,...);//初始化自定義指令二進位編碼
object[]ao=new object[3];
ao[0]=arg.0;(arg.0--loc.0)//準備loc.0
ao[1]=arg.1;(arg.1--loc.1)//準備loc.1
ao[2]=loc.0;(loc.0--loc.2)//準備loc.2
call_driver_stub(ao,ab);
loc.0=ao[2];//將loc.2回寫到原方法的局部變量loc.0
在本實施例中,上面的代碼段中的ab中包含了自定義指令的二進位編碼。
下面對經過寫入驅動層指令和包括了與驅動層指令的調用相關的代碼、指令和/或函數在內的代碼段後的可執行文件的執行過程進行具體說明。
經安全處理後的.NET可執行文件執行到test_add函數的IL指令中上述替換的代碼段(即原先的上述四條指令位置處)時,通過System.Init(ab,...)設置ab中的自定義指令二進位編碼,應用層通過ao[0]=arg.0和ao[1]=arg.1設置了test_add函數的兩個參數的信息,通過ao[2]=loc.0指明在ao[2]中存儲要返回的結果,通過call_driver_stub函數調用驅動層模擬器。
驅動層模擬器接收到應用層傳遞的信息後,通過執行vm_read_mem指令取得第一個參數的信息,通過vm_push_imm指令將第一個參數值壓入虛擬機堆棧;通過執行vm_read_mem指令取得第二個參數的信息,通過vm_push_imm指令將第二個參數值壓入虛擬機堆棧;通過vm_add指令將堆棧中的兩個參數相加,並將結果入棧和標誌寄存器入棧,通過vm_pop指令將標誌寄存器彈出,通過vm_write_mem指令將結果保存在ao[2]地址處。
應用層通過指令loc.0=ao[2]獲得了執行的結果,即得到了test_add函數對應的返回值,至此,完成了一次應用層和驅動層的交互,可執行文件繼續執行後續的指令和/代碼。
下面對當用戶需要對上述示例性的.NET可執行文件中的test_sub函數在驅動層進行模擬時的處理過程進行說明。
對於test_sub方法,對應的IL指令為
{
IL_0000:nop
IL_0001:ldarg.0
IL_0002:ldarg.1
IL_0003:sub
IL_0004:stloc.0
IL_0005:br.s IL_0007
IL_0007:ldloc.0
IL_0008:ret
}
上述用於實現test_sub函數的IL指令中可以在驅動層模擬的指令為:
IL_0001:ldarg.0
IL_0002:ldarg.1
IL_0003:sub
IL_0004:stloc.0
當用戶選定Program類中的test_sub函數為目標函數時,將與上述四條IL指令的功能對應的驅動層指令保存到可執行文件中的預定位置處。這裡對test_sub函數的上述四條IL指令採用的驅動層指令可以是:
vm_read_mem //讀取第一個參數
vm_push_imm //將參數入棧
vm_read_mem //讀取第二個參數
vm_push_imm //將參熟入棧
vm_sub //相減
vm_pop //彈出棧頂垃圾數據
vm_write_mem //將結果保存
然後將上述的四條IL指令,即:
IL_0001:ldarg.0
IL_0002:ldarg.1
IL_0003:sub
IL_0004:stloc.0
替換成包括了與驅動層指令的調用相關的代碼、指令和/或函數在內的以下代碼段:
System.Byte[]ab=new System.Byte[size];
System.Init(ab,...);//初始化自定義指令二進位編碼
object[]ao=new object[3];
ao[0]=arg.0;(arg.0--loc.0)//準備loc.0
ao[1]=arg.1;(arg.1--loc.1)//準備loc.1
ao[2]=loc.0;(loc.0--loc.2)//準備loc.2
call_driver_stub(ao,ab);
loc.0=ao[2];//將loc.2回寫到原方法的局部變量loc.0
在對test_sub函數的部分指令進行驅動層模擬的實施例中,應用層與驅動層之間的互動與對test_add函數的部分指令進行驅動層模擬的實施例類似,在此不再贅述。
本發明實施例同時提供了一種用於對可執行文件進行保護的裝置,下面參照圖5-7進行說明。
圖5為本發明的對可執行文件進行保護的裝置的一個實施例的示意性框圖。
如圖5所示,本發明實施例的對可執行文件進行保護的裝置包括:
應用程式端,其配置為運行可執行文件;
驅動層模擬器,其配置為在可執行文件運行時,對所述可執行文件中的預定代碼段的執行過程中的至少部分過程進行模擬執行,其中,所述至少部分過程不在應用程式端執行。
本發明實施例的裝置在應用程式端運行可執行文件時,將可執行文件的預定代碼段(部分代碼或指令)的至少部分執行過程從應用程式端轉移至驅動層模擬器進行模擬執行,這樣對軟體中預定代碼或指令的保護的對抗從應用層轉移到驅動層,進一步增加了調試難度,能夠同時應對應用層保護軟體抗分析性差的問題和硬體保護方法容易受限的問題。應當理解的是,可執行文件中可以包括多個上述的預定代碼段,從而在運行到每個預定代碼段處時均執行上述過程。
圖6為本發明的對可執行文件進行保護的裝置的另一個實施例的示意性框圖。
在本發明一個實施例中,如圖6所示,裝置還可以包括處理單元,其可以配置為將與實現預定代碼段的指令中的至少部分指令的功能對應的驅動層指令寫入可執行文件中預定位置處。在該實施例中,預定代碼段可對應於與其實現相關的多個指令(或代碼),處理單元可將與其中的部分指令的功能對應的驅動層指令寫入可執行文件中預定位置處。該預定位置可以是該部分指令原先所在行或其他行,或者也可以是可執行文件中的預定數組處,例如一個新增的全局數組。
在本發明一個實施例中,圖6所示的處理單元還可以配置為,對於實現預定代碼段的指令中的至少部分指令中的每條指令,在可執行文件中的預定位置寫入至少一條驅動層指令。在本發明實施例中,對於用於實現預定代碼段的指令中的至少部分指令中的每條指令,可能通過一條驅動層指令就能實現其功能,也可能通過兩條驅動層指令實現其功能,具體由所選用的驅動層指令的類型而確定。
在本發明另一個實施例中,圖6所示的處理單元可以進一步配置為將實現可執行文件中預定代碼段的指令中的至少部分指令替換為包括與驅動層指令的調用相關的指令和/或函數在內的第一代碼段。如此可將與預定代碼段的執行相關的指令中的至少部分指令完全隱藏,並且在可執行文件運行時,通過與驅動層指令的調用相關的指令和/或函數來對驅動層指令進行調度,能夠由處理單元使得驅動層指令從應用程式端發送至驅動層模擬器,並使得應用程式端從驅動層模擬器接收返回的相應執行結果,從而在將上述的部分指令隱藏的同時能夠確保可執行文件的順利執行。
圖7為本發明的對可執行文件進行保護的裝置的又一個實施例的示意性框圖。
在本發明一個實施例中,如圖7所示,裝置還包括分析單元,其配置為分析所述可執行文件中的多個函數,並將多個函數中的至少一個目標函數對應的代碼段確定為預定代碼段。分析單元可配置為基於不同的條件來確定目標函數。例如,分析單元可配置為根據如下條件確定所述目標函數:對於實現所述目標函數的指令中的至少部分指令,存在功能對應的驅動層指令。或者,分析單元可配置為將具有參數和返回值的函數確定為目標函數。另外,分析單元還可以配置為將具有同一類型的參數和返回值的函數確定為目標函數。
本發明在對可執行文件進行保護時,將部分代碼或指令的執行過程轉移至驅動層模擬執行,這樣對軟體中代碼或指令的保護的對抗從應用層轉移到驅動層,進一步增加了調試難度,從而達到了保護軟體的目的。
當然,以上所述是本發明的部分實施方式,應當指出,對於本技術領域的技術人員來說,在不脫離本發明原理的前提下,還可以做出若干改進和潤飾,這些改進和潤飾也視為落入本發明的保護範圍。