列举工作以来遇到的各种类型的软件所采用的代码保护技术,只讲原理不涉及技术细节实现,以避免产生法律问题。有些朋友说直接把代码放在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程序中的调用方法,可以忽略本机代码的逻辑。

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

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

  1. 转:Android 2.3 代码混淆proguard技术介绍

    ProGuard简介 ProGuard是一个SourceForge上非常知名的开源项目.官网网址是:http://proguard.sourceforge.net/. Java的字节码一般是非常容易反 ...

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

    大型B2C网站高性能可伸缩架构技术探秘 2010-07-21 08:51 狂放不羁 JavaEye 字号:T | T 向您介绍大型B2C网站高性能的网站架构技术,包括缓存的使用.应用程序和数据库的拆分 ...

  3. 可能对Flutter应用程序开发有用的代码/库/专有技术列表

    当我开始使用Flutter实施该应用程序时,我开始担心“如何最好地编写?”以及“如何使其更好地放置?”. 在这种情况下,您将需要参考GitHub上发布的代码和应用程​​序. 因此,我收集了似乎对Flu ...

  4. 如何快速读懂大型C++程序代码

    要搞清楚别人的代码,首先,你要了解代码涉及的领域知识,这是最重要的,不懂领域知识,只看代码本身,不可能搞的明白.其次,你得找各种文档:需求文档(要做什么),设计文档(怎么做的),先搞清楚你即将要阅读是 ...

  5. Atitit.ide技术原理与实践attilax总结

    Atitit.ide技术原理与实践attilax总结 1.1. 语法着色1 1.2. 智能提示1 1.3. 类成员outline..func list1 1.4. 类型推导(type inferenc ...

  6. 腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践

    1.概述 本文来自腾讯视频云终端技术总监rexchang(常青)技术分享,内容分别介绍了微信小程序视音视频和WebRTC的技术特征.差异等,并针对两者的技术差异分享和总结了微信小程序视音视频和WebR ...

  7. XPages访问关系型数据库技术与最佳实践

    XPage 对于 Domino 开发人员的一大好处就是能够很方便和高效的访问关系型数据库.本文通过实例代码展现了在 XPage 中访问关系型数据库的具体步骤 , 同时讲解了一些在 XPage 中高效访 ...

  8. 转 Redis集群技术及Codis实践

    转  Redis集群技术及Codis实践 转自 :http://blog.51cto.com/navyaijm/1637688 codis开源地址:https://github.com/CodisLa ...

  9. 《SaltStack技术入门与实践》——执行结果处理

    执行结果处理 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Return组件可以理解为SaltStack系统对执行Minion返回后的数据进行存储或 ...

随机推荐

  1. catalina.properties

    追踪 startup.bat set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat" call "%EXECUTABLE%&q ...

  2. android目录介绍

  3. Python学习之路--面向对象

    1.面向对象概述 面向过程:根据业务逻辑从上到下写垒代码  函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可  面向对象:对函数进行分类和封装,让开发“更快更好更强...”  面向 ...

  4. Server Tomcat v6.0 Server at localhost was unable to start within 45 seconds问题

    错误:Server Tomcat v6.0 Server at localhost was unable to start within 45 seconds. If the server requi ...

  5. Inno Setup 下载安装

    Inno Setup 是一个免费的 Windows 安装程序制作软件.第一次发表是在 1997 年,Inno Setup 今天在功能设置和稳定性上的竞争力可能已经超过一些商业的安装程序制作软件. 目前 ...

  6. .net与mono的那些事

    米格尔·德伊卡萨在.NET的文档于2000年10月发布时就马上对.NET产生了兴趣.在查看字节码解释器后,他发现对于元数据(metadata)没有相应的说明文档.2001年2月,德伊卡萨在.NET邮件 ...

  7. H5 缓存机制浅析 移动端 Web 加载性能优化

    腾讯Bugly特约作者:贺辉超 1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5 引入的离线存储, ...

  8. 如何用MediaCapture解决二维码扫描问题

    二维码扫描的实现,简单的来说可以分三步走:“成像”.“截图”与“识别”. UWP开发中,最常用的媒体工具非MediaCapture莫属了,下面就来简单介绍一下如何利用MediaCapture来实现扫描 ...

  9. Java虚拟机5:Java垃圾回收(GC)机制详解

    哪些内存需要回收? 哪些内存需要回收是垃圾回收机制第一个要考虑的问题,所谓“要回收的垃圾”无非就是那些不可能再被任何途径使用的对象.那么如何找到这些对象? 1.引用计数法 这个算法的实现是,给对象中添 ...

  10. 人人都是 DBA(XV)锁信息收集脚本汇编

    什么?有个 SQL 执行了 8 秒! 哪里出了问题?臣妾不知道啊,得找 DBA 啊. DBA 人呢?离职了!!擦!!! 程序员在无处寻求帮助时,就得想办法自救,努力让自己变成 "伪 DBA& ...