软件公司为什么要加密源代码,而且是前前后后,反反复复

转自:http://www.cnblogs.com/JamesLi2015/archive/2011/08/18/2143995.html

工作多年,接触到大大小小的数个项目,经验多起来,但阻碍进步的因素也多。因为在代码中看到这个功能是如何实现的,下次自己做,也会用到类似的办法,这样减少了思考的时间,进步也会越来越慢。

说一说软件公司为什么要加密程序的源代码。我们都知道.NET平台的目标是将多种语言,编译为同一种格式,不同的编译器将C#/VB.NET之类的符合CLS规范的.NET语言源代码,编译成IL格式,在运行时IL格式的程序时,由即时编译器转化为机器执行指令。IL格式是开放的,自描述的,在不加密的情况下可以很轻松的反编译成源代码。所以,提到源代码,经过C#/VB.NET编译器编译之后的IL格式的程序集,也可以称为源代码。 

再来回味一下这个经典的软件的反编译功能

<a href="http://images.cnblogs.com/cnblogs_com/JamesLi2015/201108/201108180913292309.png" style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 0, 0); border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: rgb(51, 51, 51);"><img title="image" border="0" alt="image" src="/ueditor/jsp/upload/image/20141002/1412218684296091763.png" width="695" height="370" style="margin: 0px; padding: 0px; border: 0px; display: inline;"/></a>

有趣的一个现象连同System.Data一起编译的程序集的强签名存放在E:\DNA目录下面。 
[assembly: <a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://mscorlib:1.0.5000.0:b77a5c561934e089/System.Reflection.AssemblyKeyFileAttribute/.ctor(String)" style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 0, 0); border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: rgb(51, 51, 51);">AssemblyKeyFile</a>(@"E:\DNA\public\tools\common\security\EcmaPublicKey.snk")]

然而好景不长,软件公司很快意识到源代码的重要性,于是用.NET Reactor 加密assembly格式的执行文件

<a href="http://images.cnblogs.com/cnblogs_com/JamesLi2015/201108/201108180913313257.png" style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 0, 0); border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: rgb(51, 51, 51);"><img title="image" border="0" alt="image" src="/ueditor/jsp/upload/image/20141002/1412218684342087794.png" width="551" height="387" style="margin: 0px; padding: 0px; border: 0px; display: inline;"/></a>

 

当再次用.NET Reflector打开这个已经被加密过的程序集时,当查看和展开方法的实现时,会收到一个.NET Reflector异常,即使有时候可以展开方法实现,也只能看到乱码一样的命名,如下图

<a href="http://images.cnblogs.com/cnblogs_com/JamesLi2015/201108/201108180913359796.png" style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 0, 0); border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: rgb(51, 51, 51);"><img title="image" border="0" alt="image" src="/ueditor/jsp/upload/image/20141002/1412218684380032484.png" width="503" height="266" style="margin: 0px; padding: 0px; border: 0px; display: inline;"/></a>

 

Contents

1  知识产权保护,利益保护,垄断

这是一个最正当的理由,给自己的代码加密。在ERP的销售单中,有以下几个金额的计算功能

<a href="http://images.cnblogs.com/cnblogs_com/JamesLi2015/201108/201108180913387481.png" style="margin: 0px; padding: 0px; text-decoration: none; color: rgb(0, 0, 0); border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: rgb(51, 51, 51);"><img title="image" border="0" alt="image" src="/ueditor/jsp/upload/image/20141002/1412218684420079435.png" width="244" height="136" style="margin: 0px; padding: 0px; border: 0px; display: inline;"/></a> 

Net Trade Amt=Total Item Amt + Tax Amt + Trade Discount,用中文意思来表达,就是

净贸易金额= 总物料金额 + 税金+ 贸易折扣

这个公式用文字表达是很简单,但是它背后的计算却有些复杂,仅仅公式的求值过程的源代码就超过1000行。

在ERP系统中,涉及到排产功能,MPS/MRP计算,计划订单发放,以及大量的像这样的公式计算,这是软件价值所在,所以要加密。

我一直怀疑ERP平台的存在性,也源于这里。ERP平台宣布称,把这一块定制的,体现价值的部分,留给最终的用户,实施人员来设置,就比如上面的公式,ERP平台可以做到公式是这样的 
Net Trade Amt=Total Item Amt + Trade Discount 
也即少了税金的计算,总之,它就是很强大。 

根据我理解的,对税金的计算。用代码敲出来的ERP,会先开一个配置项,是否实施课税,是按照整张订单还是单行物料,在计算时,依照最完整全面的公式 
Net Trade Amt=Total Item Amt + Tax Amt + Trade Discount 来计算最终的贸易金额。如果当前设置不实施税金,则Tax Amt 的值为0,也就实现了ERP平台宣布的,可以自定义的公式 
Net Trade Amt=Total Item Amt + Trade Discount 

