说明:你但愿本身用.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技术博客