好友
阅读权限25
听众
最后登录1970-1-1
|
sdzzb
发表于 2012-4-29 15:32
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。
本帖最后由 Peace 于 2012-4-30 08:15 编辑
【文章标题】: 吾爱破解2012CM大赛破文
【文章作者】: DZ
【软件名称】: crackme_zapline
【难 度】: 易
【下载地址】: http://www.52pojie.cn/thread-146108-1-1.html
【作者声明】: 一个一个来,慢慢分析,直到最难 ^^
--------------------------------------------------------------------------------
【详细过程】
第一次写破文,不知道有什么章法和讲究,就按我自己的理解和思路来叙述吧 ^^ 进入正题。。。
这个CM没有按钮,刚开始我认为是‘编辑框内容改变’(易语言说法)来引发的事件,故我下上消息断点WM_CHAR,
断下后一路跟踪,到达这里 0041C9D0 /[ DISCUZ_CODE_5 ]nbsp; 55 push ebp
0041C9D1 |. 8BEC mov ebp,esp
0041C9D3 |. 53 push ebx
0041C9D4 |. 56 push esi
0041C9D5 |. 8BD9 mov ebx,ecx
0041C9D7 |. 8B03 mov eax,dword ptr ds:[ebx]
0041C9D9 |. 57 push edi
0041C9DA |. 50 push eax ; /hWnd
0041C9DB |. FF15 DC024300 call dword ptr ds:[<&USER32.GetWindowTextLengthW>] ; \GetWindowTextLengthW
0041C9E1 |. 8D70 01 lea esi,dword ptr ds:[eax+1]
0041C9E4 |. 85F6 test esi,esi
0041C9E6 |. 79 0A jns short crackme_.0041C9F2
0041C9E8 |> 68 57000780 push 80070057
0041C9ED |. E8 BE46FEFF call crackme_.004010B0
0041C9F2 |> 8B7D 08 mov edi,[arg.1]
0041C9F5 |. 8B07 mov eax,dword ptr ds:[edi]
0041C9F7 |. 8B50 F8 mov edx,dword ptr ds:[eax-8]
0041C9FA |. B9 01000000 mov ecx,1
0041C9FF |. 2B48 FC sub ecx,dword ptr ds:[eax-4]
0041CA02 |. 2BD6 sub edx,esi
0041CA04 |. 0BCA or ecx,edx
0041CA06 |. 7D 08 jge short crackme_.0041CA10
0041CA08 |. 56 push esi ; /Arg1
0041CA09 |. 8BCF mov ecx,edi ; |
0041CA0B |. E8 605BFEFF call crackme_.00402570 ; \crackme_.00D92570
0041CA10 |> 8B07 mov eax,dword ptr ds:[edi]
0041CA12 |. 56 push esi ; /Count
0041CA13 |. 50 push eax ; |Buffer
0041CA14 |. 8B03 mov eax,dword ptr ds:[ebx] ; |
0041CA16 |. 50 push eax ; |hWnd
0041CA17 |. FF15 E0024300 call dword ptr ds:[<&USER32.GetWindowTextW>] ; \GetWindowTextW
大家可以看到了两个API(可以直接下这两个函数的断点),两个函数作用看名字就知道啦,不多说;我们返回上层,代码如下,我已经写了几句注释0041CA60 /[ DISCUZ_CODE_6 ]nbsp; 53 push ebx
0041CA61 |. 56 push esi
0041CA62 |. 8BF1 mov esi,ecx
0041CA64 |. 57 push edi
0041CA65 |. 8DBE 78030000 lea edi,dword ptr ds:[esi+378]
0041CA6B |. 57 push edi ; /Arg1
0041CA6C |. 8D8E 84030000 lea ecx,dword ptr ds:[esi+384] ; |
0041CA72 |. E8 59FFFFFF call crackme_.0041C9D0 ; \获取用户名
0041CA77 |. 8D86 7C030000 lea eax,dword ptr ds:[esi+37C]
0041CA7D |. 50 push eax ; /Arg1
0041CA7E |. 8D8E 88030000 lea ecx,dword ptr ds:[esi+388] ; |
0041CA84 |. E8 47FFFFFF call crackme_.0041C9D0 ; \获取密码
0041CA89 |. 8D9E 80030000 lea ebx,dword ptr ds:[esi+380]
0041CA8F |. 53 push ebx ; /Arg2
0041CA90 |. 57 push edi ; |Arg1
0041CA91 |. E8 1AFDFFFF call crackme_.0041C7B0 ; \判断用户名是否是 "52pojie"
0041CA96 |. 83C4 08 add esp,8
0041CA99 |. 84C0 test al,al
0041CA9B |. 74 33 je short crackme_.0041CAD0 ; 如果用户名不是‘52pojie’,下面就关闭另外2个时钟,继续检测用户名
0041CA9D |. 8B4E 04 mov ecx,dword ptr ds:[esi+4]
0041CAA0 |. 6A 35 push 35 ; /TimerID = 35 (53.)
0041CAA2 |. 51 push ecx ; |hWnd
0041CAA3 |. FF15 30034300 call dword ptr ds:[<&USER32.KillTimer>] ; \KillTimer
0041CAA9 |. 8B56 04 mov edx,dword ptr ds:[esi+4]
0041CAAC |. 6A 36 push 36 ; /TimerID = 36 (54.)
0041CAAE |. 52 push edx ; |hWnd
0041CAAF |. FF15 30034300 call dword ptr ds:[<&USER32.KillTimer>] ; \KillTimer
0041CAB5 |. 57 push edi ; /Arg1
0041CAB6 |. 8BCB mov ecx,ebx ; |
0041CAB8 |. E8 83EDFEFF call crackme_.0040B840 ; \crackme_.0040B840
0041CABD |. 8B46 04 mov eax,dword ptr ds:[esi+4]
0041CAC0 |. 6A 00 push 0 ; /Timerproc = NULL
0041CAC2 |. 68 C8000000 push 0C8 ; |Timeout = 200. ms
0041CAC7 |. 6A 34 push 34 ; |TimerID = 34 (52.)
0041CAC9 |. 50 push eax ; |hWnd
0041CACA |. FF15 F0024300 call dword ptr ds:[<&USER32.SetTimer>] ; \SetTimer
0041CAD0 |> 5F pop edi
0041CAD1 |. 5E pop esi
0041CAD2 |. 5B pop ebx
0041CAD3 \. C3 retn
我们继续返回到上层去,代码如下0041CAE0 /[ DISCUZ_CODE_7 ]nbsp; 53 push ebx ; 第一个时钟事件
0041CAE1 |. 56 push esi
0041CAE2 |. 57 push edi
0041CAE3 |. 8BF1 mov esi,ecx
0041CAE5 |. E8 76FFFFFF call crackme_.0041CA60
0041CAEA |. 8B96 78030000 mov edx,dword ptr ds:[esi+378] ; [edx] = 用户名
0041CAF0 |. 8B4A F4 mov ecx,dword ptr ds:[edx-C] ; ecx=用户名长度
0041CAF3 |. 33DB xor ebx,ebx
0041CAF5 |. 33C0 xor eax,eax
0041CAF7 |. 85C9 test ecx,ecx
0041CAF9 |. 7E 1A jle short crackme_.0041CB15
0041CAFB |. EB 03 jmp short crackme_.0041CB00
0041CAFD | 8D49 00 lea ecx,dword ptr ds:[ecx]
0041CB00 |> 85C0 /test eax,eax ; start_STEP1 --------------------
0041CB02 |. 78 44 |js short crackme_.0041CB48 ; |
0041CB04 |. 3BC1 |cmp eax,ecx ; |
0041CB06 |. 7F 40 |jg short crackme_.0041CB48 ; |
0041CB08 |. 0FB73A |movzx edi,word ptr ds:[edx] ; |
0041CB0B |. 40 |inc eax ; |
0041CB0C |. 03DF |add ebx,edi ; |
0041CB0E |. 83C2 02 |add edx,2 ; |
0041CB11 |. 3BC1 |cmp eax,ecx ; |
0041CB13 |.^ 7C EB \jl short crackme_.0041CB00 ; end_STEP1 --------------------->求name各位的ASCII之和 放在ebx
0041CB15 |> 8BB6 7C030000 mov esi,dword ptr ds:[esi+37C] ; [esi] = 密码
0041CB1B |. 8B4E F4 mov ecx,dword ptr ds:[esi-C] ; ecx = 密码长度
0041CB1E |. 33FF xor edi,edi
0041CB20 |. 33C0 xor eax,eax
0041CB22 |. 85C9 test ecx,ecx
0041CB24 |. 7E 17 jle short crackme_.0041CB3D
0041CB26 |. 8BD6 mov edx,esi
0041CB28 |> 85C0 /test eax,eax ; start_STEP2 --------------------
0041CB2A |. 78 1C |js short crackme_.0041CB48 ; |
0041CB2C |. 3BC1 |cmp eax,ecx ; |
0041CB2E |. 7F 18 |jg short crackme_.0041CB48 ; |
0041CB30 |. 0FB732 |movzx esi,word ptr ds:[edx] ; |
0041CB33 |. 40 |inc eax ; |
0041CB34 |. 03FE |add edi,esi ; |
0041CB36 |. 83C2 02 |add edx,2 ; |
0041CB39 |. 3BC1 |cmp eax,ecx ; |
0041CB3B |.^ 7C EB \jl short crackme_.0041CB28 ; end_STEP2 --------------------->求密码各位的ASCII之和 放在edi
0041CB3D |> 33C0 xor eax,eax
0041CB3F |. 3BDF cmp ebx,edi ; 比较用户名和密码的ASCII之和是否相等
0041CB41 |. 5F pop edi
0041CB42 |. 5E pop esi
0041CB43 |. 0F94C0 sete al ; 不相等 Z标志位 = 0 ;相等 Z标志位 = 1
0041CB46 |. 5B pop ebx
0041CB47 |. C3 retn
很明显 此函数过程是比较用户名和密码各位的ASCII码之和是否相等,若不相等 sete al 执行后 al = 0 ,相等的话,al = 1 ,继续返回到上层 0041CCC0 /[ DISCUZ_CODE_8 ]nbsp; 55 push ebp
0041CCC1 |. 8BEC mov ebp,esp
0041CCC3 |. 8B45 08 mov eax,[arg.1]
0041CCC6 |. 56 push esi
0041CCC7 |. 8BF1 mov esi,ecx
0041CCC9 |. 83F8 34 cmp eax,34
0041CCCC |. 75 2D jnz short crackme_.0041CCFB
0041CCCE |. E8 0DFEFFFF call crackme_.0041CAE0 ; 从此call出来
0041CCD3 |. 85C0 test eax,eax ; 返回到这里了
0041CCD5 |. 74 4D je short crackme_.0041CD24
0041CCD7 |. 8B46 04 mov eax,dword ptr ds:[esi+4]
0041CCDA |. 6A 34 push 34 ; /TimerID = 34 (52.)
0041CCDC |. 50 push eax ; |hWnd
0041CCDD |. FF15 30034300 call dword ptr ds:[<&USER32.KillTimer>] ; \KillTimer
0041CCE3 |. 8B4E 04 mov ecx,dword ptr ds:[esi+4]
0041CCE6 |. 6A 00 push 0 ; /Timerproc = NULL
0041CCE8 |. 68 C8000000 push 0C8 ; |Timeout = 200. ms
0041CCED |. 6A 35 push 35 ; |TimerID = 35 (53.)
0041CCEF |. 51 push ecx ; |hWnd
0041CCF0 |. FF15 F0024300 call dword ptr ds:[<&USER32.SetTimer>] ; \SetTimer
0041CCF6 |. 5E pop esi
0041CCF7 |. 5D pop ebp
0041CCF8 |. C2 0400 retn 4
0041CCFB |> 83F8 35 cmp eax,35
0041CCFE |. 75 24 jnz short crackme_.0041CD24
0041CD00 |. E8 5BFEFFFF call crackme_.0041CB60
0041CD05 |. 85C0 test eax,eax
0041CD07 |. 74 1B je short crackme_.0041CD24
0041CD09 |. 8B56 04 mov edx,dword ptr ds:[esi+4]
0041CD0C |. 6A 35 push 35 ; /TimerID = 35 (53.)
0041CD0E |. 52 push edx ; |hWnd
0041CD0F |. FF15 30034300 call dword ptr ds:[<&USER32.KillTimer>] ; \KillTimer
0041CD15 |. 6A 01 push 1
0041CD17 |. 68 EE030000 push 3EE
0041CD1C |. 8D4E 50 lea ecx,dword ptr ds:[esi+50]
0041CD1F |. E8 BCFEFFFF call crackme_.0041CBE0
0041CD24 |> 5E pop esi
0041CD25 |. 5D pop ebp
0041CD26 \. C2 0400 retn 4
发现eax可以决定一个时钟的关闭和另一个时钟的开启,我们把 0041CB3F 3BDF cmp ebx,edi 这句执行后的Z标志位改成1,就把第一个时钟关闭了,开始了第二个时钟事件,
第二个时钟事件跟第一个类似,代码如下0041CB60 |[ DISCUZ_CODE_9 ]nbsp; 53 push ebx ; 第二个时钟事件
0041CB61 |. 56 push esi
0041CB62 |. 57 push edi
0041CB63 |. 8BF1 mov esi,ecx
0041CB65 |. E8 F6FEFFFF call crackme_.0041CA60
0041CB6A |. 8B96 78030000 mov edx,dword ptr ds:[esi+378] ; edx保存name
0041CB70 |. 8B4A F4 mov ecx,dword ptr ds:[edx-C] ; ecx保存name长度
0041CB73 |. 33DB xor ebx,ebx
0041CB75 |. 33C0 xor eax,eax
0041CB77 |. 85C9 test ecx,ecx
0041CB79 |. 7E 1A jle short crackme_.0041CB95
0041CB7B |. EB 03 jmp short crackme_.0041CB80
0041CB7D | 8D49 00 lea ecx,dword ptr ds:[ecx]
0041CB80 |> 85C0 /test eax,eax ; start_STEP1 ====================
0041CB82 |. 78 49 |js short crackme_.0041CBCD ; ||
0041CB84 |. 3BC1 |cmp eax,ecx ; ||
0041CB86 |. 7F 45 |jg short crackme_.0041CBCD ; ||
0041CB88 |. 0FB73A |movzx edi,word ptr ds:[edx] ; ||
0041CB8B |. 40 |inc eax ; ||
0041CB8C |. 03DF |add ebx,edi ; ||
0041CB8E |. 83C2 02 |add edx,2 ; ||
0041CB91 |. 3BC1 |cmp eax,ecx ; end_STEP2 =======>同样 ebx = 用户名各位ASCII之和
0041CB93 |.^ 7C EB \jl short crackme_.0041CB80
0041CB95 |> 8BB6 7C030000 mov esi,dword ptr ds:[esi+37C] ; [esi] = 密码
0041CB9B |. 8B4E F4 mov ecx,dword ptr ds:[esi-C] ; ecx = 密码长度
0041CB9E |. 33FF xor edi,edi
0041CBA0 |. 33C0 xor eax,eax
0041CBA2 |. 85C9 test ecx,ecx
0041CBA4 |. 7E 17 jle short crackme_.0041CBBD
0041CBA6 |. 8BD6 mov edx,esi
0041CBA8 |> 85C0 /test eax,eax ; start_STEP2 =====================
0041CBAA |. 78 21 |js short crackme_.0041CBCD ; ||
0041CBAC |. 3BC1 |cmp eax,ecx ; ||
0041CBAE |. 7F 1D |jg short crackme_.0041CBCD ; ||
0041CBB0 |. 0FB732 |movzx esi,word ptr ds:[edx] ; ||
0041CBB3 |. 40 |inc eax ; ||
0041CBB4 |. 03FE |add edi,esi ; ||
0041CBB6 |. 83C2 02 |add edx,2 ; ||
0041CBB9 |. 3BC1 |cmp eax,ecx ; ||
0041CBBB |.^ 7C EB \jl short crackme_.0041CBA8 ; end_STEP2 ==========>edi = 密码各位ASCII之和
0041CBBD |> 8D045B lea eax,dword ptr ds:[ebx+ebx*2] ; eax = 3 x ebx
0041CBC0 |. 33C9 xor ecx,ecx
0041CBC2 |. 3BC7 cmp eax,edi ; 比较3 x eax 和edi
0041CBC4 |. 0F94C1 sete cl
0041CBC7 |. 5F pop edi
0041CBC8 |. 5E pop esi
0041CBC9 |. 5B pop ebx
0041CBCA |. 8BC1 mov eax,ecx
0041CBCC |. C3 retn
第二个时钟事件比较的是 用户名各位ASCII之和 x 3 和密码各位ASCII之和 ,显而易见 密码为 三个用户名
小结:
此CM流程大体这样
1、程序启动后,启动第一个时钟,检测用户名是否是‘52pojie’,如果是的话,进行第二步;
2、检测用户名和密码ASCII之和是否相等,相等的话,关闭第一个时钟并且启动第二个时钟进行第三步,否则执行1;
3、检测用户名ASCII之和 x 3 和密码各位ASCII之和是否相等 ,相等则SUCCESS,关闭第二个时钟,否则继续第二个时钟事件(第三步)。
准确解答是
用户名:52pojie
密 码:先输入52pojie
再输入2遍52pojie
--------------------------------------------------------------------------------
2012年04月29日 15:12:57
|
免费评分
-
查看全部评分
|