(不要问我为什么不在52写文章,不要问我!)
文章最后附带本次教程的WinAudioRecorder软件官方版及注册机,供大家学习交流使用
【软件名称】:WinAudio Recorder
【版本信息】:2.2.2.0
【编写语言】:Microsoft Visual C++ 7.0(PEID识别)
【软件介绍】:一款简单易用的高质量声卡录音软件。能够以彻底CD音质录制各种Windows应用程序播放的音频信息。同时支持从麦克风/录音带/录像带或者其他的输入设备中输入的音频信号。
【破解内容】:该软件在未注册情况下可正常使用,但录音功能只能录制1分钟以内的音频文件,注册后将取消这个限制。
【破解工具】:PEID、OllyDbg
首先打开安装程序正常进行安装
安装完成后进入软件主目录下,运行主程序
会出现以下界面,声明试用版只能录制生成1分钟以下的音频文件,或者点击“Buy Now”跳转到一个页面购买以获得注册码:
购买页面
(呵呵,25USD=161RMB啊,可是只能录制1分钟的音频,还不如其他免费软件呢。。。)
那就只能破解它了,我们使用PEID查壳:
是Microsoft Visual C++ 7.0的语言,没壳,这样也相对简单一点。
然后运行一下验证过程,找一下相关回显字符串的内容,如下:
“Please inputcorrect User Name!”
“Please inputcorrect Registration Code!”
这两个字符串将作为我们破解工作的切入点。
准备工作到此结束,接下来我们开始对用户名和注册码的破解。
使用OllyDbg载入软件主程序,点击F9一次进入程序入口
使用Ultra String Reference插件(没有可自行下载安装)查找字符串,可以直接搜“Please”就找到了我们之前看到的两个字符串
双击就来到了对应的代码段,这个应该就是验证注册码的代码部分,先在这加个断点,重新运行,输入便于观察的测试用户名:123456,注册码:qwerty(还不知道注册码是数字还是英文,先尝试),来到刚才断点的位置
走了一遍发现用户名要大于等于2字节,而注册码要大于等于8字节,用户名的条件满足,但注册码长度不够导致跳转到注册失败,提前结束验证。
第二次尝试,输入测试用户名:12345678,注册码:qwertyuiop
顺利进入验证部分,按F7一步步跟着走,注意观察每一步的汇编代码和寄存器变化
对于用户名的检查机制如下:从用户名第1个字节开始,逐字节进行一系列运算并将结果进行保存,估计保存结果将作为真正的注册码,运算方法在之后详细说明。
我们先继续单步跟踪,并做一些必要的注释,记录下来每一步执行的操作。
用户名检查完成之后,接下来就进行注册码的验证。
对于注册码的验证就比较简单了,首先是判断注册码是否达到了8位,这段代码很冗余,一位一位的判断直到8位,然后走到这里,才开始比较注册码
比较完第一位显然不对,达到一个较远的跳转【0040F38E】,到达这里
应该是跳到注册失败的代码,但是再次进行了注册码第一位的比较,继续跟着走,就发现如下情况:
注册码第1位与0x33(‘8’)比较
注册码第2位与0x33(‘3’)比较
注册码第3位与0x36(‘6’)比较
注册码第4位与0x36(‘6’)比较
注册码第5位与0x36(‘6’)比较
注册码第6位与0x31(‘1’)比较
注册码第7位与0x34(‘4’)比较
注册码第8位与0x36(‘6’)比较
这很明显就是个写死的硬代码“83666146”,做了这么久的跟踪结果却得到一个固定的注册码(是不是前面的那么多比较太多余了?那还弄个User Name有什么用?)
暂且是可以注册了,但是这个看起来像一个开发人员测试用的万能注册码。
可能事实并没有那么简单。
回想之前的的步骤,出现过第一次比较就跳出的情况(就是那个较远的跳转),那么推测这一段才是真正的注册码的验证,我们换个注册码再走一遍
这个位置开始把EDX对应的注册码写成对应比较的真值,一步步走下去就可以得到最终的注册码,这样证实了刚才的推测,接下来就需要了解真值的来源,也就是注册码的计算方法。
我们回到用户名的检查代码段,可以以单步进入的方式,跟踪每一位用户名的运算方法,这个时候就体现每步注释的好处了,具体如下:
EAX=第1位用户名
EAX=EAX|0x52
EAX=EAX%0x0A
第1位注册码=EAX
EAX=第2位用户名
EAX=EAX|0x45
EAX=EAX%0x0A
第2位注册码=EAX
EAX=第1位用户名
EAX=EAX|0x43
EAX=EAX%0x0A
第3位注册码=EAX
EAX=第2位用户名
EAX=EAX|0x4F
EAX=EAX%0x0A
第4位注册码=EAX
EAX=循环每一位用户名的ASCII求和
EAX=EAX%0x0A
第5位注册码=EAX
在这之后注册码就生成了,但是联系到最开始的注册码不得少于8位,因此我们还得随机补上一段,简便起见我们只加上后3位,当然可以加上更多位。
至此破解流程就结束了,接下来我们就可以写注册机算法了。
根据上述的汇编代码,我们写出注册码的算法:
char[] key = new char[9];
key[0] = (char)((name[0] | 0x52) % 10 + 0x30);
key[1] = (char)((name[1] | 0x45) % 10 + 0x30);
key[2] = (char)((name[0] | 0x43) % 10 + 0x30);
key[3] = (char)((name[1] | 0x4f) % 10 + 0x30);
key[4] = (char)(value % 10 + 0x30);// value为逐位用户名ASCII求和
//第6、7、8位采用对前5位校验的形式生成,确保对不同用户名生成不同,但对相同用户名生成相同
key[5] = (char)(((char)(key[0]+key[1]+key[2]) - 0x30) % 10 + 0x30);
key[6] = (char)(((char)(key[0] + key[2] + key[4]) - 0x30) % 10 + 0x30); ;
key[7] = (char)(((char)(key[1] + key[3] + key[4]) - 0x30) % 10 + 0x30); ;
key[8] = '\0';
//减0x30的原因只是为了将输入的字符串转换成int类型再进行运算
【编写语言】:C# .Net
【编译环境】:vs2015
【语言框架】:.Net Framework4.5.2
将上述的算法加入到函数当中,封装在程序中,方便快捷交互良好地提供注册算法计算。
注册机界面:
运行情况:
“User Name”框中输入12345678,点击“生成”按钮
这样就得到了用户名12345678的真正注册码59570562
注册成功!