首页
社区
课程
招聘
[原创] 一个利用SEH进行跳转的CrackME分析[原创]
发表于: 2008-1-4 20:43 9686

[原创] 一个利用SEH进行跳转的CrackME分析[原创]

petnt 活跃值
12
2008-1-4 20:43
9686

【文章标题】: 一个利用SEH进行跳转的CrackME分析
【文章作者】: petnt
【作者邮箱】: petnt@sohu.com
【软件名称】: CM06 by Nooby
【下载地址】: 见附件
【保护方式】: 序列号
【使用工具】: OllyIce、计算器、笔、纸
【操作平台】: XpSp2
【软件介绍】: 利用SEH进行跳转,感觉非常不错的一个CrackMe
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  这几天在看有关Armadillo的文章,没想到四处碰壁,对我的目标软件只能敬而远之,可能我的能力还没有达到能研究壳的水平。为了增强对Crack的信心和兴趣,逐步增加自己的技术水平,只好继续CrackMe。没想到碰上这个CrackMe让我有了一种相见恨晚的感觉,从研究作者的思路中让我感觉到了无限的乐趣。分析过程中使我再一次体会到我的“名言”之真:破解是一门艺术,要学会欣赏。行了,不要乱扔东西:-),我们进入正题。
  这个CrackMe是传统型的程序,我们可以用各种传统的方法断掉他。可能作者的意图仅仅是展示我们题中所提的想法,所以我遇到的困难并不多。GetWindowTextA下断,很容易找到关键的地方。
0042F627   .  55            push    ebp
0042F628   .  8BEC          mov     ebp, esp
0042F62A   .  6A FE         push    -2
0042F62C   .  68 10C34300   push    0043C310
0042F631   .  68 20D34100   push    0041D320                     ; 请留意这个地址
0042F636   .  64:A1 0000000>mov     eax, fs:[0]                  ; 安装SEH Handler 
0042F63C   .  50            push    eax
0042F63D   .  51            push    ecx

;;;;;;;;;;;;;;;;;;;;;此处省略部分内容;;;;;;;;;;;;;;;;;;;;;;;;

