前 言
本文为全中文编写,不需要有 PE文件格式知识,不需要掌握汇编或 C语言的编程技巧,一些加密算法直接由易语言提供,特殊的加密算法大家可以翻译 C语言代码、汇编代码或 VB代码。
本文中将“ Cracker ”一词翻译为“奸人”,意为“奸邪小人”之义。本人对破解者一向深恶痛绝,有人说中国的软件发展中破解者有一份功劳,可我说这话不对,看看因盗版而产生的微软对操作系统及软件业的垄断,国内软件业在盗版的夹缝中生存……,如此下去,软件作者没有收益,将不再会有优秀的软件推出。防止盗版,匹夫有责,我想通过本书的推出可以加强易语言用户的加密能力,将盗版杀死在大家共同的手中。
随着采用易语言编制程序的人们越来越多,写一个软件易被奸人破解的情况也越来越多了,有个别用户甚至于怀疑易语言是否有安全性。从技术性上来说,我只能说加密技术与编程语言无关,一个编程语言的安全性一般指所生成的机器码是否稳定、可靠,而不是防破解方面,如果想要很好地防止破解,那么掌握一门加密技术是非常必要的。
本书考虑到使用易语言的用户大部分对 PE文件结构不太熟悉,因此没有采用很底层的方法去教学,而是采用与易语言直接表达的方式试图说明如何加密。
本书基本上是按以下的顺序进行讲解的:
破解技术
反破解技术 1
反破解技术 2
反破解技术 3
防改文件
文件名验证
LOGO图片验证
窗口标题验证
防改文件大小暴破
加壳后数据签名验证
加壳后 CRC验证
文件大小验证
防调试
花指令
反调试模块
反调试支持库
内存注册机
不进行判断 ,用循环代替
字符串打乱器
及时清内存
算法注册机
RSA算法
数值计算支持库
其他
多处验证点
随机验证
命名刻意隐蔽
本书是集体创作作品,并集成了多位作者的公开著述,在此一并表示感谢。其中部分文字内容根据易语言的特性作了修正。文中不署这些作者的姓名,以防止奸人对他们的软件的刻意破解。
一.易语言程序加密的目的
在此有必要说明一下为何要为自己的程序进行加密,初步认为有以下两点:
1.保持软件的完整性
这里包括了文件名不被更改,文件版权信息不被更改,文件尺寸不被更改。
很多时候有的奸人拿到您的软件,他可以将文件名更改,将文件版权信息的字符串或图片更改,然后放上自己的东西,如放上病毒可以对其他电脑造成破坏,如果放奸人的弹出广告收益的是奸人,而不是作者。相反,使用这些软件的用户反而将作者痛骂一通,造成声誉上的损失。因此处于保护自己的完整权益来说,也是有必要保护软件的完整性。
例如 QQ软件,曾出现过多款个人行为的补丁版,更改了 QQ的一些信息与界面,为此 QQ公司十分头痛,以后的一些事大家也知道,现在看是破解 QQ的很少了,而且在安装 QQ新版本时,它会检查是否有破解补丁存在,如果存在就不运行。
2、保护软件开发者的权益
也许你会说,一个不被破解的软件一定是一个没有加密的软件,那么看看下文您就会知道,那只是一个理想中的事情,除非您是有钱了没有事干的人,否则您开发软件的目的是什么我是很难知道的。
无论是个人还是公司,如果生产一个软件得不到收益,以及后继开发资金的鼓励,那么无疑这个软件是很难再开发下去的。这样的例子很多很多,我不想举例,国内已出现了很多软件的破解版,而一旦出现了破解,那么所造成的损失是非常大的。
二.易语言程序加密的原则
早先人们的加密方法是通过在软盘上格式化一些非标准磁道,在这些磁道上写入一些数据,如软件的解密密钥等等。这种软盘成为“钥匙盘”。软件运行时用户将软盘插入,软件读取这些磁道中的数据,判断是否合法的“钥匙盘”。
软盘加密还有其它一些技术,如弱位加密等等。
随着近年来软盘的没落,这种方法基本上退出了历史舞台。新的软件加密技术也越来越多了。
1.加密前要考虑周到且严密
说实话,有很多人在易语言论坛上发贴,说自己用易语言编写的软件有了破解,还非常高兴,有人用才会被破解,但我想,如果是很高兴的这样子,除非你的软件技术含量很低,或你是微软,想被别人破解,您不应该高兴,这有点象别人打了你一耳光,你还很高兴,你的知识产权或著作权已被奸人侵犯了,性质很恶劣,后果很严重。除了拿起法律武器,劳命伤财,还有就是加强加密方式。
如果被制作出注册机,情况是最糟糕的,作者需要全部更换全部用户的注册 KEY文件,工作量相当地相当地 大。因此一个好的软件保护发布前必须考虑周到,而且是面面俱到,否则出一个新版,发现一个破解,再出一个新版去修正,那样的事情是极其弱智的。
2.需要加密的内容要制定一个计划
一开始不明白如何加密的易语言用户,一般就找一下论坛上关于注册的例程套用到自己的程序中,认为这样就是加密了,实际上本节所要讲的是制作一个学习计划,将所有需要用到的知识与软件都收集到,这个计划就是一个加密计划,也是本书所要讲述的。
3.加密时制作好文档,以备以后的修改
在加密中有可能使用了多处加密,因此需要将文档写好,以防止以后忘记,实际上您可以在易语言中使用备注的方式作以说明,这些备注在编译时是不会被编译进目标 EXE文件中的, 大家可以放心写, 同时也节省了写外部文档的时间。 以后如果找时,可以直接搜索找到加密的地方。
4.发布前问一下是否可以正式发布软件了
制定一个风险评估标准,以考验一下程序的风险性,被破解的可能性,如果你是破解者,在不知道如何加密的情况下会如何去破解这个软件。
有一个参考的评估标准在下面。
共享软件注册加密自我评测表
评测方法:以下问题, 若答案为是加1 分。
1. 是否加壳?
2. 是否采用两种以上的不同的工具来对程序进行加壳/ 压缩?
3. 是否有软件自身的完整性检查功能?(CRC 校验或其他)
4. 与软件保护相关的字符串是否有进行加密处理?
5. 是否采用了比较成熟的密码学算法?
6. 是否有多处验证点,调用多个不同函数或判断多个不同全局标志进行注册验证?
7. 是否有随机验证的功能?
8. 是否采用了在线验证功能?
9. 注册过程中是否尽量少地给用户提示信息?
10. 是否不依赖于GetLocalTime( ) 、GetSystemTime( ) 这样众所周知的函数来获取系统时间?
11. 是否有伪破解功能?
12. 是否在软件中嵌入了反跟踪的代码?
13. 是否对校验函数命名做了刻意隐蔽?
14. 是否将注册码、安装时间记录在多个不同的地方?
15. 是否在校验时故意加入冗余干扰代码来误导解密者?
16. 是否有自己独特的防破解措施?
建议:得分在6 分以上才可以正式发布软件!
制作者: 中国 共享 软 件 联 盟· lcraz
三.防止程序内容被更改
从本节开始,已进入讲解加密的正题,但可能章节不必这样划分,即按加密 /破解的方法来划分,如防反调试,反跟踪,反……。但笔者觉得,从一个一个小的知识点的进入是非常重要的。
下面的有些内容是我请教了酒桶醉死的经验后总结的,在此表示感谢。
1.防止软件名称被更改
这里是极为简单的方法:
判断(到大写(取执行文件名() =“我的程序 .EXE”)
在上述中,为何使用到“判断”命令,而不是“如果”命令呢,大家可以想一下,“判断”命令的代码安全性要比“如果”命令高,这里不会举出一个汇编的例子,只要说明一下即可。即“判断”命令是多重分支结构,这样就增加了被破解的难度,因此,大家一定要注意这样一件事情,就是在进行加密比较时一定不要使用比较的语句,那样很容易被奸人使用破解工具下断点,那么正确的做法应该是如何的呢,请看下面代码:
计次循环首(到数值(是否注册成功()),)
全局 _注册成功 = 1
计次循环尾()
通过上面的代码可以看出,这里没有使用判断语句,而采用了一个循环命令去参与。其中“是否注册成功()”确实是返回了一个逻辑值,但通过“到数值()”命令后就会被为 0或 1之间的一个数字,会用易语言的人都知道,一个循环命令中,如果循环数为 1,会执行循环中的命令,否则为 0不进入循环。生成机器码后,奸人会很难找到判断的汇编码,大大加强了保护性。
上述的基本方法是有了,但请您将这个方法隐藏于您的程序代码行的某一深处,实际上加密是各种方法的综合,现在所教的只是其中的一种,大家要将多种加密方式用于一个软件之中。这需要大量的时间学习与体会。
加密第 1定理:“如果()”语句一定不要出现在加密算法中。
加密第 2定理:用“循环”类命令代替判断语句。
2.防止窗口标题被更改
窗口标题是否被别人更改这个也可以通过与上述同样的方法实现验证。
判断( _启动窗口 .标题 =“我的程序 .EXE”)
大家也许会说,这些好象没有必要吧,谁会这么无聊,将软件的名称与窗口标题更改呢,大家看这样一个例子吧:有一个电脑培训班,采用了明伦五笔练习打字软件进行电脑培训班,他们破解了,且修改了明伦打字软件的版权信息,改为自己电脑培训班的标志,产生的教学效果即:学生认为这家培训班的技术实力很强,自己可以开发打字软件,而且经常弹出电脑培训班的标志与广告,产生了很好的广告效果,学生介绍学生,更多的学生参与进来了。
从上述事件看,很显然明伦打字软件的作者一点好处也没有,全部被破解者侵占了。因此一个好的软件保护必须是全面而且周到的。
另外,我要提醒大家的是,这样的语句也是非常不保险的,这样的话很容易被奸人改了字符串,以致于字符串也被更改了,或很快能找到比较的地方,从而轻松跳过去。较为理想的是将字符串打乱,即将“我的程序 .EXE”以“字符()”、“取代码()”、“取反()”、“异或()”等命令用字符串相加的方法加在一起成为一个字串后再比较。
判断(取数据签名( _启动窗口 .标题) =取数据签名(“我的程序 .EXE”))
3.防止 LOGO图片被更改
有的人怕程序信息被更改,采用了图片显示程序标题的方式,这样这种图片较不易被奸人修改,但可能也有个别高手进行修改,因此图片的大小是知道的,这样可以用以下语句进行判断:
计次循环首(到数值(取字节集长度( _启动窗口。底图) =342488)),)
其中上述的数字是您已知的图片大小尺寸字节数,而不是乱写得来的。
也可以将图片放在易语言的资源中,直接进行比较。
计次循环首(到数值( _启动窗口。底图) =#图片 1),)
以上方法虽然软件的体积大了一些,但带来的直接好处是,程序量一大,为破解带来了更大的困难,虽然损失了体积,但保证了安全。
你的关于窗口也要这样保护起来哦。
使用数据操作支持库中的“加密数据()”、“解密数据()”命令加密图片后存放在图片资源中,用时再解密显示出来。例如您的一些口令就直接用这个加密就可以了。解密时注意直接放在一行代码中比较,不要存到一个变量中,这样在内存中是找不到明文的。
四.防止内存注册机
“内存注册机”的原理就是在不用分析原程序的加密算法,实现直接读取原程序在加密计算过程中内存里显示出的明文注册码。
很多易语言软件加密时,算法是足够复杂了,但是就是 KEY文是存在内存中的,这样就极易为破解。破解者只要写一个小程序,将这个内存地址显示出来,就一切 OK了。特别是现在还有自动生成此类内存注册机的软件,只要填入内存地址,一下就生成了。如下图所示。
解决这个问题的办法是推荐使用 RSA注册法,如果你不想采用,那就要一些技巧了。
1.不要使用简单判断
不要使用如果这样简单的判断语句,使用循环命令进行判断。
在程序中与你的数据相结合进行判断最好。
2.采用 MD5对比
你的注册码判断过程最好不要直接判断两个注册码文本的方法,正确的应该是取文本的 MD5码,再用取到的这两个 MD5码进行对比,即用户输入在注册编辑框中的文本信息与注册码文本信息进行 MD5的直接对比。有时奸人会输入一个假的注册号,然后在内存中寻找这个数据后再进行分析,如果转换为 MD5判断后,奸人在内存中是轻易找不到自己输入的数据的;
3.多注册码拷贝
即在内存中复制大量的注册码,在验证时随机取一个进行判断就可以。这样的好处是奸人要跟踪 N多个注册码内存,不知在哪一处就验证了,这会让他烦死。
注册码分开放在 N个地方也是个好方法。
五.防止文件被暴破
暴破是指破解者在模拟算法失败的情况下,恼羞成怒,狗急跳墙,一气之下暴力破解,将软件的壳脱掉,将要求注册的部分直接跳过去,这样直接产生的后果是文件大小被改变了。
首先要说的是:一般暴力破解前奸人都要跟踪查看你关于注册文字的一些关键字,请大家不要将注册信息的明文写在软件中,如“请注册”,“注册成功!”,“注册失败!”,这些文字请打乱后显示,有可能的话再加密,这样破解者不容易找到位置。奸人有时用一种简单的字符分析工具很容易找到这些敏感的字,因此尽量避免明文显示。
其次,不要使用信息框进行提示是否注册成功,这个信息框的 API函数的使用情况很容易被奸人找到,可以单独制作一个提示窗口,上面显示注册成功与否加密后的文字,或直接在窗口中放一张提示是否注册成功的图片也行。
再次,你的注册码判断最好不要直接判断注册码,而是用两个 MD5进行对比,即用户输入在注册编辑框中的文本信息与注册码文本信息进行 MD5的直接对比。有时奸人会输入一个假的注册号,然后在内存中寻找这个数据,如果转换为 MD5判断后,奸人在内存中是轻易找不到自己输入的数据的;
最后,你的注册判断不要使用“如果”这样简单的命令,而是使用前面所说的循环命令进行判断。
加壳软件的作用就是防止自己的程序被暴破。首先破解者会脱壳,如果有的壳很硬,或有加密算法,这为脱壳带来麻烦。其次,加壳后,在外部 DLL中存一个 MD5的校验,这将防止脱壳后运行,这样奸人就不能进行运行调试了。
加壳软件分为普通壳与加密壳。加壳可压缩文件大小,并且将一些本来清晰的字串进行了打乱的效果。
普通壳的作用是压缩资源,使文件尺寸变小,一般可使易语言缩小一半以上的尺寸,有的还可以减少系统资源占用。其他编程语言生成的 EXE文件加壳后有可能变大,例如 C语言生成的程序本来就小,压缩不了尺寸,这时再加上一个壳,尺寸反而会变大。
普通壳有: UPX, ASPACK, ASProtect , PKLITE, PECompact等。
加密的壳有:幻影,软件保护神等。
加密的壳可以提供直接的注册码功能。加密的壳由于是公用壳,很多人都去购买使用,一般容易被奸人看中脱壳,灵活性也差。如果被破解了,那么后果是十分严重的。因此推荐的就是一个普通壳,如 UPX,然后进行 MD5判断是否被脱壳就可以了。
下面,再介绍一下常用的加壳软件。
1.常用加壳软件介绍
下图是 UPX Shell v3.10软件的运行界面:
下图是 ASPACK软件的运行界面:
下图是 PKLITE软件的运行界面:
下图是 PECompact软件的运行界面:
下图是“幻影”加壳软件的运行界面:
下图是“软件保护神”加壳软件的运行界面:
壳加完后,余下的工作就是防止脱壳了,一般来说,很多人都想要一个很强的壳,但一方面任何壳都有可能被破解,另一方面壳的兼容性就有很大的问题。
如采用强壳的《系统管理》采用了一个国外出品的强壳,确实是很难脱掉的,但由于破解版的原因,在 WIN98下运行时经常会死机。正式版的价格也非常高,基本上要 1000元 RMB左右。
而常用的普通壳虽然强度并不高,但通过易语言编程进行校验,可以保护您的壳不被轻易脱掉。
加密第 3定理:用最普通的壳,让弱手们去脱脱看!我还有校验等着呢。
2.加壳后文件大小验证
加壳后一些数据安全得到了保证。这包括一些没有加工过的字符串,例如:数据库密码,加密算法密码。
加压缩壳后,易语言的 EXE文件尺寸一般会变小,一般 1.5MB的软件会变小为 800KB左右。
那么最常用的文件大小验证可以用如下易语言代码:
判断(取文件尺寸(取执行文件名()) = 843674)
上述代码中的数值是经过查看编译及加壳后文件属性大小生成的,但由此造成两种不方便的地方:一是由于易语言造成每次编译后的文件大小是不一样的,因此很难将这个数值取对,二是这个值放在哪里好,如果放在主程序中的话,那么每次生成的文件大小不一样,就会造成取不准,比较不了的现象。
建议大家在比较时可以将代码写成以下形式:
判断(取文件尺寸(取执行文件名())≥ 900000)
通过以上运算符的改变后,基本上可以知道是否被脱了壳了,因为脱了壳后程序的体积会增加很多。
3.加壳后数据签名验证
易语言自带一个“数据操作支持库”,基本可以满足安全加密的需要。如下图所示:
这里较为常用的命令是“取数据摘要()”,这个命令是采用了 MD5算法,不同数据的 MD5码都不一样,因此本命令可以用作保证重要数据不会被篡改。对于不同的数据,其得出的结果是不一样的。如果奸人将您的软件脱壳了、改动了,那么前后所取得的结果也是不一样的。
“取数据摘要()”得出的结果是返回一段字节集数据的 MD5数据摘要编码文本。一般是 32位字节的数据。
但这样带来了这样一个问题:即我们取得了加壳后软件的数据摘要,但是放在软件中后再编译再加壳再取数据摘要后,本次取值与前面所取的值是不一致的。
采取的办法一般是将数据摘要文本存放在外部。
一般会采用以下的方式:
第一种方式:加密后存放在一个文件中。
第二种方式:加密后存放在 DLL中。
第一种方式可以直接存在一个文件中,也可以夹存在其他文件中,如图片文件中,或音乐文件中,或 DLL文件中(硬写在 DLL段中)。
第二种方式可取得主程序的数据摘要后,直接在 DLL程序的源程序中写比较代码。然后编译为 DLL文件,由主程序调用此比较 DLL。这样保证了主程序的数据摘要与主程序分离从而加强了主程序的安全性。
4.加壳后 CRC验证
我们很有必要给自己的软件加上更好的保护。CRC 校验就是其中的一种不错的方法。
CRC 是什么东西呢?其实我们大家都不应该会对它陌生,回忆一下?你用过RAR 和ZIP 等压缩软件吗?它们是不是常常会给你一个恼人的“CRC 校验错误” 信息呢?我想你应该明白了吧,CRC 就是块数据的计算值,它的全称是“Cyclic Redundancy Check” ,中文名是“ 循环冗余码” ,“CRC 校验” 就是“ 循环冗余校验” 。
CRC 有什么用呢?它的应用范围很广泛,最常见的就是在网络传输中进行信息的校对。其实我们大可以把它应用到软件保护中去,因为它的计算是非常非常非常严格的。严格到什么程度呢?你的程序只要被改动了一个字节(甚至只是大小写的改动),它的值就会跟原来的不同。呵呵,是不是很厉害呢?所以只要给你的“ 原” 程序计算好CRC 值,储存在某个地方,然后在程序中随机地再对文件进行CRC 校验,接着跟第一次生成并保存好的CRC 值进行比较,如果相等的话就说明你的程序没有被修改/ 破解过,如果不等的话,那么很可能你的程序遭到了病毒的感染,或者被奸人用16 进制工具暴力破解过了。
CRC 的本质是进行XOR 运算,运算的过程我们不用管它,因为运算过程对最后的结果没有意义;我们真正感兴趣的只是最终得到的余数,这个余数就是CRC 值。
易语言用户林子深提供了一个 CRC32.EC的易模块,这个模块可以在论坛上或资源网上搜索到。大家可以直接拿过来用,导入易语言后如下图所示:
调用方式可为如下代码:
判断(取循环风俗冗余校验和(读入文件(取执行文件名())) = 18293823767)
其中上述的数字为主程序的 CRC码值。
大家可以利用上述特性,即结果是数值的特性,不用进行比较,而是用加减法的方法得出前后两个 CRC验的差值,如果为 0,那说明两个数字是相等的,主程序没有被改动过。否则就是被改过的。
例如下述代码:
程序被改 = 1
计次循环首(取绝对值(取循环风俗冗余校验和(读入文件(取执行文件名())) – 18293823767),)
程序被改 = 0-
跳出循环()
计次循环尾()
返回(程序被改)
上述代码中,“取绝对值()”是将负数也转换为正数,以方便进行计次循环。
上述代码中,数值型变量“程序被改”为 1表示没有被改动过,如果为 0表示被改动过。返回的数值就可以进行一些陷阱的计算了。
我的方案的缺点分析:
CRC-32的值其实可以由奸人自行计算得出后,重新写入到程序验证处。这样的话,我们做的工作岂不是没有意义了?
其实解决的方法还是有的,我们可以在计算 CRC-32值之前,对参与转换的字符串加点手脚,例如对这个字符串进行移位、 xor等操作,或者把自己的生日等信息加入到字符串中,随你的便什么都行,总之不是单纯的文件的内容就行了,然后在最后比较的时候,也用同样的方法反计算出 CRC-32值。这样得到的 CRC-32就不是由文件的内容计算出来的,相信对破解者的阻力也会加大不少。
总结:
以上的方法大家都可以在软件中采用,最好写到一个 DLL文件中,然后多放几个需要验证的子程序,随时以备调用即可。
六.防调试方法
1.易语言的花指令
加花指令的方法有通用性,即所有的反汇编器都可以用这种方法来抵挡。这种方法主要是利用不同的机器指令包含的字节数并不相同,有的是单字节指令,有的是多字节指令。对于多字节指令来说,反汇编软件需要确定指令的第一个字节的起始位置,也就是操作码的位置,这样才能正确地反汇编这条指令,否则它就可能反汇编成另外一条指令了。并且,多字节,指令长度不定,使得反汇编器在错误译码一条指令后,接下来的许多条指令都会被错误译码。所以,这种方法是很有效的 。
易语言新版本中增加了自动插入花指令的功能,并且插入后虽然文件体积大了一些,但不会造成运行错误。大家可以点击菜单“工具”→“系统配置”。弹出的窗口如下图所示。
不采用花指令时,反编译出来的代码几乎是跟源代码一一对应的,这样一来我们的程序还有什么秘密可言呢?完全可以从反编译的结果中理解程序的功能。
其实花指令就是人为地构造一些“陷阱”和一些无用的字节,起到迷惑破解者和隐藏信息的作用。 在这里,易语言为你构造了这些“陷阱”。大家只要将上述配置项打开就可以了。同时也提醒大家,在发布新版本时采用以下的方式:第一周发布的是花指令级别为 1,第二周发布的是花指令级别为 2,第三周发布的是花指令级别为 3,第四周发布的是花指令级别为 1……,周而复始,这样破解者根本跟不上你变换的速度。
加密第 4定理:每周发布一个新版本,让破解的速度赶不上发布的速度。
2.反调试模块的使用
目前易语言论坛上出现了一些模块或支持库,带有反调试的功能,当启用后,就会查看进程中有无调试器,如 SOFTICE等调试工具,对易语言的调试也同样有效。
由林子深提供的另一个模块:“星光灭绝”模块大家也可以尝试用一下,为何说是尝试呢,这些模块并不稳定,并且极易造成 WIN98下程序死机。并且打开易语言也会认为是调试器,从而会自动退出。
大家自己在易语言论坛上搜索吧。不推荐大家使用。
3.反调试支持库的使用
海洋的支持库也提供了反调试的功能,具体是海洋增强支持库。
但要注意兼容性问题,一定要在多个操作系统下进行严格的测试后才能发布。
4.通过检查父进程得知是否被调试了
一般情况下,直接运行的程序的父进程是 EXPLOER,在易语言中调试运行的父进度是易语言,而在破解人手中运行的父进程是用于破解的调试软件。因此我们就有必要判断程序的 你 进程是否是 EXPLOER或易语言,如果不是,非常有很大的可能是在奸人的调试软件中被调用了,这时就好办了。哈哈。
易语言论坛的用户“笨笨啊”提供了一个取进程与父进程的模块,并且有模块源代码,程序主要是由 API取得进程内容。
大家可以搜索易语言论坛,用户名为“笨笨啊”,或关键字为“父进程”可以找到这个源代码。
下图是在易语言中调试程序时,父进程为易语言:
下图是易语言编译后运行,其父进程是 EXPLORER.EXE,编号为 860:
加密第 5定理:一个正常运行的 EXE的父进程是 EXPLORER.EXE
不过这里要注意的是:奸人有可能将调试程序的名称改为 EXPLORER.EXE,这样可以伪装一下吗?不可以,你需要检查一下名称为 EXPLORER.EXE的进程有几个,进程 ID是不是一样的?如果有两个不同的进程 ID,那么这时再判定就可以知道是不是被奸人调试了。
5.使用多线程
在Debug 的手册里可以看到Debug 工具的局限:第一个局限是只能下4 个内存区域的断点,每个断点不能控制超过两个字节,这样内存断点不能控制超过16 个字节的区域;第二个局限是对多线程只能同时跟踪一个线程。因此利用其的第二个弱点,大家可以多开几个线程进行来回验证。
多线程的编程方法参看易语言手册。
一般开5-8 个线程就够奸人忙活的了。
加密第 6定理:使用 5个以上多线程来回验证注册。
七.注册机制
1.简单注册原理
在易语言安装后的程序“ \e\lib\krnln\samples\软件注册 .e”就是演示了软件注册的原理。
其中有一个子程序是重复取硬件码的,存在取硬件码失败的情况,因此要重复多取几次,如果取失败就用一个默认的硬件码代替。这个大家一定要看一看,
注册机的原理就是:用户在使用过软件一段时间后,认为软件较为理想,要求向作者注册,而此软件中提供了用户本机上的硬件号,用户将此硬件号发给作者,作者给出一个注册码,用户拿到此注册码后填写,软件就注册成功。注册码的计算是由硬件号产生的,计算过程只有作者知道。
例如:用户机器上的硬件号为 34,作者返回的注册码为 1904。用户在注册码输入栏中输入 1904,那么注册成功。作者是这样计算的, 34X56=1904。那么软件中也是这样计算的。以上介绍的只是例子,大家也许会说,从 1输到 9999,总有一个会遇上的,但事实是硬件码不会这样简单,可以是 16进制的,而计算也不会这么简单,可能会用上矩阵也说不定,因此相比较而言,靠猜测的方法去破解是愚蠢的。
下面看一下易语言自带例程中的程序代码,此为要求用户输入注册码时的判断语句:
此为判断语句调用的返回注册码的子程序:
通过以上检查是否输入的硬件码与注册码对映。
而软件作者手上有一个注册机,可以生成此硬件代码,大家可以在此例程上加一个按钮,此按钮的代码如下:
这样作者就可以很轻松地得到注册码,然后将这个注册码发给用户用于注册了。
上述只是在一个理想的状态中实现的,即没有奸人对你的软件进行破解。如果奸人看上了你的软件,只靠这么简单的方法,那么一定会吃大亏的。因此大家在注册码生成的计算上要想尽一切办法使之复杂化,如:采用位异,采用加上计算数值,采用……有些办法将在后面章节中进行介绍。
2. RSA算法注册
① RSA简介
使用 RSA非对称密钥算法对指定字节集数据进行签署,支持 32到 4096之间任意合法的 RSA位数,返回签署后的结果文本。
说明一,电子签名系统简要实现方法:
首先给所有具有签署权利的人员授予不同的 RSA钥匙, RSA钥匙由“公钥”、“私钥”、“公共模数”三部分组成,为了生成符合要求的随机密钥,可以下载使用 http://dywt.com.cn/RSATool2v14.rar第三方工具软件(内有操作说明)。然后将所有人员的“公钥”和“公共模数”成对向外公布,“私钥”由被授予人员自行妥善保管。
被授权人员使用“私钥”和“公共模数”对指定数据进行签署,然后将签署后的结果文本随同被签署数据一起发送,接收者收到后,使用该签署者公开的“公钥”和“公共模数”及签署结果文本对被签署数据进行验证,如验证通过则说明该数据必定是此签署者所认可的,且没有经过任何篡改。
说明二,数字签名用作软件注册系统的实现步骤:
1、欲注册用户提供注册信息(如硬件代码、用户姓名等);
2、软件作者使用自己的私钥对该注册信息进行数字签署得到签署结果文本;
3、将此签署结果文本作为注册钥匙文件发送给用户;
4、在用户端的软件使用相同的用户信息、注册钥匙文件及软件作者的公钥进行签名验证,如果通过表明已经注册,否则表示未注册。使用本方法在私钥未泄露的前提下,可以绝对避免破解者做出软件的注册机。
② RSA工具使用简介
RSATool工具运行界面如下图所示:
有很多人说 RSA工具不会用,其实 RSA工具的使用方法吴涛已说明得非常清楚了。下面引用吴涛说明书的原文:
吴涛写的 RSATool工具使用说明书如下:
RSATool 2.14工具软件使用指南:
(软件下载地址: http://eyuyan.com/RSATool2v14.rar)
为了生成符合要求的随机 RSA密钥,请类似如下操作:
1、在“ Number Base”组合框中选择进制为 10 ;
2、单击“ Start”按钮,然后随意移动鼠标直到提示信息框出现,以获取一个随机数种子;
3、在“ KeySize(Bits)”编辑框中输入 32;
4、单击“ Generate”按钮生成;
5、复制“ Prime(P)”编辑框中的内容到“ Public Exp.(E)”编辑框;
6、在“ Number Base”组合框中选择进制为 16 ;
7、记录下“ Prime(P)”编辑框中的十六进制文本内容。
8、再次重复第 2步;
9、在“ KeySize(Bits)”编辑框中输入您所希望的密钥位数,从 32到 4096,位数越多安全性也高,但运算速度越慢,一般选择 1024位足够了;
10、单击“ Generate”按钮生成;
11、单击“ Test”按钮测试,在“ Message to encrypt”编辑框中随意输入一段文本,然后单击“ Encrypt”按钮加密,再单击“ Decrypt”按钮解密,看解密后的结果是否和所输入的一致,如果一致表示所生成的 RSA密钥可用,否则需要重新生成;
12、到此生成完成,“ Private Exp.(D)”编辑框中的内容为私钥,第 7步所记录的内容为公钥,“ Modulus (N)”编辑框中的内容为公共模数,请将上述三段十六进制文本保存起来即可。
③一个简单的 RSA注册机
例如:我们已通过上述 RSA工具得到以下三个变量:
公钥:
20063
私钥:
7FC4638275AF6B27AFD040FED32A 941D227154ECDE37ABFF73D72DB50F 9FC70C 75BC3AF0EC26016BC706D953A 9C 5D6831E0DDD27B42A 182CB92A 6E426693511E42EB0BF9D64459809D5EC305E13B2A 85BA004BA934232305D3DA1205E7AD1D01744BBCF286B23D64CC68371FDD39DAA43861920DA3DE5F 9335A 77983BFD08A 83
公共模数:
CEB774FCCE9DB84A 4452A 0774264FC55F 35A 8D8AA9D1FC5EBD3E0880B7B62A 4EF834FD6E855CD84A 4D04F 3BBDE32180FC3EE45AB5582C 2320A 6575C 6ECF923A 24EAF59F 22F 930631347E0E3B0477A 89FCE22FE741F 5053EC5320AAF6489CC407056361F 01E031A 02DB52CB0CBDFBB11F 72C 340354C 6CAB78D97630EB8A 6A 5431
初始化代码如下:
注册窗口设计界面如下:
注册按钮代码如下:
上面的程序窗口插在用户的程序中,当需要注册时即弹出注册。
作者手中的注册机软件界面如下:(注意保密)
生成按钮代码如下:(注意保密)
上述程序已在易语言 4.0中运行通过。运行抓图如下所示:
加密第 7定理: RSA算法虽然很强,但弱在钥匙文件如何保密上。
④算法实现中的注意事项
上述代码中取硬件码的命令没有采用重复取,而只取了一次,在实际操作中需要正规地多取几次,获取硬件码失败也要作相应的默认处理。并且硬件码好要转换为另一串字符串。
上述代码中所有字串均未作分解处理,实际编程中需要分解,且分别隐藏到程序各处。最好也加上密。
上述代码中注册码文本较长,可直接读取一个文本文件进行比较。即生成的注册码存在一个文本文件中,在点击注册按钮后,直接找这个文本文件的内容进行对比。文本文件的文件名可以是硬件号的名称。
上述是基本算法演示,其中的注册算法还可以再进行加工,变得更复杂一些。
上述中注有(注意保密)字样的代码与程序需要软件作者严格保密,不对外公开。
大家再看一个易语言大奖赛获奖作品:“家电维修”的例子,大家也可以在易语言新建窗口中找到这个程序,看看注册窗口的代码吧,如果您按这样的做法去发布软件,会有什么安全性可言呢。
⑤设计 RSA的变形算法
重要提示:上述是对 RSA整体进行一次性验证,虽说 RSA是一个非常强的加密算法,但是这样的算法太简单,很容易被破解,那么需要通过以下的方法进行变形。以下所举的例子只是一个参考,你自己的方法越古怪越变态越好。
例如,可以采用分解 RSA算法,每次只验证一小部分,以保证在程序的各个地方进行不同种类的验证,返回的值有的可设计为数值型,有的可设计为逻辑形,以利于在程序中不同地方调用,调用后可以根据数据进行运算,如果是破解版,那么使用破解版的人得出的结果一定是错误的。采用双 RSA密匙、多 RSA码也是个好办法,但最好两者之间再混合一下,采用 RSA与数值计算支持库混合的方法可以加强加密强度。
另外,密匙字串需要分开存放,全局变量中放一些,程序集变最中放一些,局部变量中放一些,常量中放一些,字符串一定要打乱,不可存为一个变量中,还可以 RSA之上再加密,如 RSA密钥是加密格式的,验证完后立即清变量……要注意的事项还是很多,一定要考虑周密一些,即要达到加密的目的,也不要太复杂了,以免自己也被搞糊涂了。如果有错误,误将正版用户当盗版用户对待就不太好了。
3.数值计算支持库
易语言提供的数值计算支持库很有特色,其特点就是可以计算任意位数,因此大家可以根据这个特性来制作加密算法,考虑到奸人如果制作一个注册机就必须去研究易语言,及了解了易语言的数值计算支持库后才能去破解,但即使这样,也不能轻松就能写出注册机,试想一下,数值计算支持库本身就花了很长时间写出,因此奸人们是无论如何也是制造不出注册机的。并且一般来说,奸人如果出注册机,一般都希望文件小一些,从而也不会用易语言写注册机程序,一般采用 C语言写,即使写了也要带上很大的系统支持库与数值计算支持库,太累了吧,哈哈。
在此建议的是将 RSA算法与数值计算支持库相结合的办法,这样的注册机基本上就不会再有了,只要防止内存注册机出现即可。内存注册机的防止可以通过不进行判断的方式解决。而防止暴力破解是通过对软件加壳后,在外部 CRC验证保证程序完整性,程序内部再多重检查,加上几个暗桩,这样通过层层把关,最终就可以确保万无一失了。
由于 PE文件格式的局限性,任何加密程序都有可能被破解,我们所要做的仅仅是加强加密的复杂度,让奸人知难而退,耗费他们的时间与精力,浪费他的时间就是在杀他。
八.给奸人一些教训
实际上,我们的用户已区分为以下四种人:共享试用者、正版注册者、破解使用者、破解版使用者。
当我们需要给破解者一些教训时,一定要将正常用户区分开,否则正常用户有所损失,那么就根本不会来购买您的软件,您的声誉也会下降的。
1.给破解者的教训
有句名言:“软件很生气,后果很严重!”。
给破解者的教训要深刻一些,最好让他刻骨铭心,永世不忘。
对于一个破解新手来说,很草率地去破解一个成熟的软件,对他来说是灾难的开始,给破解者制造麻烦,让破解者知难而退是一件有乐趣的事。这事一定不要忘记做哦,否则我这文章就白写了。
但最好不要在软件中写有辱骂破解者的话,这样会将奸人狗急跳墙了,反过来会非常强烈地一定要破解你,反而得不偿失,技术上的比拼是正当的,人格侮辱就不太好了。
一个通常的教训如下:
但如果你想变态地去教训奸人,那么我也没有办法阻止你了,毕竟你已在授权文件中警告过用户不要乱动你的东西了。哈哈。
有时候,奸人是使用的虚拟机,你重启、死机什么的都对他有影响,唯一他比较可怜的就是硬盘中的一些资料了。 下面是将文件删除到回收站,及清空回收站的代码:
2.给破解版使用者的教训
上面是对于奸人的教训,但对于一般破解使用者来说,也要给予配当的惩罚,但不能太过严厉,不能对他们的机器造成严重破坏。一般来说给予一次广告机会,数据错误,或设置一些小损失即可。
常见的有以下,其他的请你根据你自己软件的内容进行适当的创意吧。
第 1种:建议发现是破解版使用者在用时,可为你的软件加一些贴面广告,这样您会有一些收益,以补充你的一些损失。
第 2种:将一些数据搞错了,而且是非常明显的错误,让他有些损失。
第 3种:建议开始一段时间让他正常用,查明破解版使用者如果保存较多的内容,说明他很在乎经常使用你这个软件,并且认为破解正常,已可以正常使用了,这时等他的数据量大时,将数据库锁定,他一定欲哭无泪,只好请你帮他解锁,购买您的软件了。
易表的作者就是用这种方法。
实际上这是一种暗桩操作,即在发布几个月后再检查是否是正版,或在数据库存储到一定时间后再检查是否是正版用户,这样的加密方法值得大家学习。
可能您很生气,想让破解版使用者得不到好的下场,最好不要删除重要数据。且我个人是不建议大家删除有用的数据的,毕竟这些都是国家的财富。
加密第 8定理:加密的结果是双赢才行,用户真正认识到了来注册,同时也能用上正版了。
3.行为不要过火
作者给奸人一些教训是正当的,可是软件会存在 BUG,写加密程序也会有 BUG存在。如果将正版用户的数据损坏了就不太好了,毕竟大家还是要靠口碑生存的。即使您是对的,但如果盗版用户多,那么如果太严厉了,就没有人敢用你的软件了。
如江民事件,就是前车( JU)之鉴。
如果您能搞出一个即让破解者假象破解,为你作宜传,而又能争取到用户,那样是最皆大欢喜的了。易表就是一个例子,他的软件表面上被破解了,但实际上还存在暗桩,结果用了一段时间后,用户的重要数据被锁定了,只能乖乖注册。
加密第 9定理:口碑好的软件才能传播得更广。
九.网络验证法
现在有的人说网络验证法是最可靠,且是从未被破解过的加密方法。确实这种方法很难破解,因为注册码始终是在作者手上的,这样怎么去破解呀。
加密第 10定理:一个好的网络验证法至今没有人能破解。
1.实现的原理
网络验证法有些类似于网络游戏中的验证。
网络验证方法,即建立一个网络服务器程序,由软件作者自己保管,运行于服务器端,客户端通过编程放在共享软件中。客户所拿到的共享软件程序中带有客户端程序,当需要验证时,客户端的硬件码通过网络传送到服务器中,服务端程序将加密后的注册码通过网络传回给客户,客户软件中的客户端组件接收到后,在内存中解密进行判定,如果注册了就通过,否则就失败。作者的服务器端上保存了用户的注册码数据库,随时供验证之用。
在此可以避免以下被破解的事况:
首先,通过网络验证即使奸人拦截到了注册码,也是加密过的,如果去解密也很困难,并且服务器是由软件作者保管的,这样奸人可能始终接触不到注册码。或者他要去学习网络拦截也说不定。
其次可以预防暴力破解,软件作者可将重要数据直接放在服务器中,通过不停验证取得数据,从而被破解的客户端被暴力破解后立即成为无效软件。
再次,即使软件被破解了,软件的作者也可以较轻松地升级客户端程序,及升级服务器端的注册码数据库,从而减少破解造成的损失,让破解者阴谋失败。
最后,软件作者可以轻松看到监视客户端的使用情,如果发现有重复名称的验证,或不正常地取数据,就可以立即停止客户的使用。
2.存在的几个问题
1.用户的程序必须是需要通过上网才能使用的,不上网,将不能验证,也不能使用。
2.软件作者必须要保证服务器的稳定,如果服务器死机或掉线,那么客户机将不能使用,因此也要具备一定的防攻击能力。服务器维护人员技术要求较高,要有一定的服务器反黑经验。
3.网络验证也不能一次全部验证,这样并不保险,需要分段进行验证。并且给予暗桩的设计。
4.可能存在客户太多,一个服务器接收不过来,需要两个以上服务器的情况,或就直接架设两个以上服务器,用于备用。现在的电信与网通经常打架,可考虑一个接电信网,一个架网通网,以备不时之需。
十.加密狗加密
本文的目的是让大家了解加密狗,它并不是那样神密而可怕,大家一定要克服恐惧感哦。加密狗是个极其好用的工具,基本上如果用上一个好的型号的加密狗,可以为您省不少心,想想看吧,有一个技术团队在身后做支持呢。
易语言论坛上有人说:“不要花太多心思到加密上,而是要完善软件功能!”当然将心思放在加密上我也不想,这都是拜小人所赐呀。因此如果您想节约时间的话,只要买个好狗,加一个壳就可以了。
加密第 11定理:如果您想不要花太多心思到加密上而想要一个很强的加密,加密狗是最好的选择。
说老实话,现在的狗都比以前好多了,以前还听说有狗被防制或模拟了,现在的狗呀,越做越好了。总之,大家放心用吧。
软件狗是一种智能型加密工具。它是一个安装在并口、串口等接口上的硬件电路,同时有一套使用于各种语言的接口软件和工具软件。当被狗保护的软件运行时,程序向插在计算机上的软件狗发出查询命令,软件狗迅速计算查询并给出响应,正确的响应保证软件继续运行。如果没有软件狗,程序将不能运行,复杂的软硬件技术结合在一起防止软件盗版。真正有商业价值得软件一般都用软件狗来保护。
平时常见的狗主要有“洋狗”(国外狗)和“土狗”(国产狗)。这里国外狗主要指美国的彩虹和以色列的 HASP,国产狗主要有金天地(现在与美国彩虹合资,叫“彩虹天地”)、深思、尖石。总的说来,加密狗在软件接口、加壳、反跟踪等方面技术较好,基本上复制很困难。
1.加密狗的选用
加密狗一般分为串口狗与 USB加密狗。
串口即打印口,为 16针口可以同进串接多个串口型加密狗。如下图所示:
现在也已有一种微型加密狗的推出:
USB口为直接插入 USB接口,每个接口只能插一个。如下图所示:
从目前的资料来看,一般加密狗产商都想淘汰并口型的加密狗,而主推 USB口的加密狗。一只 USB加密狗的批发价现在大 50元左右。
USB设备是专门为多设备连接而设计,有着严格的规范,从接口本身就避免了设备间的冲突。所以 USB狗不会与遵守 USB标准的设备有任何冲突。而因为并口只是为单设备工作设计的,很多并口设备并没有考虑与其它外设公用并口的情况,为降低成本,往往独占了并口资源,使得并口的其它设备不能正常工作。因此建议使用 USB狗较好。
USB接口本身具有电源线,可为外设提供稳定的工作电源,从而对 USB狗的工作电压、功耗等要求大大降低,加密狗的工作条件得到很大改善。而并口本身没有电源线,并口狗要依靠并口的信号线或数据线提供电源,所以在因并口负载能力低等情况下,并口狗的芯片因得不到正常供电很难保证正常工作。因此建议使用 USB狗较好。
2.加密狗加壳法
一般的加密狗软件都提供傻瓜加密工具:加壳工具。这种壳是针对加密狗进行的。
加密狗有内嵌和外壳两种加密方式。外壳加密就是对 exe、 exp、数据文件直接进行加密的方式;内嵌加密是在各个语言环境中直接以函数调用形式出现的加密方式。操作系统支持 Dos16/32、 Windows3x/9x/ME/NT/2000/XP的各种版本,如有的狗提供有 37种内嵌语言加密模块,四种外壳加密工具。
加壳式加密的软件运行界面与前述的普通壳的加密界面是类似的,也是要提交需要加密的原文件,然后会生成加密后的新文件,这个大家不认为太神密了。
内嵌一般采用供货商提供 DLL,就是 API调用,以达到调用加密模块的目的。各个狗的调用都不相同,一般会提供 C语言或 VB语言调用的实例,大家模仿这类程序即可。
有论坛人士说: “心思放太多到反破解上也不是一件好事啊!”,我觉得给别人破解了更不好,是吧!如果不想放太多心思在反破解上,建议还是采取加密狗加壳的办法,方便、快捷,其他时间就可以研究如何将软件完善就行了。因为有一个加密的团队在支持你呀。
3.加密狗写存储器法
有的加密狗带有存储器,大小不一,有的是 1024字节,这样大家也可以将一些重要的信息放在这里面。实际上您也可以将 RSA的一些数据放在这里,以供程序双重检查。同样也是通过 DLL调用的。
十一.加密算法策略(暗桩)
本章所要讲述的是:加密不要拘泥于一种形式,要懂得变化之道,这样才能让破解者无从下手,这是我的软件加密之最精髓的一点。前文所说只是一些最基础的知识,大家还需要一点变通之法, 加密方法越奇怪越好, 变态一些也没有关系。看过《倚天屠龙记》的话,可以想想张三丰教张无忌太极拳时的那段对话,哈哈。
当然很多人喜欢暴破的,懒得研究写注册机,所以让他们多花费些时间,多浪费他们的生命,就要多打入一些暗桩,不要用简单的“如果”、“等于”判断,免得再精巧高深的加密算法成为华丽的摆设,破解与反破解是一场暗战,就算不能反破解,也要设计多一些迷局关卡,把破解者肥的拖瘦,把瘦的拖死,让他们痴迷、让他们上瘾、让他们欲罢不能,用代码吸光他们的精血。
1.易数据库密码怎么泻露了
易语言论坛上个别用户说自己的数据库密码被别人知道了,那么我们看一下他是如何加数据库密码的,代码如下:
打开 ( 取运行目录 ()+ “\ 工资库.edb ”, , , , ,“K39DKEKD944 ”, )
好了,我们编译一下,编译成一个EXE 文件,然后改文件后缀为TXT ,这样我们就可以不用PE 专业工具,而是直接用记事本打开了。
然后在记事本中搜索这个密码,大家看到了什么?看下图中反白的部分:
晕死,你这样编程,当然数据库密码会被别人知道了。
将前述代码改动一下,将密码分解为若干单个字符串,然后分别放于全局变量中定义一部分,再在程序集变量中放一部分,这样就不会有问题了。
如下面的试验,只改动一小部分:
口令 = “K ” + 到文本 (13× 3)+ 字符 (68)+ “K ” + “E ” + “K ” + “D ” + 到文本 (18÷ 2)+到文本 (22+ 22)
打开 ( 取运行目录 ()+ “\ 工资库.edb ”, , , , ,口令, )
再按前述的查看方法,可以看到,数据库前后的密码被处理过的部分都看不到了,如下图所示:
大家应该明白了吧,如果上述代码全部处理好的话,一定不会让别人找到口令的。
实际上,对于重要的加密口令来说,都需要分开存放,并且用取字符,位移或取反的方法,以及加减乘除的方法都可以得到一个隐藏很深的字符串。
加密第 12定理:相关加密的字符串一定要打乱加密。
作业 1:制作一个“字符串搅乱器”,要求如下:输入一字符串或其他类型的内容,输出为经过“字符,取代码,取反,位或,位与,加减乘除,平方,开方”等命令随机 配合相加的易语言源代码。界面基本如下: