软件防破解方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

共享软件如何防破解
2008-06-02 16:18
共享软件如何防破解
中文部分
1.共享软件如何防破解
首先要说的是任何软件都会被破解,下面所讲到的方法只能起到一定的保护作用,延长破解时间。

如果想永远都不被破解,那么只有一个办法:不要把它做出来。

让我们来做出最简单的注册验证算法。

1、简单的讲,就是一个数值(a)通过某种运算方法(c)变成另一个数值(b)方法。

举个例子,a1=b1 xor c1,a1就是a,表示用户名;b1就是b,表示注册码;运算部分x xor c1就是运算方法c。

根据用户名a1通过上面的表达式生成b1(当然运算方法c只能你自己知道),用户得到a1和b1,输入到软件中,如果它是成立的,表明注册成功,当然不成立则表示注册失败。

上面的例子非常简单,主要说明注册的原理。

当然用它做注册算法,普通的用户是无法破解出来,但对于一些喜欢破解软件的人来说当然太简单了。

下面让我们做出一个复杂的注册算法。

2、更为复杂的算法--RSA,这种方法和上面的方法原理基本一样,但可以生成更为复杂的注册码,其用法和源代码可以在网上找到。

注意的事是选择的参数不要太长,如果太长很麻烦,也不要太短,太短很容易被破解,用多长的注册码最好呢,以目前主流电脑上一秒种完成验证的时间长度为最好。

用RSA做注册算法理论上是做不出来注册机,但事实上仍然可能做出注册机。

所以我们把它和一些其它方法配合使用。

3、不要忘了你自己也可以做注册算法的,当然你不可能做出超过RSA的算法,但你的算法仍然是很有威力的,原因在于你的算法是独特的。

如果破解者对你的算法非常熟悉,再好的算法也没用,但如果破解者对你的算法不清楚,即使很容易,他也要思考一下。

好了,我相信你已经做出了一个类似a1=b1 xor c1的注册算法,我们的软件现在不会那么容易就被破解了。

现在告诉你一个很不幸的消息,由于你的独特算法,破解者已经对你的软件很感兴趣了。

那么我们不得不使用更好的方法来保护你的软件。

3、我们可以使用更多算法来增加难度,如何增加呢?首先不要使用明码比较,也就是不要直接用a1与b1 xor c1比较,而要使用a1 xor c1和b1 xor c2比较的方法(其中a1 xor c1和b1 xor c2都是运算方法c),因为这样破解者就不容易做出注册机。

另外,要许多算法同时使用,比如说a经过算法c得到d,d通过算法e得到f。

这样破解者就不得不把所有的算法都破解出来才行。

看来要破解你软件的人不得不搞清你所有的算法,而不单单是其中的一种。

可为什么还有那么多软件被破解?因为你的算法再难,破解者总有一天也会搞清楚了它们,我们可不能让他们看清楚我们的算法。

那只有一种办法。

4、化整为零。

由于破解者在破解时一般都是分析你软件的代码,因此只要找到软件中负责注册验证的部分,你再高明的算法也无济于事,但如果它找不到你用于注册验证的全部算法就另当别论了。

代码都在程序中,如何使破解者找不到呢?非常简单,在软件开始进行验证时不全部验证,而是保留一部分,这就要求你的注册码必须在原先已有的基础上再加入一些新东西。

我们现在新加入一部分注册码,我们把它们加在原来注册码的后面,你生成的注册码前n位都是原来的部分,它们由原来的验证部分-…机枪手‟来处理;而另外新加入的n位注册码是由你刚刚加入的新算法负责处理的,我们称这部分新加入的算法为狙击手。

那么你最好让你的狙击手可以独立使用,比如可以让其中的1个狙击手瞄准用户名的第一个字母,如果这个字母是在a到g的范围内则狙击手所负责的这位注册码为1时表示正常;否则就代
表注册失败。

这样新加入这部分注册码自然可以很简单分成了n个独立的部分(注意的是我们只需要每一个狙击手都可以独立使用,不需要它很复杂,越简单越好)。

你可以把你狙击手放到你软件的每一个脚落。

当然破解者仍然可以找到它,但在茫茫的代码中找到我们不止一处的验证算法可真够累人的了。

我们可以将它们的一部分放入核心代码,另一部分放入普通代码中,比如帮助按钮中。

