大型.NET商业软件代码保护技术 技术与实践相结合保护辛苦创造的劳动成果

列举工作以来遇到的各种类型的软件所采用的代码保护技术,只讲原理不涉及技术细节实现,以避免产生法律问题。有些朋友说直接把代码放在Github开源下载,开源可以促进技术交流与进步,然而值钱的代码都积压在硬盘里面,即使很烂的代码都卖了很多钱,赢得了许多客户与市场。珍惜爱护自己写的代码,他们都是宝贵的财富。

以下保护技术主要测重于脱机验证与保护,不涉及联网(连接到许可证服务器)验证。

1 程序集混淆 Asembly obfuscate

CLR代码的运行是即时编译执行的,.NET编译器只是将源代码文件编译成中间语言,中间语言包含丰富的元数据。使用.NET Reflector/ILSpy/JustCode这类的反编译器几乎可以还原整个源代码,所以用.NET开发软件第一个要做的任务是混淆编译后的中间语言代码。这也是我见得最多的.NET代码保护技术。

2 写注册表 Registry

虽然.NET时代强调XCOPY部属,但很多很程序依然依赖于注册表来做保护技术的基础。可以把自己想要隐藏的信息放到很深的注册表键中。

一些程序会将注册表键做一个字符串处理,比如将字符串改成16进制值,或是做一个DES混淆处理,在不知道解密键(KEY)的情况下很难看出它的意思。

3  RSA 签名  RSA Signature

RSA签名技术可以生成二个密匙,私匙用于生成许可文件,公匙用于验证许可。

string publicKey = "<BitStrength>1024</BitStrength><RSAKeyValue><Modulus>wDSWDT4ujpa+B7VkwdXGDvIEDc18O6qSnGtL38prVR18B7sjqbhR2Uq1C7hksADnF

DH+PAHv9BAWiqa1cWeaVgCwC2LNMClaJu4jZg0aFDIzhZUNHV56KS5aaVD+MHH+iEGmPok9XRz7Jd8hyjD38jHl439Uaf6oltxMRdKS5KU=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

string privateKey = "<BitStrength>1024</BitStrength><RSAKeyValue><Modulus>wDSWDT4ujpa+B7VkwdXGDvIEDc18O6qSnGtL38prVR18B7sjqbhR2Uq1C7hksADnFDH+PAHv9B

AWiqa1cWeaVgCwC2LNMClaJu4jZg0aFDIzhZUNHV56KS5aaVD+MHH+iEGmPok9XRz7Jd8hyjD38jHl439Uaf6oltxMRdKS5KU=</Modulus><Exponent>AQAB</Exponent><P>82nuszkXKLx

+NDtQLiruBlDGozAUaJ50PqHKq7jglLV740jz521+v2O6EVA+59gpGSwFrX6E7HnUrkKBQGbY/w==</P><Q>yiTO+1+xaNvmEcAyKdFboNRbP1/toUnakkREKyYCg/KLnjgpkb22gMtu

u5ocbfY2vIdyDZbYYeXmLYSJ9Io+Ww==</Q><DP>ds7Zx3iyKRv3rZ7Vv/MMQuDiU3yAOaA9tORbe/29AFiko4dUJT14hAo1I4Y7bgY/6R1nmAsM7i9486VaWQjaGQ==</DP><DQ>sRU

1zbiy7i1Vi09XopKpNmdR2F7tCVJti50KKtKNeZHNBbolkGslqgaM5wPGy/3ZTadKHuV6gaio0E8/m15P6Q==</DQ><InverseQ>YsZNcptrcalrlR5TS+rJ+m9G8+xUIJGGLSB3Czjw

q28rFgXa//avpx05E3FIN0tfAOKJhy84VKElqPNyQyacNA==</InverseQ><D>jaNy3Clxl6QgP3/90xWc0ZCpSh6eKT4GsnwjOrRpKh0DNJNEsaJhtpXmGs/0avsPToOUzVXEJP/iDKTTWtG

1GdkqZp+gaqKbp73RP21Nmd+lZ/S1WvmUTe3Ge5I5FP/7zf9KnTXBm1yLel/9N5UL6o5EncPNjqUt2+oKQ+q7vJU=</D></RSAKeyValue>";

  
因为私匙只存在于自己的电脑中,不会发布到程序中,只要私匙不泄露出去,这种加密方法是相当安全的。

