-
-
[原创]我的第一个算法注册机,适合菜鸟练手,高手请飘过
-
发表于: 2010-2-25 22:40 9825
-
【文章标题】: 我的第一个算法注册机,适合菜鸟练手,高手请飘过
【文章作者】: whuwy
【作者邮箱】: whuwy@163.com
【作者QQ号】: 503270924
【软件名称】: CrueHead'a的crackme
【软件大小】: 12K
【下载地址】: 本地下载
【加壳方式】: 无
【保护方式】: 无壳
【编写语言】: MASM32/TASM32
【使用工具】: PEiD OllyDbg
【操作平台】: Windows XP
【软件介绍】: 无
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【详细过程】
看了BGCoder的使用OllyDbg从零开始Cracking(http://bbs.pediy.com/showthread.php?t=98569),对其附件中的CrueHead'a的crackme很感兴趣,研究了一下,发现虽然该crackme不是明码比较,但比较容易写出算法注册机,很适合我等菜鸟练手。
第一部分 crackme的分析
一、 首先用PEiD对其进行扫描,无壳。OK!
二、运行该crackme,随便输入用户名和注册码,弹出错误对话框
这样就省事多了,我们直接可以根据字符串来查找关键函数。
三、在OD中打开crackme,右键查找->所有参考文本字符串,查找到如下字符串,选择“No Luck there,mate!”然后右键反汇编窗口中跟随,就到了反汇编窗口中该ASCII码对应的位置。
四、在反汇编窗口向上翻看,我们找到了弹出正确窗口的函数,就在“No Luck there,mate!”的上面,选中该函数的第一句,在信息窗口中有提示“本地调用来自 0040124C”,也就是说0040124C行调用了该函数。
五、继续滚动来到0040124C行,可以看到该行上面有一个CMP+JE结构,这是一个典型的比较判断语句,因此在先在CMP出下断点。
六、F9运行,输入用户名和密码。
来到断点处从信息窗口中我们可以看到此时EBX和EAX并不相等。从反汇编窗口中我们看到两个熟悉的ASCII字符,“WHUWY”“878787”这两个不正是我们输入的用户名和密码吗?(注:用户名经过了转换,变为了大写)也就是说用户名和密码经过了计算,返回值保存在EBX和EAX中,然后进行判断。这正是典型的“f(用户名)=f(密码)”的判断格式,这样一来我们就不能简单的根据明码判断来获得用户名和注册码,但我们可以根据其算法作出注册机。因此我们在计算用户名处下断点。
七、CTRL+F2重新运行,输入用户名和注册码,进入到第一个断点处,按F7步入。
根据上图注释中的分析,在00401394处按F7步入。
经过分析,原来该函数的目的是将小写字符转换为大写。
八、然后我们来到了0040139D |. E8 20000000 CALL CRACKME.004013C2 处,这是一个关键的算法,按F7步入。
根据分析,我们知道该函数对转换后的用户名ASCII码进行相加,得出结果存在EDI中。
继续F8,在得出用户名各字符相加的结果后,又调用XOR EDI,5678将结果与5678进行了异或处理。然后返回到最初我们调用计算用户名的语句。
九、我们在计算密码处按F7步入跟进。
经过分析,我们可知,计算用户注册码就是的算法就是将注册码的ASCII码转换为正常数字之后再与1234异或。
十、返回到判断比较的函数。
此时,如果将JE SHORT 0040124C中的JE改成JNE就可以实现爆破,但我们的目的是做出算法注册机,不然以上这么多的算法分析就白费了。O(∩_∩)O~
第二部分 注册机的制作
经过上述分析,我们可以知道该crackme的算法是先算出用户名转换为大写后的ASCII码之和,然后与5678异或,再算出用户注册码与1234的异或(注册码先经过一定的转换变为数字);最后进行比较。
由于XOR异或运算具有可逆性(姑且这么叫吧),即如果A XOR B = C,则 C XOR B = A。如下图所示(该工具是破解辅助计算器,破解必备,我会在附件中上传此工具。)
我们可以直接把算出的用户名之和与1234进行异或,即得出正确的注册码。
具体的注册机代码如下:
#include <stdio.h>
#include <string.h>
void main(void)
{
unsigned long num = 0;
int i;
char name[20];
printf("Keymaker of CrueHead'a 'CrackMe by whuwy\n");
printf("【看雪学院】http://www.pediy.com\n\n\n");
printf("Input your name:");
scanf("%s",name);
while (strlen(name)>20)
{
// 算法的原理都是一样的,在这里为了便于实现,我们将用户名限制在20位
// 实际上20位以上的用户名也是可以算出注册码的
printf("please entry your name blew 20 letters\n:");
scanf("%s",name);
}
for(i=0;name[i]!='\0';i++)
{
if (name[i]<60)
{
printf("your name must be letters\n:");
break;
}
if (name[i]>91)
{
num += name[i] - 32;
}
else
{
num += name[i];
}
}
num ^=0x5678;
num ^=0x1234;
printf("\n");
printf("Registration code = %ld\n",num);
}
测试一下,
输入用户名whuwy,算出的正确注册码为17896
重新运行crackme,输入用户名whuwy和注册码17896
大功告成!
【经验总结】:
1、 对初学者而言,比较实际的锻炼方法是多找一些高手些的crackme来练习。现在随着加密与解密的相互较量,正式软件的加密一般都比较复杂,不适合我等菜鸟的练手。高手写的crackme一般都是专门针对某一个问题或某一算法来写的,更有针对性一些。等到一定程度,学会了脱壳等技巧,可以再找些共享软件来练习。
2、 作为初学者,需要对基本的汇编语言有所了解,不需要掌握很多,关键的语句记住就行。但需要明白ASCII码与各进制的转换关系,这在反汇编中经常遇到。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2010年02月25日 22:27:53
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- [转帖]利用QQ游戏破解QQ密码 10289
- [原创]我的第一个算法注册机,适合菜鸟练手,高手请飘过 9826
- [讨论]论坛在线需要经常刷新具体是要多久刷新一次? 1932