0042F6C7   .  8945 98       mov     [ebp-68], eax
0042F6CA   .  8B45 98       mov     eax, [ebp-68]
0042F6CD   .  8945 E4       mov     [ebp-1C], eax
0042F6D0   .  6A 0A         push    0A                               ; /Arg3 = 0000000A
0042F6D2   .  FF75 D0       push    dword ptr [ebp-30]               ; |Arg2
0042F6D5   .  68 E8030000   push    3E8                              ; |Arg1 = 000003E8
0042F6DA   .  8B4D 94       mov     ecx, [ebp-6C]                    ; |
0042F6DD   .  E8 92C1FDFF   call    0040B874                         ; \CM06.0040B874   获取用户名
0042F6E2   .  8945 C8       mov     [ebp-38], eax
0042F6E5   .  6A 1E         push    1E                               ; /Arg3 = 0000001E
0042F6E7   .  FF75 D8       push    dword ptr [ebp-28]               ; |Arg2
0042F6EA   .  68 E9030000   push    3E9                              ; |Arg1 = 000003E9
0042F6EF   .  8B4D 94       mov     ecx, [ebp-6C]                    ; |
0042F6F2   .  E8 7DC1FDFF   call    0040B874                         ; \CM06.0040B874   获取序列号
0042F6F7   .  48            dec     eax
0042F6F8   .  48            dec     eax
0042F6F9   .  8945 C0       mov     [ebp-40], eax
0042F6FC   .  8365 FC 00    and     dword ptr [ebp-4], 0
0042F700   .  837D C8 04    cmp     dword ptr [ebp-38], 4            ;  用户名不能小于4
0042F704   .  7C 0C         jl      short 0042F712
0042F706   .  837D C0 08    cmp     dword ptr [ebp-40], 8
0042F70A   .  7C 06         jl      short 0042F712                   ;  注册码不能 小于10
0042F70C   .  8365 90 00    and     dword ptr [ebp-70], 0
0042F710   .  EB 07         jmp     short 0042F719
0042F712   >  C745 90 01000>mov     dword ptr [ebp-70], 1
0042F719   >  6A 04         push    4
0042F71B   .  58            pop     eax
0042F71C   .  33D2          xor     edx, edx
0042F71E   .  F775 90       div     dword ptr [ebp-70]               ;  如果用户名,注册码都符合要求,将在此产生异常
0042F721   .  85C0          test    eax, eax
0042F723   .  74 14         je      short 0042F739
0042F725   .  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
0042F727   .  68 70734300   push    00437370                         ; |Title = "Error"
0042F72C   .  68 78734300   push    00437378                         ; |Text = "Username must >= 4 && Key must >= 10"
0042F731   .  6A 00         push    0                                ; |hOwner = NULL
0042F733   .  FF15 98244300 call    [<&USER32.MessageBoxA>]          ; \MessageBoxA
0042F739   >  C745 FC FEFFF>mov     dword ptr [ebp-4], -2
0042F740   .  E9 A0020000   jmp     0042F9E5
0042F745   .  33C0          xor     eax, eax
0042F747   .  40            inc     eax
0042F748   .  C3            retn
0042F749   .  8B65 E8       mov     esp, [ebp-18]                    ; 上个异常返回点
0042F74C   .  8B45 C0       mov     eax, [ebp-40]
0042F74F   .  99            cdq
0042F750   .  F77D C8       idiv    dword ptr [ebp-38]
0042F753   .  8955 C4       mov     [ebp-3C], edx
0042F756   .  8365 B4 00    and     dword ptr [ebp-4C], 0
0042F75A   .  EB 07         jmp     short 0042F763
0042F75C   >  8B45 B4       mov     eax, [ebp-4C]
0042F75F   .  40            inc     eax
0042F760   .  8945 B4       mov     [ebp-4C], eax
0042F763   >  8B45 B4       mov     eax, [ebp-4C]
0042F766   .  3B45 C8       cmp     eax, [ebp-38]
0042F769   .  7D 11         jge     short 0042F77C                   ;  循环
0042F76B   .  8B45 D0       mov     eax, [ebp-30]
0042F76E   .  0345 B4       add     eax, [ebp-4C]
0042F771   .  0FBE00        movsx   eax, byte ptr [eax]
0042F774   .  0345 DC       add     eax, [ebp-24]
0042F777   .  8945 DC       mov     [ebp-24], eax                    ;  用户名各位 和值
0042F77A   .^ EB E0         jmp     short 0042F75C
0042F77C   >  8365 B0 00    and     dword ptr [ebp-50], 0
0042F780   .  EB 07         jmp     short 0042F789
0042F782   >  8B45 B0       mov     eax, [ebp-50]
0042F785   .  40            inc     eax
0042F786   .  8945 B0       mov     [ebp-50], eax
0042F789   >  8B45 B0       mov     eax, [ebp-50]
0042F78C   .  3B45 C0       cmp     eax, [ebp-40]
0042F78F   .  7D 11         jge     short 0042F7A2
0042F791   .  8B45 D8       mov     eax, [ebp-28]
0042F794   .  0345 B0       add     eax, [ebp-50]
0042F797   .  0FBE00        movsx   eax, byte ptr [eax]
0042F79A   .  0345 BC       add     eax, [ebp-44]
0042F79D   .  8945 BC       mov     [ebp-44], eax                    ;  注册码前 n-2 位 和值
0042F7A0   .^ EB E0         jmp     short 0042F782
0042F7A2   >  6A 10         push    10                               ; /Arg3 = 00000010
0042F7A4   .  FF75 E0       push    dword ptr [ebp-20]               ; |Arg2
0042F7A7   .  FF75 DC       push    dword ptr [ebp-24]               ; |Arg1
0042F7AA   .  E8 50FEFFFF   call    0042F5FF                         ; \CM06.0042F5FF
0042F7AF   .  83C4 0C       add     esp, 0C                          ;  用户名和值转换成小写字符串
0042F7B2   .  6A 07         push    7
0042F7B4   .  59            pop     ecx
0042F7B5   .  8B75 E0       mov     esi, [ebp-20]
0042F7B8   .  8B7D E4       mov     edi, [ebp-1C]
0042F7BB   .  F3:A5         rep     movs dword ptr es:[edi], dword p>
0042F7BD   .  66:A5         movs    word ptr es:[edi], word ptr [esi>;  
0042F7BF   .  6A 10         push    10                               ; /Arg3 = 00000010
0042F7C1   .  FF75 E0       push    dword ptr [ebp-20]               ; |Arg2
0042F7C4   .  FF75 BC       push    dword ptr [ebp-44]               ; |Arg1
0042F7C7   .  E8 33FEFFFF   call    0042F5FF                         ; \CM06.0042F5FF
0042F7CC   .  83C4 0C       add     esp, 0C                          ;  注册码和值 字符串形式
0042F7CF   .  8B45 E0       mov     eax, [ebp-20]
0042F7D2   .  8945 8C       mov     [ebp-74], eax
0042F7D5   .  8B45 8C       mov     eax, [ebp-74]
0042F7D8   .  8945 88       mov     [ebp-78], eax
0042F7DB   >  8B45 8C       mov     eax, [ebp-74]
0042F7DE   .  8A00          mov     al, [eax]
0042F7E0   .  8845 87       mov     [ebp-79], al
0042F7E3   .  FF45 8C       inc     dword ptr [ebp-74]
0042F7E6   .  807D 87 00    cmp     byte ptr [ebp-79], 0
0042F7EA   .^ 75 EF         jnz     short 0042F7DB
0042F7EC   .  8B45 8C       mov     eax, [ebp-74]
0042F7EF   .  2B45 88       sub     eax, [ebp-78]
0042F7F2   .  8B4D 88       mov     ecx, [ebp-78]
0042F7F5   .  894D 80       mov     [ebp-80], ecx                    ;  注册码和值字串
0042F7F8   .  8985 7CFFFFFF mov     [ebp-84], eax                    ;  字串长度
0042F7FE   .  8B45 E4       mov     eax, [ebp-1C]
0042F801   .  48            dec     eax
0042F802   .  8985 78FFFFFF mov     [ebp-88], eax
0042F808   >  8B85 78FFFFFF mov     eax, [ebp-88]
0042F80E   .  8A40 01       mov     al, [eax+1]
0042F811   .  8885 77FFFFFF mov     [ebp-89], al
0042F817   .  FF85 78FFFFFF inc     dword ptr [ebp-88]
0042F81D   .  80BD 77FFFFFF>cmp     byte ptr [ebp-89], 0
0042F824   .^ 75 E2         jnz     short 0042F808
0042F826   .  8BBD 78FFFFFF mov     edi, [ebp-88]
0042F82C   .  8B75 80       mov     esi, [ebp-80]
0042F82F   .  8B85 7CFFFFFF mov     eax, [ebp-84]
0042F835   .  8BC8          mov     ecx, eax
0042F837   .  C1E9 02       shr     ecx, 2
0042F83A   .  F3:A5         rep     movs dword ptr es:[edi], dword p>;  合并字串
0042F83C   .  8BC8          mov     ecx, eax
0042F83E   .  83E1 03       and     ecx, 3
0042F841   .  F3:A4         rep     movs byte ptr es:[edi], byte ptr>
0042F843   .  8B45 C0       mov     eax, [ebp-40]
0042F846   .  99            cdq
0042F847   .  F77D C8       idiv    dword ptr [ebp-38]
0042F84A   .  8945 D4       mov     [ebp-2C], eax                    ;  (Lofsn-2)/LofUser
0042F84D   .  8B45 C0       mov     eax, [ebp-40]
0042F850   .  2B45 C8       sub     eax, [ebp-38]
0042F853   .  8945 B8       mov     [ebp-48], eax                    ;  (LofSn-2)-LofUser
0042F856   .  8B45 DC       mov     eax, [ebp-24]                    ;  HezU
0042F859   .  0FAF45 C0     imul    eax, [ebp-40]                    ;  HezU*(LofSn-2)
0042F85D   .  8B4D BC       mov     ecx, [ebp-44]                    ;  HezS
0042F860   .  0FAF4D C8     imul    ecx, [ebp-38]                    ;  HezS*LofUser
0042F864   .  03C1          add     eax, ecx                         ;  上两值相加 Num1
0042F866   .  8B4D C0       mov     ecx, [ebp-40]                    ;  LofSn-2
0042F869   .  0FAF4D C8     imul    ecx, [ebp-38]                    ;  (LofSn-2)*LofUser
0042F86D   .  2BC1          sub     eax, ecx                         ;  Num1 - 上式结果 Num2
0042F86F   .  0345 B8       add     eax, [ebp-48]                    ;  Num2+[(LofSn-2)-LofUser]
0042F872   .  8945 B8       mov     [ebp-48], eax                    ;  Num3
0042F875   .  8B45 DC       mov     eax, [ebp-24]                    ;  HezU
0042F878   .  8B4D C0       mov     ecx, [ebp-40]                    ;  LofSn-2
0042F87B   .  D3E0          shl     eax, cl                          ;  左移
0042F87D   .  0345 B8       add     eax, [ebp-48]                    ;  Num3+移动结果= Num4
0042F880   .  8945 B8       mov     [ebp-48], eax                    ;  Num4
0042F883   .  8B45 BC       mov     eax, [ebp-44]                    ;  HezS
0042F886   .  8B4D C8       mov     ecx, [ebp-38]                    ;  LofUser
0042F889   .  D3E0          shl     eax, cl                          ;  左移
0042F88B   .  0345 B8       add     eax, [ebp-48]                    ;  Num4+移动结果=Num5
0042F88E   .  8945 B8       mov     [ebp-48], eax                    ;  Num5
0042F891   .  8B45 DC       mov     eax, [ebp-24]                    ;  HezU
0042F894   .  0FAF45 BC     imul    eax, [ebp-44]                    ;  HezU*HezS
0042F898   .  8B4D B8       mov     ecx, [ebp-48]
0042F89B   .  2BC8          sub     ecx, eax                         ;  Num5-HezS*HezU
0042F89D   .  894D B8       mov     [ebp-48], ecx                    ;  Num6
0042F8A0   .  8B45 D8       mov     eax, [ebp-28]
0042F8A3   .  0345 C0       add     eax, [ebp-40]
0042F8A6   .  50            push    eax                              ;  后两位
0042F8A7   .  E8 CBCEFEFF   call    0041C777                         ;  字符串 转 16进制
0042F8AC   .  59            pop     ecx
0042F8AD   .  8B4D B8       mov     ecx, [ebp-48]
0042F8B0   .  2BC8          sub     ecx, eax                         ;  Num6-十六进制
0042F8B2   .  894D B8       mov     [ebp-48], ecx                    ;  Num7
0042F8B5   .  6A 1E         push    1E
0042F8B7   .  58            pop     eax
0042F8B8   .  2B45 C0       sub     eax, [ebp-40]                    ;  1E-(LofSn-2)
0042F8BB   .  50            push    eax
0042F8BC   .  6A 00         push    0
0042F8BE   .  8B45 D8       mov     eax, [ebp-28]
0042F8C1   .  0345 C0       add     eax, [ebp-40]
0042F8C4   .  50            push    eax
0042F8C5   .  E8 16D1FEFF   call    0041C9E0
0042F8CA   .  83C4 0C       add     esp, 0C
0042F8CD   .  8B45 D8       mov     eax, [ebp-28]
0042F8D0   .  83C0 05       add     eax, 5
0042F8D3   .  50            push    eax
0042F8D4   .  E8 9ECEFEFF   call    0041C777                         ;  第6----(LofSn-2) 转16
0042F8D9   .  59            pop     ecx
0042F8DA   .  8B4D B8       mov     ecx, [ebp-48]
0042F8DD   .  2BC8          sub     ecx, eax                         ;  Num7- 转换结果
0042F8DF   .  894D B8       mov     [ebp-48], ecx                    ;  Num8
0042F8E2   .  6A 06         push    6
0042F8E4   .  59            pop     ecx
0042F8E5   .  33C0          xor     eax, eax
0042F8E7   .  8B7D D8       mov     edi, [ebp-28]
0042F8EA   .  83C7 05       add     edi, 5
0042F8ED   .  F3:AB         rep     stos dword ptr es:[edi]
0042F8EF   .  AA            stos    byte ptr es:[edi]
0042F8F0   .  FF75 D8       push    dword ptr [ebp-28]
0042F8F3   .  E8 7FCEFEFF   call    0041C777                         ;  前5位
0042F8F8   .  59            pop     ecx
0042F8F9   .  8B4D B8       mov     ecx, [ebp-48]
0042F8FC   .  2BC8          sub     ecx, eax                         ;  Num8-前5转换结果
0042F8FE   .  894D B8       mov     [ebp-48], ecx                    ;  Num9
0042F901   .  C745 FC 01000>mov     dword ptr [ebp-4], 1
0042F908   .  56            push    esi
0042F909   .  FF75 B8       push    dword ptr [ebp-48]               ; /pModule
0042F90C   .  FF15 84224300 call    [<&KERNEL32.GetModuleHandleA>]   ; \GetModuleHandleA 假注册码将在此产生异常
0042F912   .  8945 AC       mov     [ebp-54], eax
0042F915   .  50            push    eax
0042F916   .  FF75 CC       push    dword ptr [ebp-34]               ; /pOldProtect
0042F919   .  6A 40         push    40                               ; |NewProtect = PAGE_EXECUTE_READWRITE
0042F91B   .  68 FFFF0200   push    2FFFF                            ; |Size = 2FFFF (196607.)
0042F920   .  FF75 AC       push    dword ptr [ebp-54]               ; |Address
0042F923   .  FF15 88224300 call    [<&KERNEL32.VirtualProtect>]     ; \VirtualProtect
0042F929   .  C745 FC FEFFF>mov     dword ptr [ebp-4], -2
0042F930   .  EB 2C         jmp     short 0042F95E
0042F932   .  33C0          xor     eax, eax
0042F934   .  40            inc     eax
0042F935   .  C3            retn
0042F936   .  8B65 E8       mov     esp, [ebp-18]                    ; 上次异常返回点
0042F939   .  FF75 D0       push    dword ptr [ebp-30]
0042F93C   .  E8 B9C9FEFF   call    0041C2FA
0042F941   .  59            pop     ecx
0042F942   .  FF75 D8       push    dword ptr [ebp-28]
0042F945   .  E8 B0C9FEFF   call    0041C2FA
0042F94A   .  59            pop     ecx
0042F94B   .  C745 FC FEFFF>mov     dword ptr [ebp-4], -2
0042F952   .  E9 A0000000   jmp     0042F9F7                         ; 在此跳出返回

  好了,在此我们暂停一下。和一般的CrackMe不同,程序在对我们输入的用户名和注册码进行一些变换后,并没有看到我们期待的比较跳转。变换后的数据被作为一个参数传给了API,这不得不引起我们的怀疑,作者的意图是什么呢?假的注册码将在此API上产生异常,异常处理过后,程序又回到了消息循环。
  再次审视出现在我们眼前的两个API,GetModuleHandleA,功能是获得某一模块的句柄,VirtualProtect,功能是改变某一内存地址处的保护属性。“某”指的可能是谁呢?当然最有可能的是自己!好了,在 0042F90C 上下断,改最后的变换结果为零(不明白原因的清参考MSDN中关于GetModuleHandle的解释)。继续跟踪:

0042F957   .  C745 FC FEFFF>mov     dword ptr [ebp-4], -2
0042F95E   >  C745 FC 02000>mov     dword ptr [ebp-4], 2             ; Jmp到这里
0042F965   .  58            pop     eax
0042F966   .  05 74F90200   add     eax, 2F974
0042F96B   .  66:C700 F7F0  mov     word ptr [eax], 0F0F7            ; 改变 0042F974处的指令
0042F970   .  8BD8          mov     ebx, eax
0042F972   .  58            pop     eax
0042F973   .  53            push    ebx
0042F974   .  90            nop                                      ; 此处及下面的Nop 被改写成 F7F0 即 div eax
0042F975   .  90            nop                                      ; 程序到这里又会产生异常
0042F976   .  C745 FC FEFFF>mov     dword ptr [ebp-4], -2
0042F97D   .  EB 5F         jmp     short 0042F9DE
0042F97F   .  33C0          xor     eax, eax
0042F981   .  40            inc     eax
0042F982   .  C3            retn

0042F983    8B65 E8         mov     esp, [ebp-18]                    ; 上次异常的返回点
0042F986    83EC 04         sub     esp, 4
0042F989    58              pop     eax
0042F98A    33C9            xor     ecx, ecx
0042F98C    83C0 50         add     eax, 50
0042F98F    03C8            add     ecx, eax
0042F991    B9 06000000     mov     ecx, 6
0042F996    8B18            mov     ebx, [eax]
0042F998    81F3 3F2F1F0F   xor     ebx, 0F1F2F3F
0042F99E    8918            mov     [eax], ebx
0042F9A0    83C0 04         add     eax, 4
0042F9A3  ^ E2 F1           loopd   short 0042F996                   ; 利用循环解密 42F9C4 - 42F9DC 处指令
0042F9A5    EB 1D           jmp     short 0042F9C4                   ; 跳到我们期待的地方
0042F9A7    B9 06000000     mov     ecx, 6
0042F9AC    B8 C4F94200     mov     eax, 0042F9C4
0042F9B1    8B18            mov     ebx, [eax]
0042F9B3    81F3 3F2F1F0F   xor     ebx, 0F1F2F3F
0042F9B9    8918            mov     [eax], ebx
0042F9BB    83C0 04         add     eax, 4
0042F9BE  ^ E2 F1           loopd   short 0042F9B1                   ; 利用循环恢复原来指令
0042F9C0    EB 23           jmp     short 0042F9E5                   ; 跳走返回
0042F9C2    90              nop
0042F9C3    90              nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;解密前;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

0042F9C4    55              push    ebp
0042F9C5    2F              das
0042F9C6    75 0F           jnz     short 0042F9D7
0042F9C8    57              push    edi
0042F9C9    8F              ???                                      ; 未知命令
0042F9CA    6C              ins     byte ptr es:[edi], dx
0042F9CB    4C              dec     esp
0042F9CC    3F              aas
0042F9CD    A4              movs    byte ptr es:[edi], byte ptr [esi>
0042F9CE    52              push    edx
0042F9CF    9B              wait
0042F9D0    D7              xlat    byte ptr [ebx+al]
0042F9D1    9E              sahf
0042F9D2    6A F2           push    -0E
0042F9D4    C0C4 CF         rol     ah, 0CF
0042F9D7    C8 7AD3E1       enter   0D37A, 0E1
0042F9DB    F0:FFFF         ???                                      ; 未知命令

;;;;;;;;;;;;;;;;;;;;;;;;;;;;解密后;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

0042F9C4    6A 00                push    0                           ; 解密后跳到这里执行
0042F9C6    6A 00                push    0
0042F9C8    68 A0734300          push    004373A0                    ; ASCII "Good job!" 瞧我们发现了什么?
0042F9CD    8B4D 94              mov     ecx, [ebp-6C]
0042F9D0    E8 B175FDFF          call    00406F86
0042F9D5  ^ EB D0                jmp     short 0042F9A7              ; 提示正确后跳到恢复解密处
0042F9D7    C745 FC FEFFFFFF     mov     dword ptr [ebp-4], -2
0042F9DE    C745 FC FEFFFFFF     mov     dword ptr [ebp-4], -2

0042F9DE    C745 FC FEFFFFF>mov     dword ptr [ebp-4], -2
0042F9E5    FF75 D0         push    dword ptr [ebp-30]               ; 正确返回处
0042F9E8    E8 0DC9FEFF     call    0041C2FA
0042F9ED    59              pop     ecx
0042F9EE    FF75 D8         push    dword ptr [ebp-28]
0042F9F1    E8 04C9FEFF     call    0041C2FA
0042F9F6    59              pop     ecx
0042F9F7    8B4D F0         mov     ecx, [ebp-10]
0042F9FA    64:890D 0000000>mov     fs:[0], ecx                      ; 恢复SEH链
0042FA01    59              pop     ecx
0042FA02    5F              pop     edi
0042FA03    5E              pop     esi
0042FA04    5B              pop     ebx
0042FA05    C9              leave
0042FA06    C3              retn                                     ; 程序返回

  至此,我们已经了解了程序的流程及作者的意图,SEH技术我并不是很熟,所以异常处理函数也并未仔细分析,只是粗略的跟踪了一下,估计程序也仅仅是利用它做了几次并不明显的跳转。虽然程序中有几个可疑的Api,如GetTickCount,但并未感觉到anti的存在,可能是OllyICE的插件太强大了:),好了,下面我们分析算法,准备写出注册机。

  下面将引用一些符号,其代表意义如下:

  HezU = 用户名各位ASCII和值; HezS = 注册码前 n-2位和值(n为注册码长度);LofUser = 用户名长度 ;LofSn = 注册码长度 ;Num1.....Num9 = 中间数

  计算过程如下:

  Num1=HezU*(LofSn-2)+HezS*LofUser;
  Num2=Num1-(LofSn-2)*LofUser;
  Num3=Num2+[(LofSn-2)-LofUser];
  Num4=Num3+[shl HezU,LofSn-2]
  Num5=Num4+[shl HezS,LofUser]
  Num6=Num5-HezS*HezU
  Num7=Num6-注册码后两位字符转换成十进制
  Num8=Num7-注册码中间字符转换成十进制(所谓中间即除去上面的后2和下面的前5)
  Num9=Num8-注册码前5位字符转换成十进制

  .if Num9=0
  注册成功
  .else
  注册失败
  .endif

  这是一种将用户名和注册码混合运算再进行结果比较的算法,也就是说程序本身并没有产生正确注册码的过程,他也仅仅是把我们输入的注册码拿来进行了一次实验,结果对了就算成功。您可能马上想到了有效的办法,穷举他。但其长度最少都为10位,我并不想在这个问题上考验计算机的速度,看看有没有其他的办法。

  我们测试下他的字符串转换成数字的函数,如果给定的字符串的第一位字符是除了 “+”“-” “0-9” 以外的字符的话,其结果是固定的数字0。好了,有了这个特点,我们重新考虑一下算法过程:如果我们能令转换结果为零,那么只要Num6=0就符合我们的条件了。这将产生重大的意义,因为在用户名已知的条件下,前6个中间数只与HezS和LofSn有关。我们只要假定注册码长度,就可以计算出HezS,在一定的条件下就可以给出注册码。
  
  好了,我们假设注册码长度为10(下面再次简化符号 X = HezS ,L = LofUser,H = HezU):

  则:8*H+X*L-8*L+8-L+2^8*H+X*2^L-X*H=0 整理  得出 X=(264*H+8-9*L)/(H-L-2^L)
  
  如果得出的X/8是可显示的ASCII值的话,将得出X平均分配一下,就可得出注册码。但这里有两个问题:第一,平均分配之后,在关键位置上可能为数字或+ -符号。第二,X并不一定是整数。为了解决上面的问题,我们可以把要求提的更苛刻一些。

  我们假定注册码的第1、6位为固定的字符,比如P 和 T。我们可以将得出X减去P\ T的ASCII值,在平均到6个位置上,第一个问题得以解决。

  关于第二个问题,如果不能整除,Num6中将存有一定的余数,而不是零。我们再看注册码的后两位,这两位并不参与和值运算,所以这两位比较自由一些。呵呵,可能你已经想到了,把余数放到最后两位,不就能解决问题嘛。是的,如果放不下我们还有中间3位。为什么首选这两个位置,因为我们可以大致估计余数的大小,同时也是为了有更大的几率产生注册码。当选择中间3位的时候,我们将不得不在X中再次减去中间三位的ASCII码值,让得到X平均到4为上面。可能您又想到了,平均成小数怎么办,呵呵,我们把余数统一加在第一位就可以了,因为余数很小。

  其实,把上面的想法赋予实践您就会发现,10位的注册码会得出很小的X,不足以产生可显示的字符。没关系,我们再看看注册码是11位的情况:

  X=(521H+9-10L)/(H-L-2^L)
  
  同样的思想,我们可以发现这回的X足以产生可显示字符了。
  
  下面我们考虑一下极端情况,如果H很小,但L又很大,我们的分母很快就是负数了。如用户名为8个空格时,就会产生负数。如何处理呢?可能您已经嫌我罗嗦了,留下个问题吧。  
  
  其实上面的设想和计算过程是很令人享受的一个过程,虽然您看来可能有些乏味。拿着笔在纸上算啊算啊的,最后终于在自己的努力下得出了注册码,不是很享受吗?!有些时候,过程和结果同样很重要。
  
  打住,收工。虽然附带的注册机漏洞百出,但他确实可以算出大部分短用户名的注册码。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2008年01月04日 20:18:39


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 29235
活跃值: (7759)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
2
学习支持。。
2008-1-4 23:22
0
雪    币: 82
活跃值: (10)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
3
你太牛了!我膜拜你!
对算法的分析很透彻,最后那2个数字不参与前面运算,而在最后减去的目的就是为了方便产生可用字符:)
2008-1-5 12:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼主分析得好详细,支持一下!

