【破文标题】一个简单的CRACKME
【破解作者】吹风生
【使用工具】OllDbg1.10、VISUAL C++08
【破解日期】2009-08-09
【下载地址】http://bbs.pediy.com/upload/2005/37/files/crackme6.rar
【软件简介】07年CRACKME中找的。。算法是中间注册码
【破解声明】我是一只菜鸟,做个实例,发表下感想,高手别笑话哈。
前一段时间一直在看书之类的。。觉得不动手不行啊。。趁着看雪又要举办CRACKME2009,就找个以前07的
的。呵呵,这是我这个菜鸟的第一篇文章。写的不好大家见谅哈。
好了,说下这个CRACKME,这个CRACKME很早了。4nil大侠早就破过。。原文章:http://bbs.pediy.com/showthread.php?t=11222只是觉得这里面有一些地方我们不懂但他觉得很容易呵呵,所以就没写。。我给他补充补充。顺便说下里面的一个问题。。
【破解过程】
这个CRACKME加了ASPack 2.x壳,脱掉壳的过程原文章已经有了。这里不再讲了(话说自己脱壳不是很好的说)
首先自己随便输入Name:zlslyf和Serial:19891001..没提示。。用OD载入。。很简单。直接下GetDlgItemTextA断点。F9运行
,断后,ALT+F9返回。。来到:
00401509 /$ 55 push ebp
0040150A |. 89E5 mov ebp, esp
0040150C |. 81EC 00010000 sub esp, 100
00401512 |. 53 push ebx
00401513 |. 56 push esi
00401514 |. 57 push edi
00401515 |. 8DBD 00FFFFFF lea edi, [local.64]
0040151B |. 8D35 5E244000 lea esi, dword ptr ds:[40245E]
00401521 |. B9 40000000 mov ecx, 40
00401526 |. F3:A5 rep movs dword ptr es:[edi], dword ptr ds:[esi]
00401528 |. 68 00010000 push 100 ; /Count = 100 (256.)
0040152D |. 8D85 00FFFFFF lea eax, [local.64] ; |
00401533 |. 50 push eax ; |Buffer
00401534 |. 6A 65 push 65 ; |ControlID = 65 (101.)
00401536 |. FF75 08 push [arg.1] ; |hWnd
00401539 |. E8 FA010000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
0040153E |. 89C3 mov ebx, eax ; 去NAME字符串长度。0则结束。
00401540 |. 09DB or ebx, ebx
00401542 |. 75 04 jnz short unpacked.00401548
00401544 |. 31C0 xor eax, eax
00401546 |. EB 50 jmp short unpacked.00401598
00401548 |> BF BC020000 mov edi, 2BC ; [1]从这开始。
0040154D |. BE 30000000 mov esi, 30
00401552 |. B8 48000000 mov eax, 48
00401557 |. 99 cdq
00401558 |. F7FB idiv ebx
0040155A |. 29C6 sub esi, eax
0040155C |. 8D34B6 lea esi, dword ptr ds:[esi+esi*4]
0040155F |. 29F7 sub edi, esi
00401561 |. 6BFF 6B imul edi, edi, 6B
00401564 |. 81EF 6CCF0000 sub edi, 0CF6C
0040156A |. 81FF 00230000 cmp edi, 2300
00401570 |. 7F 08 jg short unpacked.0040157A
00401572 |. 81FF 90010000 cmp edi, 190
00401578 |. 7D 04 jge short unpacked.0040157E ; [1]到这结束。字符串长度name_len必须满足:0x190<=(0x2bc-(0x30-0x48/name_len)*5)*0x6b-0x0cf6c<=0x2300
0040157A |> 31C0 xor eax, eax
0040157C |. EB 1A jmp short unpacked.00401598
0040157E |> 8D85 00FFFFFF lea eax, [local.64]
00401584 |. 50 push eax ; Name
00401585 |. 53 push ebx ; Name_len
00401586 |. FF75 08 push [arg.1]
00401589 |. E8 77FDFFFF call unpacked.00401305 ; 序列号生成过程。。。
0040158E |. 83C4 0C add esp, 0C
00401591 |. 09C0 or eax, eax
00401593 |. 74 03 je short unpacked.00401598
00401595 |. 31C0 xor eax, eax
00401597 |. 40 inc eax
00401598 |> 5F pop edi
00401599 |. 5E pop esi
0040159A |. 5B pop ebx
0040159B |. C9 leave
0040159C \. C3 retn
进入序列号生成过程
00401305 /$ 55 push ebp
00401306 |. 89E5 mov ebp, esp
00401308 |. 81EC 2C040000 sub esp, 42C
0040130E |. 53 push ebx
0040130F |. 56 push esi
00401310 |. 57 push edi
00401311 |. 8DBD FCFEFFFF lea edi, [local.65]
00401317 |. 8D35 38204000 lea esi, dword ptr ds:[402038]
0040131D |. B9 40000000 mov ecx, 40
00401322 |. F3:A5 rep movs dword ptr es:[edi], dword ptr ds:[esi]
00401324 |. 8DBD E1FBFFFF lea edi, dword ptr ss:[ebp-41F]
0040132A |. 8D35 38214000 lea esi, dword ptr ds:[402138]
00401330 |. B9 40000000 mov ecx, 40
00401335 |. F3:A5 rep movs dword ptr es:[edi], dword ptr ds:[esi]
00401337 |. 8DBD E1FDFFFF lea edi, dword ptr ss:[ebp-21F]
0040133D |. 8D35 38224000 lea esi, dword ptr ds:[402238]
00401343 |. B9 40000000 mov ecx, 40
00401348 |. F3:A5 rep movs dword ptr es:[edi], dword ptr ds:[esi]
0040134A |. 8DBD E1FCFFFF lea edi, dword ptr ss:[ebp-31F]
00401350 |. 8D35 38234000 lea esi, dword ptr ds:[402338]
00401356 |. B9 40000000 mov ecx, 40
0040135B |. F3:A5 rep movs dword ptr es:[edi], dword ptr ds:[esi]
0040135D |. 8DBD DCFBFFFF lea edi, [local.265]
00401363 |. 8D35 38244000 lea esi, dword ptr ds:[402438]
00401369 |. B9 05000000 mov ecx, 5
0040136E |. F3:A4 rep movs byte ptr es:[edi], byte ptr ds:[esi]
00401370 |. 8DBD D6FBFFFF lea edi, dword ptr ss:[ebp-42A]
00401376 |. 8D35 3D244000 lea esi, dword ptr ds:[40243D]
0040137C |. B9 03000000 mov ecx, 3
00401381 |. F3:66:A5 rep movs word ptr es:[edi], word ptr ds:[esi]
00401384 |. 8DBD E1FEFFFF lea edi, dword ptr ss:[ebp-11F]
0040138A |. 8D35 43244000 lea esi, dword ptr ds:[402443]
00401390 |. B9 1B000000 mov ecx, 1B
00401395 |. F3:A4 rep movs byte ptr es:[edi], byte ptr ds:[esi] ; 前面是在初始化为0.。。。
00401397 |. C745 FC 00000>mov [local.1], 0
0040139E |. 68 00010000 push 100 ; /Count = 100 (256.)
004013A3 |. 8D85 E1FCFFFF lea eax, dword ptr ss:[ebp-31F] ; |
004013A9 |. 50 push eax ; |Buffer
004013AA |. 6A 66 push 66 ; |ControlID = 66 (102.)
004013AC |. FF75 08 push [arg.1] ; |hWnd
004013AF |. E8 84030000 call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
004013B4 |. 09C0 or eax, eax ; 取序列号。。
004013B6 |. 0F84 48010000 je unpacked.00401504
004013BC |. B8 CF110000 mov eax, 11CF ; [2]从这。
004013C1 |. 0FB68D E1FCFF>movzx ecx, byte ptr ss:[ebp-31F]
004013C8 |. 99 cdq
004013C9 |. F7F9 idiv ecx
004013CB |. 83FA 17 cmp edx, 17
004013CE |. 74 07 je short unpacked.004013D7 ; [2]到此。。对序列号的第一个字母必须满足:0x11cf%Name[0]==0x17...注册机我就直接拿一个字母H了。
004013D0 |. 31C0 xor eax, eax
004013D2 |. E9 2D010000 jmp unpacked.00401504
004013D7 |> 31DB xor ebx, ebx
004013D9 |. EB 0B jmp short unpacked.004013E6
004013DB |> 8B45 10 /mov eax, [arg.3]
004013DE |. 0FBE0418 |movsx eax, byte ptr ds:[eax+ebx]
004013E2 |. 0145 FC |add [local.1], eax
004013E5 |. 43 |inc ebx ; 这个过程计算NAME各个字母的ASCII值的总和。。
004013E6 |> 3B5D 0C cmp ebx, [arg.2]
004013E9 |.^ 7C F0 \jl short unpacked.004013DB
004013EB |. 31DB xor ebx, ebx
004013ED |. E9 83000000 jmp unpacked.00401475
004013F2 |> 8B55 10 /mov edx, [arg.3]
004013F5 |. 0FBE3C1A |movsx edi, byte ptr ds:[edx+ebx]
004013F9 |. 8B75 FC |mov esi, [local.1] ; [local.1]存放Name各字母和。。。
004013FC |. 89D9 |mov ecx, ebx
004013FE |. C1E1 02 |shl ecx, 2
00401401 |. 89DA |mov edx, ebx
00401403 |. 42 |inc edx
00401404 |. 29D1 |sub ecx, edx
00401406 |. 0FB68C0D E1FE>|movzx ecx, byte ptr ss:[ebp+ecx-11F] ;重点是这。也是写这篇文章的很多一部分原因。当i=0时。3i-1=-1,没有访问到字母表。下面讨论。。
0040140E |. 89FA |mov edx, edi
00401410 |. 31CA |xor edx, ecx
00401412 |. 89F1 |mov ecx, esi
00401414 |. 0FAFCB |imul ecx, ebx
00401417 |. 29F1 |sub ecx, esi
00401419 |. 89CE |mov esi, ecx
0040141B |. 83F6 FF |xor esi, FFFFFFFF
0040141E |. 8DB432 4D0100>|lea esi, dword ptr ds:[edx+esi+14D]
00401425 |. 8B4D 0C |mov ecx, [arg.2]
00401428 |. 89DA |mov edx, ebx
0040142A |. 83C2 03 |add edx, 3
0040142D |. 0FAFCA |imul ecx, edx
00401430 |. 0FAFCF |imul ecx, edi
00401433 |. 89F0 |mov eax, esi
00401435 |. 01C8 |add eax, ecx
00401437 |. B9 0A000000 |mov ecx, 0A
0040143C |. 31D2 |xor edx, edx
0040143E |. F7F1 |div ecx
00401440 |. 83C2 30 |add edx, 30
00401443 |. 88941D FCFEFF>|mov byte ptr ss:[ebp+ebx-104], dl
0040144A |. 0FB6BC1D FCFE>|movzx edi, byte ptr ss:[ebp+ebx-104]
00401452 |. 81F7 ACAD0000 |xor edi, 0ADAC
00401458 |. 89DE |mov esi, ebx
0040145A |. 83C6 02 |add esi, 2
0040145D |. 89F8 |mov eax, edi
0040145F |. 0FAFC6 |imul eax, esi
00401462 |. B9 0A000000 |mov ecx, 0A
00401467 |. 99 |cdq
00401468 |. F7F9 |idiv ecx
0040146A |. 83C2 30 |add edx, 30
0040146D |. 88941D FCFEFF>|mov byte ptr ss:[ebp+ebx-104], dl
00401474 |. 43 |inc ebx
00401475 |> 3B5D 0C cmp ebx, [arg.2]
00401478 |.^ 0F8C 74FFFFFF \jl unpacked.004013F2 ; 这个过程得出中间注册码。过程详见注册机。
0040147E |. 8D85 FCFEFFFF lea eax, [local.65]
00401484 |. 50 push eax
00401485 |. 6A 54 push 54
00401487 |. 8D85 DCFBFFFF lea eax, [local.265]
0040148D |. 50 push eax ; |Format
0040148E |. 8D85 E1FBFFFF lea eax, dword ptr ss:[ebp-41F] ; |
00401494 |. 50 push eax ; |s
00401495 |. E8 CE020000 call <jmp.&USER32.wsprintfA> ; \wsprintfA
0040149A |. 8B7D 0C mov edi, [arg.2] ; “T458527"以T+数字部分输出..
0040149D |. 89F8 mov eax, edi
0040149F |. 0FAF45 FC imul eax, [local.1]
004014A3 |. B9 64000000 mov ecx, 64
004014A8 |. 99 cdq
004014A9 |. F7F9 idiv ecx
004014AB |. 89D7 mov edi, edx
004014AD |. 83C7 30 add edi, 30
004014B0 |. 57 push edi
004014B1 |. 8DBD E1FBFFFF lea edi, dword ptr ss:[ebp-41F]
004014B7 |. 57 push edi
004014B8 |. 8DBD D6FBFFFF lea edi, dword ptr ss:[ebp-42A]
004014BE |. 57 push edi ; |Format
004014BF |. 8DBD E1FDFFFF lea edi, dword ptr ss:[ebp-21F] ; |
004014C5 |. 57 push edi ; |s
004014C6 |. E8 9D020000 call <jmp.&USER32.wsprintfA> ; \wsprintfA
004014CB |. 83C4 20 add esp, 20 ; "T458527-104"再加上EDI的十进制。。。
004014CE |. 8D8D E1FDFFFF lea ecx, dword ptr ss:[ebp-21F]
004014D4 |. 83C8 FF or eax, FFFFFFFF
004014D7 |> 40 /inc eax
004014D8 |. 803C01 00 |cmp byte ptr ds:[ecx+eax], 0
004014DC |.^ 75 F9 \jnz short unpacked.004014D7
004014DE |. 50 push eax ; /Arg3
004014DF |. 8D85 E1FCFFFF lea eax, dword ptr ss:[ebp-31F] ; |
004014E5 |. 50 push eax ; |Arg2
004014E6 |. 8D85 E1FDFFFF lea eax, dword ptr ss:[ebp-21F] ; |
004014EC |. 50 push eax ; |Arg1
004014ED |. E8 D0FDFFFF call unpacked.004012C2 ; \这个过程是最后验证了。。
004014F2 |. 83C4 0C add esp, 0C
004014F5 |. 83F8 00 cmp eax, 0
004014F8 |. 75 07 jnz short unpacked.00401501
004014FA |. B8 00000000 mov eax, 0
004014FF |. EB 03 jmp short unpacked.00401504
00401501 |> 31C0 xor eax, eax
00401503 |. 40 inc eax
00401504 |> 5F pop edi
00401505 |. 5E pop esi
00401506 |. 5B pop ebx
00401507 |. C9 leave
00401508 \. C3 retn
进入:
004012C2 /$ 55 push ebp
004012C3 |. 89E5 mov ebp, esp
004012C5 |. 53 push ebx
004012C6 |. 56 push esi
004012C7 |. 57 push edi
004012C8 |. 8B5D 10 mov ebx, [arg.3]
004012CB |. 31F6 xor esi, esi
004012CD |. 46 inc esi
004012CE |. EB 29 jmp short unpacked.004012F9
004012D0 |> 8B55 08 /mov edx, [arg.1]
004012D3 |. 0FBE3C32 |movsx edi, byte ptr ds:[edx+esi]
004012D7 |. 89F8 |mov eax, edi
004012D9 |. 83F0 20 |xor eax, 20
004012DC |. B9 0A000000 |mov ecx, 0A
004012E1 |. 99 |cdq
004012E2 |. F7F9 |idiv ecx
004012E4 |. 89D7 |mov edi, edx
004012E6 |. 83C7 30 |add edi, 30
004012E9 |. 8B55 0C |mov edx, [arg.2]
004012EC |. 0FBE1432 |movsx edx, byte ptr ds:[edx+esi]
004012F0 |. 39D7 |cmp edi, edx
004012F2 |. 74 04 |je short unpacked.004012F8
004012F4 |. 31C0 |xor eax, eax
004012F6 |. EB 08 |jmp short unpacked.00401300
004012F8 |> 46 |inc esi
004012F9 |> 39DE cmp esi, ebx
004012FB |.^ 7C D3 \jl short unpacked.004012D0 ; 这个过程将刚才得到的注册码进行(midname[i]^0x20)%10+0x30运算后与输入的序列号作比较。。全对则成功。。
004012FD |. 31C0 xor eax, eax
004012FF |. 40 inc eax
00401300 |> 5F pop edi
00401301 |. 5E pop esi
00401302 |. 5B pop ebx
00401303 |. 5D pop ebp
00401304 \. C3 retn
好了,整个过程很简单,就两个过程。。一个得出中间注册码,将中间注册码格式为某种形式后,进行某种运算。。运算后与输入的Serial进行比较,正确则成功。。
接下来说下上面说的访问不到字母表的问题。。在软件上运行的时候因为全被初始化为0,所以就等于与0进行异或。但在写注册机的时候,就不知道怎么初始化到table[]数组的前面的堆栈空间。。在VISUAL C++里调试中观察到name位于0x0013ff0c,table位于0x0013ff44.于是想扩大name的大小.以便能够初始化到table数组的堆栈空间前。但后来发现随着我的扩大,编译器把name的内存地址减小,这样扩大空间就没用了。尽管我计算好相差的大小来设计name的空间大小,但一直相差8.。于是想到好像以前看过内存中数组后好像还有两个指针。有知道的人请告诉我。。实在没办法就把注册机分两种情况了。大家有好的办法交流下。。。呵呵。。下面是注册机代码:
#include "stdafx.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int main()
{
char table[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";char name[20]={0};int sum=0;
char midname[20]={0};char lastname[6];char serial[20]={0};int i,p;
scanf("%s",name);
int name_len=strlen(name);
for(int i=0;i<name_len;i++)
{
sum+=name[i];
}
if(0x190<=(0x2bc-(0x30-0x48/name_len)*5)*0x6b-0x0cf6c<=0x2300)
{
serial[0]='H';
for(i=0;i<name_len;i++)
{
if(!i)
{
p=name[0];
}
else
{
int t=3*i-1; p=name[i]^table[t];
}
int SUM=(sum*i-sum)^0xffffffff;
int d=SUM+p+0x14d+name_len*(i+3)*name[i];
int result=(((d%10+0x30)^0x0adac)*(i+2))%10+0x30;
midname[0]='T';
midname[i+1]=result;
}
midname[name_len+1]='\0';
int s=(name_len*sum)%0x64+0x30;
ultoa(s,lastname,10); 这小段自己写的很繁琐,看了4nil的,觉得很好,就拿来了,请见谅哈。。
strcat(midname,"-");
strcat(midname,lastname);
int serial_len=strlen(midname);
for(i=1;i<serial_len;i++)
{
serial[i]=(midname[i]^0x20)%10+0x30;
}
printf("%s",serial);
}
system("PAUSE");
return 0;
}
PS:看了这么多。。还不如做一遍来的深刻啊。。呵呵。。另外这个CRACKME4nil大侠写过,所以有得罪之处敬请见谅!!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!