恭喜你,现在你的程序已经很完善了,一般的破解者已经不是你的对手了。

哈哈哈。

可你不要忘了,任何软件都会被破的,你只是隐藏了你的某些代码,但如果破解者愿意在你的软件上花几周甚至几个月,总会找到你所有的狙击手。

我不得不再次为你的程序担心起来,可你的算法无论怎么做都跑不出你的软件。

怎么办?有了。

5、如果更新注册码那么原有的破解不就失效了吗?就这么办,我们更新软件的注册算法,因为现在几乎所有的网站都不提供原软件的下载服务,它们都是把用户连接到你的网站上下载,那么我们修改用于生成注册码的算法c也可以防止破解了,当然我们必须每次都要发信通知我们的用户新更新的注册码,这有点辛苦。

不过是累你,不是累我,呵呵
是不是感到每次更新注册码都很累人,没关系,让我们使用一点小魔法吧。

6、现在我们还要保留软件中的机枪手,但把一部分狙击手从程序中清除掉,清除的这些狙击手我们称它为影子狙击手。

当然,这时你要假设影子狙击手仍然存在(当然影子狙击手已经不存在了),你仍然生成注册码给你的客户,当然这个注册码中一部分已经是没有意义的数字了,但你仍然要按影子狙击手存在的规则生成,而破解者可以无视影子狙击手的存在,这使得你的软件更容易被破解(注意只是容易了一些,而不是可以随意解破)。

现在你的软件被破了,和我们担心的一样,我们不能坐以待毙,现在是影子狙击手出击的时候了,在你的软件增加一个影子狙击手,它的出现使得原有的破解失效,因为破解者只能看到机枪手和普通狙击手,但却无法发现不存在的影子狙击手。

主动权在我们手上了,我们可以随时升级软件而不用向每个用户发注册码。

如果你愿意,你可以准备20个影子狙击手,这至少可以用上一年。

如果你担心注册码太长影响输入,你可以把注册码做成一个reg文件,这样用户收到注册文件后直接点击就可以把注册码写入系统注册表中。

2. 合理利用破解的办法
发布版本中添加隐藏限制,短期不会生效,等用户用上手了之后。

在特定情况下提示不能使用。

如果你的东西写的好,肯定会有人买的。

然后给一个完整版本的下载连接给用户。

不过需要能够监视下载日志,避免完整版本泄漏。