破解RSA签名的唯一方法是替换公匙,用自己生成的私匙生成许可文件。

4 参数保护 Parameter Protection

基于第3条RSA签名技术,签名之后产生的字符串是只读的,在它的基础上我们可以增加许多控制点,比如可使用的用户数,过期时间,最大账套数等。

在我的Enterprise Solution开发框架中,提供基于第3条和第4条为原理的许可保护技术的例子,在一定程度上保护产品不被未授权用户使用。

5 机器硬件识别 Hardware Recognition

为了控制软件不会被客户随意拷贝分发,一方面通过法律合同条文明确禁止,但通常这没有什么卵用,另一方面则必须做硬件识别。在生成许可文件之前,要依赖于客户的机器配置,将客户的机器硬件信息完整的保存到许可文件中,运行时逐条检测,发现有不一致的地方立刻退出应用程序。

.NET 提供了WMI接口用于读取机器相关的信息,参数如下的代码例子:

  private static string GetDiskDriveSize()
        {
            return WmiHelper.GetWmiPropertyValue("Win32_DiskDrive", "Size");
        }

        private static string GetDiskDriveTotalSectors()
        {
            return WmiHelper.GetWmiPropertyValue("Win32_DiskDrive", "TotalSectors");
        }

        private static string GetDiskDriveTotalTracks()
        {
            return WmiHelper.GetWmiPropertyValue("Win32_BaseBoard", "Manufacturer");
        }

三个方法分别读取硬盘大小,硬盘分区,主板制造商,将这些信息组合起来放到一个字符串文件中,即是电脑的硬件信息,再对这个字符串做一个DES对称加密或是RSA签名处理,处理之后,客户的硬件信息看起来是这样的字符串。

lxocnnn7ofk2+Nheb7Qo+cBRDlCbVWHCfVSFG/XnyT3F7q/avyRL3Lj7gotPMtuo41A33AjSryt5a1ydvu7tTOnsOsizy8HJIrP13T5jHbgyHZgZaQk54eGLN3eft5zijKT3hyirZ5w2Mf6mWmv/9F

68jFxsnNh//OUUAVI3lx0=KMw2gRnZ8BqL4lNw4A5j+tuDlvbsj5gp3CGZNbAXlFlGW188uliAZexb6GhcvB0VSwTV37R6NUstT/VT5MJ7wyf/zyyHpa1uHGx4/UziLCAwawnap90BkQWlH1aVz

2lTX3I93iKKYOdAJF0y5TM9njlVvqToj2cBBWLUG+sYXxo=DUjIpSbrp5cl8L//WbIs7ErSX8RBTeVMFO7OCIYoTh7yogVzJNH3D3QZHYKnNfGmJDMSleJSgdLb0GdiWdEgiLTf0uv7lQsoA076

WM5VrtG7O/h0E3DvmisP7OkkuJIMEIpExaM+3GDlIHGvHYRK0nDfzBQM8AXM2k0ue8wj0xY=k5CRv+IkEdB6yZEy65iLXsU0lQT1FbHwSH7LawWBoOZHJt1TwIAajHuqH0AHAWZgRHYDbHCxnlJFv9t

OepsJdNGL6CvjUEnyuNA3RlhKNB6K51rOjIQ1ROKRiy9z+YsbHbJxdbsj3km/kITzfHvoDqQIg4zrTR0XfSn49j0rMkI=C4oBw14/k1OWPzMC1SUe+YxrJtyUqzL2k/cKz/feAhZ0DELbUiCUcbjhHg

+ryg+E7P5Bfy53n3kH5SBud4rVBpRUZGx4xZFPB8eXQ40SUCMxs74cbQRUPh7+zQo6qF/AtrQkXKbzoiZKHCz50n6h/afaa+jwuOplYUx191269w4=RGDYBw6j5VXJO7phILX1zLRcbO3+6SrBuCLEFwk

sitOk/z+OGtFEoIfHD5DZRp9t6GVYtpdI7jPVz7lTV4DL5xfCQ8woJjpqUdB++pYaIw3gx9EL6PD+ucRfLKtiNng6ujKe0r6A51y9eGJRic9p8uAPGSEj8OtNLmO0mVWcwhE=GJg9mdr/YdDMZCVe0WPb3

S8YGKfzdPYj3xJTQtRYdFLV9E6GHzQj8FFgIrxjdoD3n9FGthhF82MTpjS3kOdIyQEc7moienSbzqevcUPs4ZmDwmveH/F4DSynS7JAiPqCcnAj7N4EI/PkXZWAtdHSra2yWBkEBw5PlVhLTLbcLGE=FL

