zcc1414 发表于 2013-12-14 00:21

【吾爱2013CM大赛解答】--CrackMe -- 苏紫方璇 BY zcc1414爆破分析

本帖最后由 zcc1414 于 2013-12-14 01:25 编辑

-------------------------------------------------【文章简介】-------------------------------------------------
【文章标题】 【吾爱2013CM大赛题目】--CrackMe -- 苏紫方璇 CM分析
【文章作者】 zcc1414
【作者邮箱】 无~
【作者主页】 无~
【软件名称】 CrackMe
【软件大小】 44.0 KB (45,056 字节)
【下载地址】 http://www.52pojie.cn/thread-228417-1-1.html
【加壳方式】 无~
【保护方式】 无~
【编写语言】 VC
【使用工具】 OD
【操作平台】 XPSP3
【软件介绍】 吾爱2013CM大赛题目
【作者声明】 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
-------------------------------------------------【文章正文】-------------------------------------------------
大家好我是zcc1414小菜好久没爆破了今天来爆破+追码分析就留给其他做吧
小菜不懂怎么截图就直接放文本了
如果不懂的同学可以看下断 我的补丁上的断点分析
成功图片:
无码的:

好吧R 大喜欢有码的:

吾爱补丁:



提供一组正确码:
0012F738   00383D50ASCII "abcdef"
0012F73C   0012F798ASCII "919394969799"
总结:
程序设置两个TIMER过程 对各个函数进行CC检测防止对函数进行下断点
程序用了几种防调试的办法
验证时用到了SEH异常跳转去到另外地点验证这种方法值得提倡


运行程序修改代码就会退出发现有TIMER过程

发现有线索了timer但是程序退出了回溯代码找到下面这些发现设置了两个TIEMR过程下面的检测断点是都是检测 CC断点
下面的检测断点是检测 CC断点
00401381   .FF15 20304000 call dword ptr ds:[<&KERNEL32.LoadLibraryA>]                   ; |\LoadLibraryA
00401387   .50            push eax                                                       ; |hModule
00401388   .FF15 00304000 call dword ptr ds:[<&KERNEL32.GetProcAddress>]               ; \GetProcAddress
0040138E   .6A 14         push 0x14                                                      ;上面动态获得SetTimer函数
00401390   .50            push eax
00401391   .E8 DA040000   call CrackMe.00401870                                          ;监视是否对SetTimer下断点 如果有则退出
00401396   .83C4 08       add esp,0x8
00401399   .85C0          test eax,eax
0040139B      EB 05         jmp XCrackMe.004013A2                                             ; 这里我已经修改成为jmp 后面也是一样
0040139D   .E8 BE040000   call CrackMe.00401860                                          ;退出
004013A2   >68 9E000000   push 0x9E
004013A7   .68 A0184000   push CrackMe.004018A0                                          ;↑@@
004013AC   .E8 BF040000   call CrackMe.00401870                                          ;监视是否对SendMessage下断点
004013B1   .83C4 08       add esp,0x8
004013B4   .85C0          test eax,eax
004013B6      EB 05         jmp XCrackMe.004013BD                                          ;修改成为jmp
004013B8   .E8 A3040000   call CrackMe.00401860                                          ;退出
004013BD   >68 2C020000   push 0x22C
004013C2   .68 50194000   push CrackMe.00401950
004013C7   .E8 A4040000   call CrackMe.00401870                                          ;监视是否对SendMessage下断点
004013CC   .83C4 08       add esp,0x8
004013CF   .85C0          test eax,eax
004013D1      EB 05         jmp XCrackMe.004013D8                                          ;修改成为jmp
004013D3   .E8 88040000   call CrackMe.00401860                                          ;退出
004013D8   >E8 97090000   call <jmp.&MFC42.#1175>
004013DD   .85C0          test eax,eax
004013DF   .74 09         je XCrackMe.004013EA
004013E1   .8B10          mov edx,dword ptr ds:
004013E3   .8BC8          mov ecx,eax
004013E5   .FF52 7C       call dword ptr ds:
004013E8   .EB 02         jmp XCrackMe.004013EC
004013EA   >33C0          xor eax,eax
004013EC   >8B40 20       mov eax,dword ptr ds:
004013EF   .8B35 00324000 mov esi,dword ptr ds:[<&USER32.SetTimer>]                      ;USER32.SetTimer
004013F5   .68 50194000   push CrackMe.00401950                                          ; /Timerproc = CrackMe.00401950
004013FA   .68 E8030000   push 0x3E8                                                   ; |Timeout = 1000. ms
004013FF   .6A 01         push 0x1                                                       ; |TimerID = 1
00401401   .50            push eax                                                       ; |hWnd
00401402   .FFD6          call esi                                                       ; \SetTimer
00401404   .E8 6B090000   call <jmp.&MFC42.#1175>
00401409   .85C0          test eax,eax
0040140B   .74 09         je XCrackMe.00401416
0040140D   .8B10          mov edx,dword ptr ds:
0040140F   .8BC8          mov ecx,eax
00401411   .FF52 7C       call dword ptr ds:
00401414   .EB 02         jmp XCrackMe.00401418
00401416   >33C0          xor eax,eax
00401418   >8B40 20       mov eax,dword ptr ds:
0040141B   .68 A0184000   push CrackMe.004018A0                                          ;↑@@
00401420   .68 E8030000   push 0x3E8
00401425   .6A 02         push 0x2
00401427   .50            push eax
00401428   .FFD6          call esi                                                       ;USER32.SetTimer
0040142A   .5F            pop edi
0040142B   .B8 01000000   mov eax,0x1
00401430   .5E            pop esi
00401431   .83C4 18       add esp,0x18
00401434   .C3            retn


