天天看點

.Net 加密原理,方法體加密資訊對應關系的實作(一)

在 per method 的dotNet加密中,首要解決的方法體對應關系,即在運作時加密殼如何确定目前要解密的方法體所對應的加密資訊。

目前大部分加密殼都直接利用了dotNet的中繼資料來儲存這種對應關系,我們知道在中繼資料中每個方法都會對應一個RVA值,加密殼可以直接把這個關系記錄在RVA的位址處。在架構運作中RVA處的資料會被作為“方法體”在處理流程中直接傳遞,加密殼通過攔截架構處理流程中的函數,來對“方法體”進行分流處理。即先判斷RVA處的資料是否“方法體加密對應資訊”,如果是進入加密殼運作庫的内部處理,不是則按原架構流程處理。

對于這個“方法體加密對應資訊”,最簡單的方式是指記錄一個指針資訊,指向另一處資料塊,四位元組空間就夠了。但是為了和普通沒有加密的方法體進行區分,除了這個之外還需要增加一些唯一辨別以便能被運作庫在運作時安全無誤的區分出來。

大家可以用UE打開,加密後的程式集,看看一個方法體RVA處的資料,應該能很容易分别出來哪些是記錄的“方法體加密對應資訊”。

正是這個原因,是以DNGuard v1.0和同類處理方式的加密殼,對方法體小于某個指定位元組數的,就不能進行加密。

因為“方法體加密對應資訊”的大小超過的方法體的空間大小,寫入的話會覆寫到後面方法體的資訊。這實際上也是因為偷懶造成的。可以通過對方法體進行重排來解決這個問題,當然要麻煩很多了。

這種模式實際上就是在中繼資料儲存了一個虛拟表實作了 MethodToken => “方法體加密對應資訊” 的對應記錄。這個表可以看着是公開的。

在DNGuard 2007 中我沒有選擇使用對方法體重排的方式來解決這個問題,而是選擇了另一個方法,自己記錄一個 虛拟表實作:MethodToken => “方法體加密對應資訊” 的對應記錄。

因為這樣有一個好處,就是 這個虛拟表也可以進行加密後儲存。另外就是“方法體加密對應資訊”中不需要添加辨別符 和普通沒有加密的方法體進行區分。

在 DNGuard 2007 試用版 中沒有使用真正的加密算法來對程式集加密,隻是采用了“代碼直接挪位”的方式,運作庫的“解密”操作隻是從另一個位置直接讀取的操作。

前面有個朋友分析到DNGuard 試用版裡面有一個虛拟表記錄了:MethodRid => ILCode。這個就是 虛拟表:MethodToken => “方法體加密對應資訊” 在 試用版中退化的模式。

另外因為方法體隻是挪位,是以它實際上還是在程式集檔案内,加載到記憶體中後也在程式集子產品的記憶體空間中。而不是那位朋友說的 運作庫在解密後将 IL代碼 填回到記憶體裡面去了。

試用版隻是提供給使用者驗證 DNGuard 是否适合自己的軟體項目以及系統釋出環境,請不要用試用版 加密程式集後直接分發。

繼續閱讀