+JSw0yGUIpIZUgq8VRt27e5J+D0vRoEw9t5NKPROysnGw=YN1yhy2reEhQPs30aCnOpNDz2

He2E9re26QBwipNgivHM8Z/FcLk0hjALeiC8zY4Dcn+0PKag6DH7tmIBwTpBus2+ZqjLlgIx7uKMPB49+yPC5qOV8vsJGV/s81xVEA+prgNbh9Sa3TSsBV3qMSyZDEyvkHc+1QbBoLd/1h2WUI=p0/G

lIKMQ7XoRom9njDq5XPn3sj4V8P137v6eDDq7uTpRcTXD/qOWi/IZMcNX56LqVb1PJko0BCUYXa8h0zzEvsmTJNXUzggZlpkzk4EOzq4GekTwM6hXcn0Es/6iZ2J5Et1h5kSOOk1MLZS3cmUHeSRn0js

Ed0O/+L8+qBNpYapf6GL2iYf5j/Qfi+2djOwqCspHawZcBZ/e/WtK0b/0F4=lmHD5BVilXA7KIQk8yma7d4dP5mawdNhMEuYG68sN15SJOUMZlGiFT17rh0Y7Z

54itnjVmhaRVXBsc/LDKYPIwsD+TZBTGDbSOebmxvDe+Jdh6ZLsmGUIdREH4/L19y1713PyJ2r6HYi9v/8GobkWWg4chIKggBhSYUJFP8jj4Q=JHNsEDYacXEIwWhR

nDfiQoWZbrZjmCgF7lo9g4BCTYD0KbLLRKdrDERNPTQs+e3kLf0/fhc0x0BsE/yCuYcnj8rh9/iA08ZUxO+TZkz/p5rseWklWboc45o90q/ZXfuu5f+TCVPnfTXCxMjwdH3

F4I7EotPzweUS/P++YDvHHWA=d8l5s9fNa0fUX4eo9LoHVT4Wb8YbHKDvDW7o1P+wTDykIrOCLoCKklrSGdHjOi8EWw=LDrOGw3pq7rv4L7YoGLaZAmXfRdcw1wp2Zi/Hn2

这样既避免了客户隐私信息泄露,也可以解决当前软件氛围环境下软件分发的困扰。

6  序列号/注册码 Serial Key

相当多的软件还是采取这一传统的序列号保护方法,比如Windows Server 2012的注册码:

NB4WH-BBBYV-3MPPC-9RCMV-46XCB

一组看似无序的数字与字母的组合,对软件保护起了很重要的作用。如果是在软件安装时验证序列号,则破解难度会更大。

序列上面的字母数字组合,可以包含很多信息,比如客户名称,过期时间,最大用户数。将这样的序列号分享给同行的其它客户,一旦软件公司追查起来很容易就能识别这个序列号是否合法。

在我的博客下载工具中用到的一个组件aspNetMHT,它就是采用这个方法来分发序列号的,序列号中包含过期时间。aspNetMHT的序列号看起来是这样的:

SM48Z-FMXGZ-25P67-4ZJKF-GS211-AQYA4-7VHUX-KCF1C-RD4RC-RU7XS-XK8JY-6JT54-M9CX

7  强名称 Strong Name

强名称不是一种代码保护技术,而是程序集标识技术。每个经过strong name签名后的程序集都是唯一的,在运行时可以验证这个文件的签名是否被改动过。

验证强名称的关键地方在于调用CLR中的基础方法:

[DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
public static extern bool StrongNameSignatureVerificationEx(string wszFilePath, bool fForceVerification, ref bool pfWasVerified);

所以开发.NET程序,不仅仅要给程序签名,还需要在运行时验证所给的签名是否被改动过。

.NET CLR支持对程序集跳过强名称验证,不过这样做的风险太大,直接修改了CLR的行为,未见有很多实例。

8 内存保护 Memory  Protection

Delphi XE采取了这种方法,运行时会生成一段验证代码,验证结束后代码销毁,因为验证在内存中进行,不会在硬盘上留下痕迹,破解的难度相对困难了很多。

Win32支持动态加载和卸载程序集,所以Win32 API中有接口LoadLibrary和UnloadLibrary供调用,可实现内存保护。

.NET也支持动态加载程序集,但不支持卸载(unload)程序集,程序集的卸载由CLR控制,这一点给破解内存保护技术提供了方便。

在我的Enterprise Solution开发框架中,将第7条和第8条组合一下,简单的解释如下:创建一个类型定义文件,然后将这个文件用强名称签名,之后将这个签名的程序集经过混淆,字符串加密等处理,附加到启动程序的资源文件中去,运行时,我从资源文件中将此程序集解析释放出来,同时强制验证程序集的强名称,运行类型定义文件中指定的验证方法,实现简单的内存保护技术。

破解这种保护需要知道签名程序集的强名称,字符串加密处理的全流程和相应的键,给破解增加了不少难度。要验证什么和怎么验证都是在我设计的类型定义文件中指定的,启动程序只是一个壳,运用反射调用要验证方法。而且这个经过签名后的程序集是附加到主程序中去的,要替换这个资源文件,也需要一些方法和技巧。

9  源代码混淆 Source code obfuscate

经过编译混淆后的.NET程序集,在运行时依旧可以被调试器附加调试。如果我能将源代码中的敏感字符串替换成乱七八糟的字符串,减少明文的出现,虽然降低了性能,但这样可以增加安全性。比如,我运行时检测找不到许可文件时,抛出以下异常:

string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"license.lic");
if (!File.Exists(path))
  throw new LicenseException("License file not found");

经过源代码敏感字符串替换后的程序如下:

string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"license.lic");
if (!File.Exists(path))
  throw new LicenseException(B("/jNloqd4U59LBT64eX1hb9eO8kYDD7tD"));
经过一个B方法的调用,无法看到异常的明文,增加了破解难度。如果代码中这样的B方法有很多,而且B方法的字符串处理方式各不相同,无疑提高了系统的安全性。

现在市场上有很多JavaScript源代码混淆工具,就是把JavaScript代码的格式打乱,让它不容易读取。

C#源代码也可以采用此方法,不过,读强大的Visual Studio有文档格式化功能(Edit-Advanced- Format Document ,Ctrl + E,D) ,瞬间变为可读的格式。

10  本机代码 Native Code

即将发布的Visual Studio 2015提供.NET Native功能,可将.NET代码编译为本机代码。然而经过近一年的等待,.NET Native目前也是仅仅限定于Windows应用程序商店项目,真正的Windows Forms/WPF/ASP.NET要实现编译为本机代码可能不现实。

这种保护方法的核心是许可验证逻辑放在本机代码中,直接编译成机器码。一般采用Visual C++/Delphi/VB6之类的工具,将重要的算法与验证编译成机器码,这样会增加破解难度。本机代码难于处理的一个方面是.NET Any CPU的问题。当我们设定.NET编译为Any CPU时,CLLRU会依据程序运行的平台(x86,x64)编译为本机代码。

在x64的系统中加载32位的本机代码,常常会抛出无效的程序集异常。破解这种保护的方法可直接修改.NET程序中的调用方法,可以忽略本机代码的逻辑。

相对于前面的几种技术,这种保护技术破解难度更大,要懂的知识点也非常多。

时间: 2024-12-08 03:06:20

大型.NET商业软件代码保护技术 技术与实践相结合保护辛苦创造的劳动成果的相关文章

大型B2C网站高性能可伸缩架构技术探秘

大型B2C网站高性能可伸缩架构技术探秘 2010-07-21 08:51 狂放不羁 JavaEye 字号:T | T 向您介绍大型B2C网站高性能的网站架构技术,包括缓存的使用.应用程序和数据库的拆分.异步通信以及非结构化数据存储等. AD:WOT2014课程推荐:实战MSA:用开源软件搭建微服务系统 在<世界最大的PHP站点 Facebook后台技术探秘>一文中介绍了一个大型SNS网站的技术组成.今天我们继续大型网站探秘,一起来探秘大型B2C网站的架构技术.作为国内最大的B2C网站,其网站架

动态基线技术——技术开创数据库审计新纪元

近年来,随着相关法律法规的完善.国家等级化保护要求,以及行业风险管理和内控指标的出台,安全审计产品慢慢的为大家所熟悉.而近年来数据盗窃和数据泄露等高危事件频发,数据安全也越来越受各大企业和单位的重视.数据库审计就是一款保护用户数据安全的产品. 数据库审计现状与局限 数据库审计相关产品已经问世很长时间了,各大厂商的审计系统的工作原理都基本相似,如旁路数据采集.审计规则.报警等,下图展示为基本工作流程: 其中审计规则功能一直在传统数据库审计系统中占据重要位置,通过配置不同的审计规则,能够识别数据库中

