[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的值,并将里面的小写字母转成大写,然后与输入的注册码比较,相同则注册成功。
------------------------------------------------------------------------
【版权声明】无

时间: 2024-08-10 00:06:33

[CRC32算法练习] CRC32CrackMe算法分析的相关文章

[MD5算法练习] MD5CrackMe算法分析

[破文标题][MD5算法练习] MD5CrackMe算法分析[破文作者]静心学习[作者邮箱][email protected][作者主页]http://www.cnblogs.com/dacainiao/[破解工具]OD[破解平台]xp sp3[软件名称]MD5CrackMe[软件大小]72KB[原版下载]http://pan.baidu.com/share/link?shareid=1620370201&uk=892352529[保护方式]无壳[软件简介]一个MD5算法练习的CrackMe[破

普林斯顿公开课 算法1-1:算法分析

为什么要分析算法 分析算法能够预測算法的性能,比較算法之间的优劣,保证算法的正确性,理解算法的理论基础. 成功算法的样例 离散傅立叶变换,假设使用暴力方法,那么算法的复杂度是是N^2,假设使用FFT高速傅立叶变换能够实现O(N logN)复杂度 N-body模拟:使用Barnes-hut算法能够将复杂度减少到N logN 顺便发一张N-body模拟的炫图 Barnes-Hut算法示意图 算法分析的步骤 观察问题的特征和想到得到的结果 依据观察结果提出如果 使用如果来预測可能发生的情况 检測预測结

算法简介及算法分析

算法简介及算法分析 算法简介 算法的定义: 算法是对特定问题求解步骤的一种描述,是指令的有限序列.(所以说只要满足上述条件,即使很简单的一个循环也是算法) 算法具备5个特征: 输入 输出 有穷性 确定性 可行性 什么是好算法: 正确性 鲁棒性 简单性 抽象分级 高效性 算法分析: 高效性是评价一个算法是否是好算法的重要标准,那么我们怎么判断算法是否高效呢?有的人说,把算法用程序语言实现一下,再输入多个测试数据实际检测运行速度(时间频度)和空间开销就好了呗!这种事后统计的方法并不能准确检测,它牵扯

[SHA-1算法练习] sha1crackme算法分析

[破文标题][SHA-1算法练习] sha1crackme算法分析[破文作者]静心学习[作者邮箱][email protected][作者主页]http://www.cnblogs.com/dacainiao/[破解工具]OD, DEDE, IDA[破解平台]xp sp3[软件名称]sha1crackme[软件大小]66KB[原版下载]http://bbs.pediy.com/showthread.php?t=131765[保护方式]无壳[软件简介]一个sha1算法练习的crackme.[破解声

[SHA-1算法练习] SHACrackMe算法分析

[破文标题][SHA-1算法练习] SHACrackMe算法分析[破文作者]静心学习[作者邮箱][email protected][作者主页]http://www.cnblogs.com/dacainiao/[破解工具]OD[破解平台]xp sp3[软件名称]SHACrackMe[软件大小]148KB[原版下载]http://bbs.pediy.com/attachment.php?attachmentid=6581&d=1183561734[保护方式]无壳[软件简介]一个SHA-1的算法练习C

CRC32算法冲突概率测试和分析

最近因为某个业务需要用到CRC32算法,但业务又不能容忍重复的数值出现,于是自然就想了解一下CRC32算法的冲突概率(或者叫碰撞概率). 本以为这种问题应该很多人分析过,结果找来找去就只看到一大堆数学公式,我这种数学盲完全看不懂. 好不容易找到一张图,但看得云里雾里(原图链接:http://preshing.com/20110504/hash-collision-probabilities/ ): 既然网上的不靠谱,那就自己来验证吧,写个php脚本很简单,我的第1次验证模型是这样的: 取1个整型

CRC32算法笔记

这几天在研究CRC32的计算过程,看了CRC算法的原理,也看了不少通过移位法实现的代码,但是算出的结果跟校验工具算的不一致. 折腾了好长时间,终于找到一个手工计算CRC32的文章,再对照IEEE 802.3标准的CRC计算过程,才算把CRC32的计算搞定. 这里把计算过程的要点记录一下: 1) CRC32是CRC算法一种,先参考Wiki上CRC算法的原理和实例搞明白基本的计算方法. 2) 最常见的CRC32算法就是IEEE 802.3里生成FCS字段用的那个: a) CRC32使用的Polyno

javascript数据结构与算法--基本排序算法分析

javascript中的基本排序算法 对计算机中存储的数据执行的两种最常见操作是排序和检索,排序和检索算法对于前端开发尤其重要,对此我会对这两种算法做深入的研究,而不会和书上一样只是会贴代码而已,下面我会一步步从自己的理解的思路来一步步学习各个排序的思想.不过这些算法依赖于javascript中的数组来存储数据.最后我会来测试下基本算法(冒泡排序,选择排序,插入排序)的那个效率更高! 下面啊,我们先可以来封装常规数组操作的函数,比如:插入新数据,显示数组数据,还有交换数组元素等操作来调用不同的排

数据结构算法1------算法和算法分析

最近面试iOS实习生.几次都是败在数据结构算法上面了.决定重新捡起大学的课本,复习一下数据结构算法相关知识. 1.反转一个链表.循环算法.               1     List   reverse(List   l)   {       2     if(!l)   return   l;       3         list   cur   =   l.next;       4     list   pre   =   l;       5     list   tmp;