然后开始往后分析 timer回调函数
004018A0   .A1 FC404000   mov eax,dword ptr ds:                              ;timer1
004018A5   .56            push esi
004018A6   .8B35 0C304000 mov esi,dword ptr ds:[<&KERNEL32.QueryPerformanceCounter>]   ;kernel32.7C80A4B7
004018AC   .85C0          test eax,eax
004018AE   .7C 23         jl XCrackMe.004018D3
004018B0   .7F 09         jg XCrackMe.004018BB
004018B2   .A1 F8404000   mov eax,dword ptr ds:
004018B7   .85C0          test eax,eax
004018B9   .76 18         jbe XCrackMe.004018D3
004018BB   >A1 00414000   mov eax,dword ptr ds:
004018C0   .8B0D 04414000 mov ecx,dword ptr ds:
004018C6   .A3 F8404000   mov dword ptr ds:,eax
004018CB   .890D FC404000 mov dword ptr ds:,ecx
004018D1   .EB 12         jmp XCrackMe.004018E5
004018D3   >68 F0404000   push CrackMe.004040F0                                          ; /pPerformanceFreq = CrackMe.004040F0
004018D8   .FF15 08304000 call dword ptr ds:[<&KERNEL32.QueryPerformanceFrequency>]      ; \QueryPerformanceFrequency:返回硬件支持的高精度计数器的频率 说白了就是检测调试器用的
004018DE   .68 F8404000   push CrackMe.004040F8
004018E3   .FFD6          call esi
004018E5   >6A 64         push 0x64                                                      ; /Timeout = 100. ms
004018E7   .FF15 04304000 call dword ptr ds:[<&KERNEL32.Sleep>]                        ; \Sleep
004018ED   .68 00414000   push CrackMe.00404100
004018F2   .FFD6          call esi
004018F4   .8B15 00414000 mov edx,dword ptr ds:
004018FA   .A1 F8404000   mov eax,dword ptr ds:
004018FF   .8B35 FC404000 mov esi,dword ptr ds:
00401905   .2BD0          sub edx,eax
00401907   .A1 04414000   mov eax,dword ptr ds:
0040190C   .6A 00         push 0x0
0040190E   .1BC6          sbb eax,esi
00401910   .68 E8030000   push 0x3E8
00401915   .50            push eax
00401916   .52            push edx
00401917   .E8 94050000   call CrackMe.00401EB0
0040191C   .8B0D F4404000 mov ecx,dword ptr ds:
00401922   .51            push ecx
00401923   .8B0D F0404000 mov ecx,dword ptr ds:
00401929   .51            push ecx
0040192A   .52            push edx
0040192B   .50            push eax
0040192C   .E8 CF040000   call CrackMe.00401E00
00401931   .3D D0070000   cmp eax,0x7D0
00401936   .5E            pop esi                                                      ;监视调试器的一样方法
00401937      EB 05         jmp XCrackMe.0040193E                                          ;爆破这里
00401939   .E8 22FFFFFF   call CrackMe.00401860                                          ;退出
0040193E   >C2 1000       retn 0x10


