原文见:
http://bbs.pediy.com/showthread.php?s=&threadid=26097
【分析】
月中人的CrackMe用到了SHA1和RC2两个算法,详细分析见下面。
根据错误提示来到
004013F7 /$ 55 push ebp
004013F8 |. 8BEC mov ebp, esp
004013FA |. 83EC 50 sub esp, 50
004013FD |. 53 push ebx
004013FE |. 56 push esi
004013FF |. 57 push edi
00401400 |. 6A 14 push 14
00401402 |. 8D45 C4 lea eax, [ebp-3C]
00401405 |. 6A 00 push 0
00401407 |. 50 push eax
00401408 |. C645 D8 29 mov byte ptr [ebp-28], 29
0040140C |. C645 D9 66 mov byte ptr [ebp-27], 66
00401410 |. C645 DA EE mov byte ptr [ebp-26], 0EE
00401414 |. C645 DB 8F mov byte ptr [ebp-25], 8F
00401418 |. C645 DC 71 mov byte ptr [ebp-24], 71
0040141C |. C645 DD 09 mov byte ptr [ebp-23], 9
00401420 |. C645 DE F7 mov byte ptr [ebp-22], 0F7
00401424 |. C645 DF 44 mov byte ptr [ebp-21], 44
00401428 |. C645 E0 57 mov byte ptr [ebp-20], 57
0040142C |. C645 E1 9E mov byte ptr [ebp-1F], 9E
00401430 |. C645 E2 B5 mov byte ptr [ebp-1E], 0B5
00401434 |. C645 E3 2D mov byte ptr [ebp-1D], 2D
00401438 |. C645 E4 60 mov byte ptr [ebp-1C], 60
0040143C |. C645 E5 B0 mov byte ptr [ebp-1B], 0B0
00401440 |. C645 E6 B0 mov byte ptr [ebp-1A], 0B0
00401444 |. C645 E7 F5 mov byte ptr [ebp-19], 0F5
00401448 |. C645 E8 55 mov byte ptr [ebp-18], 55
0040144C |. C645 E9 58 mov byte ptr [ebp-17], 58
00401450 |. C645 EA E5 mov byte ptr [ebp-16], 0E5
00401454 |. C645 EB 74 mov byte ptr [ebp-15], 74
上面20个字节,是最后要比较的RSA值
00401458 |. C645 EC 40 mov byte ptr [ebp-14], 40
0040145C |. C645 ED 4F mov byte ptr [ebp-13], 4F
00401460 |. C645 EE 50 mov byte ptr [ebp-12], 50
00401464 |. C645 EF 0A mov byte ptr [ebp-11], 0A
00401468 |. C645 F0 D7 mov byte ptr [ebp-10], 0D7
0040146C |. C645 F1 A1 mov byte ptr [ebp-F], 0A1
00401470 |. C645 F2 67 mov byte ptr [ebp-E], 67
00401474 |. C645 F3 B6 mov byte ptr [ebp-D], 0B6 ; 一共28个字节
上面8个字节,是后面进行RC2加密解密的数据
00401478 |. E8 43090000 call 00401DC0 ; 分配20BYTE 0
0040147D |. 6A 14 push 14
0040147F |. 8D45 B0 lea eax, [ebp-50]
00401482 |. 6A 00 push 0
00401484 |. 50 push eax
00401485 |. E8 36090000 call 00401DC0 ; 分配20个自己0
0040148A |. 83C4 18 add esp, 18
0040148D |. E8 ACFCFFFF call 0040113E ; 变换serial,等会分析
00401492 |. 85C0 test eax, eax
00401494 |. 0F85 D1010000 jnz 0040166B
0040149A |. E8 60040000 call 004018FF ; sha初始化
0040149F |. BE 5C654000 mov esi, 0040655C
004014A4 |. 56 push esi
004014A5 |. E8 96080000 call 00401D40
004014AA |. 50 push eax ; name长度
004014AB |. 8D45 C4 lea eax, [ebp-3C]
004014AE |. 56 push esi
004014AF |. 50 push eax
004014B0 |. E8 6B090000 call 00401E20 ; 内存传递name
004014B5 |. 8D45 C4 lea eax, [ebp-3C]
004014B8 |. 6A 0B push 0B
004014BA |. 50 push eax
004014BB |. 8D45 B0 lea eax, [ebp-50]
004014BE |. 50 push eax
004014BF |. E8 6E040000 call 00401932 ; SHA
004014C4 |. BF 00040000 mov edi, 400
004014C9 |. 8D45 B0 lea eax, [ebp-50]
004014CC |. 57 push edi
004014CD |. 6A 14 push 14
004014CF |. 50 push eax
004014D0 |. E8 24050000 call 004019F9 ; 初始化RC2 SHA20个字节 ebp-50
004014D5 |. 6A 08 push 8
004014D7 |. BE FF000000 mov esi, 0FF
004014DC |. 5B pop ebx
004014DD |. 8D45 C4 lea eax, [ebp-3C]
004014E0 |. 53 push ebx
004014E1 |. 56 push esi
004014E2 |. 50 push eax
004014E3 |. E8 D8080000 call 00401DC0 ; 分配8个字节FF eax地址
004014E8 |. 8D45 B0 lea eax, [ebp-50]
004014EB |. 50 push eax ; SHA的值
004014EC |. 8D45 C4 lea eax, [ebp-3C]
004014EF |. 50 push eax ; 上面分配的内存
004014F0 |. E8 D5050000 call 00401ACA ; RC2_Encipher(8个字节的ff)
004014F5 |. 8D45 C4 lea eax, [ebp-3C]
004014F8 |. 50 push eax
004014F9 |. 8D45 B0 lea eax, [ebp-50]
004014FC |. 50 push eax
004014FD |. E8 C8050000 call 00401ACA ; RC_Encipher上面结果
00401502 |. 83C4 44 add esp, 44
00401505 |. 33C9 xor ecx, ecx
00401507 |> 8A81 40654000 /mov al, [ecx+406540]
0040150D |. 8D540D C4 |lea edx, [ebp+ecx-3C]
00401511 |. 3202 |xor al, [edx]
00401513 |. 41 |inc ecx
00401514 |. 3BCB |cmp ecx, ebx
00401516 |. 8881 63674000 |mov [ecx+406763], al
0040151C |. 8802 |mov [edx], al
0040151E |.^ 7C E7 \jl short 00401507 ; serial产生的8字节 xor 上面加密的结果
00401520 |. E8 99FEFFFF call 004013BE ; 406764 XOR 8BYTE
00401525 |. 57 push edi ; 1024
00401526 |. 8D45 C4 lea eax, [ebp-3C] ; 上面ebp-3c XOR结果
00401529 |. 53 push ebx
0040152A |. 50 push eax
0040152B |. E8 C9040000 call 004019F9 ; RC2_Init 8字节 ebp-3c
00401530 |. 53 push ebx
00401531 |. 8D45 C4 lea eax, [ebp-3C]
00401534 |. 56 push esi
00401535 |. 50 push eax
00401536 |. E8 85080000 call 00401DC0 ; 分配8BYTE FF
0040153B |. 8D45 B0 lea eax, [ebp-50]
0040153E |. 50 push eax
0040153F |. 8D45 C4 lea eax, [ebp-3C]
00401542 |. 50 push eax
00401543 |. E8 82050000 call 00401ACA ; RC2_En(0xffffffff)=>ebp-50
00401548 |. 8D45 C4 lea eax, [ebp-3C]
0040154B |. 50 push eax
0040154C |. 8D45 EC lea eax, [ebp-14]
0040154F |. 50 push eax
00401550 |. E8 89060000 call 00401BDE ; RC2_De(ebp-14)=>ebp-3c
00401555 |. 83C4 28 add esp, 28
00401558 |. 33C0 xor eax, eax
0040155A |> 8A4C05 B0 /mov cl, [ebp+eax-50]
0040155E |. 304C05 C4 |xor [ebp+eax-3C], cl
00401562 |. 40 |inc eax
00401563 |. 3BC3 |cmp eax, ebx
00401565 |.^ 7C F3 \jl short 0040155A
00401567 |. 8D45 B0 lea eax, [ebp-50]
0040156A |. 50 push eax
0040156B |. 8D45 EC lea eax, [ebp-14]
0040156E |. 50 push eax
0040156F |. E8 56050000 call 00401ACA ; RC2_En(ebp-14)=>ebp-50
00401574 |. 8B45 B0 mov eax, [ebp-50]
00401577 |. 6A 04 push 4
00401579 |. 35 BA7C0943 xor eax, 43097CBA ; 加密结果的前一个DWORD
0040157E |. 5E pop esi ; esi=4
0040157F |. 8945 F4 mov [ebp-C], eax ; number
00401582 |. 8D45 F4 lea eax, [ebp-C]
00401585 |. 56 push esi
00401586 |. 50 push eax
00401587 |. 8D45 CC lea eax, [ebp-34]
0040158A |. 50 push eax
0040158B |. E8 90080000 call 00401E20 ; ebp-c 4BYTE => ebp-34
00401590 |. 8D45 C4 lea eax, [ebp-3C]
00401593 |. 6A 0C push 0C
00401595 |. 50 push eax
00401596 |. 8D45 B0 lea eax, [ebp-50]
00401599 |. 50 push eax
0040159A |. E8 93030000 call 00401932 ; SHA
0040159F |. 8D45 D8 lea eax, [ebp-28]
004015A2 |. 6A 14 push 14
004015A4 |. 50 push eax
004015A5 |. 8D45 B0 lea eax, [ebp-50]
004015A8 |. 50 push eax
004015A9 |. E8 B20B0000 call 00402160 ; 比较SHA结果 和ebp-28 0x14字节
004015AE |. 83C4 2C add esp, 2C
004015B1 |. 85C0 test eax, eax
004015B3 |. 75 5C jnz short 00401611 //不等就跳
004015B5 |. 8A45 C3 mov al, [ebp-3D]
004015B8 |. 83E0 0F and eax, 0F
004015BB |. 8A4405 B0 mov al, [ebp+eax-50]
004015BF |. 83E8 03 sub eax, 3
004015C2 |. 23C3 and eax, ebx
004015C4 |. 0BC6 or eax, esi
004015C6 |. 3BC6 cmp eax, esi
004015C8 |. 8945 FC mov [ebp-4], eax
004015CB |. 7E 03 jle short 004015D0
004015CD |. 295D FC sub [ebp-4], ebx
004015D0 |> 6A 20 push 20
004015D2 |. B8 64674000 mov eax, 00406764
004015D7 |. 59 pop ecx
004015D8 |. 8BF8 mov edi, eax
004015DA |. 2B4D FC sub ecx, [ebp-4]
004015DD |. 8BD8 mov ebx, eax
004015DF |. 894D F8 mov [ebp-8], ecx
004015E2 |> 8B07 /mov eax, [edi]
004015E4 |. 8B4D F8 |mov ecx, [ebp-8]
004015E7 |. 8BD0 |mov edx, eax
004015E9 |. 56 |push esi
004015EA |. D3E2 |shl edx, cl
004015EC |. 8B4D FC |mov ecx, [ebp-4]
004015EF |. D3E8 |shr eax, cl
004015F1 |. 0BD0 |or edx, eax
004015F3 |. 8D45 F4 |lea eax, [ebp-C]
004015F6 |. 50 |push eax
004015F7 |. 53 |push ebx
004015F8 |. 8955 F4 |mov [ebp-C], edx
004015FB |. E8 20080000 |call 00401E20
00401600 |. 03DE |add ebx, esi
00401602 |. 83C4 0C |add esp, 0C
00401605 |. 03FE |add edi, esi
00401607 |. 81FB 6C674000 |cmp ebx, 0040676C
0040160D |.^ 7C D3 \jl short 004015E2
0040160F |. EB 5A jmp short 0040166B
00401611 |> 8A45 B0 mov al, [ebp-50]
00401614 |. C745 F8 20000>mov dword ptr [ebp-8], 20
0040161B |. 83E0 0F and eax, 0F
0040161E |. 8A4C05 B0 mov cl, [ebp+eax-50]
00401622 |. B8 64674000 mov eax, 00406764
00401627 |. 83E1 1E and ecx, 1E
0040162A |. 8BF8 mov edi, eax
0040162C |. 83C9 01 or ecx, 1
0040162F |. 8BD8 mov ebx, eax
00401631 |. 294D F8 sub [ebp-8], ecx
00401634 |. 894D FC mov [ebp-4], ecx
00401637 |> 8B07 /mov eax, [edi]
00401639 |. 8B4D F8 |mov ecx, [ebp-8]
0040163C |. 8BD0 |mov edx, eax
0040163E |. 56 |push esi
0040163F |. D3EA |shr edx, cl
00401641 |. 8B4D FC |mov ecx, [ebp-4]
00401644 |. D3E0 |shl eax, cl
00401646 |. 0BD0 |or edx, eax
00401648 |. 8D45 F4 |lea eax, [ebp-C]
0040164B |. 50 |push eax
0040164C |. 53 |push ebx
0040164D |. 8955 F4 |mov [ebp-C], edx
00401650 |. E8 CB070000 |call 00401E20
00401655 |. 03DE |add ebx, esi
00401657 |. 83C4 0C |add esp, 0C
0040165A |. 03FE |add edi, esi
0040165C |. 81FB 6C674000 |cmp ebx, 0040676C
00401662 |.^ 7C D3 \jl short 00401637
00401664 |. 8025 64674000>and byte ptr [406764], 0
0040166B |> 5F pop edi
0040166C |. 5E pop esi
0040166D |. 5B pop ebx
0040166E |. C9 leave
0040166F \. C3 retn
serial变换成8个字节,是可逆变换
0040113E /$ 55 push ebp
0040113F |. 8BEC mov ebp, esp
00401141 |. 51 push ecx
00401142 |. 804D FF FF or byte ptr [ebp-1], 0FF
00401146 |. 53 push ebx
00401147 |. 56 push esi
00401148 |. 57 push edi
00401149 |. 33DB xor ebx, ebx
0040114B |. 6A 64 push 64
0040114D |. 53 push ebx
0040114E |. 68 64674000 push 00406764
00401153 |. E8 680C0000 call 00401DC0 ; 分配100个字节
00401158 |. BE 5C654000 mov esi, 0040655C
0040115D |. 56 push esi ; 取name
0040115E |. E8 DD0B0000 call 00401D40
00401163 |. 8BF8 mov edi, eax ; name的长度
00401165 |. 83C4 10 add esp, 10
00401168 |. 33C9 xor ecx, ecx
0040116A |. 3BFB cmp edi, ebx ; 判断长度是否为0
0040116C |. 7C 31 jl short 0040119F
0040116E |> 80B9 5C654000>/cmp byte ptr [ecx+40655C], 20
00401175 |. 75 07 |jnz short 0040117E
00401177 |. 41 |inc ecx
00401178 |. 3BCF |cmp ecx, edi
0040117A |.^ 7E F2 \jle short 0040116E
0040117C |. EB 21 jmp short 0040119F
0040117E |> 3BCB cmp ecx, ebx
00401180 |. 7E 1D jle short 0040119F
00401182 |. 3BCF cmp ecx, edi
00401184 |. 8BD1 mov edx, ecx
00401186 |. 7F 17 jg short 0040119F
00401188 |> 8A9A 5C654000 /mov bl, [edx+40655C]
0040118E |. 8BC2 |mov eax, edx
00401190 |. 2BC1 |sub eax, ecx
00401192 |. 42 |inc edx
00401193 |. 3BD7 |cmp edx, edi
00401195 |. 8898 5C654000 |mov [eax+40655C], bl
0040119B |.^ 7E EB \jle short 00401188
0040119D |. 33DB xor ebx, ebx
0040119F |> 56 push esi
004011A0 |. E8 9B0B0000 call 00401D40
004011A5 |. 59 pop ecx
004011A6 |> 48 /dec eax
004011A7 |. 78 1B |js short 004011C4
004011A9 |. 80B8 5C654000>|cmp byte ptr [eax+40655C], 20
004011B0 |. 75 0C |jnz short 004011BE
004011B2 |. 3BC3 |cmp eax, ebx
004011B4 |.^ 75 F0 |jnz short 004011A6
004011B6 |. 881D 5C654000 |mov [40655C], bl
004011BC |.^ EB E8 \jmp short 004011A6
004011BE |> 8898 5D654000 mov [eax+40655D], bl
004011C4 |> 56 push esi
004011C5 |. E8 760B0000 call 00401D40
004011CA |. 83F8 04 cmp eax, 4
004011CD |. 59 pop ecx
004011CE |. 881D 67654000 mov [406567], bl
004011D4 |. 7D 08 jge short 004011DE
004011D6 |> 6A 01 push 1
004011D8 |. 58 pop eax
004011D9 |. E9 88000000 jmp 00401266
004011DE |> BF C0654000 mov edi, 004065C0
004011E3 |. 57 push edi
004011E4 |. E8 570B0000 call 00401D40 ; 取长度
004011E9 |. 59 pop ecx
004011EA |. 8BF0 mov esi, eax
004011EC |. 33C9 xor ecx, ecx
004011EE |. 3BF3 cmp esi, ebx
004011F0 |. 7C 31 jl short 00401223
004011F2 |> 80B9 C0654000>/cmp byte ptr [ecx+4065C0], 20
004011F9 |. 75 07 |jnz short 00401202
004011FB |. 41 |inc ecx
004011FC |. 3BCE |cmp ecx, esi
004011FE |.^ 7E F2 \jle short 004011F2
00401200 |. EB 21 jmp short 00401223
00401202 |> 3BCB cmp ecx, ebx
00401204 |. 7E 1D jle short 00401223
00401206 |. 3BCE cmp ecx, esi
00401208 |. 8BD1 mov edx, ecx
0040120A |. 7F 17 jg short 00401223
0040120C |> 8A9A C0654000 /mov bl, [edx+4065C0]
00401212 |. 8BC2 |mov eax, edx
00401214 |. 2BC1 |sub eax, ecx
00401216 |. 42 |inc edx
00401217 |. 3BD6 |cmp edx, esi
00401219 |. 8898 C0654000 |mov [eax+4065C0], bl
0040121F |.^ 7E EB \jle short 0040120C
00401221 |. 33DB xor ebx, ebx
00401223 |> 57 push edi
00401224 |. E8 170B0000 call 00401D40
00401229 |. 59 pop ecx
0040122A |> 48 /dec eax
0040122B |. 78 1B |js short 00401248
0040122D |. 80B8 C0654000>|cmp byte ptr [eax+4065C0], 20
00401234 |. 75 0C |jnz short 00401242
00401236 |. 3BC3 |cmp eax, ebx
00401238 |.^ 75 F0 |jnz short 0040122A
0040123A |. 881D C0654000 |mov [4065C0], bl
00401240 |.^ EB E8 \jmp short 0040122A
00401242 |> 8898 C1654000 mov [eax+4065C1], bl
00401248 |> 57 push edi
00401249 |. E8 F20A0000 call 00401D40
0040124E |. 83F8 0D cmp eax, 0D ; serail 13位 序列号是13位的
00401251 |. 59 pop ecx
00401252 |.^ 75 82 jnz short 004011D6
00401254 |. 8D45 FF lea eax, [ebp-1]
00401257 |. 50 push eax
00401258 |. E8 0E000000 call 0040126B 关键变换CALL,进入
0040125D |. 33C0 xor eax, eax
0040125F |. 385D FF cmp [ebp-1], bl ; 有个为0
00401262 |. 59 pop ecx
00401263 |. 0F95C0 setne al
00401266 |> 5F pop edi
00401267 |. 5E pop esi
00401268 |. 5B pop ebx
00401269 |. C9 leave
0040126A \. C3 retn
进入关键CALL 看如何变换serial成8个 BYTE
0040126B /$ 55 push ebp
0040126C |. 8BEC mov ebp, esp
0040126E |. 51 push ecx
0040126F |. A0 CC654000 mov al, [4065CC]
00401274 |. 3C 61 cmp al, 61
00401276 |. 7C 06 jl short 0040127E
00401278 |. 3C 7A cmp al, 7A
0040127A |. 7F 02 jg short 0040127E
0040127C |. 2C 20 sub al, 20 ; 小写变大写
0040127E |> 3C 30 cmp al, 30
00401280 |. 7C 0C jl short 0040128E
00401282 |. 3C 39 cmp al, 39
00401284 |. 7F 08 jg short 0040128E
00401286 |. 0FBEC0 movsx eax, al
00401289 |. 83E8 30 sub eax, 30 ; 数字-0x30
0040128C |. EB 16 jmp short 004012A4
0040128E |> 3C 41 cmp al, 41
00401290 |. 0F8C 26010000 jl 004013BC
00401296 |. 3C 46 cmp al, 46
00401298 |. 0F8F 1E010000 jg 004013BC ; A-F
0040129E |. 0FBEC0 movsx eax, al
004012A1 |. 83E8 37 sub eax, 37 ; 变成对应值
004012A4 |> 53 push ebx
004012A5 |. 56 push esi ; 最后一个值
004012A6 |. 57 push edi
004012A7 |. 33FF xor edi, edi
004012A9 |. BB 40654000 mov ebx, 00406540 ; 变换serial
004012AE |> 8A8F C0654000 /mov cl, [edi+4065C0]
004012B4 |. 80F9 61 |cmp cl, 61
004012B7 |. 7C 08 |jl short 004012C1
004012B9 |. 80F9 7A |cmp cl, 7A
004012BC |. 7F 03 |jg short 004012C1 ; a-z
004012BE |. 80E9 20 |sub cl, 20
004012C1 |> 80F9 41 |cmp cl, 41
004012C4 |. 7C 0D |jl short 004012D3 ; A-Z
004012C6 |. 80F9 5A |cmp cl, 5A
004012C9 |. 7F 08 |jg short 004012D3
004012CB |. 0FBEF1 |movsx esi, cl
004012CE |. 83EE 41 |sub esi, 41
004012D1 |. EB 10 |jmp short 004012E3
004012D3 |> 80F9 32 |cmp cl, 32
004012D6 |. 7C 6A |jl short 00401342
004012D8 |. 80F9 37 |cmp cl, 37
004012DB |. 7F 65 |jg short 00401342 ; 2-7
004012DD |. 0FBEF1 |movsx esi, cl
004012E0 |. 83EE 18 |sub esi, 18 ; -0x18
004012E3 |> 83FF 05 |cmp edi, 5
004012E6 |. 7D 07 |jge short 004012EF
004012E8 |. C1E0 05 |shl eax, 5
004012EB |. 0BC6 |or eax, esi
004012ED |. EB 47 |jmp short 00401336
004012EF |> 75 23 |jnz short 00401314
004012F1 |. 8BCE |mov ecx, esi
004012F3 |. 6A 04 |push 4
004012F5 |. C1E9 02 |shr ecx, 2
004012F8 |. C1E0 03 |shl eax, 3
004012FB |. 0BC8 |or ecx, eax
004012FD |. 8D45 FC |lea eax, [ebp-4]
00401300 |. 50 |push eax
00401301 |. 53 |push ebx
00401302 |. 894D FC |mov [ebp-4], ecx
00401305 |. E8 160B0000 |call 00401E20 ; 成生406540
0040130A |. 83C4 0C |add esp, 0C
0040130D |. 83E6 03 |and esi, 3
00401310 |. 8BC6 |mov eax, esi
00401312 |. EB 22 |jmp short 00401336
00401314 |> C1E0 05 |shl eax, 5
00401317 |. 0BC6 |or eax, esi
00401319 |. 83FF 0B |cmp edi, 0B
0040131C |. 8945 FC |mov [ebp-4], eax
0040131F |. 75 15 |jnz short 00401336
00401321 |. 8D45 FC |lea eax, [ebp-4]
00401324 |. 6A 04 |push 4
00401326 |. 50 |push eax
00401327 |. 68 44654000 |push 00406544 ; ASCII "蹙w?
0040132C |. E8 EF0A0000 |call 00401E20 ; serial生成406544
00401331 |. 83C4 0C |add esp, 0C
00401334 |. 33C0 |xor eax, eax
00401336 |> 47 |inc edi
00401337 |. 83FF 0C |cmp edi, 0C
0040133A |.^ 0F8C 6EFFFFFF \jl 004012AE
00401340 |. EB 14 jmp short 00401356
00401342 |> 8365 FC 00 and dword ptr [ebp-4], 0
00401346 |. 6A 08 push 8
00401348 |. 68 FF000000 push 0FF
0040134D |. 53 push ebx
0040134E |. E8 6D0A0000 call 00401DC0 ; 分配406540 8个FF
00401353 |. 83C4 0C add esp, 0C
00401356 |> 83FF 0C cmp edi, 0C
00401359 |. 5F pop edi
0040135A |. 5E pop esi
0040135B |. 5B pop ebx
0040135C |. 75 06 jnz short 00401364
0040135E |. 8B45 08 mov eax, [ebp+8]
00401361 |. 8020 00 and byte ptr [eax], 0
00401364 |> A0 40654000 mov al, [406540]
00401369 |. 8A0D 43654000 mov cl, [406543]
0040136F |. 880D 40654000 mov [406540], cl
00401375 |. 8A0D 42654000 mov cl, [406542]
0040137B |. A2 43654000 mov [406543], al
00401380 |. A0 41654000 mov al, [406541]
00401385 |. 880D 41654000 mov [406541], cl
0040138B |. 8A0D 47654000 mov cl, [406547]
00401391 |. A2 42654000 mov [406542], al
00401396 |. A0 44654000 mov al, [406544]
0040139B |. 880D 44654000 mov [406544], cl
004013A1 |. 8A0D 46654000 mov cl, [406546]
004013A7 |. A2 47654000 mov [406547], al
004013AC |. A0 45654000 mov al, [406545]
004013B1 |. 880D 45654000 mov [406545], cl
004013B7 |. A2 46654000 mov [406546], al
上面是BIG_ENDIAN的变换
004013BC |> C9 leave
004013BD \. C3 retn
serial是13位的,变换是可逆的。变换和逆变换,见下面C源码的翻译。
经过我的测试。
DWORD serialresult1,serialresult2;
char serialresult[14];
void StrToResult(char* serial)
{
DWORD eax;
if(serial[12]>='A'&&serial[12]<='Z')
{
eax=serial[12]-0x37;
}
else if(serial[12]>='0'&&serial[12]<='9')
{
eax=serial[12]-0x30;
}
int i;
DWORD temp;
for(i=0;i<6;i++)
{
if(serial[i]>='A'&&serial[i]<='Z')
{
temp=serial[i]-0x41;
}
else if(serial[i]>='2'&&serial[i]<='7')
{
temp=serial[i]-0x18;
}
if(i!=5)
{
eax=eax<<5;
eax=eax|temp;
}
else
{
DWORD temp2=temp>>2;
eax=eax<<3;
eax=eax|temp2;
serialresult1=eax;
eax=temp&0x3;
}
}
for(i=6;i<12;i++)
{
if(serial[i]>='A'&&serial[i]<='Z')
{
temp=serial[i]-0x41;
}
else if(serial[i]>='2'&&serial[i]<='7')
{
temp=serial[i]-0x18;
}
eax=eax<<5;
eax=eax|temp;
}
serialresult2=eax;
serialresult1=BIG_ENDIAN(serialresult1);
serialresult2=BIG_ENDIAN(serialresult2);
}
void ResultToSerial()
{
DWORD temp;
int i;
serialresult1=BIG_ENDIAN(serialresult1);
serialresult2=BIG_ENDIAN(serialresult2);
for(i=11;i>=6;i--)
{
temp=serialresult2&0x1F;
serialresult2=serialresult2>>5;
if(temp>=0&&temp<=0x19)
{
serialresult[i]=(char)(temp+0x41);
}
else
{
serialresult[i]=(char)(temp+0x18);
}
}
temp=serialresult2;
DWORD temp2=serialresult1&0x7;
serialresult1=serialresult1>>3;
temp=temp|(temp2<<2);
if(temp>=0&&temp<=0x19)
{
serialresult[5]=(char)(temp+0x41);
}
else
{
serialresult[5]=(char)(temp+0x18);
}
for(i=4;i>=0;i--)
{
temp=serialresult1&0x1F;
serialresult1=serialresult1>>5;
if(temp>=0&&temp<=0x19)
{
serialresult[i]=(char)(temp+0x41);
}
else
{
serialresult[i]=(char)(temp+0x18);
}
}
temp=serialresult1;
if(temp>=0&&temp<=0x9)
{
serialresult[12]=(char)(temp+0x30);
}
else
{
serialresult[12]=(char)(temp+0x37);
}
serialresult[13]='\0';
}
下面用C语言重新分析一边这个CrackMe:
int main(int argc, char* argv[])
{
char name[100];
scanf("%s",name);
int len=strlen(name); //输入name
int i;
char serail[14];
scanf("%s",serial); //输入序列号 13位
StrToResult(serial); //变换serial到serialresult1,serialresult2
BYTE serial_key[8];
((DWORD*)serial_key)[0]=serialresult1;
((DWORD*)serial_key)[1]=serialresult2; //结果送到8个BYTE中
BYTE data[0xB];
ZeroMemory(data,0xB);
memcpy(data,name,len>0xB?0xB:len);
BYTE digest[20];
CSHA1 sha1;
SHA1_CTX sha1_ctx;
sha1.SHA1Init(&sha1_ctx);
sha1.SHA1Update(&sha1_ctx,(BYTE*)data,0xB);
sha1.SHA1Final(digest,&sha1_ctx); //SHA变换name
CRC2 rc2;
rc2.InitUserKey(digest,20,1024); //用sha变换的结果做key,初始化rc2
BYTE inbox[8]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
};
BYTE outbox[8],result[8];
rc2.Encipher(inbox,outbox); //加密{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}=>outbox
rc2.Encipher(outbox,result); //加密outbox=>result可以得到,也就是说result这8字节可以得到
BYTE xor[8]={0x10,0x32,0x54,0x76,0x98,0xBA,0xDC,0xFE
};
BYTE key[8]; //RC2初始化用的 由result和serial_key变化结果xor出来
for(i=0;i<8;i++)
{
key[i]=result[i]^serial_key[i];
}
BYTE key1[8];
for(i=0;i<8;i++)
{
key1[i]=key[i]^xor[i];
} //这个我没分析到有什么用处,保留在这
CRC2 rc2_new;
rc2_new.InitUserKey(key,8,1024); //用key初始化rc2
BYTE result1[8],result2[8];
rc2_new.Encipher(inbox,result1); //ebp-50 加密{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}=>result1
BYTE data1[8]={0x40,0x4f,0x50,0x0a,0xd7,0xa1,0x67,0xb6
}; //固定的数据
rc2_new.Decipher(data1,result2); //ebp-3c 解密{0x40,0x4f,0x50,0x0a,0xd7,0xa1,0x67,0xb6}=>result2
for(i=0;i<8;i++)
{
result2[i]^=result1[i]; //ebp-3c XOR ebp-50
}
rc2_new.Encipher(data1,result1); //ebp-50 加密{0x40,0x4f,0x50,0x0a,0xd7,0xa1,0x67,0xb6}=>result1
DWORD number=*((DWORD*)result1);
number^=0x43097CBA; //取result1前4个BYTE xor 0x43097CBA
BYTE data2[0xC];
memcpy(data2,result2,8); //前8个byte是result2
((DWORD*)data2)[2]=number; //取result1前4个BYTE xor 0x43097CBA 送到最后4个BYTE上
BYTE digest1[20];
CSHA1 sha2;
SHA1_CTX sha2_ctx;
sha2.SHA1Init(&sha2_ctx);
sha2.SHA1Update(&sha2_ctx,(BYTE*)data2,0xC);
sha2.SHA1Final(digest1,&sha2_ctx); //SHA变换data2 结果要和下面相等,就是正确的注册码。
BYTE digest_result[20]={
0x29,0x66,0xEE,0x8F,0x71,0x09,0xF7,0x44,0x57,0x9E,
0xB5,0x2D,0x60,0xB0,0xB0,0xF5,0x55,0x58,0xE5,0x74
};
if(memcmp(digest1,digest_result,20)==0)
{
printf("correct serial");
}
}
这是CrackMe大概的过程。
怎么破解了,关键在后面的一些。
CRC2 rc2_new;
rc2_new.InitUserKey(key,8,1024); //用key初始化rc2
BYTE result1[8],result2[8];
rc2_new.Encipher(inbox,result1); //ebp-50 加密{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}=>result1
BYTE data1[8]={0x40,0x4f,0x50,0x0a,0xd7,0xa1,0x67,0xb6
}; //固定的数据
rc2_new.Decipher(data1,result2); //ebp-3c 解密{0x40,0x4f,0x50,0x0a,0xd7,0xa1,0x67,0xb6}=>result2
for(i=0;i<8;i++)
{
result2[i]^=result1[i]; //ebp-3c XOR ebp-50
}
rc2_new.Encipher(data1,result1); //ebp-50 加密{0x40,0x4f,0x50,0x0a,0xd7,0xa1,0x67,0xb6}=>result1
DWORD number=*((DWORD*)result1);
number^=0x43097CBA; //取result1前4个BYTE xor 0x43097CBA
BYTE data2[0xC];
memcpy(data2,result2,8); //前8个byte是result2
((DWORD*)data2)[2]=number; //取result1前4个BYTE xor 0x43097CBA 送到最后4个BYTE上
BYTE digest1[20];
CSHA1 sha2;
SHA1_CTX sha2_ctx;
sha2.SHA1Init(&sha2_ctx);
sha2.SHA1Update(&sha2_ctx,(BYTE*)data2,0xC);
sha2.SHA1Final(digest1,&sha2_ctx); //SHA变换data2 结果要和下面相等,就是正确的注册码。
BYTE digest_result[20]={
0x29,0x66,0xEE,0x8F,0x71,0x09,0xF7,0x44,0x57,0x9E,
0xB5,0x2D,0x60,0xB0,0xB0,0xF5,0x55,0x58,0xE5,0x74
};
if(memcmp(digest1,digest_result,20)==0)
{
printf("correct serial");
}
很明显,这一部分的key是固定的,是8个常BYTE,我猜了一些简单都没有试出来,后来猜BYTE xor[8]={0x10,0x32,0x54,0x76,0x98,0xBA,0xDC,0xFE};也许是的,结果也不是,总好穷举了,2的64次方啊,月中人兄算你狠,哪位知道key告诉我一声啊:)算了一天了,还没出结果,再让它跑一天吧,唉。
跑出 key后就好办了,根据
for(i=0;i<8;i++)
{
key[i]=result[i]^serial_key[i];
}
那么
for(i=0;i<8;i++)
{
serial_key[i]=result[i]^key[i];
}
因为result是通过name得出来的,是知道的,所以serial_key就知道了,所以serialresult1,serialresult2就出来了,在通过ResultToSerial()就可以得到注册码了。
【总结】
月中兄你好狠啊,我的机器好命苦啊,跑了一天都没出来,555
这里起个抛砖引玉的作用,探讨一下如何找到这个key吧,如果不用穷举的话。
[注意]APP应用上架合规检测服务,协助应用顺利上架!