【140810】VC++数字图像模式识别技术及工程实践pdf电子书

VC++数字图像模式识别技术及工程实践pdf电子书,本书介绍模式识别和人工智能中的一些基本理论和相关模型,比如神经网络.聚类技术.线性差别函数等,同时结合了模式识别中的一些经典问题,比如人脸检测.车牌识别.印章识别等内容,从不同角度介绍了这些问题的解决思路. 源码: 电子书下载地址:点击下载 本书源码下载地址:点击下载 [140810]VC++数字图像模式识别技术及工程实践pdf电子书

电子书 Python自动化运维:技术与最佳实践.pdf

本书在中国运维领域将有"划时代"的重要意义:一方面,这是国内一本从纵.深和实践角度探讨Python在运维领域应用的著作:一方面本书的作者是中国运维领域的"偶像级"人物,本书是他在天涯社区和腾讯近10年工作经验的结晶.因为作者实战经验丰富,所以能高屋建瓴.直指痛处,围绕Python自动化运维这个主题,不仅详细介绍了系统基础信息.服务监控.数据报表.系统安全等基础模块,而且深入讲解了自动化操作.系统管理.配置管理.集群管理及大数据应用等高级功能.重要的是,完整重现了4个

《SaltStack技术入门与实践》—— 实践案例 &lt;中小型Web架构&gt;3 Memcached配置管理

实践案例 <中小型Web架构>3 Memcached配置管理 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Memcached介绍 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态数据库驱动网站的访问速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通

蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践读后感

架构的提出主要就是解决人的问题,在讨论此架构之前,先谈一下周二看完“梦想改造家”的感想. 在阅读此文章后,大概对架构有了浅浅的了解. 什么是架构? 1.根据要解决的问题,对目标系统的边界进行界定. 2.并对目标系统按某个原则进行切分.切分的原则,要便于不同的角色,对切分出来的部分,并行或串行开展工作,一般并行才能减少时间. 3.并对这些切分出来的部分,设立沟通机制. 4.根据3,使得这些部分之间能够进行有机的联系,合并组装成为一个整体,完成目标系统的所有工作. 这是通过阅读此篇博客,得出来的对“

嵌入式技术基础与实践-学习札记(二)

嵌入式技术基础与实践-学习札记(二) 异步串行通信的通用基础知识 串口通信接口,简称"串口".\(UART\)或\(SCI\).\(MCU\)中的串口通信,在硬件上分为发送线\((TxD)\).接受线\((RxD)\)和地线\((GND)\):在通信方式上,属于单字节通信,是嵌入式开发中重要的打桩调试手段. 串行通信的基本概念 "位"\((bit)\)是单个二进制数字的简称.在计算机中,通常一个信息单位用\(8\)位二进制表示,成为一个"字节"\

.NET 产品版权保护方案 (.NET源码加密保护) (转载)

说 明:你希望自己用.net辛辛苦苦做出来的软件被人轻易破解吗?你希望自己花了大量人力物力用.net开发出来的产品被竞争对手轻易获取核心代码吗?这是 一篇比较详尽地介绍如何保护自己的.net源代码的文章,如混淆.加密和强名称等,出于保护原作者的角度,所以本人没有掐头去尾作为自己个人的文章,正因 为是全文转载,所以并不代表本人完全赞同作者的全部观点,也不代表本人本人提作者提到的软件做广告,这一点请大家注意,不要认为我为别人做广告而骂我,其 实我根本不认识作者.一.   前言 大家好,我是康世杰,大

[C#防止反编译].NET 产品版权保护方案 (.NET源码加密保护)

[C#防止反编译].NET 产品版权保护方案 (.NET源码加密保护) 标签: .net加密产品c#dll工具 2011-03-24 21:06 27009人阅读 评论(13) 收藏 举报 分类: C#/.NET(4)  Decompile(6) 说 明:你希望自己用.net辛辛苦苦做出来的软件被人轻易破解吗?你希望自己花了大量人力物力用.net开发出来的产品被竞争对手轻易获取核心代码吗?这是 一篇比较详尽地介绍如何保护自己的.net源代码的文章,如混淆.加密和强名称等,出于保护原作者的角度,所