[CRC32算法练习] CRC32CrackMe算法分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CRC32算法练习] CRC32CrackMe算法分析相关的知识,希望对你有一定的参考价值。
【破文标题】[CRC32算法练习] CRC32CrackMe算法分析
【破文作者】静心学习
【作者邮箱】[email protected]
【作者主页】http://www.cnblogs.com/dacainiao/
【破解工具】OD, DEDE, IDA
【破解平台】xp sp3
【软件名称】CRC32CrackMe
【软件大小】40KB
【原版下载】http://bbs.pediy.com/attachment.php?attachmentid=6579&d=1183561716
【保护方式】无壳
【软件简介】一个CRC32算法练习的CrackMe。
【破解声明】初学密码学,跟着看雪前辈们的脚步学习,错误之处敬请诸位前辈不吝赐教。
------------------------------------------------------------------------
【破解过程】软件无壳,vc编写,bp GetDlgItemTextA可以很快找到入口点。
00401309 > \\8D8424 0C020000 LEA EAX, DWORD PTR SS:[ESP+0x20C] 00401310 . 8D8C24 0C010000 LEA ECX, DWORD PTR SS:[ESP+0x10C] 00401317 . 50 PUSH EAX ; //Buff 00401318 . 51 PUSH ECX ; //用户名 00401319 . E8 F2FDFFFF CALL CRC32Cra.00401110 ; //计算CRC32 0040131E . 8D9424 14020000 LEA EDX, DWORD PTR SS:[ESP+0x214] 00401325 . 8D4424 14 LEA EAX, DWORD PTR SS:[ESP+0x14] 00401329 . 52 PUSH EDX ; //CRC32 0040132A . 50 PUSH EAX ; //注册码 0040132B . E8 D0FCFFFF CALL CRC32Cra.00401000 00401330 . 83C4 10 ADD ESP, 0x10 00401333 . 83F8 01 CMP EAX, 0x1 00401336 . 6A 40 PUSH 0x40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL 00401338 . 68 8C604000 PUSH CRC32Cra.0040608C ; |Title = "注册提示" 0040133D . 75 18 JNZ SHORT CRC32Cra.00401357 ; | 0040133F . 68 48604000 PUSH CRC32Cra.00406048 ; |Text = "恭喜你,注册码正确!" 00401344 . 56 PUSH ESI ; |hOwner 00401345 . FF15 A8504000 CALL NEAR DWORD PTR DS:[<&USER32.MessageBoxA>] ; \\MessageBoxA 0040134B . 5F POP EDI 0040134C . 5E POP ESI 0040134D . 33C0 XOR EAX, EAX 0040134F . 5B POP EBX 00401350 . 81C4 00030000 ADD ESP, 0x300 00401356 . C3 RETN
代码很少,直接看计算CRC32的CALL (CALL 00401110):
00401110 /$ 83EC 0C SUB ESP, 0xC 00401113 |. 56 PUSH ESI 00401114 |. 57 PUSH EDI 00401115 |. E8 B6FFFFFF CALL CRC32Cra.004010D0 ; //生成CRC32表 0040111A |. 8B7424 18 MOV ESI, DWORD PTR SS:[ESP+0x18] ; //用户名 0040111E |. 83C9 FF OR ECX, 0xFFFFFFFF 00401121 |. 8BFE MOV EDI, ESI 00401123 |. 33C0 XOR EAX, EAX 00401125 |. 83CA FF OR EDX, 0xFFFFFFFF 00401128 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 0040112A |. F7D1 NOT ECX 0040112C |. 49 DEC ECX ; //取用户名长度 0040112D |. 85C9 TEST ECX, ECX 0040112F |. 7E 1F JLE SHORT CRC32Cra.00401150 ; //小于等于0则跳 00401131 |. 53 PUSH EBX 00401132 |> 8BC2 /MOV EAX, EDX ; //上一次CRC值 00401134 |. 33DB |XOR EBX, EBX 00401136 |. 8A1E |MOV BL, BYTE PTR DS:[ESI] ; //用户名1字节 00401138 |. 25 FF000000 |AND EAX, 0xFF ; //eax & 0xff 0040113D |. 33C3 |XOR EAX, EBX ; //(eax & 0xff) ^ ebx 0040113F |. C1EA 08 |SHR EDX, 0x8 ; //edx >> 8 00401142 |. 8B0485 20854000 |MOV EAX, DWORD PTR DS:[EAX*4+0x408520] ; //408250[(eax & 0xff) ^ ebx] 00401149 |. 33D0 |XOR EDX, EAX ; //(edx >> 8) ^ 408250[(eax & 0xff) ^ ebx] 0040114B |. 46 |INC ESI 0040114C |. 49 |DEC ECX 0040114D |.^ 75 E3 \\JNZ SHORT CRC32Cra.00401132 0040114F |. 5B POP EBX 00401150 |> 33C9 XOR ECX, ECX 00401152 |. 8D4424 08 LEA EAX, DWORD PTR SS:[ESP+0x8] 00401156 |. 894C24 09 MOV DWORD PTR SS:[ESP+0x9], ECX 0040115A |. 6A 10 PUSH 0x10 0040115C |. F7D2 NOT EDX ; //~edx 0040115E |. 894C24 11 MOV DWORD PTR SS:[ESP+0x11], ECX 00401162 |. 50 PUSH EAX 00401163 |. 52 PUSH EDX 00401164 |. C64424 14 00 MOV BYTE PTR SS:[ESP+0x14], 0x0 00401169 |. 884C24 1D MOV BYTE PTR SS:[ESP+0x1D], CL 0040116D |. E8 24380000 CALL CRC32Cra.00404996 00401172 |. 8D7C24 14 LEA EDI, DWORD PTR SS:[ESP+0x14] 00401176 |. 83C9 FF OR ECX, 0xFFFFFFFF 00401179 |. 33C0 XOR EAX, EAX 0040117B |. 83C4 0C ADD ESP, 0xC 0040117E |. 33F6 XOR ESI, ESI 00401180 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 00401182 |. F7D1 NOT ECX 00401184 |. 49 DEC ECX ; //CRC32长度 00401185 |. 74 25 JE SHORT CRC32Cra.004011AC ; //长度为0则跳 00401187 |> 0FBE4C34 08 /MOVSX ECX, BYTE PTR SS:[ESP+ESI+0x8] ; //取CRC32第1字节 0040118C |. 51 |PUSH ECX 0040118D |. E8 4E020000 |CALL CRC32Cra.004013E0 ; //小写字母转大写 00401192 |. 884434 0C |MOV BYTE PTR SS:[ESP+ESI+0xC], AL 00401196 |. 83C4 04 |ADD ESP, 0x4 00401199 |. 8D7C24 08 |LEA EDI, DWORD PTR SS:[ESP+0x8] 0040119D |. 83C9 FF |OR ECX, 0xFFFFFFFF 004011A0 |. 33C0 |XOR EAX, EAX 004011A2 |. 46 |INC ESI 004011A3 |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI] 004011A5 |. F7D1 |NOT ECX 004011A7 |. 49 |DEC ECX ; //求CRC32长度 004011A8 |. 3BF1 |CMP ESI, ECX ; //大于等于则跳出循环 004011AA |.^ 72 DB \\JB SHORT CRC32Cra.00401187 004011AC |> 8B4424 1C MOV EAX, DWORD PTR SS:[ESP+0x1C] 004011B0 |. 8D5424 08 LEA EDX, DWORD PTR SS:[ESP+0x8] 004011B4 |. 52 PUSH EDX ; /String2 004011B5 |. 50 PUSH EAX ; |String1 004011B6 |. FF15 00504000 CALL NEAR DWORD PTR DS:[<&KERNEL32.lstrcpyA>] ; \\lstrcpyA 004011BC |. 5F POP EDI 004011BD |. 5E POP ESI 004011BE |. 83C4 0C ADD ESP, 0xC 004011C1 \\. C3 RETN
首先动态初始化CRC32表 (CALL 004010D0):
004010D0 /$ 56 PUSH ESI 004010D1 |. 33D2 XOR EDX, EDX 004010D3 |. B9 20854000 MOV ECX, CRC32Cra.00408520 ; //CRC32表首地址 004010D8 |> 8BC2 /MOV EAX, EDX 004010DA |. BE 08000000 |MOV ESI, 0x8 004010DF |> A8 01 |/TEST AL, 0x1 004010E1 |. 74 09 ||JE SHORT CRC32Cra.004010EC 004010E3 |. D1E8 ||SHR EAX, 1 004010E5 |. 35 2083B8ED ||XOR EAX, 0xEDB88320 004010EA |. EB 02 ||JMP SHORT CRC32Cra.004010EE 004010EC |> D1E8 ||SHR EAX, 1 ; //动态生成CRC32表 004010EE |> 4E ||DEC ESI 004010EF |.^ 75 EE |\\JNZ SHORT CRC32Cra.004010DF 004010F1 |. 8901 |MOV DWORD PTR DS:[ECX], EAX 004010F3 |. 83C1 04 |ADD ECX, 0x4 004010F6 |. 42 |INC EDX 004010F7 |. 81F9 20894000 |CMP ECX, CRC32Cra.00408920 004010FD |.^ 7C D9 \\JL SHORT CRC32Cra.004010D8 004010FF |. 5E POP ESI 00401100 \\. C3 RETN
然后获取用户名长度,开始循环计算CRC:
0040111A |. 8B7424 18 MOV ESI, DWORD PTR SS:[ESP+0x18] ; //用户名 0040111E |. 83C9 FF OR ECX, 0xFFFFFFFF 00401121 |. 8BFE MOV EDI, ESI 00401123 |. 33C0 XOR EAX, EAX 00401125 |. 83CA FF OR EDX, 0xFFFFFFFF 00401128 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 0040112A |. F7D1 NOT ECX 0040112C |. 49 DEC ECX ; //取用户名长度 0040112D |. 85C9 TEST ECX, ECX 0040112F |. 7E 1F JLE SHORT CRC32Cra.00401150 ; //小于等于0则跳 00401131 |. 53 PUSH EBX 00401132 |> 8BC2 /MOV EAX, EDX ; //上一次CRC值 00401134 |. 33DB |XOR EBX, EBX 00401136 |. 8A1E |MOV BL, BYTE PTR DS:[ESI] ; //用户名1字节 00401138 |. 25 FF000000 |AND EAX, 0xFF ; //eax & 0xff 0040113D |. 33C3 |XOR EAX, EBX ; //(eax & 0xff) ^ ebx 0040113F |. C1EA 08 |SHR EDX, 0x8 ; //edx >> 8 00401142 |. 8B0485 20854000 |MOV EAX, DWORD PTR DS:[EAX*4+0x408520] ; //408250[(eax & 0xff) ^ ebx] 00401149 |. 33D0 |XOR EDX, EAX ; //(edx >> 8) ^ 408250[(eax & 0xff) ^ ebx] 0040114B |. 46 |INC ESI 0040114C |. 49 |DEC ECX 0040114D |.^ 75 E3 \\JNZ SHORT CRC32Cra.00401132 0040114F |. 5B POP EBX 00401150 |> 33C9 XOR ECX, ECX 00401152 |. 8D4424 08 LEA EAX, DWORD PTR SS:[ESP+0x8] 00401156 |. 894C24 09 MOV DWORD PTR SS:[ESP+0x9], ECX 0040115A |. 6A 10 PUSH 0x10 0040115C |. F7D2 NOT EDX ; //~edx
最终将CRC32中的小写字母转大写字母:
00401172 |. 8D7C24 14 LEA EDI, DWORD PTR SS:[ESP+0x14] 00401176 |. 83C9 FF OR ECX, 0xFFFFFFFF 00401179 |. 33C0 XOR EAX, EAX 0040117B |. 83C4 0C ADD ESP, 0xC 0040117E |. 33F6 XOR ESI, ESI 00401180 |. F2:AE REPNE SCAS BYTE PTR ES:[EDI] 00401182 |. F7D1 NOT ECX 00401184 |. 49 DEC ECX ; //CRC32长度 00401185 |. 74 25 JE SHORT CRC32Cra.004011AC ; //长度为0则跳 00401187 |> 0FBE4C34 08 /MOVSX ECX, BYTE PTR SS:[ESP+ESI+0x8] ; //取CRC32第1字节 0040118C |. 51 |PUSH ECX 0040118D |. E8 4E020000 |CALL CRC32Cra.004013E0 ; //小写字母转大写 00401192 |. 884434 0C |MOV BYTE PTR SS:[ESP+ESI+0xC], AL 00401196 |. 83C4 04 |ADD ESP, 0x4 00401199 |. 8D7C24 08 |LEA EDI, DWORD PTR SS:[ESP+0x8] 0040119D |. 83C9 FF |OR ECX, 0xFFFFFFFF 004011A0 |. 33C0 |XOR EAX, EAX 004011A2 |. 46 |INC ESI 004011A3 |. F2:AE |REPNE SCAS BYTE PTR ES:[EDI] 004011A5 |. F7D1 |NOT ECX 004011A7 |. 49 |DEC ECX ; //求CRC32长度 004011A8 |. 3BF1 |CMP ESI, ECX ; //大于等于则跳出循环 004011AA |.^ 72 DB \\JB SHORT CRC32Cra.00401187
最终和输入的注册码比较,相同则注册成功。
------------------------------------------------------------------------
【破解总结】软件使用CRC32算法,将输入的用户名计算出CRC32的值,并将里面的小写字母转成大写,然后与输入的注册码比较,相同则注册成功。
------------------------------------------------------------------------
【版权声明】无
以上是关于[CRC32算法练习] CRC32CrackMe算法分析的主要内容,如果未能解决你的问题,请参考以下文章