0042F631 . 68 20D34100 push 0041D320 ; 请留意这个地址
0042F636 . 64:A1 0000000>mov eax, fs:[0] ; 安装SEH Handler

0041D320,请留意这个地址,指什么?


0042F749 . 8B65 E8 mov esp, [ebp-18] ; 上个异常返回点


用户名和注册码满足要求将在0042F71E处产生除0的异常,如何知道异常的返回点是0042F749
调试时如何到达0042F749处?
请指点一下,谢谢!
2008-1-5 21:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不懂
那跟到异常处应该这么处理那??  
直接nop掉??
把0改一下??
如何知道异常的返回点??
谢谢。。。
2008-1-6 00:00
0
雪    币: 82
活跃值: (10)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
6
一般情况下出现异常的话,打开内存察看,在原程序的代码段上面设访问断点,shift+f9就能停到异常处理开始
2008-1-6 00:46
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
7
请留意的那个地址 就是异常处理程序了;
在那个地址上下断就能抓住Nooby的异常处理过程了:)
然后慢慢的跟踪就能知道程序会返回到哪里了;
再一个,不能Nop掉异常,因为程序要利用这些异常进行跳转。

另:感谢Nooby并希望多出品如此好的CrackMe
2008-1-6 08:25
0
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
8
好文,支持一个!
2008-1-6 09:43
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
谢谢Nooby和petnt
受教了
我膜拜你们啊。
2008-1-6 13:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
感谢Nooby和petnt的指点,学习了!
2008-1-6 18:52
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
11
各位谢谢捧场
2008-1-7 21:11
0
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
12
分析得很不错,学习。
2008-1-8 11:01
0
雪    币: 134
活跃值: (84)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
学习了!
2008-1-29 16:39
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
那个游戏一共就六关是么?点不到东西了
三四五都是一样的跳转法,2分钟一关了
就第二关需要向上多找几处
2008-1-31 10:07
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
15
应该是只有六关。

多分析几遍之后,你就会发现e语言的风格,所以你会越分析越上手,你还可以再找几个e语言的Crackme玩玩感觉一下。

看代码看一遍和看10遍的感觉绝对不一样。
2008-1-31 10:24
0
游客
登录 | 注册 方可回帖
返回
//