这也是刊载在PEDIY CrackMe2007序列号部分,因为貌似前辈们没写注册机, 小弟初出茅庐斗胆分析了算法,写了一个, 如果代码写的不好的地方, 望指出。
0040117E |. 68 C9000000 push 0C9 ; /Count = C9 (201.)
00401183 |. 50 push eax ; |Buffer
00401184 |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
00401189 |. 57 push edi ; |hWnd
0040118A |. FFD5 call ebp ; \GetDlgItemTextA
0040118C |. 8BF0 mov esi, eax
0040118E |. 83FE 04 cmp esi, 4
00401191 |. 0F8C CA000000 jl 00401261
00401197 |. 8BCE mov ecx, esi
00401199 |. 81E1 01000080 and ecx, 80000001 ; 判断NameLen奇偶 奇数完蛋
0040119F |. 79 05 jns short 004011A6
004011A1 |. 49 dec ecx
004011A2 |. 83C9 FE or ecx, FFFFFFFE
004011A5 |. 41 inc ecx
004011A6 |> 0F85 B5000000 jnz 00401261
004011AC |. 8D9424 D80000>lea edx, dword ptr [esp+D8] ; Name[]
004011B3 |. 56 push esi ; NameLen
004011B4 |. 52 push edx
004011B5 |. E8 B6000000 call 00401270 ;
{
00401270 /$ 53 push ebx
00401271 |. 8B5C24 0C mov ebx, dword ptr [esp+C] ; NameLen或者SerialLen
00401275 |. 56 push esi
00401276 |. 33F6 xor esi, esi ; i
00401278 |. 85DB test ebx, ebx
0040127A |. 57 push edi
0040127B |. 7E 4D jle short 004012CA
0040127D |. 8B7C24 10 mov edi, dword ptr [esp+10] ; Name[]或者SerialLen
00401281 |> 833D E0624000>/cmp dword ptr [4062E0], 1
00401288 |. 7E 14 |jle short 0040129E
0040128A |. 0FBE043E |movsx eax, byte ptr [esi+edi]
0040128E |. 68 03010000 |push 103
00401293 |. 50 |push eax
00401294 |. E8 13010000 |call 004013AC
00401299 |. 83C4 08 |add esp, 8
0040129C |. EB 13 |jmp short 004012B1
0040129E |> 0FBE0C3E |movsx ecx, byte ptr [esi+edi] ; Name[i]或者Serial[i]
004012A2 |. 8B15 D4604000 |mov edx, dword ptr [4060D4] ; CrackMe_.004060DE
004012A8 |. 66:8B044A |mov ax, word ptr [edx+ecx*2]
004012AC |. 25 03010000 |and eax, 103 ; 大写为1小写为2数字为0
004012B1 |> 85C0 |test eax, eax ; 这可以看出验证码和用户名都必须为字母
004012B3 |. 74 1E |je short 004012D3
004012B5 |. 0FBE043E |movsx eax, byte ptr [esi+edi]
004012B9 |. 50 |push eax
004012BA |. E8 21000000 |call 004012E0 ; 把小写转换成大写
{
004012E0 /$ 55 push ebp ; USER32.GetDlgItemTextA
004012E1 |. 8BEC mov ebp, esp
004012E3 |. 51 push ecx
004012E4 |. 833D 78854000>cmp dword ptr [408578], 0
004012EB |. 53 push ebx
004012EC |. 75 1D jnz short 0040130B
004012EE |. 8B45 08 mov eax, dword ptr [ebp+8] ; 判断Name(Serial)是否为小写
004012F1 |. 83F8 61 cmp eax, 61
004012F4 |. 0F8C AF000000 jl 004013A9
004012FA |. 83F8 7A cmp eax, 7A
004012FD |. 0F8F A6000000 jg 004013A9
00401303 |. 83E8 20 sub eax, 20 ; 把Name(Serial)小写变大写
00401306 |. E9 9E000000 jmp 004013A9
0040130B |> 8B5D 08 mov ebx, dword ptr [ebp+8]
0040130E |. 81FB 00010000 cmp ebx, 100
00401314 |. 7D 28 jge short 0040133E
00401316 |. 833D E0624000>cmp dword ptr [4062E0], 1
0040131D |. 7E 0C jle short 0040132B
0040131F |. 6A 02 push 2
00401321 |. 53 push ebx
00401322 |. E8 85000000 call 004013AC
00401327 |. 59 pop ecx
00401328 |. 59 pop ecx
00401329 |. EB 0B jmp short 00401336
0040132B |> A1 D4604000 mov eax, dword ptr [4060D4]
00401330 |. 8A0458 mov al, byte ptr [eax+ebx*2]
00401333 |. 83E0 02 and eax, 2
00401336 |> 85C0 test eax, eax
00401338 |. 75 04 jnz short 0040133E
0040133A |> 8BC3 mov eax, ebx
0040133C |. EB 6B jmp short 004013A9
0040133E |> 8B15 D4604000 mov edx, dword ptr [4060D4] ; CrackMe_.004060DE
00401344 |. 8BC3 mov eax, ebx
00401346 |. C1F8 08 sar eax, 8
00401349 |. 0FB6C8 movzx ecx, al
0040134C |. F6444A 01 80 test byte ptr [edx+ecx*2+1], 80
00401351 |. 74 0E je short 00401361
00401353 |. 8065 0A 00 and byte ptr [ebp+A], 0
00401357 |. 8845 08 mov byte ptr [ebp+8], al
0040135A |. 885D 09 mov byte ptr [ebp+9], bl
0040135D |. 6A 02 push 2
0040135F |. EB 09 jmp short 0040136A
00401361 |> 8065 09 00 and byte ptr [ebp+9], 0
00401365 |. 885D 08 mov byte ptr [ebp+8], bl
00401368 |. 6A 01 push 1
0040136A |> 58 pop eax
0040136B |. 8D4D FC lea ecx, dword ptr [ebp-4]
0040136E |. 6A 01 push 1
00401370 |. 6A 00 push 0
00401372 |. 6A 03 push 3
00401374 |. 51 push ecx
00401375 |. 50 push eax
00401376 |. 8D45 08 lea eax, dword ptr [ebp+8]
00401379 |. 50 push eax
0040137A |. 68 00020000 push 200
0040137F |. FF35 78854000 push dword ptr [408578]
00401385 |. E8 D6010000 call 00401560
0040138A |. 83C4 20 add esp, 20
0040138D |. 85C0 test eax, eax
0040138F |.^ 74 A9 je short 0040133A
00401391 |. 83F8 01 cmp eax, 1
00401394 |. 75 06 jnz short 0040139C
00401396 |. 0FB645 FC movzx eax, byte ptr [ebp-4]
0040139A |. EB 0D jmp short 004013A9
0040139C |> 0FB645 FD movzx eax, byte ptr [ebp-3]
004013A0 |. 0FB64D FC movzx ecx, byte ptr [ebp-4]
004013A4 |. C1E0 08 shl eax, 8
004013A7 |. 0BC1 or eax, ecx
004013A9 |> 5B pop ebx
004013AA |. C9 leave
004013AB \. C3 retn
}
004012BF |. 83C4 04 |add esp, 4
004012C2 |. 88043E |mov byte ptr [esi+edi], al ; 把转换过的Name[i](Serial[i])放到 Name[i](Serial[i])
004012C5 |. 46 |inc esi
004012C6 |. 3BF3 |cmp esi, ebx ; i与NameLen比较
004012C8 |.^ 7C B7 \jl short 00401281
004012CA |> 5F pop edi
004012CB |. 5E pop esi
004012CC |. B8 01000000 mov eax, 1
004012D1 |. 5B pop ebx
004012D2 |. C3 retn
004012D3 |> 5F pop edi
004012D4 |. 5E pop esi
04012D5 |. 33C0 xor eax, eax
004012D7 |. 5B pop ebx
004012D8 \. C3 retn
}
004011BA |. 83C4 08 add esp, 8
004011BD |. 85C0 test eax, eax
004011BF |. 0F84 9C000000 je 00401261
004011C5 |. 8D4424 10 lea eax, dword ptr [esp+10]
004011C9 |. 68 C9000000 push 0C9
004011CE |. 50 push eax
004011CF |. 68 E9030000 push 3E9
004011D4 |. 57 push edi
004011D5 |. FFD5 call ebp ; GetDlgItemTextA 把用户输入注册码输入内存
004011D7 |. 3BC6 cmp eax, esi ; SerialLen与NameLen比较 不等完蛋
004011D9 0F85 82000000 jnz 00401261
004011DF |. 8D4C24 10 lea ecx, dword ptr [esp+10] ; Serial
004011E3 |. 50 push eax
004011E4 |. 51 push ecx
004011E5 |. E8 86000000 call 00401270
004011EA |. 83C4 08 add esp, 8
004011ED |. 85C0 test eax, eax
004011EF 74 70 je short 00401261
004011F1 |. 8BC6 mov eax, esi ; NameLen
004011F3 |. 33FF xor edi, edi
004011F5 |. 99 cdq
004011F6 |. 2BC2 sub eax, edx ; NameLen
004011F8 |. 8BE8 mov ebp, eax
004011FA |. D1FD sar ebp, 1 ; NameLen/2
004011FC |. 3BEB cmp ebp, ebx
004011FE |. 7E 51 jle short 00401251
00401200 |> 8A4C7C 11 /mov cl, byte ptr [esp+edi*2+11] ; Serial[2*i+1]
00401204 |. 8A447C 10 |mov al, byte ptr [esp+edi*2+10] ; Serial[2*i]
00401208 |. 80E9 41 |sub cl, 41 ; Serial[2*i+1]-0x41
0040120B |. 2C 41 |sub al, 41 ; Serial[2*i]-0x41
0040120D |. 0FBEF1 |movsx esi, cl ; esi=Serial[2*i+1]-0x41
00401210 |. 0FBEC8 |movsx ecx, al ; ecx=Serial[2*i]-0x41
00401213 |. BB 1A000000 |mov ebx, 1A
00401218 |. 8D14C9 |lea edx, dword ptr [ecx+ecx*8] ; edx=9*(Serial[2*i]-0x41)
0040121B |. 8D0472 |lea eax, dword ptr [edx+esi*2] ; eax=9*(Serial[2*i]-0x41)+2*(Serial[2*i+1]-0x41)
0040121E |. 99 |cdq
0040121F |. F7FB |idiv ebx ; edx=(9*(Serial[2*i]-0x41)+2*(Serial[2*i+1]-0x41))%0x1a
00401221 |. 0FBE847C D800>|movsx eax, byte ptr [esp+edi*2+D8] ; Name[2*i]
00401229 |. 83E8 41 |sub eax, 41 ; eax=Name[2*i]-0x41
0040122C |. 3BD0 |cmp edx, eax
0040122E 75 31 jnz short 00401261
00401230 |. 8D0476 |lea eax, dword ptr [esi+esi*2] ; eax=3*(Serial[2*i+1]-0x41)
00401233 |. 8D0C81 |lea ecx, dword ptr [ecx+eax*4] ; ecx=12*(Serial[2*i+1]-0x41)+Serial[2*i]-0x41
00401236 |. 03C1 |add eax, ecx ; eax=15*(Serial[2*i+1]-0x41)+Serial[2*i]-0x41
00401238 |. 8BCB |mov ecx, ebx ; ecx=0x1a
0040123A |. 99 |cdq
0040123B |. F7F9 |idiv ecx ; edx=(15*(Serial[2*i+1]-0x41)+Serial[2*i]-0x41)%0x1a
0040123D |. 0FBE847C D900>|movsx eax, byte ptr [esp+edi*2+D9] ; eax=Name[2*i+1]
00401245 |. 83E8 41 |sub eax, 41 ; eax=Name[2*i+1]-0x41
00401248 |. 3BD0 |cmp edx, eax
0040124A 75 15 jnz short 00401261
0040124C |. 47 |inc edi
0040124D |. 3BFD |cmp edi, ebp
0040124F |.^ 7C AF \jl short 00401200
00401251 |> 5F pop edi
00401252 |. 5E pop esi
00401253 |. 5D pop ebp
00401254 |. B8 01000000 mov eax, 1
00401259 |. 5B pop ebx
0040125A |. 81C4 90010000 add esp, 190
00401260 |. C3 retn
00401261 |> \5F pop edi ; 0012FAE8
00401262 |. 5E pop esi
00401263 |. 5D pop ebp
00401264 |. 33C0 xor eax, eax
00401266 |. 5B pop ebx
00401267 |. 81C4 90010000 add esp, 190
0040126D \. C3 retn
注册算法的关键:Name[2*i] = (9*(Serial[2*i] - 0x41) + 2*(Serial[2*i+1]-0x41))%0x1a + 0x41;
Name[2*i+1] = (15*(Serial[2*i+1]-0x41) + Serial[2*i]-0x41)%0x1a + 0x41;
下面是我写的注册机代码:
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
cout<<"输入验证码,是验证码哦,验证码个数必须是偶数(A-Z or a-z)"<<endl;
char serial[20];
string::size_type Len;
cin>>serial;
Len = strlen(serial);
string Serial(serial);
string::size_type SerialLen = Serial.size();
string::iterator pos = Serial.begin();
transform(Serial.begin(),
Serial.end(),
Serial.begin(),
toupper);
string Name(Serial);
string::size_type j = SerialLen / 2;
for(string::size_type i = 0; i < j; i++)
{
Name[2*i] = (9*(Serial[2*i] - 0x41) + 2*(Serial[2*i+1]-0x41))%0x1a + 0x41;
Name[2*i+1] = (15*(Serial[2*i+1]-0x41) + Serial[2*i]-0x41)%0x1a + 0x41;
}
cout<<"Name : "<<Name<<endl;
cout<<"Serial : "<<Serial<<endl;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)