破解的最高境界就是分析算法并写出注册机,以实现最完美的破解。算法分析需要破解者拥有深厚的逆向反汇编功底,而编写注册机则需要懂得程序开发。因此很多学习破解的都只停留在暴力破解和简单的追踪注册码阶段,为了让大家能够轻松的晋级到更高的境界,本文我就把自己总结出来的一些经验写出来和大家分享一下。
我们以Free Intemet Window Washer为例来讲解算法分析和编写注册机的一般方法和步骤,这是一个垃圾清理软件,还是比较不错的。在此声明,本文仅限于技术研究目的,请勿非法的传播注册机,请勿对软件开发者的利益造成侵犯。
第一部分:算法分析
第一步、安装完该程序后,先使用PEID进行查壳,发现程序是使用Borland Delphi编写的,并没有加壳。
第二步、打开程序,随意输入一个假的注册码进行注册,结果弹出了注册失败的信息,我们把这个提示信息记录下来。
第三步、使用OD载入程序进行调试,加载完毕后,查找关键字,也就是上面注册失败的提示信息了,使用OD插件中的字符串查找工具即可。
通过查找后发现,字符串中并没有注册失败的信息,通常如果在这里没有找到注册失败信息,我们就会使用下api断点等辅助方法。在程序的安装目录下发现该程序支持多种语言显示,我们找到了一个名为WLan_English.ini的文件并打开,通过文件名可以得知这是英文显示语言包,打开后搜索注册失败信息。
我们从中可以看到这样一条信息:“RES_Registration_Error= Regstration s not valid,please try again.”,于是我们在OD中查找RES_egistrtion_Error字符串。果然找到了一处,这也就是说程序为了实现支持多语言显示,将注册失败信息使用RES_Registration_Error变量显示了,RES_RegiStfaion_Error变量可以根据不同的语言包来显示不同的内容。
双击RES_Registration_Error信息,来到了反汇编窗口进行注册流程的分析,004D3C5处就是res_reistration_error变量,也就是显示错误信息的地方了。向上阅读反汇编代码,为了简单,一般我们会在这个函数的头部下断点来进行调试,这样就省去了逐行阅读反汇编代码的烦恼。根据OD的提示,函数的头部在004D3464处,按F2下断点,然后进行动态调试。
第四步、下好了断点后就可以运行程序进行动态调试了,按F9运行程序,程序运行后继续使用假注册码进行注册,点击OK后程序就断在了我们下的断点上,然后我们就可以进行单步调试了,按F8进行单步调试,每一次按F8后都要注意寄存器和缓冲区的变化,尤其是要关注注册码信息是否出现。
当程序执行到004D348E时,堆栈信息有所变换了,出现了我们输入的假注册码信息。这时就要留意了,一般注册算法就会在这个附近出现。根据经验来看,一般注册算法会在004D348E后的第一个call指令处,而关键跳则会出现在004D348E后的跳向注册失败信息的跳转指令上。先不管这些。我们向下按F7进行单步进入,也就是进入004D3491处的“call 004D8300”指令,来到004D8300处进行分析。
第五步、来到004D8300后进行F8单步调试,当程序运行到004D832B时出现了一个cmp指令进行比较,然后就是一个jne跳转,一般遇到了这样的比较,后面接跳转的地方我们都要格外注意,因为这很有可能是和注册算法有关的地方。
“Cmp eax,9”是将eax寄存器中的数字和9进行比较,我们来看看eax中的数值是多少呢?我们看到是十六进制的A,转换成十进制也就是10,正好是我们输入的假注册码的位数。也就是说这里是在判断我们输入的注册码是不是9位的,如果是的话则继续进行算法注册,如果不是则跳转到下面。通过分析可以得知,注册码必须是9位才可以进行正常的注册,现在我们按ctrl+F2重新加载程序进行调试,这次输入的注册码为“123456789”,正好是九位的注册码来进行调试,当再次运行到004D832B时,提供判断后继续执行算法。
第六步、下面就要进行算法分析了,可以说后面的反汇编代码就是整个注册算法了,我们可以通过边阅读边调试的方法来进行分析,分析如下:
通过上面对算法的反汇编代码的阅读与分析,可以得到以下的总结:注册码为九位字符,注册码第一位与第四位之和要大于8,注册码的第一、三、四位之和除10取余数必须与第六位相等,注册码第二位必须大于5,注册码第五位必须小于3,而注册码的其它位则没有限制,这是典型的序列号形式验证,有了算法后那么剩下的就是编写注册机了。
第二部分:编写注册机
注册机可以使用任何一种你熟悉的计算机语言来编写,我就使用Delphi来演示如何编写注册机吧。我们通过上面的算法发现,如果注册码全是数字的,则注册机编写起来就比较方便了,首先我们定义9个整型变量来分别代表注册码的九位:var one,two,three,four,five,six,seven,eight,nine:lnteger,。然后开始注册算法过程,首先注册码的第一位取小于9的一个随机数,然后使第一位与第四位之和要大于8,我们可以让注册码的第四位等于9减去注册码第一位。
注册码的第三位可以任意取值,这里我们就取小于10的随机数three:= Random(10);。第六位需要等于注册码第一、三、四位之和除10取余数six:=(one+threa+four) mod 10;。注册码第二位必须大于5,注册码第五位必须小于3,因此分别取大于5和小于3的随机数。
其它位数的注册码没有限制,可以任意赋值,这里我们就都取小于10的随机数了。
现在注册机的算法部分就已经写完了,下面使用Delphi创建一个窗体,添加一个文本框和按钮控件,双击“生成注册码”按钮进行代码的编写,将上面算法的核心代码复制过来就可以了,最后再将注册码输出到“注册码”文本框:edt1.Text:=inttostr(one)+inttostr(two)+inttostr(three)+inttostr(four)+inttostr(five)+inttostr(six)+inttostr(seven)+inttostr(eight)+inttostr(nine);。这样一个简单的注册机就编写完成了,编译运行一下来看看效果吧,每点击一下“生成注册码”后就会生成一个随机的注册码了,使用生成的注册码进行注册,已经成功的注册了。
算法分析和注册机编写到这里也就结束了,多加练习相信你也可以编写出属于自己的注册机的。
本文内容所提及均为本地测试或经过目标授权同意,旨在提供教育和研究信息,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,作者不鼓励或支持任何形式的非法破解行为。