向書本學習,還要向?qū)嵺`學習、向生活學習。消化已有知識,
而且要力求有所發(fā)現(xiàn)、有所發(fā)明、有所創(chuàng)造
2019/3/30 11:28:55
在 per method 的dotNet加密中,首要解決的方法體對應關(guān)系,即在運行時加密殼如何確定當前要解密的方法體所對應的加密信息。
目前大部分加密殼都直接利用了dotNet的元數(shù)據(jù)來保存這種對應關(guān)系,我們知道在元數(shù)據(jù)中每個方法都會對應一個RVA值,加密殼可以直接把這個關(guān)系記錄在RVA的地址處。在框架運行中RVA處的數(shù)據(jù)會被作為“方法體”在處理流程中直接傳遞,加密殼通過攔截框架處理流程中的函數(shù),來對“方法體”進行分流處理。即先判斷RVA處的數(shù)據(jù)是否“方法體加密對應信息”,如果是進入加密殼運行庫的內(nèi)部處理,不是則按原框架流程處理。
對于這個“方法體加密對應信息”,最簡單的方式是指記錄一個指針信息,指向另一處數(shù)據(jù)塊,四字節(jié)空間就夠了。但是為了和普通沒有加密的方法體進行區(qū)分,除了這個之外還需要增加一些唯一標識以便能被運行庫在運行時安全無誤的區(qū)分出來。
大家可以用UE打開,加密后的程序集,看看一個方法體RVA處的數(shù)據(jù),應該能很容易分別出來哪些是記錄的“方法體加密對應信息”。
正是這個原因,所以DNGuard v1.0和同類處理方式的加密殼,對方法體小于某個指定字節(jié)數(shù)的,就不能進行加密。
因為“方法體加密對應信息”的大小超過的方法體的空間大小,寫入的話會覆蓋到后面方法體的信息。這實際上也是因為偷懶造成的??梢酝ㄟ^對方法體進行重排來解決這個問題,當然要麻煩很多了。
這種模式實際上就是在元數(shù)據(jù)保存了一個虛擬表實現(xiàn)了 MethodToken => “方法體加密對應信息” 的對應記錄。這個表可以看著是公開的。
在DNGuard 2007 中我沒有選擇使用對方法體重排的方式來解決這個問題,而是選擇了另一個方法,自己記錄一個 虛擬表實現(xiàn):MethodToken => “方法體加密對應信息” 的對應記錄。
因為這樣有一個好處,就是 這個虛擬表也可以進行加密后保存。另外就是“方法體加密對應信息”中不需要添加標識符 和普通沒有加密的方法體進行區(qū)分。
在 DNGuard 2007 試用版 中沒有使用真正的加密算法來對程序集加密,只是采用了“代碼直接挪位”的方式,運行庫的“解密”操作只是從另一個位置直接讀取的操作。
有個朋友分析到DNGuard 試用版里面有一個虛擬表記錄了:MethodRid => ILCode。這個就是 虛擬表:MethodToken => “方法體加密對應信息” 在 試用版中退化的模式。
另外因為方法體只是挪位,所以它實際上還是在程序集文件內(nèi),加載到內(nèi)存中后也在程序集模塊的內(nèi)存空間中。而不是那位朋友說的 運行庫在解密后將 IL代碼 填回到內(nèi)存里面去了。
試用版只是提供給用戶驗證 DNGuard 是否適合自己的軟件項目以及系統(tǒng)發(fā)布環(huán)境,請不要用試用版 加密程序集后直接分發(fā)。
深圳市南山區(qū)南山街道南海大道西桂廟路北陽光華藝大廈1棟4F、4G-04
咨詢電話:136 8237 6272
大客戶咨詢:139 0290 5075
業(yè)務QQ:195006118
技術(shù)QQ:179981967