Diablo 2oo2’s CrackMe 2 算法分析

【目     标】:Diablo 2oo2’s CrackMe 2
【工     具】:IDA 4.7
【任     务】:算法分析
【操作平台】:Windows 2003 server
【作     者】: LOVEBOOM[DFCG][FCG][US]
【相关链接】: 见附件
【简要说明】: 用IDA再分析一篇简单的算法。
【详细过程】:
        因为CRACKME是用masm写的,所以非常方便分析的。这次目标用yoda加了壳,怎么脱壳我就不说了,很简单的。脱壳后,用IDA分析一下结果就出来了:

code:00401028 DialogFunc:                                       ; DATA XREF: start+Eo
code:00401028                 push    ebp
code:00401029                 mov     ebp, esp
code:0040102B                 cmp     dword ptr [ebp+0Ch], 111h
code:00401032                 jnz     loc_401245
code:00401038                 mov     eax, [ebp+10h]            ; CASE EAX==WM_COMMAND
code:0040103B                 cmp     ax, 65h
code:0040103F                 jnz     loc_40125D
code:00401045                 pusha                             ; CASE AX==IDC_BTN_CHECKREG
code:00401046                 mov     byte ptr ds:UCASE_Buffer, 53h ; "SJKAZBVTECGIDFNG"
code:0040104D                 mov     byte ptr ds:UCASE_Buffer+1, 4Ah
code:00401054                 mov     byte ptr ds:UCASE_Buffer+2, 4Bh
code:0040105B                 mov     byte ptr ds:UCASE_Buffer+3, 41h
code:00401062                 mov     byte ptr ds:UCASE_Buffer+4, 5Ah
code:00401069                 mov     byte ptr ds:UCASE_Buffer+5, 42h
code:00401070                 mov     byte ptr ds:UCASE_Buffer+6, 56h
code:00401077                 mov     byte ptr ds:UCASE_Buffer+7, 54h
code:0040107E                 mov     byte ptr ds:UCASE_Buffer+8, 45h
code:00401085                 mov     byte ptr ds:UCASE_Buffer+9, 43h
code:0040108C                 mov     byte ptr ds:UCASE_Buffer+0Ah, 47h
code:00401093                 mov     byte ptr ds:UCASE_Buffer+0Bh, 49h
code:0040109A                 mov     byte ptr ds:UCASE_Buffer+0Ch, 44h
code:004010A1                 mov     byte ptr ds:UCASE_Buffer+0Dh, 46h
code:004010A8                 mov     byte ptr ds:UCASE_Buffer+0Eh, 4Eh
code:004010AF                 mov     byte ptr ds:UCASE_Buffer+0Fh, 47h ; 准备获取注册码
code:004010B6                 push    28h                       ; nMaxCount
code:004010B8                 push    offset SN_Buffer          ; lpString
code:004010BD                 push    68h                       ; nIDDlgItem
code:004010BF                 push    dword ptr [ebp+8]         ; hDlg
code:004010C2                 call    GetDlgItemTextA           ; 获取注册码
code:004010C7                 cmp     eax, 10h
code:004010CA                 jnz     short Reg_Failed          ; 比较注册码,如果注册码长度不是10h则over
code:004010CC                 push    28h                       ; nMaxCount
code:004010CE                 push    offset SzName_Buffer      ; lpString
code:004010D3                 push    67h                       ; nIDDlgItem
code:004010D5                 push    dword ptr [ebp+8]         ; hDlg
code:004010D8                 call    GetDlgItemTextA           ; 获取用户名
code:004010DD                 test    eax, eax
code:004010DF                 jz      short loc_401101
code:004010E1                 cmp     eax, 8                    ; 用户名长度不能大于8
code:004010E4                 jg      short loc_401115
code:004010E6                 cmp     eax, 1                    ; 如果用户名小于1则提示,问题提示,后面的提示最少2位,这里判断却是不为空就算过关了
code:004010E9                 jl      short loc_4010ED
code:004010EB                 jmp     short @UCASE              ; 这里实际就是一个转为大写的函数。
code:004010EB                                                   ; 如果小于'A'则加20h,相加后值还是小于'A'则把字符转为'F'
code:004010EB                                                   ; 如果大于'Z'则减20h(就是转为大写),运算值大于'Z'则字符转为'G'
code:004010EB                                                   ; 运算值小于'A',则把字符转为'S'
code:004010ED ; ----------------------------------------------------------------------------
code:004010ED
code:004010ED loc_4010ED:                                       ; CODE XREF: code:004010E9j
code:004010ED                 push    offset aNameMustBeAtLe    ; lpString
code:004010F2                 push    68h                       ; nIDDlgItem
code:004010F4                 push    dword ptr [ebp+8]         ; hDlg
code:004010F7                 call    SetDlgItemTextA           ; 显示错误信息 
code:004010FC                 jmp     loc_401242
code:00401101 ; ----------------------------------------------------------------------------
code:00401101
code:00401101 loc_401101:                                       ; CODE XREF: code:004010DFj
code:00401101                 push    offset aEnterAName        ; lpString
code:00401106                 push    68h                       ; nIDDlgItem
code:00401108                 push    dword ptr [ebp+8]         ; hDlg
code:0040110B                 call    SetDlgItemTextA
code:00401110                 jmp     loc_401242
code:00401115 ; ----------------------------------------------------------------------------
code:00401115
code:00401115 loc_401115:                                       ; CODE XREF: code:004010E4j
code:00401115                 push    offset aNameIsTooLong     ; lpString
code:0040111A                 push    68h                       ; nIDDlgItem
code:0040111C                 push    dword ptr [ebp+8]         ; hDlg
code:0040111F                 call    SetDlgItemTextA
code:00401124                 jmp     loc_401242
code:00401129 ; ----------------------------------------------------------------------------
code:00401129
code:00401129 Reg_Failed:                                       ; CODE XREF: code:004010CAj
code:00401129                                                   ; code:0040120Fj ...
code:00401129                 push    offset String             ; lpString
code:0040112E                 push    68h                       ; nIDDlgItem
code:00401130                 push    dword ptr [ebp+8]         ; hDlg
code:00401133                 call    SetDlgItemTextA
code:00401138                 jmp     loc_401242
code:0040113D
code:0040113D ; ************** S U B R O U T I N E *****************************************
code:0040113D
code:0040113D ; 这里实际就是一个转为大写的函数。
code:0040113D ; 如果小于'A'则加20h,相加后值还是小于'A'则把字符转为'F'
code:0040113D ; 如果大于'Z'则减20h(就是转为大写),运算值大于'Z'则字符转为'G'
code:0040113D ; 运算值小于'A',则把字符转为'S'
code:0040113D
code:0040113D @UCASE          proc near                         ; CODE XREF: code:004010EBj
code:0040113D                 xor     ebx, ebx
code:0040113F                 xor     ecx, ecx                  ; 初始化相关寄存器
code:00401141                 xor     edx, edx
code:00401143                 xor     edi, edi
code:00401145                 xor     esi, esi
code:00401147
code:00401147 loc_401147:                                       ; CODE XREF: @UCASE+47j
code:00401147                 mov     bl, ds:SzName_Buffer[ecx]
code:0040114D                 cmp     bl, 41h                   ; 如果用户名小于'A'则跳去加20h
code:00401150                 jl      short ADD_20h
code:00401152
code:00401152 loc_401152:                                       ; CODE XREF: @UCASE:loc_401163j
code:00401152                 cmp     bl, 5Ah                   ; 如果用户名大于'Z'则跳去减20h,也就是uCASE
code:00401155                 jg      short UPCASE
code:00401157
code:00401157 loc_401157:                                       ; CODE XREF: @UCASE:loc_401176j
code:00401157                 jmp     short loc_401178
code:00401159 ; ----------------------------------------------------------------------------
code:00401159
code:00401159 ADD_20h:                                          ; CODE XREF: @UCASE+13j
code:00401159                 add     bl, 20h
code:0040115C                 cmp     bl, 41h                   ; 如果+20后还是小于41则直接置BL为46H('F')
code:0040115F                 jge     short loc_401163
code:00401161                 mov     bl, 46h
code:00401163
code:00401163 loc_401163:                                       ; CODE XREF: @UCASE+22j
code:00401163                 jmp     short loc_401152          ; 如果用户名大于'Z'则跳去减20h,也就是uCASE
code:00401165 ; ----------------------------------------------------------------------------
code:00401165
code:00401165 UPCASE:                                           ; CODE XREF: @UCASE+18j
code:00401165                 sub     bl, 20h
code:00401168                 cmp     bl, 5Ah                   ; 如果-20小于或等于则跳
code:0040116B                 jle     short loc_40116F          ; 如果减后小于'A'则改为'S'
code:0040116D                 mov     bl, 47h                   ; 如果-20后还是大于'Z'则把BL改为'D'
code:0040116F
code:0040116F loc_40116F:                                       ; CODE XREF: @UCASE+2Ej
code:0040116F                 cmp     bl, 41h                   ; 如果减后小于'A'则改为'S'
code:00401172                 jge     short loc_401176
code:00401174                 mov     bl, 53h
code:00401176
code:00401176 loc_401176:                                       ; CODE XREF: @UCASE+35j
code:00401176                 jmp     short loc_401157
code:00401178 ; ----------------------------------------------------------------------------
code:00401178
code:00401178 loc_401178:                                       ; CODE XREF: @UCASE:loc_401157j
code:00401178                 mov     byte ptr ds:UCASE_Buffer[edx], bl ; "SJKAZBVTECGIDFNG"
code:0040117E                 add     edx, 2                    ; 每次加2,替换原有的数据,偶数替换
code:00401181                 inc     ecx
code:00401182                 cmp     ecx, eax
code:00401184                 jnz     short loc_401147
code:00401184 @UCASE          endp
code:00401184
code:00401186                 xor     ecx, ecx                  ; 初始化相关寄存器
code:00401188                 xor     edx, edx
code:0040118A                 xor     ebx, ebx
code:0040118C
code:0040118C Lp_Sum_value:                                     ; CODE XREF: code:00401198j
code:0040118C                 mov     bl, byte ptr ds:UCASE_Buffer[ecx] ; 取出转为大写后字符
code:00401192                 add     edx, ebx                  ; 计算大写替换后字符串的和sumValue
code:00401194                 inc     ecx
code:00401195                 cmp     ecx, 10h
code:00401198                 jnz     short Lp_Sum_value        ; 取出转为大写后字符
code:0040119A                 imul    eax, 0FFh                 ; 用户名长度乘以0FFh的值key1
code:004011A0                 imul    edx, eax                  ; 再用key1乘以sumValue,设为imulvalue
code:004011A3                 xor     edx, 0ACEBDFABh           ; 用imulValue 异或常数0ACEBDFABH的值设为XorValue
code:004011A9                 bswap   edx                       ; 计算出的xorValue反转
code:004011AB                 push    edx
code:004011AC                 push    offset szLx               ; "%lX"
code:004011B1                 push    offset sz_save_fmstr      ; 转换后的十六进制值输出为字符串
code:004011B6                 call    wsprintfA
code:004011BB                 add     esp, 0Ch
code:004011BE                 xor     ebx, ebx
code:004011C0                 xor     ecx, ecx
code:004011C2
code:004011C2 loc_4011C2:                                       ; CODE XREF: code:004011DCj
code:004011C2                 mov     bl, ds:sz_save_fmstr[ecx]
code:004011C8                 cmp     bl, 3Ah                   ; 比较值是否小于':'
code:004011CB                 jl      short jl3a                ; 如果值小于':'则加11h
code:004011CD                 jmp     short loc_4011D8
code:004011CF ; ----------------------------------------------------------------------------
code:004011CF
code:004011CF jl3a:                                             ; CODE XREF: code:004011CBj
code:004011CF                 add     bl, 11h                   ; 如果值小于':'则加11h
code:004011D2                 mov     ds:sz_save_fmstr[ecx], bl
code:004011D8
code:004011D8 loc_4011D8:                                       ; CODE XREF: code:004011CDj
code:004011D8                 inc     ecx
code:004011D9                 cmp     ecx, 8
code:004011DC                 jnz     short loc_4011C2          ; 循环判断替换
code:004011DE                 xor     ebx, ebx
code:004011E0                 xor     ecx, ecx
code:004011E2                 xor     edx, edx
code:004011E4
code:004011E4 loc_4011E4:                                       ; CODE XREF: code:004011F7j
code:004011E4                 mov     bl, ds:sz_save_fmstr[ecx] ; 再次取出运算后的值
code:004011EA                 mov     byte ptr ds:(UCASE_Buffer+1)[edx], bl ; 奇数替换字符
code:004011F0                 add     edx, 2
code:004011F3                 inc     ecx
code:004011F4                 cmp     edx, 10h
code:004011F7                 jnz     short loc_4011E4          ; 再次取出运算后的值
code:004011F9                 xor     ebx, ebx
code:004011FB                 xor     ecx, ecx
code:004011FD                 xor     edx, edx
code:004011FF                 xor     eax, eax
code:00401201
code:00401201 Loop_Compare_Data:                                ; CODE XREF: code:00401231j
code:00401201                 mov     bl, ds:SN_Buffer[edx]     ; 取出假码
code:00401207                 mov     al, byte ptr ds:UCASE_Buffer[edx] ; 取出真码
code:0040120D                 xor     eax, ebx
code:0040120F                 jnz     Reg_Failed                ; 如果不相等则over
code:00401215                 mov     bl, ds:byte_4030C9[edx]
code:0040121B                 mov     al, byte ptr ds:(UCASE_Buffer+1)[edx]
code:00401221                 add     al, 5                     ; 比较真注册码的偶数位-5是否等于假码的偶数位
code:00401223                 cmp     bl, al
code:00401225                 jnz     Reg_Failed
code:0040122B                 add     edx, 2
code:0040122E                 cmp     edx, 10h
code:00401231                 jnz     short Loop_Compare_Data   ; 取出假码
code:00401233                 push    offset aThankYouForYou    ; lpString
code:00401238                 push    68h                       ; nIDDlgItem
code:0040123A                 push    dword ptr [ebp+8]         ; hDlg
code:0040123D                 call    SetDlgItemTextA           ; 显示正确信息
code:00401242
code:00401242 loc_401242:                                       ; CODE XREF: code:004010FCj
code:00401242                                                   ; code:00401110j ...
code:00401242                 popa
code:00401243                 jmp     short loc_401257
code:00401245 ; ----------------------------------------------------------------------------


 
算法总结:
       又抓了个软杮子, 算法也是非常这简单的,先把注册名转为大写,然后替换固定字符串里奇数位的字符,s1,然后把s1的值累加s2,s2*0ff*用户名长度key1,key1再异或固定值0ACEBDFABh结果保存为key2,key2的每一位比较是否小于’:’,小于则加上11h,然后再加上5,结果替换固定字符串里偶数位的字符。
 
Greetz:
 Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my friends and you!
 
By loveboom[DFCG][FCG][US]
Email:loveboom#163.com
Date:2005-6-13 14:32
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值