小弟最近刚学破解,看了一天视频了,想试试手,于是上网找了点题目练练
下面便是小弟的处女作,程序很简单。但是毕竟自己动手搞出来的注册机,还是蛮激动的,比前两天玩爆破貌似感觉进步了一些,嘿嘿,好了,不扯了,下面进入正题
【文章标题】: 新人首次破解一小程序完成注册机~
【文章作者】: 黄瓜熟了
【软件名称】: 无名
【下载地址】: 网上搜索
【加壳方式】: 无壳
【使用工具】: PEiD、OD
【作者声明】: 记录破解学习,体验学习过程的美妙。。
首先打开 PeiD 查壳,发现没加壳。
打开程序输入用户和序列号如下
发现关键字符串,用OD载入程序,在汇编窗口单击鼠标右键,选择Ultra字符串参考—1.查找ASCII,发现有两个no luck!字符串,只有一个good work!
双击good work这一行,来到主程序窗口,下面果然有一个no luck!在此处按F2下断
F9运行程序,Help->Register,再次输入刚才的账号(随便输个错的也行)
点”OK”后程序会被OD断下(断点的位置没下错,嘿嘿),按F8向下执行
下面第一个retn返回后,不要动,到达下面这个地方
注意了 00401241位置有一个cmp命令,很有可能是我们想要的东西。
00401228 68 8E214000 push Cruehead.0040218E ; dsds
0040122D E8 4C010000 call Cruehead.0040137E
00401232 50 push eax
00401233 68 7E214000 push Cruehead.0040217E ; 43
00401238 E8 9B010000 call Cruehead.004013D8
0040123D 83C4 04 add esp,4
00401240 58 pop eax
00401241 3BC3 cmp eax,ebx
00401243 74 07 je short Cruehead.0040124C
00401245 E8 18010000 call Cruehead.00401362
0040124A ^ EB 9A jmp short Cruehead.004011E6
0040124C E8 FC000000 call Cruehead.0040134D
00401251 ^ EB 93 jmp short Cruehead.004011E6
这里面的00401232 50 push eax
把Cruehead.0040137E中的返回值保存了下来,之后又pop eax,并拿它做比较,可以看出来密码测试与它有关,于是可在00401228处下断之后F9,发现程序果然在这地方被OD断了下来
观察最后cmp要用到eax和ebx但是现在两个值都不清楚,因此下面两个函数都进去看看吧,F7单步进入0040122D处的函数,程序进入如下位置
其中这一行 0040138B 721F jb short Cruehead.004013AC
是在AL的值小于’A’时直接跳出来了,输出no luck!,因此账号不能用数字了哦。
00401394 E8 39000000 call Cruehead.004013D2
这一行为al为小写字母的ASCII码时的情况,单步跟进去看看吧
原来是把al的值减20H,也就是把小写字母变成大写字母了
返回继续F8单步,让程序运行到这一行
0040139C 5E pop esi ; Cruehead.0040218E
下面还有个函数,F7再进去看看
好了,到了关键地方了,这个函数是通过刚才输入的账号 abcd来计算edi的值,很简单,只是把 abcd(此处已经变成ABCD)的值按ASCII码加起来了,即edi=’A’+’B’+’C’+’D’
算好edi后返回到这里
可以看出来再把刚才的edi与5678异或一下,放于eax中然后返回
好了,第一个函数终于计算完成了,下面继续F7单步,进入第二个函数中吧,如下
这个函数简单,只是把密码简单进行一下10进制字符串到16进制的处理,处理后的数放在edi中,然后再用edi与1234H进去异或,存在ebx中返回,至此,上面两个对字符串处理的函数均已经处理完毕,现在开始比较两个函数计算机出来的数了
可以看出来我们刚才输入的账号密码经过运算后是不相同的,下面我们根据刚才所分析的算法写一个注册机,简单用C语言写了个程序测试一下。
#include<stdio.h>
void main()
{
char str[10];
int i,sum=0;
printf("输入账号:");
scanf("%s",&str);
for(i=0;str[i]!='\0';i++)
{
if(str[i]>='a'&&str[i]<='z')
str[i] = str[i] - 0x20;
}
for(i=0;str[i]!='\0';i++)
{
sum += str[i];
}
sum = sum^0x5678^0x1234;
printf("密码应为:%d\n",sum);
}
下面我们来试试结果正确与否,打开程序输入上述账号密码,得出下面的结果:
再多试几个,发现注册算法没有问题,其中账号长度最长为10
费了一下午时间写这个帖子,大家见笑了。。
Cruehead.1.rar
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课