首页
社区
课程
招聘
[原创]对happytown第九个crackme破解的一点补充
发表于: 2010-3-27 19:36 7499

[原创]对happytown第九个crackme破解的一点补充

2010-3-27 19:36
7499

偶然看到了Ryosuke前辈关于happytown第九个crackme的破解一文(原文链接http://bbs.pediy.com/showthread.php?threadid=21531 ),现在我补上自己的一点研究心得,希望对大家有所帮助。
     
     第一步去壳。od载入后按十几下F7,直到出现如下代码:
       
        00459D2C      55            DB 55               
        00459D2D      8B            DB 8B
        00459D2E      EC            DB EC
        00459D2F      83            DB 83
        00459D30      C4            DB C4
        00459D31      F0            DB F0
        00459D32      B8            DB B8
        00459D33   .  34 9B         XOR AL,9B
        00459D35   .  45            INC EBP
       
        然后右键第一行选“分析”-->“从模块删除分析”,代码变为下面的样子:
       
        00459D2C    55              PUSH EBP
        00459D2D    8BEC            MOV EBP,ESP
        00459D2F    83C4 F0         ADD ESP,-10
        00459D32    B8 349B4500     MOV EAX,CrackMe_.00459B34
        00459D37    E8 0CC1FAFF     CALL CrackMe_.00405E48
        00459D3C    A1 ECC04500     MOV EAX,DWORD PTR DS:[45C0EC]
        00459D41    8B00            MOV EAX,DWORD PTR DS:[EAX]
           接着用OD自带的ollydump就行了,查壳显示Borland Delphi 6.0 - 7.0
   
         
          第二步去anti-debug。由于脱壳后的程序运行不弹出窗口,猜想可能直接退出了。
     试着下断点TerminateProcess,这时运行脱壳后的程序会立刻断下,堆栈中显示为:
       
        0012FCA0   004589C9  /CALL 到 TerminateProcess 来自  004589C4
        0012FCA4   000000A0  |hProcess = 000000A0 (窗口)
        0012FCA8   FFFFFFFF  \ExitCode = FFFFFFFF (-1.)
        0012FCAC   0012FE24  指向下一个 SEH 记录的指针
       
        我们根据来自 004589C4这句,跳过去看看,发现代码如下:
       
        004589A4  |.  50            |PUSH EAX                                ; /pProcessID
        004589A5  |.  8B45 FC       |MOV EAX,DWORD PTR SS:[EBP-4]            ; |
        004589A8  |.  50            |PUSH EAX                                ; |hWnd
        004589A9  |.  E8 72DDFAFF   |CALL <JMP.&user32.GetWindowThreadProces>; \GetWindowThreadProcessId
        004589AE  |.  837D C8 00    |CMP DWORD PTR SS:[EBP-38],0
        004589B2  |.  74 15         |JE SHORT CrackMe_.004589C9
        004589B4  |.  6A FF         |PUSH -1                                 ; /ExitCode = FFFFFFFF (-1.)
        004589B6  |.  8B45 C8       |MOV EAX,DWORD PTR SS:[EBP-38]           ; |
        004589B9  |.  50            |PUSH EAX                                ; |/ProcessId
        004589BA  |.  6A 00         |PUSH 0                                  ; ||Inheritable = FALSE
        004589BC  |.  6A 01         |PUSH 1                                  ; ||Access = TERMINATE
        004589BE  |.  E8 FDD7FAFF   |CALL <JMP.&kernel32.OpenProcess>        ; |\OpenProcess
        004589C3  |.  50            |PUSH EAX                                ; |hProcess
        004589C4  |.  E8 47D8FAFF   |CALL <JMP.&kernel32.TerminateProcess>   ; \TerminateProcess
          
               这里就是检测到OD进程并结束的地方。于是再往上看来到:
   
        004586E4  /$  55            PUSH EBP
        004586E5  |.  8BEC          MOV EBP,ESP
        004586E7  |.  B9 29000000   MOV ECX,29
        004586EC  |>  6A 00         /PUSH 0
        004586EE  |.  6A 00         |PUSH 0
        004586F0  |.  49            |DEC ECX
        004586F1  |.^ 75 F9         \JNZ SHORT CrackMe_.004586EC
        004586F3  |.  51            PUSH ECX
        004586F4  |.  33C0          XOR EAX,EAX
        004586F6  |.  55            PUSH EBP
     
             选中第一行004586E4  PUSH EBP,在提示窗口显示“局部调用来自 00459705”,那么再到那去看看,原来是这样:
   
        004596EC  /.  55            PUSH EBP
        004596ED  |.  8BEC          MOV EBP,ESP
        004596EF  |.  83C4 F0       ADD ESP,-10
        004596F2  |.  8955 F0       MOV DWORD PTR SS:[EBP-10],EDX
        004596F5  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX
        004596F8  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
        004596FB  |.  E8 C420FEFF   CALL CrackMe_.0043B7C4
        00459700  |.  A3 F4DF4500   MOV DWORD PTR DS:[45DFF4],EAX
        00459705  |.  E8 DAEFFFFF   CALL CrackMe_.004586E4  // 这里就是结束OD的call必须nop掉
        0045970A  |.  E8 51F8FFFF   CALL CrackMe_.00458F60
        0045970F  |.  E8 5CE9FFFF   CALL CrackMe_.00458070  // 计算文件的校验值
        00459714  |.  8945 F4       MOV DWORD PTR SS:[EBP-C],EAX   //[EBP-C]= 当前文件的校验值
        00459717  |.  A1 E0DF4500   MOV EAX,DWORD PTR DS:[45DFE0]  //注意45DFE0这个内存地址(exe文件偏移144处的dword取出来放这里)
        0045971C  |.  3B45 F4       CMP EAX,DWORD PTR SS:[EBP-C]   //判断文件是否修改过
        0045971F  |.  74 05         JE SHORT sss.00459726    //相等文件未修改过继续运行  可以修改为JNZ SHORT 00459726
        00459721  |.  E8 CEA7FAFF   CALL sss.00403EF4       //修改过就结束
        00459726  |>  68 7C974500   PUSH sss.0045977C                        ; /ResourceType = "WAV"
        0045972B  |.  68 80974500   PUSH sss.00459780                        ; |ResourceName = "BackSound"
        00459730  |.  A1 F0DF4500   MOV EAX,DWORD PTR DS:[45DFF0]            ; |
        00459735  |.  50            PUSH EAX                                 ; |hModule => NULL
        00459736  |.  E8 3DC9FAFF   CALL <JMP.&kernel32.FindResourceA>       ; \FindResourceA

          在脱壳后的程序中把 CALL 004586E4一行nop掉保存后运行发现仍然没有反应。但是运行到刚nop掉那行结束时是没有问题的,
     那就从这里开始继续往后看,发现0045971F处不跳就结束了。显然是比较0045970F 处 CALL  00458070 的
     返回值eax与DWORD PTR DS:[45DFE0]是否相等。那么CALL 00458070应该就是anti call了。
     进去看一下发现:
      
        0045809B  |.  8945 E0       MOV DWORD PTR SS:[EBP-20],EAX
        0045809E  |.  6A 00         PUSH 0                                   ; /hTemplateFile = NULL
        004580A0  |.  6A 20         PUSH 20                                  ; |Attributes = ARCHIVE
        004580A2  |.  6A 03         PUSH 3                                   ; |Mode = OPEN_EXISTING
        004580A4  |.  6A 00         PUSH 0                                   ; |pSecurity = NULL
        004580A6  |.  6A 01         PUSH 1                                   ; |ShareMode = FILE_SHARE_READ
        004580A8  |.  68 00000080   PUSH 80000000                            ; |Access = GENERIC_READ
        004580AD  |.  8B45 E0       MOV EAX,DWORD PTR SS:[EBP-20]            ; |
        004580B0  |.  50            PUSH EAX                                 ; |FileName
        004580B1  |.  E8 92DFFAFF   CALL <JMP.&kernel32.CreateFileA>         ; \CreateFileA
        004580B6  |.  8945 EC       MOV DWORD PTR SS:[EBP-14],EAX
        004580B9  |.  6A 00         PUSH 0                                   ; /pFileSizeHigh = NULL
        004580BB  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]            ; |
        004580BE  |.  50            PUSH EAX                                 ; |hFile
        004580BF  |.  E8 0CE0FAFF   CALL <JMP.&kernel32.GetFileSize>         ; \GetFileSize
        ..............
        00458101  |.  B9 3C000000   MOV ECX,3C
        00458106  |.  034D FC       ADD ECX,DWORD PTR SS:[EBP-4]
        00458109  |.  8B09          MOV ECX,DWORD PTR DS:[ECX]
        0045810B  |.  83C1 44       ADD ECX,44
        0045810E  |.  034D FC       ADD ECX,DWORD PTR SS:[EBP-4]
        00458111  |.  8B01          MOV EAX,DWORD PTR DS:[ECX]
        00458113  |.  A3 E0DF4500   MOV DWORD PTR DS:[45DFE0],EAX    //取出exe文件偏移144h处的dword 用于文件校验
        ............
        00458136  |.  8945 CC       MOV DWORD PTR SS:[EBP-34],EAX
        00458139  |.  C745 D0 01000>MOV DWORD PTR SS:[EBP-30],1
        00458140  |>  8B55 F8       /MOV EDX,DWORD PTR SS:[EBP-8]
        00458143  |.  8A02          |MOV AL,BYTE PTR DS:[EDX]
        00458145  |.  0FB6C0        |MOVZX EAX,AL
        00458148  |.  8945 F4       |MOV DWORD PTR SS:[EBP-C],EAX
        0045814B  |.  42            |INC EDX
        0045814C  |.  8955 F8       |MOV DWORD PTR SS:[EBP-8],EDX
        0045814F  |.  A1 2CBE4500   |MOV EAX,DWORD PTR DS:[45BE2C]      
        00458154  |.  3345 F4       |XOR EAX,DWORD PTR SS:[EBP-C]
        00458157  |.  25 FF000000   |AND EAX,0FF
        0045815C  |.  8945 D4       |MOV DWORD PTR SS:[EBP-2C],EAX
        0045815F  |.  A1 2CBE4500   |MOV EAX,DWORD PTR DS:[45BE2C]
        00458164  |.  C1E8 08       |SHR EAX,8
        00458167  |.  25 FFFFFF00   |AND EAX,0FFFFFF
        0045816C  |.  8B55 D4       |MOV EDX,DWORD PTR SS:[EBP-2C]
        0045816F  |.  330495 E0DB45>|XOR EAX,DWORD PTR DS:[EDX*4+45DBE0]
        00458176  |.  A3 2CBE4500   |MOV DWORD PTR DS:[45BE2C],EAX
        0045817B  |.  FF45 D0       |INC DWORD PTR SS:[EBP-30]
        0045817E  |.  FF4D CC       |DEC DWORD PTR SS:[EBP-34]
        00458181  |.^ 75 BD         \JNZ SHORT sss.00458140
        00458183  |> \F715 2CBE4500 NOT DWORD PTR DS:[45BE2C]
        00458189  |.  A1 2CBE4500   MOV EAX,DWORD PTR DS:[45BE2C] //保存计算好的当前文件的校验值

       总结一下: 1) 00459705  CALL  004586E4  // 这里就是结束OD的call必须nop掉
                     
                 通过枚举得到窗口句柄-->进程ID-->进程句柄,再对特定的程序用TerminateProcess结束掉。
                 用到如下函数:
                 HWND GetWindow(      //得到窗口句柄
                        HWND hWnd,        // handle of original window
                        UINT uCmd         // relationship flag
                     );
                  
                DWORD GetWindowThreadProcessId(//得到对应的ProcessId
                        HWND hWnd,               // handle of window
                        LPDWORD lpdwProcessId         // address of variable for process identifier
                     );
                 
                HANDLE OpenProcess(         //the return value is the handle to the process
                        DWORD dwDesiredAccess,        // access flag
                        BOOL bInheritHandle,        // handle inheritance flag
                        DWORD dwProcessId         // process identifier
                    );       
                  
                BOOL TerminateProcess(
                        HANDLE hProcess,        // handle to the process
                        UINT uExitCode         // exit code for the process  
                    );
                  
              
               2)去除文件校验
               
                0045970F  |.  E8 5CE9FFFF   CALL CrackMe_.00458070  // 计算文件的校验值
                00459714  |.  8945 F4       MOV DWORD PTR SS:[EBP-C],EAX   //[EBP-C]= 当前文件的校验值
                00459717  |.  A1 E0DF4500   MOV EAX,DWORD PTR DS:[45DFE0]  //exe文件偏移144处的dword取出来放这里
                0045971C  |.  3B45 F4       CMP EAX,DWORD PTR SS:[EBP-C]   //判断文件是否修改过
                0045971F  |.  74 05         JE SHORT sss.00459726    //未修改过跳走 修改为JNZ SHORT 00459726
                00459721  |.  E8 CEA7FAFF   CALL sss.00403EF4       //修改过就结束
               

             第三步就是找算法call。运行去除anti的程序,弹出窗口后随便输入name和serial,
        然后在内存中搜到只有一处,然后在内存中的serial后下好内存断点。在刚才的serial
        的后面接着输入,立即断下。

     

      显然是文本输入框的OnChange事件。这时用dede和IDA查找都能发现txtSerialChange事件,他的位置就是004597EC。

     

      

      
               
                004597EC  /.  55            push    ebp
                004597ED  |.  8BEC          mov     ebp, esp
                004597EF  |.  B9 0B000000   mov     ecx, 0B
                004597F4  |>  6A 00         /push    0
                004597F6  |.  6A 00         |push    0
                004597F8  |.  49            |dec     ecx
                004597F9  |.^ 75 F9         \jnz     short 004597F4
                004597FB  |.  53            push    ebx
                004597FC  |.  56            push    esi
                004597FD  |.  8955 C4       mov     [ebp-3C], edx
                00459800  |.  8945 FC       mov     [ebp-4], eax
                00459803  |.  33C0          xor     eax, eax
                00459805  |.  55            push    ebp
                00459806  |.  68 6E9A4500   push    00459A6E
                0045980B  |.  64:FF30       push    dword ptr fs:[eax]
                0045980E  |.  64:8920       mov     fs:[eax], esp
                00459811  |.  8D55 C0       lea     edx, [ebp-40]
                00459814  |.  8B45 FC       mov     eax, [ebp-4]
                00459817  |.  8B80 04030000 mov     eax, [eax+304]
                0045981D  |.  E8 C6B7FDFF   call    00434FE8                    // GetText
                00459822  |.  8B45 C0       mov     eax, [ebp-40]               // serail

           我就补充到这,剩下的内容Ryosuke前辈讲得已经非常详细了。最后写了个注册机,
       貌似happytown的crackme。最后感谢happytown和Ryosuke前辈,只有站在巨人的肩上,我们才能看得更远!
   
      

                                                   
                                                    天易love  
                                                                             2010-03-26


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
头像很好看
2010-3-28 00:43
0
雪    币: 11
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
天意love的头像是谁啊
2010-3-28 14:07
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
兄才名字又不错
2010-3-28 14:09
0
雪    币: 2015
活跃值: (902)
能力值: ( LV12,RANK:1000 )
在线值:
发帖
回帖
粉丝
5
2000后大概不知道我的头像是谁,真是年轻有为啊!感谢支持,至少具备看贴回贴的美德,尽管有点水。
2010-3-28 18:15
0
雪    币: 242
活跃值: (1664)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
6
不错,写的很好,支持一下...
2010-3-29 08:42
0
雪    币: 474
活跃值: (96)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
跟着大牛后面学习!
2010-3-29 12:55
0
雪    币: 435
活跃值: (1282)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
8
全智贤,是我小时候的梦中情人,现在娱乐圈尽是美女,审美疲劳了
2010-4-2 15:04
0
游客
登录 | 注册 方可回帖
返回
//