說明:你但願本身用.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 format d:.
而後再用萬惡的
ilasm
編譯一下,用貴公司的名義打個如出一轍的包,升級爲
1.2
試用版,而後放到
ftp
或
shareware site
上供人試用下載。試想一下,不久您就會接到用戶的投訴,甚至是起訴。
再比方說:要離開公司的員工,對公司的種種形爲不滿,在離職交接之後,把公司
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
(非託管代碼)
下面介紹的內容是無論你是菜鳥,或是高手,都沒法獲得核心代碼的方
它可稱之爲終極的保護手段,由於它就是「非託管代碼」。
什麼是託管代碼,什麼是非託管代碼。
簡單的說,託管代碼就是須要
Jit
去解釋的中間語言代碼,而非託管代碼
就是本機代碼。下面要介紹的方式就是教您如何在本身的程序集中即擁有託管代碼,又擁有非託管代碼。注意,非託管代碼是沒法被如今的反編譯工具反編譯的。
特別注意一點,我沒有本身試過,但我看人作過,並獲得了證明。
在
Dotnet
程序集中,容許託管代碼和非託管代碼共存,怎樣實現呢?這並非無償的,這是須要條件的。它的條件就是必須使用
VC++.NET
非託管方式來寫
dll
,再用
VC++
託管方式創建工程引入這個本機代碼的
dll
。最終生成一個
Dotnet
程序集的
dll
。那麼這個程序集裏面即有託管代碼,又有非託管代碼。託管代碼是能夠反編譯的,而非託管代碼不可能被反編譯。
有人可能要問了,這和本身用
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
加密的過程及結果
:
加密後的程序運行結果
:

使用 Reflector 反編譯的結果

使用 MS 自帶的工具 Ildasm 進行反編譯

使用 Ildasm 查看代碼區內容

源代碼都爲空了,徹底不能夠反編譯.杜絕了反編譯的問題.
本文出自 51CTO.COM技術博客