首页
社区
课程
招聘
[原创]看雪CTF 2016 第一题分析
发表于: 2016-11-2 00:15 10083

[原创]看雪CTF 2016 第一题分析

2016-11-2 00:15
10083
【文章标题】: 看雪CTF 2016 第一题分析
【文章作者】: xietao
【下载地址】: 自己搜索下载
【使用工具】: OllyDBG v2.01
【操作平台】: Windows 10 专业版
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
【备注】: 本贴内容已备份在附件txt中。
--------------------------------------------------------------------------------
【详细过程】
  首先通过反复输入错误的注册码可以得出以下几个结论:
  1. 弹出的错误对话框来自于WM_COMMAND消息, 其中WPARAM参数一定为0x40F:
  CPU Disasm
  Address   Hex dump               Command                            Comments
  0084241C  |> \6A 00              push    0                          ; /Type = MB_OK|MB_DEFBUTTON1|MB_APPLMODAL,
  0084241E  |.  68 68DA8500        push    offset 0085DA68            ; |Caption = "Failed"
  00842423  |.  68 38DB8500        push    offset 0085DB38            ; |Text = "something you lost!"
  00842428  |.  6A 00              push    0                          ; |hOwner = NULL
  0084242A  |.  FF15 48818500      call    dword ptr [<&USER32.Messag ; \USER32.MessageBoxW
  00842430  |.  E9 40030000        jmp     00842775

  此时栈的情况:
  CPU Stack
  Address   Value      Comments
  $ ==>     |010FF670
  $+4       \7519D2B3  ; RETURN to USER32.7519D2B3
  $+8       /000505E4
  $+C       |00000111  ; WM_COMMAND消息
  $+10      |0000040F  ; WPARAM参数, 反复对比后发现40F对应于错误提示
  $+14      |00000000
  $+18      |0000040F

  2. 通过鼠标向下翻滚或字符串搜索可以很快定位到显示正确注册码对话框处, 可以知道注册成功时的WPARAM参数应该是0x40B:
  CPU Disasm
  Address   Hex dump               Command                            Comments
  00842290  |> \8B4D 10            mov     ecx, dword ptr [arg.3]     ; Case 111 (WM_COMMAND) of switch Crack_Me.
  00842293  |.  0FB7C1             movzx   eax, cx                    ; 参数三为WPARAM参数
  00842296  |.  3D 0A040000        cmp     eax, 40A                   ; Switch (cases 68..40F, 8 exits)
  0084229B  |.  0F87 45010000      ja      008423E6
  ……
  008423E6  |> \2D 0B040000        sub     eax, 40B
  008423EB  |.  0F84 0D010000      jz      008424FE
  ……
  008424FE  |> \0F1005 98DB8500    movups  xmm0, dqword ptr [85DB98]  ; 如果WPARAM等于40B, 则显示注册成功对话框!, case 40B of s
  00842505  |.  66:A1 C8DB8500     mov     ax, word ptr [85DBC8]
  0084250B  |.  68 96000000        push    96                         ; /Arg3 = 96
  00842510  |.  0F1185 E4FEFFFF    movups  dqword ptr [local.71], xmm ; |
  00842517  |.  66:8985 14FFFFFF   mov     word ptr [local.59], ax    ; |
  0084251E  |.  8D85 16FFFFFF      lea     eax, [local.59+2]          ; |
  00842524  |.  0F1005 A8DB8500    movups  xmm0, dqword ptr [85DBA8]  ; |float 1.074492e-38, 8.908203e-39, 9.4592
  0084252B  |.  6A 00              push    0                          ; |Arg2 = 0
  0084252D  |.  50                 push    eax                        ; |Arg1
  0084252E  |.  0F1185 F4FEFFFF    movups  dqword ptr [local.67], xmm ; |
  00842535  |.  0F1005 B8DB8500    movups  xmm0, dqword ptr [85DBB8]  ; |float 3.030733e-39, 1.010206e-38, 9.6428
  0084253C  |.  0F1185 04FFFFFF    movups  dqword ptr [local.63], xmm ; |
  00842543  |.  E8 88140000        call    008439D0                   ; \Crack_Me.008439D0
  00842548  |.  83C4 0C            add     esp, 0C
  0084254B  |.  8D85 E4FEFFFF      lea     eax, [local.71]
  00842551  |.  6A 00              push    0                          ; /Type = MB_OK|MB_DEFBUTTON1|MB_APPLMODAL
  00842553  |.  68 CCDB8500        push    offset 0085DBCC            ; |Caption = "Successed"
  00842558  |.  50                 push    eax                        ; |Text => offset LOCAL.71
  00842559  |.  53                 push    ebx                        ; |hOwner => [ARG.1]
  0084255A  |.  FF15 48818500      call    dword ptr [<&USER32.Messag ; \USER32.MessageBoxW

  3. 点击OK对话框会创建一个线程, 然后主线程返回, 由子线程对比输入的注册码, 可以得到校验子线程线程入口为Crack_Me.008420E0.
  CPU Disasm
  Address   Hex dump               Command                            Comments
  0084276B  |> \6A 00              push    0                          ; |StackSize = 0
  0084276D  |.  6A 00              push    0                          ; |pSecurity = NULL
  0084276F  |.  FF15 74808500      call    dword ptr [<&KERNEL32.Crea ; \KERNEL32.CreateThread
  00842775  |>  8B4D FC            mov     ecx, dword ptr [local.1]   ; Case 68 of switch Crack_Me.842296

  创建线程处栈的情况:
  CPU Stack
  Address   Value      Comments
  $-3D4     [00842775  ; /RETURN from KERNEL32.CreateThread to Crack_Me.00842775
  $-3D0     /00000000  ; |pSecurity = NULL
  $-3CC     |00000000  ; |StackSize = 0
  $-3C8     |008420E0  ; |StartAddress = Crack_Me.8420E0   ; 线程入口地址
  $-3C4     |038D3A00  ; |Parameter = 038D3A00             ; 线程参数
  $-3C0     |00000000  ; |CreationFlags = 0
  $-3BC     |00000000  ; \pThreadId = NULL

  4. 在主模块中查找所有SendMessageW函数的引用参考, 对比多个SendMessageW函数的WPARAM参数入栈传参均是由68指令完成(如下所示):
  CPU Disasm
  Address   Hex dump               Command                            Comments
  00841D33  |> \6A 00              push    0                          ; /hControl = NULL
  00841D35  |.  68 0F040000        push    40F                        ; |wParam = (由上面分析得知,40F代表注册失败)
  00841D3A  |.  68 11010000        push    111                        ; |Msg = WM_COMMAND
  00841D3F  |.  FF77 04            push    dword ptr [edi+4]          ; |hWnd => [ARG.ECX+4]
  00841D42  |.  FF15 50818500      call    dword ptr [<&USER32.SendMe ; \USER32.SendMessageW

  所以我们可以对应的搜索push 40B指令, 应该是此处发出了注册成功的消息,很快我们就搜到了唯一一处(如下所示):
  CPU Disasm
  Address   Hex dump               Command                            Comments
  00841870   $  55                 push    ebp                        ; 此函数尾部发送注册成功或失败的消息(重要)
  00841871   .  8BEC               mov     ebp, esp                   ; 要想注册成功必调用了此函数
  00841873   .  83EC 54            sub     esp, 54
  00841876   .  A1 14F08500        mov     eax, dword ptr [85F014]
  0084187B   .  33C5               xor     eax, ebp
  0084187D   .  8945 FC            mov     dword ptr [ebp-4], eax
  ……
  00841A32  |.  68 0B040000        push    40B                        ; 此处PUSH了代表注册成功的40B(也是唯一一处)
  00841A37  |.  EB 07              jmp     short 00841A40
  00841A39  |>  6A 00              push    0
  00841A3B  |>  68 0A040000        push    40A                        ; 此处PUSH了代表注册失败的40A
  00841A40  |>  68 11010000        push    111                        ; |Msg = WM_COMMAND
  00841A45  |.  FF73 04            push    dword ptr [ebx+4]          ; |hWnd
  00841A48  |.  FF15 54818500      call    dword ptr [<&USER32.PostMe ; \USER32.PostMessageW

  5. 通过第4步我们找到了一个00841870的重要函数,然后Ctrl+F查找call 00841870指令, 我们能找到唯一一处结果(如下所示):
  CPU Disasm
  Address   Hex dump               Command                            Comments
  00841A60  /$  55                 push    ebp                        ; 判断了注册码, 并调用了最终显示结果的函数(重要)
  00841A61  |.  8BEC               mov     ebp, esp
  00841A63  |.  81EC 9C010000      sub     esp, 19C
  00841A69  |.  A1 14F08500        mov     eax, dword ptr [85F014]
  00841A6E  |.  33C5               xor     eax, ebp
  00841A70  |.  8945 FC            mov     dword ptr [local.1], eax
  ……
  00841BCA  |> \53                 push    ebx                        ; /Arg1 => ARG.EDX
  00841BCB  |.  E8 0F110000        call    00842CDF                   ; \Crack_Me.0084C93D
  00841BD0  |.  8B8D 68FEFFFF      mov     ecx, dword ptr [local.102]
  00841BD6  |.  83C4 04            add     esp, 4
  00841BD9  |.  8BD6               mov     edx, esi
  00841BDB  |.  E8 90FCFFFF        call    00841870                   ; <<==调用了00841870的重要函数
  00841BE0  |.  8B4D FC            mov     ecx, dword ptr [local.1]
  00841BE3  |.  5F                 pop     edi
  00841BE4  |.  5E                 pop     esi

  我们向上翻滚到该函数的函数头00841A60处, 重复上一步骤, 继续搜索call 00841A60, 几番循环我们便来到了步骤3种找到的那个检测注册码线程的入口函数处(如下所示):
  CPU Disasm
  Address   Hex dump               Command                            Comments
  008420E0  /.  55                 push    ebp                        ; 检测注册码线程入口函数
  008420E1  |.  8BEC               mov     ebp, esp
  008420E3  |.  8B4D 08            mov     ecx, dword ptr [arg.1]
  008420E6  |.  33D2               xor     edx, edx
  008420E8  |.  E8 C3FBFFFF        call    00841CB0                   ; <<==判断注册码
  008420ED  |.  6A 14              push    14
  008420EF  |.  FF75 08            push    dword ptr [arg.1]
  008420F2  |.  E8 ED0B0000        call    00842CE4                   ; 释放内存
  008420F7  |.  83C4 08            add     esp, 8
  008420FA  |.  33C0               xor     eax, eax
  008420FC  |.  5D                 pop     ebp
  008420FD  \.  C2 0400            ret     4

  到此处我们便从注册成功处(分析之旅的终点)向回溯到了线程入口函数处(分析之旅的起点), 所以我们总结出了追溯正确注册码的逻辑流程图应该是:

  =======================================================================================================================
  以上图为基础开始分别分析三个注册函数代码中的重点之处:
  
  一. 注册码判断函数1: 0x00841CB0
  CPU Disasm
  Address   Hex dump               Command                             Comments
  00841CB0  /$  55                 push    ebp                         ; 注册码判断函数1
  00841CB1  |.  8BEC               mov     ebp, esp
  00841CB3  |.  81EC D0000000      sub     esp, 0D0
  00841CB9  |.  A1 14F08500        mov     eax, dword ptr [85F014]
  00841CBE  |.  33C5               xor     eax, ebp
  00841CC0  |.  8945 FC            mov     dword ptr [local.1], eax
  00841CC3  |.  57                 push    edi
  00841CC4  |.  8BF9               mov     edi, ecx
  00841CC6  |.  85FF               test    edi, edi
  00841CC8  |.  0F84 61010000      jz      00841E2F
  00841CCE  |.  85D2               test    edx, edx                    ; 线程入口调用时edx为0, 本函数递归调用时为1
  00841CD0  |.  0F85 81000000      jnz     00841D57                    ; 递归调用时跳转条件成立
  00841CD6  |.  E8 25FFFFFF        call    00841C00                    ; <<==判断输入的注册码中是否存在小写字母b
  00841CDB  |.  85C0               test    eax, eax                    ; 不存在小写字母b则跳到发送注册失败处
  00841CDD  |.  74 54              jz      short 00841D33
  00841CDF  |.  68 C8000000        push    0C8                         ; /Arg3 = 0C8
  00841CE4  |.  8D85 34FFFFFF      lea     eax, [local.51]             ; |
  00841CEA  |.  6A 00              push    0                           ; |Arg2 = 0
  00841CEC  |.  50                 push    eax                         ; |Arg1 => offset LOCAL.51
  00841CED  |.  E8 DE1C0000        call    memset                      ; \Crack_Me.memset
  00841CF2  |.  83C4 0C            add     esp, 0C
  00841CF5  |.  8D85 34FFFFFF      lea     eax, [local.51]
  00841CFB  |.  6A 64              push    64                          ; /MaxCount = 100.
  00841CFD  |.  50                 push    eax                         ; |String => offset LOCAL.51
  00841CFE  |.  FF77 0C            push    dword ptr [edi+0C]          ; |hWnd => [ARG.ECX+0C]
  00841D01  |.  FF15 4C818500      call    dword ptr [<&USER32.GetWind ; \USER32.GetWindowTextW
  00841D07  |.  6A 70              push    70                          ; /Arg1 = 70
  00841D09  |.  8D95 34FFFFFF      lea     edx, [local.51]             ; |
  00841D0F  |.  E8 3C0D0000        call    00842A50                    ; \Crack_Me.00842A50, <<==判断注册码中是否存在小写字母p
  00841D14  |.  85C0               test    eax, eax
  00841D16  |.  74 1B              jz      short 00841D33
  00841D18  |.  BA 01000000        mov     edx, 1                      ; 成功分支, 参数二传入1, 然后递归调用本函数
  00841D1D  |.  8BCF               mov     ecx, edi
  00841D1F  |.  E8 8CFFFFFF        call    00841CB0
  00841D24  |.  5F                 pop     edi
  00841D25  |.  8B4D FC            mov     ecx, dword ptr [local.1]
  00841D28  |.  33CD               xor     ecx, ebp
  00841D2A  |.  E8 960F0000        call    00842CC5
  00841D2F  |.  8BE5               mov     esp, ebp
  00841D31  |.  5D                 pop     ebp
  00841D32  |.  C3                 ret
  00841D33  |>  6A 00              push    0                           ; /hControl = NULL
  00841D35  |.  68 0F040000        push    40F                         ; |wParam = NotifyCode = MENU/BN_CLICKED..., ID = 10
  00841D3A  |.  68 11010000        push    111                         ; |Msg = WM_COMMAND
  00841D3F  |.  FF77 04            push    dword ptr [edi+4]           ; |hWnd => [ARG.ECX+4]
  00841D42  |.  FF15 50818500      call    dword ptr [<&USER32.SendMes ; \USER32.SendMessageW
  00841D48  |.  5F                 pop     edi
  00841D49  |.  8B4D FC            mov     ecx, dword ptr [local.1]
  00841D4C  |.  33CD               xor     ecx, ebp
  00841D4E  |.  E8 720F0000        call    00842CC5
  00841D53  |.  8BE5               mov     esp, ebp
  00841D55  |.  5D                 pop     ebp
  00841D56  |.  C3                 ret
  00841D57  |>  56                 push    esi
  00841D58  |.  E8 812B0000        call    008448DE                    ; [Crack_Me.008448DE, [反调试]读取时间
  00841D5D  |.  68 C8000000        push    0C8                         ; /Arg3 = 0C8
  00841D62  |.  8985 30FFFFFF      mov     dword ptr [local.52], eax   ; |
  00841D68  |.  8D85 34FFFFFF      lea     eax, [local.51]             ; |
  00841D6E  |.  6A 00              push    0                           ; |Arg2 = 0
  00841D70  |.  50                 push    eax                         ; |Arg1 => offset LOCAL.51
  00841D71  |.  E8 5A1C0000        call    memset                      ; \Crack_Me.memset
  00841D76  |.  83C4 0C            add     esp, 0C
  00841D79  |.  8D85 34FFFFFF      lea     eax, [local.51]
  00841D7F  |.  68 C8000000        push    0C8                         ; /MaxCount = 200.
  00841D84  |.  50                 push    eax                         ; |String => offset LOCAL.51
  00841D85  |.  FF77 0C            push    dword ptr [edi+0C]          ; |hWnd => [ARG.ECX+0C]
  00841D88  |.  FF15 4C818500      call    dword ptr [<&USER32.GetWind ; \USER32.GetWindowTextW
  00841D8E  |.  33F6               xor     esi, esi
  00841D90  |.  8D85 34FFFFFF      lea     eax, [local.51]
  00841D96  |.  66:39B5 34FFFFFF   cmp     word ptr [local.51], si
  00841D9D  |.  74 0B              je      short 00841DAA
  00841D9F  |.  90                 nop
  00841DA0  |>  8D40 02            /lea     eax, [eax+2]
  00841DA3  |.  46                 |inc     esi
  00841DA4  |.  66:8338 00         |cmp     word ptr [eax], 0
  00841DA8  |.^ 75 F6              \jne     short 00841DA0
  00841DAA  |>  33C9               xor     ecx, ecx
  00841DAC  |.  8D46 01            lea     eax, [esi+1]
  00841DAF  |.  BA 02000000        mov     edx, 2
  00841DB4  |.  F7E2               mul     edx
  00841DB6  |.  53                 push    ebx
  00841DB7  |.  0F90C1             seto    cl
  00841DBA  |.  F7D9               neg     ecx
  00841DBC  |.  0BC8               or      ecx, eax
  00841DBE  |.  51                 push    ecx                         ; /Arg1
  00841DBF  |.  E8 120F0000        call    分配内存                        ; \Crack_Me.分配内存
  00841DC4  |.  83C4 04            add     esp, 4
  00841DC7  |.  8BD8               mov     ebx, eax
  00841DC9  |.  E8 102B0000        call    008448DE                    ; [Crack_Me.008448DE, [反调试]再次读取时间
  00841DCE  |.  2B85 30FFFFFF      sub     eax, dword ptr [local.52]
  00841DD4  |.  83F8 02            cmp     eax, 2                      ; [反调试]判断时间差
  00841DD7  |.  7F 65              jg      short 00841E3E              ; 此处跳转代码nop掉
  00841DD9  |.  8D85 34FFFFFF      lea     eax, [local.51]
  00841DDF  |.  50                 push    eax                         ; /Arg2 => offset LOCAL.51
  00841DE0  |.  53                 push    ebx                         ; |Arg1
  00841DE1  |.  E8 8A0A0000        call    00842870                    ; \Crack_Me.00842870, 将注册码复制到新申请的内存
  00841DE6  |.  83FE 07            cmp     esi, 7                      ; 判断注册码长度是否为7, cascaded IF (cases 0..7, 3 exits)
  00841DE9  |.  73 0B              jae     short 00841DF6
  00841DEB  |.  6A 00              push    0
  00841DED  |.  6A 00              push    0
  00841DEF  |.  68 0E040000        push    40E
  00841DF4  |.  EB 0B              jmp     short 00841E01
  00841DF6  |>  76 2C              jbe     short 00841E24
  00841DF8  |.  6A 00              push    0                           ; Default case of cascaded IF Crack_Me.841DE6
  00841DFA  |.  6A 00              push    0
  00841DFC  |.  68 0D040000        push    40D
  00841E01  |>  FF77 04            push    dword ptr [edi+4]           ; |hWnd => [ARG.ECX+4], cases 0, 1, 2, 3, 4, 5, 6 of
  00841E04  |.  FF15 50818500      call    dword ptr [<&USER32.SendMes ; \USER32.SendMessageW
  00841E0A  |.  53                 push    ebx                         ; /Arg1
  00841E0B  |.  E8 CF0E0000        call    00842CDF                    ; \Crack_Me.0084C93D
  00841E10  |.  83C4 04            add     esp, 4
  00841E13  |.  5B                 pop     ebx
  00841E14  |.  5E                 pop     esi
  00841E15  |.  5F                 pop     edi
  00841E16  |.  8B4D FC            mov     ecx, dword ptr [local.1]
  00841E19  |.  33CD               xor     ecx, ebp
  00841E1B  |.  E8 A50E0000        call    00842CC5
  00841E20  |.  8BE5               mov     esp, ebp
  00841E22  |.  5D                 pop     ebp
  00841E23  |.  C3                 ret
  00841E24  |>  8BD3               mov     edx, ebx                    ; 注册码长度等于7表示正确, 否则发送注册失败消息, case 7 of cascaded IF Cr
  00841E26  |.  8BCF               mov     ecx, edi
  00841E28  |.  E8 33FCFFFF        call    00841A60                    ; <<==进入注册码判断函数2
  00841E2D  |.  5B                 pop     ebx
  00841E2E  |.  5E                 pop     esi
  00841E2F  |>  8B4D FC            mov     ecx, dword ptr [local.1]
  00841E32  |.  33CD               xor     ecx, ebp
  00841E34  |.  5F                 pop     edi
  00841E35  |.  E8 8B0E0000        call    00842CC5
  00841E3A  |.  8BE5               mov     esp, ebp
  00841E3C  |.  5D                 pop     ebp
  00841E3D  |.  C3                 ret

  
  二. 注册码判断函数2: 0x00841A60, 此函数没有对注册码进行判断, 只进行了干扰操作和注册码的简单加密.
  CPU Disasm
  Address   Hex dump               Command                              Comments
  00841A60  /$  55                 push    ebp                          ; 注册码判断函数2
  00841A61  |.  8BEC               mov     ebp, esp
  00841A63  |.  81EC 9C010000      sub     esp, 19C
  00841A69  |.  A1 14F08500        mov     eax, dword ptr [85F014]
  00841A6E  |.  33C5               xor     eax, ebp
  00841A70  |.  8945 FC            mov     dword ptr [local.1], eax
  00841A73  |.  53                 push    ebx
  00841A74  |.  56                 push    esi
  00841A75  |.  57                 push    edi
  ……
  00841B4C  |>  8D41 01            lea     eax, [ecx+1]
  00841B4F  |.  BA 02000000        mov     edx, 2
  00841B54  |.  33C9               xor     ecx, ecx
  00841B56  |.  F7E2               mul     edx
  00841B58  |.  0F90C1             seto    cl
  00841B5B  |.  F7D9               neg     ecx
  00841B5D  |.  0BC8               or      ecx, eax
  00841B5F  |.  51                 push    ecx                          ; /Arg1
  00841B60  |.  E8 71110000        call    分配内存                         ; \Crack_Me.分配内存
  00841B65  |.  8BF0               mov     esi, eax
  00841B67  |.  83C4 04            add     esp, 4
  00841B6A  |.  33C0               xor     eax, eax
  00841B6C  |.  66:3903            cmp     word ptr [ebx], ax
  00841B6F  |.  74 16              je      short 00841B87
  00841B71  |.  0FB70B             movzx   ecx, word ptr [ebx]
  00841B74  |.  33D2               xor     edx, edx
  00841B76  |>  40                 /inc     eax
  00841B77  |.  66:890C32          |mov     word ptr [esi+edx], cx      ; 复制注册码到新申请的缓冲区
  00841B7B  |.  8D1400             |lea     edx, [eax+eax]
  00841B7E  |.  0FB70C1A           |movzx   ecx, word ptr [ebx+edx]
  00841B82  |.  66:85C9            |test    cx, cx
  00841B85  |.^ 75 EF              \jnz     short 00841B76
  00841B87  |>  33C9               xor     ecx, ecx
  00841B89  |.  66:890C46          mov     word ptr [eax*2+esi], cx
  00841B8D  |.  8BC6               mov     eax, esi
  00841B8F  |.  85F6               test    esi, esi
  00841B91  |.  74 37              jz      short 00841BCA
  00841B93  |.  66:390E            cmp     word ptr [esi], cx
  00841B96  |.  74 0A              je      short 00841BA2
  00841B98  |>  8D40 02            /lea     eax, [eax+2]
  00841B9B  |.  41                 |inc     ecx
  00841B9C  |.  66:8338 00         |cmp     word ptr [eax], 0
  00841BA0  |.^ 75 F6              \jne     short 00841B98
  00841BA2  |>  33C0               xor     eax, eax
  00841BA4  |.  85C9               test    ecx, ecx
  00841BA6  |.  74 22              jz      short 00841BCA
  00841BA8  |>  83F8 02            /cmp     eax, 2
  00841BAB  |.  73 07              |jae     short 00841BB4
  00841BAD  |.  66:833446 0F       |xor     word ptr [eax*2+esi], 000F
  00841BB2  |.  EB 11              |jmp     short 00841BC5
  00841BB4  |>  83F8 04            |cmp     eax, 4
  00841BB7  |.  73 07              |jae     short 00841BC0
  00841BB9  |.  66:833446 50       |xor     word ptr [eax*2+esi], 0050
  00841BBE  |.  EB 05              |jmp     short 00841BC5
  00841BC0  |>  66:833446 42       |xor     word ptr [eax*2+esi], 0042
  00841BC5  |>  40                 |inc     eax
  00841BC6  |.  3BC1               |cmp     eax, ecx
  00841BC8  |.^ 72 DE              \jb      short 00841BA8              ; 此循环对字符串进行加密
  00841BCA  |>  53                 push    ebx                          ; /Arg1 => ARG.EDX
  00841BCB  |.  E8 0F110000        call    释放内存                         ; \Crack_Me.0084C93D, 释放内存
  00841BD0  |.  8B8D 68FEFFFF      mov     ecx, dword ptr [local.102]
  00841BD6  |.  83C4 04            add     esp, 4
  00841BD9  |.  8BD6               mov     edx, esi
  00841BDB  |.  E8 90FCFFFF        call    00841870                     ; <<==调用注册码判断函数3
  00841BE0  |.  8B4D FC            mov     ecx, dword ptr [local.1]
  00841BE3  |.  5F                 pop     edi
  00841BE4  |.  5E                 pop     esi
  00841BE5  |.  33CD               xor     ecx, ebp
  00841BE7  |.  5B                 pop     ebx
  00841BE8  |.  E8 D8100000        call    00842CC5
  00841BED  |.  8BE5               mov     esp, ebp
  00841BEF  |.  5D                 pop     ebp
  00841BF0  \.  C3                 ret

  
  三. 注册码判断函数3: 0x00841870, 在发送注册成功之前有一个重要的函数, 此函数的返回值直接影响到了注册的结果
  CPU Disasm
  Address   Hex dump               Command                              Comments
  00841870   $  55                 push    ebp                          ; 注册码判断函数3
  00841871   .  8BEC               mov     ebp, esp
  00841873   .  83EC 54            sub     esp, 54
  00841876   .  A1 14F08500        mov     eax, dword ptr [85F014]
  0084187B   .  33C5               xor     eax, ebp
  0084187D   .  8945 FC            mov     dword ptr [ebp-4], eax
  00841880   .  53                 push    ebx
  00841881   .  56                 push    esi
  00841882   .  57                 push    edi
  00841883   .  6A 36              push    36                           ; /Arg3 = 36
  00841885   .  8D45 B0            lea     eax, [ebp-50]                ; |
  00841888   .  8BD9               mov     ebx, ecx                     ; |
  0084188A   .  6A 00              push    0                            ; |Arg2 = 0
  0084188C   .  50                 push    eax                          ; |Arg1
  0084188D   .  8BFA               mov     edi, edx                     ; |
  0084188F   .  895D AC            mov     dword ptr [ebp-54], ebx      ; |
  00841892   .  E8 39210000        call    memset                       ; \Crack_Me.memset
  00841897   .  83C4 0C            add     esp, 0C
  0084189A   .  8D4D E8            lea     ecx, [ebp-18]
  0084189D   .  B8 30000000        mov     eax, 30
  008418A2   >  66:8901            mov     word ptr [ecx], ax
  008418A5   .  8D49 02            lea     ecx, [ecx+2]
  008418A8   .  40                 inc     eax
  008418A9   .  83F8 39            cmp     eax, 39
  008418AC   .^ 7E F4              jle     short 008418A2               ; 初始化字符串0-9
  008418AE   .  B8 61000000        mov     eax, 61
  008418B3   .  8D4D B0            lea     ecx, [ebp-50]
  008418B6   >  66:8901            mov     word ptr [ecx], ax
  008418B9   .  8D49 02            lea     ecx, [ecx+2]
  008418BC   .  40                 inc     eax
  008418BD   .  83F8 7A            cmp     eax, 7A
  008418C0   .^ 7E F4              jle     short 008418B6               ; 初始化字符串a-z
  008418C2   .  33D2               xor     edx, edx
  008418C4   .  8D45 B0            lea     eax, [ebp-50]
  008418C7   .  66:3955 B0         cmp     word ptr [ebp-50], dx
  008418CB   .  74 0D              je      short 008418DA
  008418CD   .  0F1F00             nop     dword ptr [eax]
  008418D0   >  8D40 02            lea     eax, [eax+2]
  008418D3   .  42                 inc     edx
  008418D4   .  66:8338 00         cmp     word ptr [eax], 0
  008418D8   .^ 75 F6              jne     short 008418D0
  008418DA   >  33C9               xor     ecx, ecx
  008418DC   .  85D2               test    edx, edx
  008418DE   .  74 1C              je      short 008418FC
  008418E0   >  0FB7444D B0        movzx   eax, word ptr [ecx*2+ebp-50]
  008418E5   .  83F8 61            cmp     eax, 61                      ; Switch (cases 61..7A, 2 exits)
  008418E8   .  72 0D              jb      short 008418F7
  008418EA   .  83F8 7A            cmp     eax, 7A
  008418ED   .  77 08              ja      short 008418F7
  008418EF   .  83C0 E0            add     eax, -20                     ; Cases 61 ('a'), 62 ('b'), 63 ('c'), 64 ('d'), 65 (
  008418F2   .  66:89444D B0       mov     word ptr [ecx*2+ebp-50], ax
  008418F7   >  41                 inc     ecx                          ; Default case of switch Crack_Me.8418E5
  008418F8   .  3BCA               cmp     ecx, edx
  008418FA   .^ 72 E4              jb      short 008418E0               ; 此循环将上面初始化的字符串进行小写转大写操作
  008418FC   >  33C9               xor     ecx, ecx
  008418FE   .  8BC7               mov     eax, edi
  00841900   .  85FF               test    edi, edi                     ; 取出已加密的注册码
  00841902   .  74 76              je      short 0084197A
  00841904   .  66:390F            cmp     word ptr [edi], cx
  00841907   .  74 11              je      short 0084191A
  00841909   .  0F1F80 00000000    nop     dword ptr [eax]
  00841910   >  8D40 02            lea     eax, [eax+2]
  00841913   .  41                 inc     ecx
  00841914   .  66:8338 00         cmp     word ptr [eax], 0
  00841918   .^ 75 F6              jne     short 00841910
  0084191A   >  33C0               xor     eax, eax
  0084191C   .  85C9               test    ecx, ecx
  0084191E   .  74 22              je      short 00841942
  00841920   >  83F8 02            cmp     eax, 2
  00841923   .  73 07              jae     short 0084192C
  00841925   .  66:833447 0F       xor     word ptr [eax*2+edi], 000F
  0084192A   .  EB 11              jmp     short 0084193D
  0084192C   >  83F8 04            cmp     eax, 4
  0084192F   .  73 07              jae     short 00841938
  00841931   .  66:833447 50       xor     word ptr [eax*2+edi], 0050
  00841936   .  EB 05              jmp     short 0084193D
  00841938   >  66:833447 42       xor     word ptr [eax*2+edi], 0042
  0084193D   >  40                 inc     eax
  0084193E   .  3BC1               cmp     eax, ecx
  00841940   .^ 72 DE              jb      short 00841920               ; 对已加密的注册码进行解密操作
  00841942   >  33D2               xor     edx, edx
  00841944   .  8BC7               mov     eax, edi
  00841946   .  66:3917            cmp     word ptr [edi], dx
  00841949   .  74 0F              je      short 0084195A
  0084194B      0F1F4400 00        nop     dword ptr [eax+eax]
  00841950   >  8D40 02            lea     eax, [eax+2]
  00841953   .  42                 inc     edx
  00841954   .  66:8338 00         cmp     word ptr [eax], 0
  00841958   .^ 75 F6              jne     short 00841950
  0084195A   >  33C9               xor     ecx, ecx
  0084195C   .  85D2               test    edx, edx
  0084195E   .  74 1A              je      short 0084197A
  00841960   >  0FB7044F           movzx   eax, word ptr [ecx*2+edi]
  00841964   .  83F8 61            cmp     eax, 61                      ; Switch (cases 61..7A, 2 exits)
  00841967   .  72 0C              jb      short 00841975
  00841969   .  83F8 7A            cmp     eax, 7A
  0084196C   .  77 07              ja      short 00841975
  0084196E   .  83C0 E0            add     eax, -20                     ; Cases 61 ('a'), 62 ('b'), 63 ('c'), 64 ('d'), 65 (
  00841971   .  66:89044F          mov     word ptr [ecx*2+edi], ax
  00841975   >  41                 inc     ecx                          ; Default case of switch Crack_Me.841964
  00841976   .  3BCA               cmp     ecx, edx
  00841978   .^ 72 E6              jb      short 00841960               ; 对注册码中的字母进行小写转大写操作
  0084197A   >  33F6               xor     esi, esi
  0084197C   .  0F57C0             xorps   xmm0, xmm0
  0084197F   .  660FD645 F0        movq    qword ptr [ebp-10], xmm0
  00841984   .  66:8975 F8         mov     word ptr [ebp-8], si
  00841988   .  66:3937            cmp     word ptr [edi], si
  0084198B   .  74 48              je      short 008419D5
  0084198D   .  66:8B4D B0         mov     cx, word ptr [ebp-50]
  00841991   .  8D5D F0            lea     ebx, [ebp-10]
  00841994   .  8BC7               mov     eax, edi
  00841996   >  66:85C9            test    cx, cx
  00841999   .  74 2C              je      short 008419C7
  0084199B   .  0FB710             movzx   edx, word ptr [eax]
  0084199E   .  8D4D B0            lea     ecx, [ebp-50]
  008419A1   .  33C0               xor     eax, eax
  008419A3   >  66:3B11            cmp     dx, word ptr [ecx]
  008419A6   .  74 10              je      short 008419B8
  008419A8   .  40                 inc     eax
  008419A9   .  8D4D B0            lea     ecx, [ebp-50]
  008419AC   .  66:833C41 00       cmp     word ptr [eax*2+ecx], 0
  008419B1   .  8D0C41             lea     ecx, [eax*2+ecx]
  008419B4   .^ 75 ED              jne     short 008419A3
  008419B6   .  EB 0B              jmp     short 008419C3
  008419B8   >  66:8B4445 B0       mov     ax, word ptr [eax*2+ebp-50]
  008419BD   .  66:8903            mov     word ptr [ebx], ax
  008419C0   .  83C3 02            add     ebx, 2
  008419C3   >  66:8B4D B0         mov     cx, word ptr [ebp-50]
  008419C7   >  46                 inc     esi
  008419C8   .  66:833C77 00       cmp     word ptr [esi*2+edi], 0
  008419CD   .  8D0477             lea     eax, [esi*2+edi]
  008419D0   .^ 75 C4              jne     short 00841996               ; 此循环取出注册码中的字母部分
  008419D2   .  8B5D AC            mov     ebx, dword ptr [ebp-54]
  008419D5   >  33C9               xor     ecx, ecx
  008419D7   .  8D45 F0            lea     eax, [ebp-10]
  008419DA   .  66:394D F0         cmp     word ptr [ebp-10], cx        ; 判断注册码中是否存在字母
  008419DE   .  74 59              je      short 00841A39               ; 注册码中不存在字母则发送注册失败消息
  008419E0   >  8D40 02            lea     eax, [eax+2]
  008419E3   .  41                 inc     ecx
  008419E4   .  66:8338 00         cmp     word ptr [eax], 0
  008419E8   .^ 75 F6              jne     short 008419E0
  008419EA   .  83F9 02            cmp     ecx, 2                       ; 判断注册码中的字母个数是否等于2
  008419ED   .  75 4A              jne     short 00841A39               ; 不相等则发送注册失败消息
  008419EF   .  33C0               xor     eax, eax
  008419F1   .  C745 F0 31003500   mov     dword ptr [ebp-10], 350031
  008419F8   .  C745 F4 50004200   mov     dword ptr [ebp-0C], 420050
  008419FF   .  8D77 04            lea     esi, [edi+4]
  00841A02   .  66:8945 F8         mov     word ptr [ebp-8], ax
  00841A06   .  33C9               xor     ecx, ecx
  00841A08      0F1F8400 00000000  nop     dword ptr [eax+eax]
  00841A10  />  66:8B444D F0       /mov     ax, word ptr [ecx*2+ebp-10]
  00841A15  |.  66:3B06            |cmp     ax, word ptr [esi]
  00841A18  |.  75 1F              |jne     short 00841A39
  00841A1A  |.  41                 |inc     ecx
  00841A1B  |.  83C6 02            |add     esi, 2
  00841A1E  |.  83F9 04            |cmp     ecx, 4
  00841A21  |.^ 72 ED              \jb      short 00841A10              ; 判断注册码中的3-6位是否依次为"15PB"
  00841A23  |.  8BD7               mov     edx, edi
  00841A25  |.  8BCB               mov     ecx, ebx
  00841A27  |.  E8 14FDFFFF        call    00841740                     ; <<==调用注册码判断函数4(重要)
  00841A2C  |.  6A 00              push    0                            ; 返回1注册成功
  00841A2E  |.  85C0               test    eax, eax
  00841A30  |.  74 09              jz      short 00841A3B
  00841A32  |.  68 0B040000        push    40B                          ; 设置注册成功标志
  00841A37  |.  EB 07              jmp     short 00841A40
  00841A39  |>  6A 00              push    0
  00841A3B  |>  68 0A040000        push    40A                          ; 设置注册失败标志
  00841A40  |>  68 11010000        push    111                          ; |Msg = WM_COMMAND
  00841A45  |.  FF73 04            push    dword ptr [ebx+4]            ; |hWnd
  00841A48  |.  FF15 54818500      call    dword ptr [<&USER32.PostMess ; \USER32.PostMessageW
  00841A4E  |.  8B4D FC            mov     ecx, dword ptr [ebp-4]
  00841A51  |.  5F                 pop     edi
  00841A52  |.  5E                 pop     esi
  00841A53  |.  33CD               xor     ecx, ebp
  00841A55  |.  5B                 pop     ebx
  00841A56  |.  E8 6A120000        call    00842CC5
  00841A5B  |.  8BE5               mov     esp, ebp
  00841A5D  |.  5D                 pop     ebp
  00841A5E  \.  C3                 ret

  
  四. 注册码判断函数4: 0x00841740, 只有此函数返回1才能注册成功, edx中为待判断的注册码
  CPU Disasm
  Address   Hex dump               Command                            Comments
  00841740   $  55                 push    ebp                        ; 注册码判断函数4
  00841741   .  8BEC               mov     ebp, esp
  00841743   .  83EC 50            sub     esp, 50
  00841746   .  A1 14F08500        mov     eax, dword ptr [85F014]
  0084174B   .  33C5               xor     eax, ebp
  0084174D   .  8945 FC            mov     dword ptr [ebp-4], eax
  00841750   .  53                 push    ebx
  00841751   .  8BDA               mov     ebx, edx                   ; 注册码
  00841753   .  C745 F4 00000000   mov     dword ptr [ebp-0C], 0
  0084175A   .  8BD1               mov     edx, ecx
  0084175C   .  66:C745 F8 0000    mov     word ptr [ebp-8], 0
  00841762   .  0F57C0             xorps   xmm0, xmm0
  00841765   .  8955 B4            mov     dword ptr [ebp-4C], edx
  00841768   .  56                 push    esi
  00841769   .  57                 push    edi
  0084176A   .  0F1145 DC          movups  dqword ptr [ebp-24], xmm0
  0084176E   .  8D4D DC            lea     ecx, [ebp-24]
  00841771   .  B8 31000000        mov     eax, 31
  00841776   .  660FD645 EC        movq    qword ptr [ebp-14], xmm0
  0084177B      0F1F4400 00        nop     dword ptr [eax+eax]
  00841780  />  66:8901            /mov     word ptr [ecx], ax
  00841783  |.  8D49 02            |lea     ecx, [ecx+2]
  00841786  |.  40                 |inc     eax
  00841787  |.  83F8 39            |cmp     eax, 39
  0084178A  |.^ 7E F4              \jle     short 00841780
  0084178C  |.  8B02               mov     eax, dword ptr [edx]       ; 初始化字符串1-9
  0084178E  |.  33F6               xor     esi, esi
  00841790  |.  8D0C43             lea     ecx, [eax*2+ebx]
  00841793  |.  8BC3               mov     eax, ebx
  00841795  |.  85DB               test    ebx, ebx
  00841797  |.  74 11              jz      short 008417AA
  00841799  |.  66:3933            cmp     word ptr [ebx], si
  0084179C  |.  74 0C              je      short 008417AA
  0084179E  |.  66:90              nop
  008417A0  |>  8D40 02            /lea     eax, [eax+2]
  008417A3  |.  46                 |inc     esi
  008417A4  |.  66:8338 00         |cmp     word ptr [eax], 0
  008417A8  |.^ 75 F6              \jne     short 008417A0
  008417AA  |>  51                 push    ecx                        ; /Arg2, 字符串 注册码的后6位
  008417AB  |.  8D45 DC            lea     eax, [ebp-24]              ; |
  008417AE  |.  50                 push    eax                        ; |Arg1, 字符串1-9
  008417AF  |.  E8 1C110000        call    008428D0                   ; \Crack_Me.008428D0, 连接两个字符串
  008417B4  |.  8D76 FF            lea     esi, [esi-1]
  008417B7  |.  8BF8               mov     edi, eax
  008417B9  |.  8D0473             lea     eax, [esi*2+ebx]           ; 算出注册码最后一个字符的指针
  008417BC  |.  897D B8            mov     dword ptr [ebp-48], edi
  008417BF  |.  33F6               xor     esi, esi
  008417C1  |.  8945 B0            mov     dword ptr [ebp-50], eax
  008417C4  |.  66:3975 DC         cmp     word ptr [ebp-24], si
  008417C8  |.  74 31              je      short 008417FB
  008417CA  |.  0FB738             movzx   edi, word ptr [eax]
  008417CD  |.  8D4D DC            lea     ecx, [ebp-24]
  008417D0  |.  83E7 01            and     edi, 00000001
  008417D3  |>  66:8B01            /mov     ax, word ptr [ecx]
  008417D6  |.  66:C1E8 02         |shr     ax, 2
  008417DA  |.  66:03C7            |add     ax, di
  008417DD  |.  66:83F8 32         |cmp     ax, 32
  008417E1  |.  74 78              |je      short 0084185B
  008417E3  |.  66:83F8 64         |cmp     ax, 64
  008417E7  |.  74 0F              |je      short 008417F8
  008417E9  |.  46                 |inc     esi
  008417EA  |.  8D4D DC            |lea     ecx, [ebp-24]
  008417ED  |.  8D1436             |lea     edx, [esi+esi]
  008417F0  |.  03CA               |add     ecx, edx
  008417F2  |.  66:8339 00         |cmp     word ptr [ecx], 0
  008417F6  |.^ 75 DB              \jne     short 008417D3            ; [冗余操作]1-9字符串必然符合条件
  008417F8  |>  8B7D B8            mov     edi, dword ptr [ebp-48]
  008417FB  |>  8D4D DC            lea     ecx, [ebp-24]
  008417FE  |.  8BF3               mov     esi, ebx                   ; 注册码
  00841800  |.  8BC1               mov     eax, ecx
  00841802  |.  BA 31000000        mov     edx, 31
  00841807  |.  2BF0               sub     esi, eax
  00841809  |.  0F1F80 00000000    nop     dword ptr [eax]
  00841810  |>  66:8B01            /mov     ax, word ptr [ecx]
  00841813  |.  66:3B040E          |cmp     ax, word ptr [ecx+esi]
  00841817  |.  75 42              |jne     short 0084185B            ; 不相等返回0, 注册失败
  00841819  |.  83C2 06            |add     edx, 6
  0084181C  |.  83C1 02            |add     ecx, 2
  0084181F  |.  83FA 39            |cmp     edx, 39
  00841822  |.^ 7E EC              \jle     short 00841810            ; 循环两次,分别判断注册码的前两个字符是否分别为1和2
  00841824  |.  0FB74F 12          movzx   ecx, word ptr [edi+12]     ; 取出注册码的第二个字符
  00841828  |.  0FB703             movzx   eax, word ptr [ebx]        ; 取出注册码的第一个字符
  0084182B  |.  03C8               add     ecx, eax
  0084182D  |.  83F9 63            cmp     ecx, 63                    ; 两个字符相加是否等于0x63
  00841830  |.  75 29              jne     short 0084185B             ; 不相等返回0, 注册失败
  00841832  |.  8B45 B4            mov     eax, dword ptr [ebp-4C]
  00841835  |.  0FB74F 0C          movzx   ecx, word ptr [edi+0C]     ; 取出常量字符串中的第七个字符0x37
  00841839  |.  0308               add     ecx, dword ptr [eax]       ; 加上点击ok按钮的次数(本次启动验证注册码的次数)
  0084183B  |.  8B45 B0            mov     eax, dword ptr [ebp-50]    ; 相加等于ascii码0x38
  0084183E  |.  0FB700             movzx   eax, word ptr [eax]
  00841841  |.  3BC1               cmp     eax, ecx                   ; 判断与注册码最后一位是否相等
  00841843  |.  75 16              jne     short 0084185B             ; 不相等返回0, 注册失败
  00841845  |.  5F                 pop     edi                        ; UNICODE "1215PB8"
  00841846  |.  5E                 pop     esi
  00841847  |.  B8 01000000        mov     eax, 1                     ; 返回1, 注册成功分支
  0084184C  |.  5B                 pop     ebx
  0084184D  |.  8B4D FC            mov     ecx, dword ptr [ebp-4]
  00841850  |.  33CD               xor     ecx, ebp
  00841852  |.  E8 6E140000        call    00842CC5
  00841857  |.  8BE5               mov     esp, ebp
  00841859  |.  5D                 pop     ebp
  0084185A  |.  C3                 ret
  0084185B  |>  8B4D FC            mov     ecx, dword ptr [ebp-4]     ; 返回0, 注册失败分支
  0084185E  |.  33C0               xor     eax, eax
  00841860  |.  5F                 pop     edi
  00841861  |.  5E                 pop     esi
  00841862  |.  33CD               xor     ecx, ebp
  00841864  |.  5B                 pop     ebx
  00841865  |.  E8 5B140000        call    00842CC5
  0084186A  |.  8BE5               mov     esp, ebp
  0084186C  |.  5D                 pop     ebp
  0084186D  \.  C3                 ret

  
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于xietao, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2016年11月02日 0:02:07

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

上传的附件:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
额 ,大段的汇编看出来的最后两个函数?
2017-1-20 18:01
0
雪    币: 0
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
3
牛牛    我也在尝试分析这个  题目,  但是我的ollydbg  加载crackme.exe后运行一下就直接终止了,  后来使用52pojie的虚拟机里面的ollydbg也是同样的问题,  想问下牛牛你是怎么使用od动态加载的。。。    希望牛牛能帮忙解答一下    十分感谢 
2017-10-26 16:37
0
雪    币: 870
活跃值: (2264)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习一下
2018-7-24 14:59
0
雪    币: 207
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
nagezei 牛牛 我也在尝试分析这个 题目, 但是我的ollydbg 加载crackme.exe后运行一下就直接终止了, 后来使用52pojie的虚拟机里面的ollydbg也是同样的问题, 想问下牛牛你是怎么使 ...
这题有反调试,而且还有子线程,要nop掉反调试和跳到子程序中才能分析。。。
2019-1-18 15:55
0
游客
登录 | 注册 方可回帖
返回
//