这个应该不难吧!今天没有球赛,所以看了下这个程序。
【注册过程】
载入程序,输入用户名:rdsnow、注册码:987654321abcd,然后 bp GetWindowTextA,断下返回到程序程序领空:
00015724 |. 55 push ebp
00015725 |. 68 EA570100 push keygenme.000157EA
0001572A |. 64:FF30 push dword ptr fs:[eax]
0001572D |. 64:8920 mov dword ptr fs:[eax],esp
00015730 |. E8 EFFAFFFF call keygenme.00015224 ; SEH
00015735 |. 8D55 FC lea edx,dword ptr ss:[ebp-4]
00015738 |. A1 C8760100 mov eax,dword ptr ds:[176C8]
0001573D |. E8 C6FEFFFF call keygenme.00015608 ; 取出用户名 szUserName
00015742 |. 8D55 F8 lea edx,dword ptr ss:[ebp-8]
00015745 |. A1 CC760100 mov eax,dword ptr ds:[176CC]
0001574A |. E8 B9FEFFFF call keygenme.00015608 ; 取出注册码 szUserCode
0001574F |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
00015752 |. E8 ADD9FFFF call keygenme.00013104 ; 用户名的长度 strlen( szUserName )
00015757 |. 83F8 05 cmp eax,5
0001575A |. 7C 4D jl short keygenme.000157A9 ; 用户名的长度不小于 5
0001575C |. 8B55 F8 mov edx,dword ptr ss:[ebp-8]
0001575F |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
00015762 |. E8 F9FEFFFF call keygenme.00015660 ; 需要跟进的关键处
00015767 |. 833D A06001>cmp dword ptr ds:[160A0],1
0001576E |. 75 5A jnz short keygenme.000157CA ; [160A0] 是注册标志
跟进“00015762 |. E8 F9FEFFFF call keygenme.00015660 ; 需要跟进的关键处”这一行:
…………………………
00015683 |. 55 push ebp
00015684 |. 68 0C570100 push keygenme.0001570C
00015689 |. 64:FF30 push dword ptr fs:[eax]
0001568C |. 64:8920 mov dword ptr fs:[eax],esp
0001568F |. E8 90FBFFFF call keygenme.00015224 ; SEH
00015694 |. 8D55 F4 lea edx,dword ptr ss:[ebp-C]
00015697 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0001569A |. E8 91F9FFFF call keygenme.00015030 ; 这个 Call 用来生成注册码
0001569F |. 837D F8 00 cmp dword ptr ss:[ebp-8],0
000156A3 |. 74 47 je short keygenme.000156EC
000156A5 |. 8B45 F4 mov eax,dword ptr ss:[ebp-C]
000156A8 |. E8 57DAFFFF call keygenme.00013104 ; 取生成注册码的长度
000156AD |. 85C0 test eax,eax
000156AF |. 7E 3B jle short keygenme.000156EC
000156B1 |. 8945 EC mov dword ptr ss:[ebp-14],eax
000156B4 |. C745 F0 010>mov dword ptr ss:[ebp-10],1
000156BB |> 8B45 F4 /mov eax,dword ptr ss:[ebp-C] ; 下面这个循环只是将加码跟生成的真码比较
000156BE |. 8B55 F0 |mov edx,dword ptr ss:[ebp-10]
000156C1 |. 8A4410 FF |mov al,byte ptr ds:[eax+edx-1]
000156C5 |. 8B55 F8 |mov edx,dword ptr ss:[ebp-8]
000156C8 |. 8B4D F0 |mov ecx,dword ptr ss:[ebp-10]
000156CB |. 3A440A FF |cmp al,byte ptr ds:[edx+ecx-1]
000156CF |. 75 0C |jnz short keygenme.000156DD
000156D1 |. C705 A06001>|mov dword ptr ds:[160A0],1 ; 注册标志赋值 1
000156DB |. EB 07 |jmp short keygenme.000156E4
000156DD |> 33C0 |xor eax,eax
000156DF |. A3 A0600100 |mov dword ptr ds:[160A0],eax ; 注册标志赋值 0
000156E4 |> FF45 F0 |inc dword ptr ss:[ebp-10]
000156E7 |. FF4D EC |dec dword ptr ss:[ebp-14]
000156EA |.^ 75 CF \jnz short keygenme.000156BB
000156EC |> E8 77FCFFFF call keygenme.00015368
000156F1 |. 33C0 xor eax,eax
000156F3 |. 5A pop edx
000156F4 |. 59 pop ecx
000156F5 |. 59 pop ecx
000156F6 |. 64:8910 mov dword ptr fs:[eax],edx
000156F9 |. 68 13570100 push keygenme.00015713
000156FE |> 8D45 F4 lea eax,dword ptr ss:[ebp-C]
00015701 |. BA 03000000 mov edx,3
00015706 |. E8 A5D8FFFF call keygenme.00012FB0
0001570B \. C3 retn
跟进“0001569A |. E8 91F9FFFF call keygenme.00015030 ; 这个 Call 用来生成注册码”这一行:
跟进可以看到注册过程分三步完成:
1、根据用户名计算byte型变量 sum0,sum1,sum2,sum3 的值
2、定义 byte 型数组 bResult[26],利用 sum0,sum1,sum2,sum3 参与运算,结果写入 bResult[26]
3、依次将 bResult[26] 转为十进制文本,并连接得到注册码
好,我们跟进看看具体代码:
…………………………
0001505F |. 33F6 xor esi,esi
00015061 |. 33FF xor edi,edi
00015063 |. 33C0 xor eax,eax
00015065 |. 8945 F0 mov dword ptr ss:[ebp-10],eax
00015068 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0001506B |. E8 94E0FFFF call keygenme.00013104 ; 取出注册码的长度
00015070 |. 85C0 test eax,eax
00015072 |. 7E 71 jle short keygenme.000150E5
00015074 |. 8945 EC mov dword ptr ss:[ebp-14],eax
00015077 |. BB 01000000 mov ebx,1
0001507C |> 8B45 FC /mov eax,dword ptr ss:[ebp-4]
0001507F |. E8 80E0FFFF |call keygenme.00013104 ; 取出注册码的长度
00015084 |. 8B55 FC |mov edx,dword ptr ss:[ebp-4]
00015087 |. 0FB6541A FF |movzx edx,byte ptr ds:[edx+ebx-1] ; szUserName[i]
0001508C |. 0355 F4 |add edx,dword ptr ss:[ebp-C]
0001508F |. 03C2 |add eax,edx ; sum0 += szUserName[i] + strlen(szUserName)
00015091 |. 8945 F4 |mov dword ptr ss:[ebp-C],eax
00015094 |. 8B45 FC |mov eax,dword ptr ss:[ebp-4]
00015097 |. E8 68E0FFFF |call keygenme.00013104 ; 取出注册码的长度
0001509C |. 48 |dec eax
0001509D |. 8B55 FC |mov edx,dword ptr ss:[ebp-4]
000150A0 |. 0FB6541A FE |movzx edx,byte ptr ds:[edx+ebx-2] ; szUserName[i-1]
000150A5 |. 03F2 |add esi,edx
000150A7 |. 03C6 |add eax,esi ; sum1 += szUserName[i-1] + strlen(szUserName) - 1
000150A9 |. 8BF0 |mov esi,eax
000150AB |. 8B45 FC |mov eax,dword ptr ss:[ebp-4]
000150AE |. E8 51E0FFFF |call keygenme.00013104 ; 取出注册码的长度
000150B3 |. 83E8 02 |sub eax,2
000150B6 |. 8B55 FC |mov edx,dword ptr ss:[ebp-4]
000150B9 |. 0FB6541A FD |movzx edx,byte ptr ds:[edx+ebx-3] ; szUserName[i-2]
000150BE |. 03FA |add edi,edx
000150C0 |. 03C7 |add eax,edi ; sum2 += szUserName[i-2] + strlen(szUserName) - 2
000150C2 |. 8BF8 |mov edi,eax
000150C4 |. 8B45 FC |mov eax,dword ptr ss:[ebp-4]
000150C7 |. E8 38E0FFFF |call keygenme.00013104 ; 取出注册码的长度
000150CC |. 83E8 03 |sub eax,3
000150CF |. 8B55 FC |mov edx,dword ptr ss:[ebp-4]
000150D2 |. 0FB6541A FC |movzx edx,byte ptr ds:[edx+ebx-4] ; szUserName[i-3]
000150D7 |. 0355 F0 |add edx,dword ptr ss:[ebp-10]
000150DA |. 03C2 |add eax,edx ; sum3 += szUserName[i-3] + strlen(szUserName) - 3
000150DC |. 8945 F0 |mov dword ptr ss:[ebp-10],eax
000150DF |. 43 |inc ebx
000150E0 |. FF4D EC |dec dword ptr ss:[ebp-14]
000150E3 |.^ 75 97 \jnz short keygenme.0001507C
000150E5 |> 8A45 F4 mov al,byte ptr ss:[ebp-C] ; 取 sum0 的低 8 位
000150E8 |. 34 90 xor al,90
000150EA |. 8845 D2 mov byte ptr ss:[ebp-2E],al ; bResult[0] = sum0 ^ 0x90
000150ED |. 8A55 F4 mov dl,byte ptr ss:[ebp-C]
000150F0 |. 80F2 FF xor dl,0FF
000150F3 |. 8855 D3 mov byte ptr ss:[ebp-2D],dl ; bResult[1] = sum0 ^ 0xFF
000150F6 |. 8845 D4 mov byte ptr ss:[ebp-2C],al ; bResult[2] = bResult[0]
000150F9 |. 8855 D5 mov byte ptr ss:[ebp-2B],dl ; bResult[3] = bResult[1]
000150FC |. 8A45 F4 mov al,byte ptr ss:[ebp-C]
000150FF |. 34 0F xor al,0F ; bResult[4] = sum0 ^ 0xF
00015101 |. 8845 D6 mov byte ptr ss:[ebp-2A],al
00015104 |. 8BC6 mov eax,esi ; 取 sum1 的低 8 位
00015106 |. 8BD0 mov edx,eax
00015108 |. 80F2 58 xor dl,58
0001510B |. 8855 D7 mov byte ptr ss:[ebp-29],dl ; bResult[5] = sum1 ^ 0x58
0001510E |. 8BD0 mov edx,eax
00015110 |. 80F2 44 xor dl,44
00015113 |. 8855 D8 mov byte ptr ss:[ebp-28],dl ; bResult[6] = sum1 ^ 0x44
00015116 |. 8BD0 mov edx,eax
00015118 |. 80F2 43 xor dl,43
0001511B |. 8855 D9 mov byte ptr ss:[ebp-27],dl ; bResult[7] = sum1 ^ 0x43
0001511E |. 8BD0 mov edx,eax
00015120 |. 80F2 56 xor dl,56
00015123 |. 8855 DA mov byte ptr ss:[ebp-26],dl ; bResult[8] = sum1 ^ 0x56
00015126 |. 8BD0 mov edx,eax
00015128 |. 80F2 23 xor dl,23
0001512B |. 8855 DB mov byte ptr ss:[ebp-25],dl ; bResult[9] = sum1 ^ 0x23
0001512E |. 8BD7 mov edx,edi ; 取 sum2 的低 8 位
00015130 |. 8BCA mov ecx,edx
00015132 |. 80F1 55 xor cl,55
00015135 |. 884D DC mov byte ptr ss:[ebp-24],cl ; bResult[10] = sum2 ^ 0x55
00015138 |. 8BCA mov ecx,edx
0001513A |. 80F1 44 xor cl,44
0001513D |. 884D DD mov byte ptr ss:[ebp-23],cl ; bResult[11] = sum2 ^ 0x44
00015140 |. 8BCA mov ecx,edx
00015142 |. 80F1 64 xor cl,64
00015145 |. 884D DE mov byte ptr ss:[ebp-22],cl ; bResult[12] = sum2 ^ 0x64
00015148 |. 8BCA mov ecx,edx
0001514A |. 80F1 57 xor cl,57
0001514D |. 884D DF mov byte ptr ss:[ebp-21],cl ; bResult[13] = sum2 ^ 0x57
00015150 |. 8BCA mov ecx,edx
00015152 |. 80F1 45 xor cl,45
00015155 |. 884D E0 mov byte ptr ss:[ebp-20],cl ; bResult[14] = sum2 ^ 0x45
00015158 |. 8BCA mov ecx,edx
0001515A |. 80F1 95 xor cl,95
0001515D |. 884D E1 mov byte ptr ss:[ebp-1F],cl ; bResult[15] = sum2 ^ 0x95
00015160 |. 8A4D F0 mov cl,byte ptr ss:[ebp-10] ; 取出 sum3 的低 8 位
00015163 |. 324D F4 xor cl,byte ptr ss:[ebp-C]
00015166 |. 884D E2 mov byte ptr ss:[ebp-1E],cl ; bResult[16] = sum3 ^ sum0
00015169 |. 8A4D F0 mov cl,byte ptr ss:[ebp-10]
0001516C |. 8BDE mov ebx,esi
0001516E |. 32CB xor cl,bl
00015170 |. 884D E3 mov byte ptr ss:[ebp-1D],cl ; bResult[17] = sum3 ^ sum1
00015173 |. 8A4D F0 mov cl,byte ptr ss:[ebp-10]
00015176 |. 8BDF mov ebx,edi
00015178 |. 32CB xor cl,bl
0001517A |. 884D E4 mov byte ptr ss:[ebp-1C],cl ; bResult[18] = sum3 ^ sum2
0001517D |. 8A4D F4 mov cl,byte ptr ss:[ebp-C]
00015180 |. 02C8 add cl,al
00015182 |. 324D F0 xor cl,byte ptr ss:[ebp-10]
00015185 |. 884D E5 mov byte ptr ss:[ebp-1B],cl ; bResult[19] = ( sum0 + sum1 ) ^ sum3
00015188 |. 02C2 add al,dl
0001518A |. 3245 F0 xor al,byte ptr ss:[ebp-10]
0001518D |. 8845 E6 mov byte ptr ss:[ebp-1A],al ; bResult[20] = ( sum2 + sum1 ) ^ sum3
00015190 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
00015193 |. 8A00 mov al,byte ptr ds:[eax]
00015195 |. 34 44 xor al,44
00015197 |. 8845 E7 mov byte ptr ss:[ebp-19],al ; bResult[21] = szUserName[0] ^ 0x44
0001519A |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0001519D |. 8A40 01 mov al,byte ptr ds:[eax+1]
000151A0 |. 34 44 xor al,44
000151A2 |. 8845 E8 mov byte ptr ss:[ebp-18],al ; bResult[22] = szUserName[1] ^ 0x44
000151A5 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
000151A8 |. 8A40 02 mov al,byte ptr ds:[eax+2]
000151AB |. 34 44 xor al,44
000151AD |. 8845 E9 mov byte ptr ss:[ebp-17],al ; bResult[23] = szUserName[2] ^ 0x44
000151B0 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
000151B3 |. 8A40 03 mov al,byte ptr ds:[eax+3]
000151B6 |. 34 22 xor al,22
000151B8 |. 8845 EA mov byte ptr ss:[ebp-16],al ; bResult[24] = szUserName[3] ^ 0x22
000151BB |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
000151BE |. 8A40 04 mov al,byte ptr ds:[eax+4]
000151C1 |. 34 11 xor al,11
000151C3 |. 8845 EB mov byte ptr ss:[ebp-15],al ; bResult[25] = szUserName[4] ^ 0x11
000151C6 |. 8B45 F8 mov eax,dword ptr ss:[ebp-8]
000151C9 |. E8 BEDDFFFF call keygenme.00012F8C
000151CE |. BE 1A000000 mov esi,1A
000151D3 |. 8D5D D2 lea ebx,dword ptr ss:[ebp-2E] ; 取出 bResult[26] 的地址
000151D6 |> 33C0 /xor eax,eax
000151D8 |. 8A03 |mov al,byte ptr ds:[ebx]
000151DA |. 33D2 |xor edx,edx
000151DC |. 52 |push edx
000151DD |. 50 |push eax
000151DE |. 8D45 CC |lea eax,dword ptr ss:[ebp-34]
000151E1 |. E8 D6FCFFFF |call keygenme.00014EBC ; 将 bResult[i] 转成十进制文本
000151E6 |. 8B55 CC |mov edx,dword ptr ss:[ebp-34]
000151E9 |. 8B45 F8 |mov eax,dword ptr ss:[ebp-8]
000151EC |. E8 1BDFFFFF |call keygenme.0001310C ; 连接得到的 26 个十进制文本
000151F1 |. 8B45 F8 |mov eax,dword ptr ss:[ebp-8]
000151F4 |. 43 |inc ebx
000151F5 |. 4E |dec esi
000151F6 |.^ 75 DE \jnz short keygenme.000151D6
000151F8 |. 33C0 xor eax,eax
000151FA |. 5A pop edx
000151FB |. 59 pop ecx
000151FC |. 59 pop ecx
000151FD |. 64:8910 mov dword ptr fs:[eax],edx
00015200 |. 68 1D520100 push keygenme.0001521D
00015205 |> 8D45 CC lea eax,dword ptr ss:[ebp-34]
00015208 |. E8 7FDDFFFF call keygenme.00012F8C
0001520D |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
00015210 |. E8 77DDFFFF call keygenme.00012F8C
00015215 \. C3 retn
00015216 .^ E9 0DD8FFFF jmp keygenme.00012A28
0001521B .^ EB E8 jmp short keygenme.00015205
0001521D . 5F pop edi
0001521E . 5E pop esi
0001521F . 5B pop ebx
00015220 . 8BE5 mov esp,ebp
00015222 . 5D pop ebp
00015223 . C3 retn
--------------------------------------------------------------------------------
【注册机源码】
将上面的过程略微整理,便可写出 keygen 了。
void CKeygenDlg::OnOK()
{
// TODO: Add extra validation here
UpdateData(true);
unsigned char bResult[26],sum0=0,sum1=0,sum2=0,sum3=0,i,n;
char szUserName[256],szResult[4];
n = m_Edit1.GetLength ();
if ( n < 5 ){
m_Edit2 = "用户名不少于5个字符";
UpdateData(false);
return;
}
strcpy(szUserName,m_Edit1);
for(i=0;i<n;i++){
sum0 += n;
sum0 += szUserName[i];
sum1 += ( n - 1 );
if( i>0 ) sum1 += szUserName[i-1];
sum2 += ( n - 2 );
if( i>1 ) sum2 += szUserName[i-2];
sum3 += ( n - 3 );
if( i>2 ) sum3 += szUserName[i-3];
}
bResult[0] = sum0 ^ 0x90;
bResult[1] = sum0 ^ 0xFF;
bResult[2] = bResult[0];
bResult[3] = bResult[1];
bResult[4] = sum0 ^ 0xF;
bResult[5] = sum1 ^ 0x58;
bResult[6] = sum1 ^ 0x44;
bResult[7] = sum1 ^ 0x43;
bResult[8] = sum1 ^ 0x56;
bResult[9] = sum1 ^ 0x23;
bResult[10] = sum2 ^ 0x55;
bResult[11] = sum2 ^ 0x44;
bResult[12] = sum2 ^ 0x64;
bResult[13] = sum2 ^ 0x57;
bResult[14] = sum2 ^ 0x45;
bResult[15] = sum2 ^ 0x95;
bResult[16] = sum3 ^ sum0;
bResult[17] = sum3 ^ sum1;
bResult[18] = sum3 ^ sum2;
bResult[19] = ( sum0 + sum1 ) ^ sum3;
bResult[20] = ( sum2 + sum1 ) ^ sum3;
bResult[21] = szUserName[0] ^ 0x44;
bResult[22] = szUserName[1] ^ 0x44;
bResult[23] = szUserName[2] ^ 0x44;
bResult[24] = szUserName[3] ^ 0x22;
bResult[25] = szUserName[4] ^ 0x11;
m_Edit2.Empty ();
for(i=0;i<26;i++){
sprintf(szResult,"%d",bResult[i]);
m_Edit2 += szResult;
}
UpdateData(false);
}