│破解作者│ 大菜一号(西哈`就是偶啦!)
│对 象│ 一个CrackMe->简单
│平 台│ 自己乱封装的D版XP
│目 的│ 很简单的CrackMe,主要分析算法,纯技术交流!
│声明声明│
很久没来看雪呀,也很久没crack了,呵,突然发现了个,就献丑一下!:)这是菜鸟破文`西西~~~
************************************
嗯嗯,peid大哥告诉偶们说是VC写的一个程序`运行一看,呵,镜框式的编辑框。好咧快ctrl+n找个对话框函数GetDlgItemText->`有了`回车一下,断就设在第一个参考下咯!
name:大菜一号
code:121212
00401048 |. 8B35 A0404000 mov esi, dword ptr [<&USER32.GetDlgI>; USER32.GetDlgItem
我们断在这了,下面省了N个代码`直接看算法处吧~~~
004010A3 |. 6A 64 push 64
004010A5 |. 50 push eax
004010A6 |. 56 push esi
004010A7 |. FFD3 call ebx |GetWindowText ->这个函数`够熟悉了吧```取文本了
004010A9 |. 8D45 94 lea eax, dword ptr [ebp-6C]--------->name传到eax
004010AC |. 50 push eax
004010AD |. E8 CE020000 call 00401380
004010B2 |. 8BF8 mov edi, eax------------------------>name长度到edi
004010B4 |. 59 pop ecx
004010B5 |. 85FF test edi, edi
004010B7 |. 75 07 jnz short 004010C0
004010B9 |. 68 8C504000 push 0040508C
004010BE |. EB 30 jmp short 004010F0
004010C0 |> 83FF 03 cmp edi, 3------------------------->和3比较
004010C3 |. 7F 07 jg short 004010CC----------------->小于就完了
004010C5 |. 68 6C504000 push 0040506C
004010CA |. EB 24 jmp short 004010F0
004010CC |> 8D85 30FFFFFF lea eax, dword ptr [ebp-D0]-------->假码到eax
004010D2 |. 50 push eax
004010D3 |. E8 A8020000 call 00401380
004010D8 |. 85C0 test eax, eax
004010DA |. 59 pop ecx
004010DB |. 75 08 jnz short 004010E5
004010DD |. 68 5C504000 push 0040505C
004010E2 |. 56 push esi
004010E3 |. EB 0E jmp short 004010F3
004010E5 |> 837D 08 03 cmp dword ptr [ebp+8], 3---------->长度和3比较
004010E9 |. 7F 13 jg short 004010FE
004010EB |. 68 38504000 push 00405038
004010F0 |> FF75 F8 push dword ptr [ebp-8]
004010F3 |> FF15 AC404000 call dword ptr [<&USER32.SetWindowTex>
004010F9 |. E9 2C010000 jmp 0040122A
004010FE |> 33D2 xor edx, edx
00401100 |. 85FF test edi, edi
00401102 |. 7E 23 jle short 00401127
00401104 |> 8A4C15 94 /mov cl, byte ptr [ebp+edx-6C]---->每次循环都取name字符
00401108 |. 0FBEC1 |movsx eax, cl---------------------->name字符到eax
0040110B |. 0145 FC |add dword ptr [ebp-4], eax------->加上上次循环结果,第一次是加上0
0040110E |. 80F9 4A |cmp cl, 4A----------------------->字符和4a比较
00401111 |. 7C 06 |jl short 00401119--------------->小于就跳
00401113 |. 0FAF45 FC |imul eax, dword ptr [ebp-4]------->大于就*加上后的值
00401117 |. EB 06 |jmp short 0040111F
00401119 |> 0FAF45 FC |imul eax, dword ptr [ebp-4]------->小于就乘以加上后的值
0040111D |. D1E0 |shl eax, 1----------------------->再左移1位
0040111F |> 42 |inc edx
00401120 |. 8945 FC |mov dword ptr [ebp-4], eax------->把结果传到ebp-4
00401123 |. 3BD7 |cmp edx, edi
00401125 |.^ 7C DD \jl short 00401104
00401127 |> 8B45 FC mov eax, dword ptr [ebp-4]-------->把循环结果传到eax
0040112A |. 33D2 xor edx, edx
0040112C |. B9 24070000 mov ecx, 724---------------------->0x724到ecx
00401131 |. F7F1 div ecx--------------------------->除,下面分析后,知道只用其余数,就看作是取到edx就行了
00401133 |. 33C0 xor eax, eax
00401135 |. 85FF test edi, edi
00401137 |. 7E 20 jle short 00401159
00401139 |> 8A5C05 94 /mov bl, byte ptr [ebp+eax-6C]---->每次循环都取name字符
0040113D |. 0FBECB |movsx ecx, bl---------------------->name字符到ecx
00401140 |. 03D1 |add edx, ecx--------------------->加上上次循环结果(第一次循环为加上余数)
00401142 |. 80FB 40 |cmp bl, 40----------------------->字符和40比较
00401145 |. 7C 05 |jl short 0040114C--------------->小于就跳
00401147 |. 0FAFCA |imul ecx, edx--------------------->大于就*上面加后结果
0040114A |. EB 06 |jmp short 00401152
0040114C |> 0FAFCA |imul ecx, edx--------------------->小于就*上面加上后的结果
0040114F |. C1E1 02 |shl ecx, 2----------------------->再左移2位
00401152 |> 40 |inc eax
00401153 |. 8BD1 |mov edx, ecx--------------------->结果传到edx
00401155 |. 3BC7 |cmp eax, edi
00401157 |.^ 7C E0 \jl short 00401139
00401159 |> 8BC2 mov eax, edx---------------------->循环结束后的结果传到eax
0040115B |. 33D2 xor edx, edx
0040115D |. B9 25220000 mov ecx, 2225--------------------->0x2225传到ecx
00401162 |. 33DB xor ebx, ebx
00401164 |. F7F1 div ecx--------------------------->取余到edx
00401166 |. 33F6 xor esi, esi
00401168 |. 3BFB cmp edi, ebx
0040116A |. 7E 21 jle short 0040118D
0040116C |> 8A4435 94 /mov al, byte ptr [ebp+esi-6C]
00401170 |. 0FBEC8 |movsx ecx, al------------------------->每次循环都取name字符
00401173 |. 03D1 |add edx, ecx------------------------>加上上次循环结果(第一次是加上余数)
00401175 |. 3C 54 |cmp al, 54 ------------------------->字符和54比较
00401177 |. 7C 07 |jl short 00401180
00401179 |. 0FAFCA |imul ecx, edx------------------------>大于54就乘以加上后的结果
0040117C |. 8BD1 |mov edx, ecx------------------------>结果到edx
0040117E |. EB 08 |jmp short 00401188
00401180 |> 0FAFCA |imul ecx, edx------------------------>小于也乘上上面加上后的结果
00401183 |. 8D1449 |lea edx, dword ptr [ecx+ecx*2]------>乘积*2后加上乘积
00401186 |. D1E2 |shl edx, 1-------------------------->再左移1位
00401188 |> 46 |inc esi
00401189 |. 3BF7 |cmp esi, edi
0040118B |.^ 7C DF \jl short 0040116C
0040118D |> 33F6 xor esi, esi
0040118F |. 3BFB cmp edi, ebx
00401191 |. 7E 1F jle short 004011B2
00401193 |> 8A4435 94 /mov al, byte ptr [ebp+esi-6C]
00401197 |. 0FBEC8 |movsx ecx, al------------------------->每次循环都取name字符
0040119A |. 03D1 |add edx, ecx------------------------>加上上次循环结果(第一次就是加上上面循环结果)
0040119C |. 3C 4A |cmp al, 4A-------------------------->字符和4a比较
0040119E |. 7C 07 |jl short 004011A7
004011A0 |. 0FAFCA |imul ecx, edx------------------------>大于就乘以上面加上后的结果
004011A3 |. 8BD1 |mov edx, ecx------------------------>结果到edx
004011A5 |. EB 06 |jmp short 004011AD
004011A7 |> 0FAFCA |imul ecx, edx------------------------>小于就乘以上面加上后的结果
004011AA |. 8D1489 |lea edx, dword ptr [ecx+ecx*4]------>再*4加上后的乘积
004011AD |> 46 |inc esi
004011AE |. 3BF7 |cmp esi, edi
004011B0 |.^ 7C E1 \jl short 00401193
004011B2 |> 8BC2 mov eax, edx------------------------->循环结束后的结果到eax
004011B4 |. 33D2 xor edx, edx
004011B6 |. B9 342E0000 mov ecx, 2E34------------------------>0x2e34到ecx
004011BB |. 33F6 xor esi, esi
004011BD |. F7F1 div ecx------------------------------>取余到edx
004011BF |. 3BFB cmp edi, ebx
004011C1 |. 7E 20 jle short 004011E3
004011C3 |> 8A4C35 94 /mov cl, byte ptr [ebp+esi-6C]
004011C7 |. 0FBEC1 |movsx eax, cl------------------------->每次循环都取name字符
004011CA |. 03D0 |add edx, eax------------------------>字符加上上次循环结果(第一次加上余数)
004011CC |. 80F9 40 |cmp cl, 40 ------------------------->字符和40比较
004011CF |. 7C 05 |jl short 004011D6
004011D1 |. 0FAFC2 |imul eax, edx ----------------------->大于就乘以加上后的结果
004011D4 |. EB 06 |jmp short 004011DC
004011D6 |> 0FAFC2 |imul eax, edx ----------------------->小于也乘以加上后的结果
004011D9 |. 6BC0 07 |imul eax, eax, 7--------------------->再乘以7
004011DC |> 46 |inc esi
004011DD |. 8BD0 |mov edx, eax------------------------>结果传到edx
004011DF |. 3BF7 |cmp esi, edi
004011E1 |.^ 7C E0 \jl short 004011C3
004011E3 |> 52 push edx ; /<%lu> ->这是十进制长整型无符号整数形式
004011E4 |. 52 push edx ; |<%X> ->这是大写字母表示的十六进制形式
004011E5 |. 8D85 CCFEFFFF lea eax, dword ptr [ebp-134] ; |
004011EB |. 68 30504000 push 00405030 ; |%X%lu ->注册码格式
004011F0 |. 50 push eax ; |s
004011F1 |. FF15 B0404000 call dword ptr [<&USER32.wsprintfA>] ; \wsprintfA-->这个call就是按上面的格式连起来了
********************************************************************
好了好了`终于写到这了!呼~~~~~算法总结下:
name必须大于3位,总共进行五次循环的运算
1、每次循环都取name字符,先加上上一次循环的结果(记作a),字符再和0x4a 比较,大于就乘以a,小于就乘以a再左移1位
N次后再和0x724取余
2、每次循环都取name字符,第一次先加第一次循环得出来的余数(后面N-1次就加上上次运算的结果)->结果记作b,字符再和0x40比较,大于就 乘以b,小于乘以b再左移2位...N次后再和0x2225取余
3、每次循环都取name字符,第一次先加上第二次循环得出来的余数(后面N-1次就加上上次运算的结果)->结果记作c,字符再和0x54比较,大于就 乘以c,小于乘以c,再乘以2,加上乘以c后的值...N次后结果记作d
4、每次循环都取name字符,第一次先加每三次循环结果(后面N-1次就加上上次运算的结果)->结果记作d,字符再和0x4a比较,大于就 乘以d,小于就乘以d,再乘以4,加上乘以d后的值...N次后再和0x2e34取余
5、每次循环都取name字符,第一次先加上第四次循环得出来的余数(后面N-1次就加上上次运算的结果)->结果记作e,字符再和0x40比较,大于就乘以e,小于乘以e,再乘以7...N次后结果记作e
最后,将e以<%x%lu>这种格式连起来,也就是先以十六进制形式,再转成十进制无符号的形式连在后面,就是注册码了!
name:大菜一号
code:A583F2752776887925
********************************************
嗯呖,下面C++注册机:
#include <iostream.h>
#include <stdio.h>
#include <string.h>
main()
{
int i,k;
unsigned long lx=0,lu=0,li=0;
char name[100];
loop: cout<<"Enter your name: ";
cin>>name;
k=strlen(name);
if(k<3)
{
cout<<"no!your name is less than 3."<<endl;
goto loop;
}
else
{
for(i=0;i<k;i++)
{
lx+=name[i];
if(name[i]<0x4a)
{
lx=(lx*name[i]);
lx<<=1;
}
else
lx*=name[i];
}
lu=lx%0x724;
for(i=0;i<k;i++)
{
lu+=name[i];
if(name[i]<0x40)
{
lu=(lu*name[i]);
lu<<=2;
}
else
lu*=name[i];
}
lx=lu%0x2225;
for(i=0;i<k;i++)
{
lx+=name[i];
if(name[i]<0x54)
{
li=lx*name[i];
lx=(li*2+li);
lx<<=1;
}
else
lx*=name[i];
}
for(i=0;i<k;i++)
{
lx+=name[i];
if(name[i]<0x4a)
{
li=lx*name[i];
lx=li*4+li;
}
else
lx*=name[i];
}
lu=lx%0x2e34;
for(i=0;i<k;i++)
{
lu+=name[i];
if(name[i]<0x40)
lu=lu*name[i]*7;
else
lu*=name[i];
}
sprintf(name,"%X%lu",lu,lu);
cout<<endl<<"Your Serial: "<<name<<endl;
again:
goto again;
}
}
喳喳``混蛋们,可以收工啦!
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!