程序信息:
编号 | 制作者 | 保护方式 |
---|---|---|
002 | Afkayas | Name/Serial |
工具:
-
ollyDbg(简称OD)
-
Exeinfo PE
开始破解:
1.先用Exeinfo PE查看下程序(打开工具,将程序拖拽进去即可查看),得到信息如下图,可知该程序没有加壳,而且是用VB写的
2.接下来我们运行下程序,发现程序很简单,就是对用户名与序列号进行验证,验证错误会弹出提示对话框,同时用户名不能为空,序列号可以为空。
3.我们先用字符串试试看能能搜索到,用OD加载程序,右键->中文搜索引擎->智能搜索,可以发现搜索到的字符串比较少,很容易就发现了我们的错误提示字符串,同时看到了正确提示字符串,我们直接跟随正确字符串(选中右键->跟随或者选中回车键)
4.在正确提示“You Get It” 这一句上面有个je跳转指令跳过了弹出注册成功窗口的指令,直接跳到弹出注册失败窗口的指令处,显然这是个关键跳转,我们只要让其不跳转就行了,直接nop掉或者改成jnz(注意修改成jnz后输入正确的用户名与序列号反而不能验证成功,因为jnz与je跳转条件是反的),然后保存修改后的文件就完成了爆破。
5.我们继续向上看是哪处指令影响了此跳转,上面不远处就能发现是SI的值决定了此处跳转,那么继续往上看,发现SI的值由vbaStrCmp函数的返回值决定,当vbaStrCmp返回值为0,SI=-1,返回值不为0时,SI=0。上网查找该函数可知,这是字符串比较函数,当比较的两个字符串相同时,返回0,不相同是返回非0(具体返回1还是-1这里不讨论),所以这段代码就是比较两个字符串,如果相同,就不跳转到弹出错误框指令处,不相同,就会跳转到弹出错误框指令处
6.那么这么一分析,比较的很有可能是序列号,我们在00402533 调用比较函数处下个断点(F2),再次运行让程序断在此处,观察栈区和寄存器的值,可以在栈区发现我们输入的假码(用户随意输入的一般叫假码)和疑似真码的序列号AKA-682837(用户名不同,此值不同,以自己的为准)
7.运行将之前的序列号改成疑似真码的序列号AKA-682837重新验证,验证通过。也就是这就是我们要找的真码,那么我们继续向上分析这个真码是通过vbaStrCat拼接而成,其中AKA-是固定的。
8.继续向上一堆不知所云的函数,比较难跟,我们直接向上找到这个函数头部,然后在头部下个断点(F2),然后让程序跑起来,再次验证停在此处(用户名还是之前的,不要变),然后一直F8,观察寄存器与栈区的值,发现有682837(此值就是第六步中后面的数值,以自己的为准)就停下来。
9.一路单步到0x402445处出现了我们要的值,也就可以确定算法在上面
10.这次很幸运,上面就是算法,算法是:
(用户名长度 * 0x17CFB + 用户名第一个字符对应的ascii值)转换为10进制
11.那么算法知道了,我们就可以自己写个程序算出序列号了,还是用C++写的:
#include <stdio.h> #include <stdlib.h> #include <string> int main() { char name[20]; printf("请输入用户名: "); //获取用户名 scanf_s("%s", &name,20); //获取用户名的长度 int len = strlen(name); len *= 0x17CFB; len += name[0]; printf("序列号:AKA-%4d ", len); system("pause"); }
12.最后上效果图