標籤:
[C#防止反編譯].NET 產品著作權保護方案 (.NET源碼加密保護)
標籤: .net加密產品c#dll工具
2011-03-24 21:06 27009人閱讀 評論(13) 收藏 舉報
分類:
C#/.NET(4) Decompile(6)
說 明:你希望自己用.net辛辛苦苦做出來的軟體被人輕易破解嗎?你希望自己花了大量人力物力用.net開發出來的產品被競爭者輕易擷取核心代碼嗎?這是 一篇比較詳盡地介紹如何保護自己的.net原始碼的文章,如混淆、加密和強式名稱等,出於保護原作者的角度,所以本人沒有掐頭去尾作為自己個人的文章,正因 為是全文轉載,所以並不代表本人完全贊同作者的全部觀點,也不代表本人本人提作者提到的軟體做廣告,這一點請大家注意,不要認為我為別人做廣告而罵我,其 實我根本不認識作者。
一. 前言
大家好,我是康世傑,大家可以叫我Jason。
我和大家一樣,都是搞技術出身,也未當過講師,所以口材有限,如果講得不好之處,還希望大家多多海含,謝謝。
今天是我們第一次見面,能認識你們,真的很高興。
下面我們不要耽誤大家的寶貴時間,讓我們馬上開始上課吧。
DotNet 是 ms開發並推廣的企業解決方案,也是Ms以後幾年的核心發展戰略之一,所以我覺得 DotNet 是有前途的,他有一個優秀的概念,還有一個強大的財團,想失敗都很難啊。DotNet 缺乏的是大型企業高層管理員對它的信心,這還需要時間和案例去證明,世界上待開發的大案例還很多,Java 和 DotNet 最終誰的市場比例多,現在還說不清楚。
二. 簡介DOTNET 編譯原理
相信大家都使用過 Dotnet ,可能還有不少高手。不過我還要講講Dotnet的基礎知識,Dotnet的編譯原理。
Dotnet是一種建立在虛擬機器上執行的語言,它直接產生 MSIL 的中繼語言,再由DotNet編譯器 JIT 解釋映象為機器碼並交付CPU執行。它和Java是一種機制的語言。這種語言的優點就是您不需要去考慮您的程式在那裡運行,您只需要把功能做出來,虛擬機器會在任何地方實現您的功能。這是一個很好的趨勢和想法,但虛擬機器的中繼語言由於帶了大量的“中繼資料”資訊,所以也極容易被反編譯。
MSIL 的代碼事實上和 C# 或 VB 沒有多大的區別,只要您記住20來個指令,您應該可以很容易的讀懂它。
保護代碼和開源並不衝突,需要保護的一定有自己的理由,所以今天我也不是來反對開源的。。呵呵
三. 中繼語言的缺點
中繼語言如此容易被反編譯,有許多可怕之處。
1. 我們最關心的智慧財產權
辛苦研究出來的演算法,多少個不眠夜研究出來的成果。這本來是你賺錢的法寶,可是被公開了,智慧財產權沒有了,那個時候恨誰啊。
2. 原始碼泄漏,被競爭者拿去和你競爭(這種事很多)
就我知道的都有幾起,不過不方便說出來。
他們從客戶那裡想辦法copy回一份別的公司的產品,然後反編譯後,改改圖片,圖片以及著作權資訊和註冊資訊,就拿出去賣了。
正規的公司一套賣二萬,它們一套才8千。功能基本上一樣,你說你是客戶,你買誰的?
3. 自己產品的註冊機滿天飛
做個共用軟體吧,賺點錢改善一下生活吧,產品剛上市,還沒幾天註冊機每個網站都有。影響了銷售還影響心情,以後不做產品了,還是做服務靠得住,至少盜版不了啊, 呵呵,不過做服務,還沒那麼多資金,真是做什麼都難啊。
4. 被別人植入惡意程式,後果得由作者或開發商承擔
以上說的都只是被別人佔便宜的事情,還好,只是讓能佔佔便宜,算了,虧也虧不了多少。可是,我再講一個,那可就不是被人佔便宜那麼簡單了。
比方說:貴公司出了套產品,放在網上給人下載試用,定好版本為1.0,某個惡意的公司不懷好意,把產品下載下來,用萬惡的Ildasm 反編譯一下,然後在裡面加入一段按條件觸發的命令,命令的內容是format c: or formatd:. 然後再用萬惡的ilasm 編譯一下,用貴公司的名義打個一模一樣的包,升級為1.2試用版,然後放到ftp 或 sharewaresite 上供人試用下載。試想一下,不久您就會接到使用者的投訴,甚至是起訴。
再比方說:要離開公司的員工,對公司的種種形為不滿,在離職交接以後,把公司Release好的項目的某個dll改一改,必定造成這個項目的重大損失。當然,我可不是在教各位用這種方法對待自己不滿的公司。我只是告訴各位,Dotnet的程式集,不保護是不行的。
四. 保護方案分類
下面,我開始介紹一下.NET的各種保護方案。
我把Dotnet的保護分為三大類
- 由m$ 提供的非第三方保護方案
a) 強式名稱
強式名稱是MS提供的保護機制。
它需要使用 sn 這個命令。
強式名稱是什麼意思呢?在這裡稍作解釋。強式名稱的作用就是防止程式集被非法修改,當對程式集修改後,必須重新用您的私密金鑰再對程式集加一次強式名稱,這也是如果含有強式名稱的程式集在混淆或加密後必須要重新加強式名稱的原因。
Sn / ? 可以看到它的使用方法,如果你安裝的 Framework是中文的,那麼參數的解釋也是中文的,我就不多講了。
那麼強式名稱有用嗎?網上輕鬆破解強式名稱的方法很多,Ildasm反編譯加過強式名稱的程式集後,在IL檔案中將強式名稱的相關資訊去掉,再利用Ilasm編譯,就可以解除強式名稱的限制了。這個我已經過測試過,您的強式名稱的PublcKey不管是加在程式集中,還是加在Class中,都可以被去掉,所以強式名稱不是一個完善的保護方式。不過在這裡要說一下,如果有一個好的方案能和強式名稱一起使用,那麼將建立一個非常好的機制,防修改,防濫用。
說到濫用,這是強式名稱的一個特殊用途,它可以使您的dll不被第三方調用,如果您的dll能保護自己的話。
關於強命稱講到這裡,他的使用方式有必要的情況下,我們以後再深入的講解。
b) 編譯MSIL為機器碼 (誤區?)
關於這一點,我經常能在MS上的社區看到有MVP這樣面對問題:
問:C#寫的程式能編譯成機器碼嗎?
答:可以,使用 Ngen.exe 即可以 MSIL 代碼編譯為 機器碼。
MVP這樣回答錯了嗎?其實,嚴格的說,MVP的回答是沒錯的,Ngen.exe的確是可以將 MSIL 編譯為機器碼,並可以使JIT不需要進行再次編譯MSIL。這樣能加快程式的執行效率。
但使用者這樣的問題其實,並不是對執行效率不滿意,而是對中繼語言不滿意,可惜 Ngen 並不能解決使用者的問題。
讓我們來淺淺的分析一下 Ngen的工作吧。
Ngen是MS提供的 本機映象產生器,它可以將中繼語言程式集編譯為機器碼存放在緩衝中。這裡請大家注意,是存放在緩衝中,Dotnet在記憶體中建立了一個緩衝,這個緩衝中存放了許多常用的程式集編譯後的機器碼,它們是常駐的,由此來加快Dotnet的執行速度。
所謂一個機器碼,因為本機映射時,會映射出一些 Framework 裡需要的Method,編譯為彙編就是Call 0x0200000這樣的樣子,而這些東西必須是事件編譯好的。那麼理論上說 Ngen 必須要在當前執行的機器上運行,而直接編譯成機器碼的程式copy到另一個地方不一定可以用,而且我一直沒有找到能將緩衝中的機器碼 copy 出來的方法。
講到這裡,不知道大家明白我的意思沒有,不管如何 Ngen.exe 只是一個提速的工具,因為要執行編譯為機器碼必須還是要原程式集,而原程式集中存在MSIL,所以讓程式無法脫離被反編譯的目地。
大家回家,如果有空,可以做做實驗。
Ngen /show 就可以看到緩衝中所有的已編譯好的程式集,所以Dotnet並不慢。
Ngen <assembly path or display name> 可以把指定程式集映象為機器碼。
Ngen /? 可以看到其它參數
以上是ms提供的工具,下在講講,自己在編程的過程中,如何提示來防止破解或反編譯。
- 編程技巧保護方案
在這裡,我會給大家介紹兩種三種方式
1. 人為混淆
在這裡,我就要先簡單的講講什麼叫做混淆
混淆顧名思意,就是混亂,不明確的意思。MetaData中都有一個Rid,程式集運行時就已經和名稱沒什麼關係了,都使用Rid來調用的,所以可以將名稱省去。
什麼叫人為混淆呢,就是人為的製造混淆。
曾經看過一個程式集,手工的將一個Method折成幾十個或上百個,從而達到讓你看不懂的目的。不過可惜的說一句:現在的Dotnet程式集的分析工具都很強大,正引用,反調用都可以用程式來實現,所以即實這麼做,了沒多大用處。著名的Reflector就有這些功能。
2. 隱藏程式集
剛剛談到了Reflector,它就是使用這種方式來隱藏自己的核心程式集的。相信我,Reflector並不是您看到的那一個可執行程式,它的可執行程式只是一個殼而以,裡面是一個定義和介面,沒有執行個體的方法。如果你想得到他是怎樣反編譯的核心,恐怕你會在它這個迷宮中迷失方向。
它是怎樣做的呢?讓我來告訴你,它的核心程式集事實上就是它的一個資源。而這個資源是一個加密的資源。如果我沒記錯,他應該是在雙擊第一個需要反編譯的Method的時候開始釋放這個資源,並對資源解密然後動態載入。這樣做的優點核心程式集是不會在硬碟上留下任何痕迹的,它只解在記憶體中解密並被載入,你基本上無法得到這個程式集。而且Dotnet是不允許記憶體 Dump的。
大家是不是覺得這種保護方法不錯呢?你可以把你的核心代碼加密後做成資源套件在程式裡,在使用的時候再解密出來,這隻需要你自己去實現就可以了。
不過我還得說句負責任的話,如果你有精力,並且很有耐心和技術,相信你還是可以在幾天時間內找出它的核心程式集解密演算法的位置。並成功的解出它的資來源程式集。
如果是高手又非常有經驗,這種方式的加密手段應該是秒殺。
3. 將程式集中的相關Method(方法)編譯成Unmanaged(Unmanaged 程式碼)
下面介紹的內容是不管你是菜鳥,或是高手,都無法得到核心代碼的方
它可稱之為終極的保護手段,因為它就是“Unmanaged 程式碼”。
什麼是Managed 程式碼,什麼是Unmanaged 程式碼。
簡單的說,Managed 程式碼就是需要Jit去解釋的中繼語言代碼,而Unmanaged 程式碼
就是機器碼。下面要介紹的方式就是教您如何在自己的程式集中即擁有Managed 程式碼,又擁有Unmanaged 程式碼。注意,Unmanaged 程式碼是無法被現在的反編譯工具反編譯的。
特別注意一點,我沒有自己試過,但我看人做過,並得到了證實。
在Dotnet程式集中,允許Managed 程式碼和Unmanaged 程式碼共存,怎樣實現呢?這並不是無償的,這是需要條件的。它的條件就是必須使用VC++.NET非託管方式來寫dll,再用VC++託管方式建立工程引入這個機器碼的dll。最終產生一個Dotnet程式集的dll。那麼這個程式集裡面即有Managed 程式碼,又有Unmanaged 程式碼。Managed 程式碼是可以反編譯的,而Unmanaged 程式碼不可能被反編譯。
有人可能要問了,這和自己用VC++寫個dll有什麼區別?區別就是這樣的結合更緊密一些,而且也不能用常規的分析Asm的工具去分析這個dll。
這裡還要解釋一個誤解,有人說,利用Win32的機器碼寫註冊演算法,並產生dll供給Dotnet程式集調用,防止破解。其實這句話只說對了一半,這隻能增加破解註冊機的難度,並防止不了破解。為什麼呢?因為註冊對不對還是要在Dotnet程式集中進行判斷,所以,只要改掉這個判斷,一樣達到了破解效果。但是如果要分析註冊演算法,那可就是困難了一些了。
- 第三方保護工具
下面,我們講一講第三方的保護工具和概念
第三方保護工具較好的廠商有:
1. Aiasted.SOFT
a) 產品 :MaxtoCode ,種類 :加密、混淆
2. PerEmptive Solutions
a) 產品 :Dotfuscator Community ,種類 :混淆
3. Remotesoft
a) 產品 :Remotesoft Protect ,種類 :加密
b) 產品 :Remotesoft Dotfuscator ,種類 :混淆
4. XenoCode
a) 產品 :XenoCode ,種類:混淆
5. 其它的一些公司,最近上海有一款公司出了國內第一款混淆工具,如果大家要選擇混淆產品的話,支援一下國產也不錯。
第三方工具的保護方式分類
1. 混淆 ?
這是目前最流行的方式吧。今天我們就來做個剖析。讓大家去衡量一下混淆的強度如何。
混淆軟體一般都有三個功能
1. 字串加密
2. 名稱混淆
3. 流程混淆
目前流行的混淆軟體有
XenoCode、Dotfuscator、Remotesoft,MaxtoCode裡也整合了少許混淆功能。
利用投影片講解流程混淆原理
利用程式當場示範如何反流程混淆
1.目標程式
2.被混淆的程式使用 Reflector 查看
3.使用Ildasm反編譯出 IL 檔案
ildasm XenoCodeTest.exe/out=XenoCodeTest.il
4.將IL 檔案中的某個方法抽出
5.使用 Deflow 進行反混淆
6.回填,並使用 Ilasm 進行編譯
Ilasm XenoCodeTest.il /resource=XenoCodeTest.res /output=XenoCodeTestNew.exe
7.再回到 Reflector 中進行查看
2. 打包 ?
ThInstall 是一個打包工具,他可以打包幾乎所有的應用程式,也包括
Dotnet。
他將多個Dotnet程式集包在一個大程式裡,達到無法反編譯的目地。不過想想也知道,即然是打包,在需要運行時肯定會釋放,如果找到了釋放出來的檔案,就跟沒保護一樣了,所以,這算是一個最爛的保護手段。當然,本來我沒想把它列進來的,是因為看到論壇上經常有人用這個Thinstall回複別人說可以保護Dotnet程式集,所以我才特別忠告大家,別信。
3. 加密 ?
加密保護並不同於混淆,它是目前最好的保護方式,也是保護能力最強的。
他把Dotnet的先天不足在一定程度上大幅提高,為Dotnet引來更多的開發人員。加密保護的軟體都有一個共同點,即把Dotnet的反編譯引深到Win32的反組譯碼中了,可惜的是,也限制了Dotnet跨平台的優勢。
此類的代表軟體有
MaxtoCode 、Remotesoft protect ,其它的一些國外的,我就不說了,實在讓人用不下去。
由於Remotesoft公司過於小氣,Protect連試用版都不提供,所以我只能找到他的一個加密過的產品 WebGrid3.5,但WebGrid4.0就未用Protect了,不知道為什麼,幾千美金就這麼廢了?分析WebGrid3.5以後,發現他和MaxtoCode一樣,產生的結果就是看不到IL代碼了,而且也會產生一個機器碼的DLL作為運行環境。
由於對Remotesoft Protect無法深入研究,只知道效果和MaxtoCode一樣,那麼我們就來講講MaxtoCode的實現原理吧。
MaxtoCode是為了迷補Dotnet的先天性不足而出世的。它是中國第一款高強度的Dotnet保護軟體,在世界的Dotnet保護水平線上也處於優勢性的領先。
其實MaxtoCode的原理很簡單,它是將程式集中所有的IL進行加密,所以使用反編譯器無法看到IL,從而不能進行反編譯。基於Framework提取Method的IL作為基礎原理,當JIT需要IL時,我就將加過密的IL解密給JIT去編譯,這樣就形成了MaxtoCode的基本原理。
下面是MaxtoCode 加密的過程及結果:
1.選擇程式集
2.選擇進階加密的選項
3.選擇混淆的選項
4.加密
5.結果
加密後的程式運行結果:
使用 Reflector 反編譯的結果
使用 MS 內建的工具 Ildasm 進行反編譯
使用 Ildasm 查看代碼區內容
原始碼都為空白了,完全不可以反編譯.杜絕了反編譯的問題.
from:http://zhoufoxcn.blog.51cto.com/792419/163944
[C#防止反編譯].NET 產品著作權保護方案 (.NET源碼加密保護)