当熟练掌握了MIS的或是与数据库打交道的系统的开发方法后,我以为,上面提到的这些逻辑,是最宝贵的进阶方向。所以,要加密。做MIS/ERP久了,容易形成一个坏习惯,客户你告诉我怎么做,我就怎么做。因为改来改去,反反复复的修改,已经让我们认为,ERP/MIS系统就是客户怎么想的,我们就怎么做。但是,有时候客户没有办法呢,那我们不就做不出来了吗?软件公司给我的答案是,先有自己的解决办法,提供给客户,或是与客户的实际情况对比,甚至定制一下,以符合客户需求。一个公司的ERP/MIS项目,应当充满了上述方案的解决办法,而不是等待客户的需求来开发。我也认为,这是深圳市充满了大大小小的许多ERP/MIS公司的原因,需求差异化,行业不同,隔行如隔山,这就是有价值的方案,当把这些解决方案变成代码后,肯定要加密,以保护公司的利益。

我的心得是,要做ERP/MIS,公司没有现成的解决方案,也没有应用程序框架,甚至连需求都没有,往客户那里一站,客户怎么说,我们怎么做,这样的ERP/MIS风险太大,找工作时碰到这样的公司,请谨慎入职。

 

2 加密源代码可以杜绝抄袭,模仿

只要有程序员在,在源代码可读的情况下,无论多么复杂的系统,总有人可以破解其中的奥妙。 
就比如Windows Server 2008的激活(没有源代码的情况),最新版的Windows Server 2008需要联机才能激活,即使这样,也有人可以做出注册机。没有源代码的Windows尚且如此,那有源代码就更容易破解了。 
在网上经常可以看到,仿XX之类的软件源码。这类型的源码,在一定程度上,不可否认它推广了技术,但同时也打击了软件的原创者。记得在2005/2006年的时候,公司要求做一套像阿里巴巴一样的贸易网站,换作是今天,各种仿阿里巴巴的网站源代码已经很多了。但那时似乎找不到这类型源码,硬着头皮做,ASP+SQL Server,折腾的死去活来。 
这种类型的仿制软件,多半是界面上的仿造,而且会开源。360和QQ医生,是功能的仿造,不开源的。 
很多ERP/MIS的实现,实现起来不难,是各种方案的集合,加密软件的源代码,可以很大程度上减少仿造软件的产生,阻止抄袭。说一句题外话,我如果能做一个漂亮的软件A,很受欢迎,下载量不错,我想我肯定也会做一个仿A的软件,并且把它开源,让最终用户和程序员一起帮忙发展你的软件。Visual Studio Express,各种软件的Community版都是非商业版,可以免许可使用的,这也可以杜绝各类的仿制软件的产生,因为你开源的或是免费的版本已经很好用了,开放的源代码也让爱钻研的人过过瘾了,它会手下留情,放过对你的软件的仿造。 
也听说过,网络游戏的私服程序,会故意放一部分到网络上流传,是故意泄露的,然后在服务器端作出处理,这也是帮忙改善软件的很clever的办法,软件人的头脑真的很不错。 

我的另一个心得是,如果公司要你去做一个防阿里巴巴一样的贸易网站,或是一个妨腾讯的地方门户网站,找工作时碰到这样的公司,请谨慎入职。

 

3 版本控制,功能控制,资源保护的一种策略

先说功能控制,举例QQ医生和360之间的相互打架,都互掐对方,说扫描用户硬盘,暴露用户隐私。可是,这也是谣传,你没有它的源代码,不知道它为什么让你心爱的硬盘一直忙个不停,加密源代码可以做到这一点,死不认帐。 

ERP/MIS软件加密,有个小bug不小心把客户的采购单的金额计算错误,因为代码是加密的,可以帮忙用户做data fix,以用户为主,也很少会告诉客户是程序的bug,因为代码是加密的。ERP/MIS类型的软件,基本上都靠服务赚钱了,卖软件连维持公司生存都难,所以,这类型的软件一定要加密。可配置的地方,暗藏在系统中,但在文档中不表达的地方,多如牛毛,一不小心就出了问题,只好请专业的人员来做维护。 
再来说PPLive,网络电视,优库,土豆网的播放软件,这类型的软件与资源绑定紧密,软件是不能获取任何费用的,只有从与它绑定的资源中获取利润,加密源代码,可以保护资源,保护公司利益。 

