注册算法入门

上网下了个crackme,传说中的方法都不行,难道那些教程都坑爹。突发奇想重下了个OD,发现注释功能强了N倍,多了很多api注释,看着舒服多了,汇编句子也更容易理解了,建议大家如果感觉费劲可以下个diy过的od。

下面是关键处的od里的汇编代码(根据输入的name算出序列号):

004011C1 |> /6A 32 /push 0x32 ; /Count = 32 (50.)
004011C3 |. |68 84624000 |push crackme2.00406284 ; |Buffer = crackme2.00406284,说明name字符串放在了00406284
004011C8 |. |6A 01 |push 0x1 ; |ControlID = 1
004011CA |. |FF75 08 |push [arg.1] ; |hWnd
004011CD |. |E8 16020000 |call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004011D2 |. |64:8B15 18000>|mov edx,dword ptr fs:[0x18]
004011D9 |. |8B52 30 |mov edx,dword ptr ds:[edx+0x30]
004011DC |. |0FB652 02 |movzx edx,byte ptr ds:[edx+0x2]
004011E0 |. |83F8 00 |cmp eax,0x0       name字符串必须长于0
004011E3 |. |7F 11 |jg Xcrackme2.004011F6
004011E5 |. |68 D8604000 |push crackme2.004060D8 ; /Text = "nameless",否则弹框提示nameless
004011EA |. |6A 01 |push 0x1 ; |ControlID = 1
004011EC |. |FF75 08 |push [arg.1] ; |hWnd
004011EF |. |E8 0C020000 |call <jmp.&user32.SetDlgItemTextA> ; \SetDlgItemTextA
004011F4 |.^\EB CB \jmp Xcrackme2.004011C1
004011F6 |> 8D35 84624000 lea esi,dword ptr ds:[0x406284]    前面说了name放在00406284,这里把name的地址给了esi
004011FC |. 33C9 xor ecx,ecx
004011FE |> 0FBE06 /movsx eax,byte ptr ds:[esi]     下面开始是循环算法,处理name的每个字节,开始取出每个字节赋给eax
00401201 |. 8BD8 |mov ebx,eax       ebx=eax
00401203 |. 2BF2 |sub esi,edx
00401205 |. C1E0 04 |shl eax,0x4      左移
00401208 |. C1EB 05 |shr ebx,0x5     右移
0040120B |. 33C3 |xor eax,ebx         两个进行异或
0040120D |. 83C0 26 |add eax,0x26       
00401210 |. 33C1 |xor eax,ecx       
00401212 |. 03C8 |add ecx,eax          
00401214 |. 46 |inc esi                esi指针进1,指向下一个字符
00401215 |. 803E 00 |cmp byte ptr ds:[esi],0x0     查看name指向结尾吗?是则退出循环
00401218 |.^ 75 E4 \jnz Xcrackme2.004011FE 
0040121A |. B8 EF0D0C00 mov eax,0xC0DEF   
0040121F |. 2BC1 sub eax,ecx
00401221 |. 0FAFC0 imul eax,eax       eax平方
00401224 |. 50 push eax ; /<%lX>
00401225 |. 51 push ecx ; |<%lX>
00401226 |. 68 E1604000 push crackme2.004060E1 ; |Format = "CM2-%lX-%lX"      格式化字符串CM2-ecx-eax
0040122B |. 68 B6624000 push crackme2.004062B6 ; |s = crackme2.004062B6
00401230 |. E8 9B010000 call <jmp.&user32.wsprintfA> ; \wsprintfA          结果输出到缓冲区,准备比较

 

这就是注册算法了,找到了它就可以自己算出注册码了

大家可以根据自己喜欢的语言写个注册机吧,这里我用vc为例,因为算法里有左移和异或这些较底层的东西,c的支持较好

代码:

#include <iostream.h>
#include <stdio.h>
#include <string.h>
void main()
{
int i,k;
int a=0,b=0,c=0;
char name[100];
cout<<"cracked by Zhuang"<<endl<<endl;
cout<<"Enter your name: ";
cin>>name;
k=strlen(name);

for(i=0;i<k;i++)
{
a=name[i];

b=a;
a<<=4;
b>>=5;
a=a^b;
a+=0x26;
a=a^c;
c+=a;
}
a=0x0C0DEF;
a-=c;
a=a*a;
sprintf(name,"CM2-%X-%X",c,a);
cout<<endl<<"Your Serial: "<<name<<endl<<endl;
again:
goto again;
}

根据这个算法算出其中一个注册码吧   name: zhuhai

                                                serial(序列号):  CM2-B6B9-9C59BF64

 

ps:附上crackme下载地址,注册机也放在里面了crackme

原文地址:https://www.cnblogs.com/encode/p/2726764.html