打印本文 打印本文  关闭窗口 关闭窗口  
保护知识产权 共享软件防破经验
作者:陈鹏  文章来源:eNet  点击数  更新时间:2009/9/11 19:28:03  文章录入:陈鹏  责任编辑:陈鹏

编者语:共享软件一直是软件的重要组成部分。开发者以极大的热忱投入其中,用自己的“汗水”和“心血”换回应得的报酬,然而,有一个问题一直让大家头疼,那就是软件破解。

  在软件的破解方法里,“暴力破解”(俗称“暴破”)算得上最为普及且行之有效的方式了。经过“暴破”后的软件拥有授权版本才具备的所有功能。笔者也是一位软件开发者,对于这种盗窃“知识产权”的行为深恶痛绝,因此将一些个人的防“暴破”经验共享出来,与大家交流和学习。


  一、认识“暴破”手段


  首先探讨一下破解组织的“暴破”手段。无论是技术多么精湛的组织,他们都会遵守以下的基本步骤来完成“暴破”。


  1.判断软件是否加“壳”。
  2.运行“暴破”工具,显示软件的源程序。
  3.进行软件源程序的分析,找到注册信息语句。
  4.修改注册信息的源程序,让注册功能不再生效,或者让注册码显示出来。


  从上面的步骤中不难看到,软件之所以被轻易地“暴破”,主要还是因为开发者粗心大意,或者编译技术不完善导致源程序存在诸多漏洞而造成的。只要开发者在编写源程序时设置多层障碍,便可以在一定程度上防止“暴破”(笔者并不敢夸下“海口”,说自己的方法可以完全杜绝“暴破”,但起码可以增强软件的注册保护性能)。


  二、防止“暴破”的方法


给软件“加壳”和添加反跟踪代码


  1.软件发布前需要将可执行程序进行“加壳”处理,使其他人无法直接修改源程序。“加壳”可以利用很多优秀的“加壳”工具,且最好采用两种以上的工具对程序进行“加壳”。此外,还应尽可能地利用这些工具提供的反跟踪功能。


小提示:
  开发者最好是设计自己的“加壳”方法。如果采用现成的工具,建议不要选择流行的,因为这些工具已被广泛研究,有了通用的“脱壳”办法。


  2.除了“加壳”处理外,最好在软件开发的过程中嵌入反跟踪代码,防止“暴破”工具找到软件的注册漏洞。
软件的反跟踪方式较多,比较常见的有利用花指令随机改变关键代码的内存地址。下面看一个例子。

  程序最初的源代码如下:
start_:
xor eax,1
add eax,2
jmp label1
label1: xor eax,3
add eax,4
xor eax,5
end start_


  先将源程序进行编译,然后用W32Dasm进行反汇编,得到的反汇编结果与源代码相同。接着我们将上述源程序作如下修改:
start_:
xor eax,1
add eax,2
jnz label1 \\注意这里,用两句条件跳转代替了:jmp label1
jz label1
db 0E8h \\注意这个无用的字节和源程序的区别
label1: xor eax,3
add eax,4
xor eax,5
end start_


  再把源程序进行编译,然后用W32Dasm进行反汇编。由此得到如下结果:W32Dasm反汇编的结果和事先写的汇编指令不一样,从反汇编的结果中已经无法理解程序的“真实”功能了。这是因为上述改动在W32Dasm的反汇编工作中做了“错误指引”,从而使得它犯下错误。

  增加注册认证算法的难度


  注册认证部分的源程序是“破解组织”进行“暴破”的突破口,注册认证算法的难易度直接影响软件被“暴破”的几率。增加注册认证算法的难度可以从以下方面入手。


  1.选择相对复杂的算法进行注册开发(现行的加密算法中可以选择RSA算法)。当然,最好的方法还是自己编写算法。如果采用一些常见的密码学的算法,这跟引狼入室没有多大的区别,毕竟这些常见的算法已经被“暴破”高手们研究透彻了,哪里还有安全可言,而采用自己设计的算法就不同了,人的思维有所区别,这就在很大程度上增加了破解的难度。


  2.检查注册信息代码编写得越分散越好。如果将注册模块编写到一起,就好比将财宝放在保险箱里,虽然非常坚固难以打开,但对于开锁高手而言,一旦打开它,里面的财宝尽失。具体的操作方法是:软件在注册时,不要让其调用同一个函数或判断同一个全局标志。


  3.在检查注册信息的时候插入大量的无用运算代码。这样做的目的是误导解密者,让他们以为找到了真正的破解方法,在尝试以后却发现无效。这好比战场上的士兵用“迷彩服”与稻草来伪装自己一样,敌人很难发现他们到底在哪里。


增加注册信息步骤


  增加注册认证算法的难度后,还需要在注册信息的步骤上下功夫,以此巩固防“暴破”的城墙。


  1.可以使用优秀的随机数算法来让软件的注册方式带有随机性。譬如,除了启动时检查注册码外,还可以在软件运行的某个时段随机检查注册码。


  2.采用一机一码的保护方式。这样设计以后,一台计算机上的注册码就无法在另外一台计算机上使用,就像很多软件以机器码为基础生成注册码一样。


  3.删除试用版的功能代码。如果试用版与正式版是分开的两个版本。在试用版中不要仅仅锁定相关的菜单,而是彻底删除相关的功能代码。


增强软件自身源程序的完整性


  在共享软件的开发过程中,除了对局部的注册代码进行加强外,还必须要考虑软件本身程序的完整性。可以通过以下方面进行加强。


  1.增加对软件自身的完整性检查。这包括对磁盘文件和内存映像的检查,防止有人未经允许修改程序以达到破解的目的。


  2.隐藏注册信息代码。不要采用例如“IsLicensedVersion( )”和“key.dat”等常见的注册代码名称。另外所有与软件保护相关的字符串都不要以明文形式存放在可执行文件中,最好是动态生成。


  3.尽可能少地给用户提示信息,因为这些蛛丝马迹都可能导致解密者直接深入到受保护的内核。可以设计软件为当检测到破解企图后,不立即给用户提示信息,而是在系统的某个地方做一个记号,经过一段时间后软件自动停止工作。


  4.不要依赖于“GetLocalTime( )”和“GetSystemTime( )”这些常见的函数来获取系统时间,可以通过读取关键系统文件的修改时间来得到系统时间信息。


  5.如果采用keyfile(钥匙文件)保护方式,则其尺寸不宜太小,可将其结构设计得比较复杂,在程序中不同的地方对keyfile的不同部分进行复杂的运算和检查。


小提示:


  上面提到的一些信息语句是“暴破组织”最基本的突破点,如果在软件开发的过程中,非常显眼地给出了这些提示,无疑慢性自杀。对这些“暴破”高手来说,有了这些提示,软件必将毁灭性的打击。所以开发者必须慎重,不要犯下如此低级的错误。

  共享软件的防“暴破”的确是一项复杂而艰巨的任务,我们需要对“暴破”者的思维模式进行细致的研究。先假设暴破者可能采用的“暴破”方法,然后对症下药,对某些薄弱环节进行加强。可以说“暴破”跟防“暴破”是一场智力游戏,就像“猫捉老鼠”一样,虽然“暴破”者无孔不入,但只要开发者采用的“防暴”方法得当,即可将他们拒之门外。
打印本文 打印本文  关闭窗口 关闭窗口