举个例子:你写数据库相关的,那么在SQL语句上面做手脚,比如where 后面加一个(select count(*) from """"" ) < 1000
这样那个表中数据小于1000条的时候,工作正常,等他用到一定时候了。

数据都进系统了,欲罢不能的时候,只好买了。

这样的限制是没有办法破解的,他没法改你的SQL语句。

哈哈。

然后,写一个简单的加密手段,让别人破解。

然后让别人传播。

越多人用越好,这就是在帮助你的共享软件了。

实在没有人破解,你就自己写一个注册机去0Day上发布。

呵呵。

一个方法,抛砖引玉。

3. 关于防止破解-转贴自csdn
刚刚Copy了CXU兄的高论,不知道是否对你有用,接住!
破解永远比加密容易,唉!
假设你的注册部分有300行,你可以分成30个inline函数调用(一定要inline),func1(),func2()... func30(). 将他们随意放到程序的各个部分,一定不能放在一起(自己能找
到就行了)。

不要用Memcpy等常用系统调用拷贝注册码,近可能自己写,像Memcpy很好写,性能差点无所谓。

经过编译后inline函数展开,注册部分和其他代码混在一起,他要写出注册机就像大海里捞针,在几十万甚至上百万汇编代码里找出有用的注册部分。

另外注册码也不要放在一起,假设你的注册码是12位,千万不要用一个12位的数组放注册码,你可以在程序的不同位置定义12个全局字符变量,每个放一位,这样注册码在内存就不连续了。

最好再加密处理一下(简单的字符异或就可以),验证时再解密。

非技术方法在中国几乎没有用,这么多有钱有实力的公司的软件都被盗版,你个人还能有什么办法。

忘了说了,只要破解者找不到你验证结束的地方,暴力和Loader破解也没有可能。

很重要的一点是不要用连续内存保存验证用到的变量,尽量将用到的验证临时变量分散定义在程序的不同处,再在验证中,不断转移一些值到其他变量中,对付暴力和Loader会比较有效。

没有必要用复杂的加密算法,更容易成为追踪的目标。

只要你将注册部分隐藏的足够好,也没有漏洞,你花1天写的加密算法,破解者可能会花100-1000倍的时间破解。

大部分人都会放弃。

你将注册做在一起,就像将你的财宝放在现代保险箱里,虽然非常坚固难以解密,对于开锁高手两分钟就打开了。

而古代海盗用的方法是将财宝埋在海岛上,这样没有藏宝图,对应高手和低手都只有一条路,拿一把铁撬挖,可能要挖一生。

程序有那么多代码,你将注册部分藏在里面,藏的好就如同将财宝埋在海岛里。

那些所谓的Crackme只是给高手玩儿的现代保险箱而已,用原始的方法可以达到同样效果。

这是农民的方法,我也不会汇编,高深的反破解都不会。

程序一出来就被0day破解了,而且被暴力破解了两次,为了对付0day, 只好想了这么一个农民的方法,结果发现简单的东西比复杂的更有用,古老的方法似乎比现代的更有效。

对于一些比较专业的破解者采用上面的方法也是很有效的但是,还是要避免一些低级失误例如:
不要在内存中直接出现注册码和明显的注册码比较部分
不要给用户太多的有关注册验证的信息
不要接收到注册码后立刻就进行比较,在软件的不同功能处实现验证时的好处还有就是不会立刻执行到验证代码
注册码可以分多次验证可以分成几部分验证可以分成几层验证
验证时,可以尽量多执行一些无用的操作,加上一些象递归之类难于调试追踪的代码,但在其中要穿插实现软件功能的代码否则人家直接就跳了过去…………
反正就是越不引人注意越好:)越乱越好
……………………
这些在一般的破解教程里也都会有的
//如果能找到几个不常见的加壳软件最好!:)
只要能避免这样的低级错误,再加上上面的那些不太难实现的方法可以应付一般水平的破解了//因为大家都怕麻烦:)
只要这些措施得当,一般的破解者都会知难而退:)
不过如果你的软件太好了………………
你还是找一个专业人士与你一起写吧,很麻烦的:)
btw:我只是以前对破解有些兴趣,所以找过些资料懂的其实不多而且没做过破解的事,不要误会我的人格哦:)嘿嘿
4. 共享软件开发常识
一、献给某人的话:
首先说一下,这篇文章仅仅是一个入门、是一个讨论,我也仅站在门外汉的角度上对共享软件开发所需要注意的几个方面进行罗列,文章并不能将所有需要注意的环节写清楚,因而如果你认为此文不好,大可不看。

另外一点,我上面已经提到了,这是给刚刚接触共享软件开发的人阅读的,在他们看来也许能够有些收获,而在于高手看来,这篇文章中所述也许并不值一提,但是请不要忘记,新手在学习类和继承的时候,感觉是多么困难,因而请不要用你那种评委般近乎苛刻的目光对本文进行挑剔。

二、开发需要整体规划:
我们在做大多数事情的时候都需要进行整体规划,共享软件开发也是如此。

如果你希望做一套功能完善、健全,能够经得起时间考验的软件,就一定要在开始写代码之前做一个整体的功能列表。

这个功能列表至少应该包括软件的所有功能、功能细节、功能实现的方法,并且为日后可能加入的功能做好充分的准备工作。

为什么要这么做呢?原因很简单,如果你在编写的软件中包含多个功能,而功能之间又相互存在某些联系,那么如果你没有进行很好的规划,在编写代码的过程中你就会发现自己的思路越来越乱,直到最后几千行的代码到达“牵一发而动全身”的混乱局面,让你根本就没有可能对软件继续开发下去,结果可想而知。

举个例子,不知道大家知不知道网景公司的浏览器,曾经就因为混乱的开发模式而最终走向了死亡。

那是一家大公司,开发团队的程序员很多,而程序员之间没有达到很好的默契,自己做自己的,做到最后竟然把一个功能强大的浏览器做死了。

个人编写共享软件虽然有别于团体开发,然而也可以看作是一个“大脑内部的团体”,你在编写软件的每一个功能的时候,都要充分考虑到其他功能对此可能带来的影响,因而开始之前的规划尤为重要。

我曾经编写软件并没有注意这一点,因而一个软件通常要经过两三次的失败,然后在脑子中有了软件的整体印象,才能最终完整,与其这样反复,不如开始就作出完整的需求分析,所谓磨刀不费砍柴功。

三、建立漏洞记录和解决记录:
在编写程序的过程中,共享软件作者也许只有一个人,而所要进行的工作却非常多,美化、编码、调试等等,如此多的工作要由个人独自完成,脑子必然混乱,不要在这里说我牵强附会,谁敢说自己编写程序的时候脑子从来是清醒的?
因而无论是发现了程序中的错误,还是有了更好的想法,都要将它记录下来。

如果是程序中的错误,至少应该记录下错误产生的原因、操作过程,并且把错误的解决方案也一同写出来。

这样做并不是我个人的经验,任何正规程序开发团体都要建立一个“已知漏洞列表”的漏洞数据库,这是为多人之间配合而设立的此表,而我们虽然只有一个人,但是这个记录也是必不可少的。

想想看,如果你今天写程序已经写到深夜,而正当你准备睡觉的时候,突然想到了程序中的一个错误,如果你没有把这个错误记录下来,等第二天你是否还能记得昨晚临睡觉前所发生的事情?你又要和我叫真,非要说你能记住?好吧,那么假如是30个错误呢?假如你第二天有事情要出去,写代码的工作一定要两个星期后才能继续呢?不要说我走极端,在你看来多么不可能发生的事情也有可能发生,好记性不如烂笔头,将问题记录下来是最牢靠的。

四、注释要内外兼修:
也许有些人看到这条建议又要倚老卖老:我从来只把注释写在代码里面。

我不和这些人顶撞,他们既然能说出这种话,说明他们没有遇到过苦头。

但是亲爱的朋友们,如果你们还没有什么习惯可言,那么从现在开始要养成这条习惯。

写程序一定要写注释,同时还要写“外部注释”,也就是说你的代码中嵌入注释,同时还要为整个程序或者某个功能模块写份详细的外部说明,这份说明也需早在你做整体规划的时候就制作出来了,如果没有,那么就请在完成每个函数之后将函数的作用、调用方法、实现方法都写出来,写出来的目的无非就是为了更好的维护。

假如你不这么做会怎么样呢?我们做个假设:你的软件经过了3个月的搁置,现在又要继续进行开发了,这次开发的主要目的是完善程序。

当你打开了代码之后,你要在代码中不断的阅读自己3个月前编写代码的时候遗留的注释,那写注释也许只是只言片语,从这种断断续续的言语中,你是否还能够回忆起3个月前究竟是为什么写的这些注释吗?
而假若你拥有完整的函数说明,那情况就大不一样了,你只要阅读完整的说明文字,就能够很快的回忆起自己的代码是如何编写出来的。

什么?你编程已经达到融会贯通的程度了?那你还看这篇文字做什么?
五、还说注释:
注释的重要性我就不说了,要说的是如果你的代码中某个地方进行了修改,千万不要忘记加上注释,并且暂时不要删除原来的代码,将原来的代码也用注释注上,这里要说明为什么进行更改,原来的代码存在什么问题。

如果你在某个地方进行多次更改,就为每一个更加加上注释和日期,因为我说过,你的代码中的每个函数见也许都相互关联着,它们之间的联系很可能达到牵一发动全身的效果,因而尽可能不要将自己辛辛苦苦编写的代码随便删除,也许那一天你会发现原来曾经认为有问题的代码还要使用,到那个时候想单凭记忆找回来就有些困难了。

六、保留软件的重要版本:
除非你的硬盘很小,否则建议将代码的重要版本都保留下来,原因和上面第5条差不多,因为你不知道什么时候会需要以前的代码,做好备份工作是非常重要的。

我曾经参与学校内的某个项目,虽然说是个非常简单的项目,但是每天晚上的时候,我们都要将整个程序的所有代码、文档用刻录机做成光盘,并写上日期保留起来。

虽然说每天的任务之向前推动了一点点,但依然是如此“浪费”的将曾经已经保存过的代码在保存一便,这样做的原因还用说吗?说说吧,原因就是一旦在哪一天你的程序出了问题,直接将上一次的保存拿出来,然后继续开发就可以了。

但是如果你每天保存的都只是“当天新写的代码”,那么你就会发现你还要经过一步或多步的“还原”操作,你能保证自己所有新写的代码都不会对原来的代码进行任何修改吗?
另外保存软件的早期版本还有一个妙用,那就是你在制作过程中也许会发现自己的代码有不同的发展方向,这是在一开始并没有发现的。

从某一版本开始,你就已经开始策划另一个软件了,那么只要将那个“分支版本”拿出来,从那里开始继续你的工作就可以了。

七、善用免费的公共代码:
也许你有这样一个想法:我要自己完成程序中所有的代码。

那样的话我要说你有些傻。

网络上有很多免费的代码可以直接应用到你的程序中,当你发现自己正需要某个功能的时候,先到网上找找有没有适合自己的代码,如果有直接用就是了。

记得曾经听过一个笑话,高级程序员和初级程序员遇到相同的问题需要编程解决,初级程序员会查阅资料编写代码,高级程序员会打电话问其他程序员要一份代码,两者不同之处在于后者懂得了“拿来主义”。

做为共享软件开发人员,大多数是通过程序解决实际问题,这样就
好像搭积木,只要你手里“积木”够多,通过不同的组合就能够写出多个优秀的程序。

而前者则更好象是用原始的木料制作积木,做了半天也没有成型的产品,那么前者所做的工作并不是制作软件,而是在制作零件。

当然对于此点在标题中已经鲜明的指出“善用”,便写程序不要一味的编写代码,也不能完全“拿来”,如果是完全的拿来主义,那你不如直接拿一个现成的软件通过修改资源界面痛快。

八、结语:
天下文章没有任何一篇能涵盖古今,即使恢弘的《史记》也无法道尽历史沧桑,更何况不足万字的这么一篇短文?因而你无法通过这篇文章掌握所有共享软件开发需要注意的事项。

另外,对于文章而言,只是一家之词,其中错误难免。

但是正象余秋雨先生所说,读文章重在正篇的意义,而不应该拘泥于某些微不足道的问题上。

如果楞有人在这篇文章上咬文嚼字,那也只能用可笑两个字来形容。

我希望能够有人来一同交流讨论,总结个人的心得体会,同时我也希望大家不要迷信这种理论性的总结,因为每个人的实际情况不同,在你真正开始进行某项工作的时候,也许你会发现他人的总结并不适合你,因而对于指导性的讨论并没有过多的意义,重在实际应用。

5. 怎么防止软件被破解
Visual CHM 推出已经3个月了,2.0版后我见过几个破解版本,但是到现在都没有一个成功的破解版本,很多朋友问我是怎么加密的,我现在决定公布一下 2.X(每个版本的加密方法都是一致的)采用了什么方法防破解。

算是对中国共享软件作的一点点微小贡献吧!
首先要防止被写出注册机,你的软件的注册机一旦被发表,那你完全有理由做成免费软件了。

防止被写出注册机最简单的方法就是保护你的校验算法,具体的做法就是千万别使用校验函数,把你的校验算法嵌入功能代码里是比较保险的,这样破解者至少要花很多精力去研究那一部分是校验算法。

当然这还不够,你还可以把检验算法分散到2个地方,当然更多地方效果会更好,只是将来代码维护起来会很麻烦的。

我想如果不是象WinZIP、ACDsee 这样的大牌软件,很少会有人去找出检验算法了(太头疼了)。

做完了这些,你还可以用Aspack,upx之类的压缩执行文件工具做进一步的保护。

完了吗?还没有,我这里还有一些更用的东西。

现在的脱壳工具太多了,可以说是没有脱不掉的壳。

那怎么办?我这里有一段Delphi5代码更进一步的保护你的软件:
procedure TForm1.FormCreate(Sender: TObject);
Var
exefile :file of byte;
ConstStr:byte;
begin
AssignFile(exefile, Application.ExeName);
reset(exefile);
filemode := 0; //读写属性设置为只读,这样才不会出错!
seek(exefile,5); //exe文件的第5+1个位置(自己设要查找的位置)
Read(exefile,ConstStr);
//showmessage(inttostr(ord(constmi)));//看看实际是多少(假定为56)
closefile(exefile);
if ConstStr <> chr(56) then exit;//如果第5+1个位置的值不是56退出(说明你的软件被改动了)end;
这段代码随时随地都可以加入,真的非常方便。

不过你要注意的是,万一用户的机器染上了病毒怎么办。

保护了检验算法,还要保护什么呢?校验算法只是让Cracker很难写出。

相关文档
最新文档