下面为另一个TIMER过程也有大量的检测CC 00401A71   .51            push ecx                                                       ; /Text
00401A72   .52            push edx                                                       ; |hWnd
00401A73   .FF15 F4314000 call dword ptr ds:[<&USER32.SetWindowTextA>]                   ; \SetWindowTextA
00401A79   .8D4424 48   lea eax,dword ptr ss:
00401A7D   .C74424 48 3F0>mov dword ptr ss:,0x1003F
00401A85   .50            push eax                                                       ; /pContext
00401A86   .FF15 14304000 call dword ptr ds:[<&KERNEL32.GetCurrentThread>]               ; |[GetCurrentThread
00401A8C   .50            push eax                                                       ; |hThread
00401A8D   .FF15 10304000 call dword ptr ds:[<&KERNEL32.GetThreadContext>]               ; \GetThreadContext
00401A93   .395C24 4C   cmp dword ptr ss:,ebx                              ;又是一种检测调试的方法
00401A97   .75 12         jnz XCrackMe.00401AAB                                       ; 这里可以NOP JNZ 失败也可以将后面的退出函数NOP掉
00401A99   .395C24 50   cmp dword ptr ss:,ebx                     
00401A9D   .75 0C         jnz XCrackMe.00401AAB
00401A9F   .395C24 54   cmp dword ptr ss:,ebx
00401AA3   .75 06         jnz XCrackMe.00401AAB
00401AA5   .395C24 58   cmp dword ptr ss:,ebx
00401AA9   .74 05         je XCrackMe.00401AB0
00401AAB      90            nop                                                            ;退出
00401AAC      90            nop                                                            ;nop掉
00401AAD      90            nop
00401AAE      90            nop
00401AAF      90            nop
00401AB0   >8B35 20304000 mov esi,dword ptr ds:[<&KERNEL32.LoadLibraryA>]                ;kernel32.LoadLibraryA
00401AB6   .8D4C24 20   lea ecx,dword ptr ss:
00401ABA   .8D5424 0C   lea edx,dword ptr ss:
00401ABE   .51            push ecx                                                       ; /ProcNameOrOrdinal
00401ABF   .52            push edx                                                       ; |/FileName
00401AC0   .FFD6          call esi                                                       ; |\LoadLibraryA
00401AC2   .8B3D 00304000 mov edi,dword ptr ds:[<&KERNEL32.GetProcAddress>]            ; |kernel32.7C80AE30
00401AC8   .50            push eax                                                       ; |hModule
00401AC9   .FFD7          call edi                                                       ; \GetProcAddress
00401ACB   .6A 14         push 0x14
00401ACD   .50            push eax
00401ACE   .E8 9DFDFFFF   call CrackMe.00401870                                          ;再次检测是否对SetTimer下断点
00401AD3   .83C4 08       add esp,0x8
00401AD6   .85C0          test eax,eax
00401AD8      EB 05         jmp XCrackMe.00401ADF                                          ; 直接JMP
00401ADA   .E8 81FDFFFF   call CrackMe.00401860                                          ;退出
00401ADF   >8D4424 2C   lea eax,dword ptr ss:
00401AE3   .8D4C24 0C   lea ecx,dword ptr ss:
00401AE7   .50            push eax
00401AE8   .51            push ecx
00401AE9   .FFD6          call esi
00401AEB   .50            push eax
00401AEC   .FFD7          call edi                                                       ;得到KillTimer地址
00401AEE   .6A 14         push 0x14
00401AF0   .50            push eax
00401AF1   .E8 7AFDFFFF   call CrackMe.00401870                                          ;检测是否对KillTimer下断点
00401AF6   .83C4 08       add esp,0x8
00401AF9   .85C0          test eax,eax
00401AFB      EB 05         jmp XCrackMe.00401B02                                    ; 直接JMP
00401AFD   .E8 5EFDFFFF   call CrackMe.00401860
00401B02   >8D5424 38   lea edx,dword ptr ss:
00401B06   .8D4424 0C   lea eax,dword ptr ss:
00401B0A   .52            push edx
00401B0B   .50            push eax
00401B0C   .FFD6          call esi
00401B0E   .50            push eax
00401B0F   .FFD7          call edi                                                       ;得到"SetWindowTextA"地址
00401B11   .6A 14         push 0x14
00401B13   .50            push eax
00401B14   .E8 57FDFFFF   call CrackMe.00401870                                          ;检测是否对SetWindowTextA下断点
00401B19   .83C4 08       add esp,0x8
00401B1C   .85C0          test eax,eax
00401B1E   .5F            pop edi
00401B1F   .5E            pop esi
00401B20   .5B            pop ebx
00401B21      EB 05         jmp XCrackMe.00401B28                                             ; 直接JMP
00401B23   .E8 38FDFFFF   call CrackMe.00401860
00401B28   >68 56020000   push 0x256
00401B2D   .68 10154000   push CrackMe.00401510                                          ;入口地址
00401B32   .E8 39FDFFFF   call CrackMe.00401870                                          ;检测入口点是否下CC断点
00401B37   .83C4 08       add esp,0x8
00401B3A   .85C0          test eax,eax
00401B3C      EB 05         jmp XCrackMe.00401B43                                              ; 直接JMP
00401B3E   .E8 1DFDFFFF   call CrackMe.00401860
00401B43   >6A 0B         push 0xB
00401B45   .68 68174000   push CrackMe.00401768
00401B4A   .E8 21FDFFFF   call CrackMe.00401870                                          ;对代码中间一个地方检测CC
00401B4F   .83C4 08       add esp,0x8
00401B52   .85C0          test eax,eax
00401B54      EB 05         jmp XCrackMe.00401B5B                                             ; 直接JMP
00401B56   .E8 05FDFFFF   call CrackMe.00401860
00401B5B   >68 CD000000   push 0xCD
00401B60   .68 75174000   push CrackMe.00401775
00401B65   .E8 06FDFFFF   call CrackMe.00401870                                          ;对代码中间一个地方检测CC
00401B6A   .83C4 08       add esp,0x8
00401B6D   .85C0          test eax,eax
00401B6F      EB 05         jmp XCrackMe.00401B76                                          ; 直接JMP
00401B71   .E8 EAFCFFFF   call CrackMe.00401860
00401B76   >81C4 08030000 add esp,0x308
00401B7C   .C2 1000       retn 0x10


接下来下断点 GetWindowTextA解决了上面的退出代码就可以下断点进行调试了输入abcdef         123456 错误下面来到   将下面的验证X处全部NOP掉即可完成爆破因为是CrackMe我就不分析加密过程了直接爆破
00401666   .8B65 E8       mov esp,dword ptr ss:
00401669   .8B85 C4FEFFFF mov eax,dword ptr ss:
0040166F   .8B48 64       mov ecx,dword ptr ds:
00401672   .898D D0FEFFFF mov dword ptr ss:,ecx
00401678   .8B95 D0FEFFFF mov edx,dword ptr ss:
0040167E   .8995 BCFEFFFF mov dword ptr ss:,edx
00401684   .8D85 E4FEFFFF lea eax,dword ptr ss:
0040168A   .8985 B8FEFFFF mov dword ptr ss:,eax
00401690   >8B8D B8FEFFFF mov ecx,dword ptr ss:
00401696   .8A11          mov dl,byte ptr ds:
00401698   .8895 B7FEFFFF mov byte ptr ss:,dl
0040169E   .8B85 BCFEFFFF mov eax,dword ptr ss:
004016A4   .3A10          cmp dl,byte ptr ds:               ;这里是最后跳到这里 同学们先看后面的分析,最后SEH调回来 进行的最后验证
004016A6   .75 46         jnz XCrackMe2.004016EE                   ;验证3   直接NOP掉
004016A8   .80BD B7FEFFFF>cmp byte ptr ss:,0x0          ;这里有点难理解大家可以调试看看就明白了
004016AF   .74 31         je XCrackMe2.004016E2
004016B1   .8B8D B8FEFFFF mov ecx,dword ptr ss:
004016B7   .8A51 01       mov dl,byte ptr ds:
004016BA   .8895 B6FEFFFF mov byte ptr ss:,dl
004016C0   .8B85 BCFEFFFF mov eax,dword ptr ss:
004016C6   .3A50 01       cmp dl,byte ptr ds:
004016C9   .75 23         jnz XCrackMe2.004016EE                   ;验证4直接NOP掉
004016CB   .8385 B8FEFFFF>add dword ptr ss:,0x2
004016D2   .8385 BCFEFFFF>add dword ptr ss:,0x2
004016D9   .80BD B6FEFFFF>cmp byte ptr ss:,0x0
004016E0   .^ 75 AE         jnz XCrackMe2.00401690
004016E2   >C785 B0FEFFFF>mov dword ptr ss:,0x0
004016EC   .EB 0B         jmp XCrackMe2.004016F9
004016EE   >1BC9          sbb ecx,ecx
004016F0   .83D9 FF       sbb ecx,-0x1
004016F3   .898D B0FEFFFF mov dword ptr ss:,ecx
004016F9   >8B95 B0FEFFFF mov edx,dword ptr ss:
004016FF   .8995 ACFEFFFF mov dword ptr ss:,edx
00401705   .83BD ACFEFFFF>cmp dword ptr ss:,0x0
0040170C   .75 1E         jnz XCrackMe2.0040172C
0040170E   .8D85 D8FEFFFF lea eax,dword ptr ss:
00401714   .50            push eax
00401715   .68 EA030000   push 0x3EA
0040171A   .8B8D C4FEFFFF mov ecx,dword ptr ss:
00401720   .E8 79060000   call <jmp.&MFC42.#3092>
00401725   .8BC8          mov ecx,eax
00401727   .E8 6C060000   call <jmp.&MFC42.#6199>                  ;这里是设置成功标志
0040172C   >C745 FC FFFFF>mov dword ptr ss:,-0x1
00401733   .E9 FA000000   jmp CrackMe2.00401832
00401738   >E8 23010000   call CrackMe2.00401860
0040173D   .E9 F0000000   jmp CrackMe2.00401832
00401742   >6A 01         push 0x1
00401744   .8B8D C4FEFFFF mov ecx,dword ptr ss:
0040174A   .E8 43060000   call <jmp.&MFC42.#6334>
0040174F   .6A 00         push 0x0
00401751   .8B8D C4FEFFFF mov ecx,dword ptr ss:
00401757   .E8 36060000   call <jmp.&MFC42.#6334>
0040175C   .8B8D C4FEFFFF mov ecx,dword ptr ss:
00401762   .8B51 60       mov edx,dword ptr ds:
00401765   .8995 CCFEFFFF mov dword ptr ss:,edx
0040176B   .8D85 E4FEFFFF lea eax,dword ptr ss:
00401771   .50            push eax
00401772   .8B8D CCFEFFFF mov ecx,dword ptr ss:
00401778   .51            push ecx
00401779   .E8 92FDFFFF   call CrackMe2.00401510                   ;根据用户名得到密码
0040177E   .83C4 08       add esp,0x8                              ;在这里可以看到堆栈中有正确的密码
00401781   .8B95 C4FEFFFF mov edx,dword ptr ss:
00401787   .8B42 64       mov eax,dword ptr ds:
0040178A   .8985 C8FEFFFF mov dword ptr ss:,eax
00401790   .8B8D C8FEFFFF mov ecx,dword ptr ss:
00401796   .898D A8FEFFFF mov dword ptr ss:,ecx
0040179C   .8D95 E4FEFFFF lea edx,dword ptr ss:
004017A2   .8995 A4FEFFFF mov dword ptr ss:,edx
004017A8   >8B85 A4FEFFFF mov eax,dword ptr ss:
004017AE   .8A08          mov cl,byte ptr ds:
004017B0   .888D A3FEFFFF mov byte ptr ss:,cl
004017B6   .8B95 A8FEFFFF mov edx,dword ptr ss:
004017BC   .3A0A          cmp cl,byte ptr ds:
004017BE   .75 46         jnz XCrackMe2.00401806                   ;验证1 直接NOP掉
004017C0   .80BD A3FEFFFF>cmp byte ptr ss:,0x0
004017C7   .74 31         je XCrackMe2.004017FA
004017C9   .8B85 A4FEFFFF mov eax,dword ptr ss:
004017CF   .8A48 01       mov cl,byte ptr ds:
004017D2   .888D A2FEFFFF mov byte ptr ss:,cl
004017D8   .8B95 A8FEFFFF mov edx,dword ptr ss:
004017DE   .3A4A 01       cmp cl,byte ptr ds:
004017E1   .75 23         jnz XCrackMe2.00401806                   ;验证2直接NOP掉
004017E3   .8385 A4FEFFFF>add dword ptr ss:,0x2
004017EA   .8385 A8FEFFFF>add dword ptr ss:,0x2
004017F1   .80BD A2FEFFFF>cmp byte ptr ss:,0x0
004017F8   .^ 75 AE         jnz XCrackMe2.004017A8
004017FA   >C785 9CFEFFFF>mov dword ptr ss:,0x0
00401804   .EB 0B         jmp XCrackMe2.00401811
00401806   >1BC0          sbb eax,eax
00401808   .83D8 FF       sbb eax,-0x1
0040180B   .8985 9CFEFFFF mov dword ptr ss:,eax
00401811   >8B8D 9CFEFFFF mov ecx,dword ptr ss:
00401817   .898D 98FEFFFF mov dword ptr ss:,ecx
0040181D   .83BD 98FEFFFF>cmp dword ptr ss:,0x0
00401824   .75 07         jnz XCrackMe2.0040182D                           ;这里不跳
00401826   .^ E9 11FEFFFF   jmp CrackMe2.0040163C                     ; 这里调向上面的SEH 进入SEH最后再进入上面的验证3
0040182B   .EB 05         jmp XCrackMe2.00401832
0040182D   >^ E9 06FFFFFF   jmp CrackMe2.00401738                  ;调向失败
00401832   >8B4D F0       mov ecx,dword ptr ss:
00401835   .64:890D 00000>mov dword ptr fs:,ecx
0040183C   .5F            pop edi
0040183D   .5E            pop esi
0040183E   .5B            pop ebx
0040183F   .8BE5          mov esp,ebp
00401841   .5D            pop ebp
00401842   .C3            retn

分析道这里就完毕了


Rookietp 发表于 2013-12-14 00:40

{:1_928:}来个有码的,

马斯维尔 发表于 2013-12-14 01:11

好思路,感谢大牛的分析!

vipcrack 发表于 2013-12-14 01:16

好好学习下,这方面我是一窍不通.
页: [1]
查看完整版本: 【吾爱2013CM大赛解答】--CrackMe -- 苏紫方璇 BY zcc1414爆破分析