本文是对happytown的Crackme_0006.exe的算法分析,另外还附带了一个注册机,我也是初学者,希望对初学者有所帮助!
(原程序在http://bbs.pediy.com/upload/2005/37/files/crackme_0006.rar)
经过分析,本算法分为两个部分:
(以下分析去除了反编译代码中繁琐的函数调用,改用两个循环来说明问题的实质)
第一部分为从Name得到一个基础数eax,如下:
初始:
esi=00403104 [esi]="hejian"存放的是我们输入的Name(hejian是我的姓名^_^)
循环1的开始:
xor edx,edx
mov eax,1
movzx ecx,byte ptr ds:[esi]
inc esi
or ecx,ecx
je 跳出
mul ecx
add eax,edx
jmp 循环1的开始
循环1结束后:eax=704c8482,edx=00000046
接着:
rol eax,1 eax:e0990904
or eax,50BD5D92 eax:F0BD5D96
and eax,0fffffff eax:00BD5D96
第二部分为以eax为基础的一个算法进行循环,如下
初始:
edi=00402073 [edi]="071362de9f8ab45c"为作者存放的一组常数
esi=00403000 [esi]存放的是要计算的注册码,开始为空
循环2的开始:
mov dword ptr ss:[ebp-14],eax ;在堆栈中暂存eax的值
idiv 10 ;反编译的代码中这一段用一个函数实现的
mov eax,edx
mov ecx,eax
mov al,byte ptr ds:[edi+ecx]
mov byte ptr ds:[esi],al
mov eax,dword ptr ss:[ebp-14]
idiv 4 ;反编译的代码中这一段用一个函数实现的
mov dword ptr ss:[ebp-14],eax
or eax,eax
je 跳出去比较
inc esi
inc edi
jmp 循环2的开始
循环2结束后:[esi=00403000]="d2fd4e224ca1",(为注册码)
最后到了比较的部分:
push 00403000 ;[00403000]="d2fd4e224ca1"
push eax ;[eax]="19840203"
call kernel32.lstrcmpA
注:以上汇编代码中的数全部是16进制。
其实在调试的过程中,我们可以用Ctrl+N调出当前模块调用的函数名,
找到kernel32.lstrcmpA,在其上面下断点,运行后可直接在中断处得到
注册码,本文详尽地分析了其中的细节,把算法中重要的部分罗列在上.
本想用KeyMaker做一个注册机的,怎奈瑞星总报说是病毒,只好用C++。
下面是我为本算法写的注册机(使用了C++中嵌入式汇编):
#include <iostream>
int main()
{
char *C="071362de9f8ab45c"; //一个作者定义的常数
char *Name;
Name=new char[20];
memset(Name,0,20);
char *Serial;
Serial=new char[20];
memset(Serial,0,20);
std::cout<<"Please input Name:";
std::cin>>Name;
_asm
{
mov esi,Name
xor edx,edx
mov eax,1
loop1:
movzx ecx,byte ptr ds:[esi]
inc esi
or ecx,ecx
je end1
mul ecx
add eax,edx
jmp loop1
end1:
rol eax,1
or eax,0x50BD5D92 ;这个数不知道作者的本意是什么,为什么是0x50BD5D92
and eax,0x0FFFFFFF
mov edi,C
mov esi,Serial
xor ecx,ecx
loop2:
xor edx,edx
mov ebx,eax ;ebx暂放eax的数值
mov ecx,0x10
idiv ecx
mov eax,edx
mov ecx,eax
mov edi,C ;有了它,后面的 inc edi 无用
mov al,byte ptr ds:[edi+ecx]
mov byte ptr ds:[esi],al
mov eax,ebx
xor edx,edx
mov ecx,4
idiv ecx
mov ebx,eax
or eax,eax
je end2
inc esi
inc edi ;其实这一条指令去掉也可以
jmp loop2
end2:
}
std::cout<<"Serial is:"<<Serial<<std::endl<<"Writen by smarter! aganno2@163.com Good luck!"<<std::endl;
delete Name;
delete Serial;
return 0;
}
注册机的相关代码及程序可在这里下载。
附件:keygen.rar
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)