再回到功能控制上来,由于加密了源代码,再配合客户端自动升级技术,像360,QQ医生之类的软件可以为所欲为,它真的干了什么,谁也不知道。以扫描用户隐私这一项来说,当要闹官司,求清白的时候,都说自己的软件是以客户为上帝时,可是一但配合自动升级技术,他们说的都是真的。可是,我一直都在怀疑,安装完成后的360要300多MB的硬盘,360杀毒要200多MB的硬盘,软件的发展,应该是接口越来越简单好用,代码量越来越少,可他们越来越肥胖了,胖到你不可理解的地步。我无意批判这些软件,我只是想表达,C/S软件,配合自动升级技术,再把你的源代码加密,你想干什么,都取决于你了。 
我理解的版本控制,就是前后版本间,有bug或是要更新什么,由于加密的源代码,你无从得知。当然,我们只是软件的用户,不是开发人员,不需要关心这个细节,只是偶尔好奇为什么硬盘忙个不停。 

4  知识创新,软件业分工细化的必然要求

加密软件的源代码,造成一定程度的技术垄断,但也促进了知识创新。以Form Designer的开发为例子,原本世界上只有三家公司可以开发窗体设计器这种软件,Microsoft的Visual Studio,IBM的Eclipse和Borland的Delphi,这三家公司,可以开发出世界上最好用的窗体设计器,Borland很早就退出了软件开发工具市场,只剩下了Microsoft和IBM。看窗体设计器的演化,也只有看这两家公司的产品了,这是垄断。另一方面,程序语言的却越来越多。Borland垄断了Delphi/C++/Java系列的开发工具,Microsoft垄断了C#/VB.NET的开发工具,Sun垄断了Oracle/Java Developer开发工具,但是,近几年,程序语言的数量也增长的非常快。以我为例子,我要找到Delphi在.NET环境下的一种语言,通过Delphi.NET来操作.NET Framework已经失败,但是由此也诞生了许多类似的商业化的语言及其开发工具,比如Visual Studio 2005时就诞生了RemObjects Chrome for VisualStudio,直接以Delphi的语法,调用.NET Framework,编译成IL格式。这也令我想起了J#,以Java的语法,.NET 平台的API,环境来创作.NET程序。 
到了后来,这个项目又发展成Delphi Prism,更加完善。这是知识创新的结果。 
Microsoft垄断了.NET开发的基础平台,自从C# Builder消失后,再没有第三方的开发工具供应商生产C#开发工具,扼腕叹息,与此同时,聪明的人另开辟路径,避开IDE的战争,进入到重新设计一门语言,然后提供基于这个语言的解决方案,Delphi.NET的失败,也给后来开发Delphi的方向提供了经验。 

5  信任,责任,自私,一切皆是心态

在博客园主页看到文章,跟随高手工作半年,只能看到一些dll,看不到源代码。有的说很正常,想保护自己的成果,有的认为太自私,连员工都看不到源代码,肯定不信任,用人不疑,疑人不用。 

以我的工作例子,曾在一家台湾人的IT部门,当时的职位是中级程序员,上司也是很注意保护自己的代码,我的工作就是给他写方法,他告诉我要做个什么功能,笔划一下,我就要给他提供这个功能的实现,也没有定义接口,写好了功能,他调用一下,觉得没有问题,就被他合并到他的源代码中去了,至于他做了什么修改,或是加了什么,我也看不到。有时候实在需要调用现有的功能,他就故意重开一个demo工程,来给我测试用,而不是直接对现有的系统进行测试。 

一开始的工作还顺利,到后来交货期越来越紧,功能变化频繁,常常写好了一个功能,简单的测试一下就需要修改,不是有bug,是有新的需求在不停的加,有时候加一个需求,会导致代码要完全重写,因为考虑不到以后的变化。举例为证,就为了实现读取文件的功能,我不可能会弄一个IFileReader接口,来应对现在是读取文本文件,以后还要读取Xml文件或是二进制文件,这样太浪费了,当时也达不到这么深厚的功力。想想当时,连自己的代码放在哪里运行都不知道,真令人叹息。后来的工作,公司用文章开头提到的.NET Reactor加密了程序集,也就不好奇了。起码在这里,我还知道自己的代码是与这几个加密的程序集一起工作的。 
ERP/MIS类的逻辑很容易模范,学习,公司加密这些程序集,也可以理解。 
也碰到过很爽快的程序员朋友,很有价值的程序,从不加密,你要知道为什么,自己去反编译查看就好了,这其实是给好学的人一种进修的机会。不是每个人下班后都会继续看一下书,再敲一下代码,当激情释放之后,剩下的拼的是毅力,坚持,不放弃。要相信自己研究所得,终有所用。

有一句话很重要,只要是自己写的代码,我们都要对它负责,不管它是否会被加密,我们都要为它的行为负责。