首页
社区
课程
招聘
[原创]Happytown's CrackMe_0038.exe 破解笔记
发表于: 2006-12-17 16:41 6786

[原创]Happytown's CrackMe_0038.exe 破解笔记

2006-12-17 16:41
6786

【文章标题】: Happytown's CrackMe_0038.exe 破解笔记
【文章作者】: ylp1332
【作者邮箱】: [email]ylp1332@yahoo.com.cn[/email]
【作者主页】: N/A
【作者QQ号】: N/A
【软件名称】: CrackMe_0038.exe
【软件大小】: 187kB
【下载地址】: 自己搜索下载
【加壳方式】: N/A
【保护方式】: Modified MD5
【编写语言】: VC6
【使用工具】: PEiD,IDA,OllyDBG,UE,VC6
【操作平台】: win32
【软件介绍】: Happytown's CrackMe No.38
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  
  1、首先用PEiD 0.94检查,用visual c++ 6编译,没有加壳。
  
  2、用PEiD的插件Krypto ANAlyzer检查,没有发现任何加密算法的痕迹。
  
  3、用IDA载入,进行初步的静态分析。
  
  分析结论:
          修改过的MD5算法,有4处调用;
          使用Windows API GetDlgItemTextA从控件中取得用户名、组织和注册码,
          用户名和组织名至少要2个字符长,注册码字符串必须由64个16进制字符组成。
         
  验证过程的反汇编代码如下:
  
  .text:00401000 ; int __cdecl OnCheck(HWND hDlg)
  .text:00401000 OnCheck         proc near               ; CODE XREF: DialogFunc+55p
  .text:00401000
  .text:00401000 tmp_str2        = byte ptr -2D4h
  .text:00401000 var_2CF         = byte ptr -2CFh
  .text:00401000 var_2CB         = dword ptr -2CBh
  .text:00401000 var_2C7         = word ptr -2C7h
  .text:00401000 var_2C5         = byte ptr -2C5h
  .text:00401000 tmp_str1        = dword ptr -2C4h
  .text:00401000 var_2BF         = dword ptr -2BFh
  .text:00401000 var_2BB         = dword ptr -2BBh
  .text:00401000 var_2B7         = word ptr -2B7h
  .text:00401000 var_2B5         = byte ptr -2B5h
  .text:00401000 tmp_str0        = byte ptr -2B4h
  .text:00401000 var_2AF         = dword ptr -2AFh
  .text:00401000 var_2AB         = dword ptr -2ABh
  .text:00401000 var_2A7         = word ptr -2A7h
  .text:00401000 var_2A5         = byte ptr -2A5h
  .text:00401000 hash_context    = dword ptr -2A4h
  .text:00401000 tmp_str3        = byte ptr -284h
  .text:00401000 tmp_str4        = byte ptr -27Eh
  .text:00401000 serbytes0       = dword ptr -278h
  .text:00401000 serbytes1       = dword ptr -268h
  .text:00401000 Name            = byte ptr -258h
  .text:00401000 Group           = byte ptr -190h
  .text:00401000 Serial          = dword ptr -0C8h
  .text:00401000 hDlg            = dword ptr  4
  .text:00401000
  .text:00401000                 sub     esp, 2D4h
  .text:00401006                 push    ebx
  .text:00401007                 push    esi
  .text:00401008                 push    edi
  .text:00401009                 xor     ebx, ebx
  .text:0040100B                 mov     ecx, 49
  .text:00401010                 xor     eax, eax
  .text:00401012                 lea     edi, [esp+89h]
  .text:00401019                 mov     [esp+2E0h+Name], bl
  .text:00401020                 rep stosd
  .text:00401022                 stosw
  .text:00401024                 stosb
  .text:00401025                 mov     ecx, 49
  .text:0040102A                 xor     eax, eax
  .text:0040102C                 lea     edi, [esp+151h]
  .text:00401033                 mov     [esp+2E0h+Group], bl
  .text:0040103A                 rep stosd
  .text:0040103C                 stosw
  .text:0040103E                 stosb
  .text:0040103F                 mov     ecx, 49
  .text:00401044                 xor     eax, eax
  .text:00401046                 lea     edi, [esp+2E0h+Serial+1]
  .text:0040104D                 mov     byte ptr [esp+2E0h+Serial], bl
  .text:00401054                 rep stosd
  .text:00401056                 stosw
  .text:00401058                 stosb
  .text:00401059                 xor     eax, eax
  .text:0040105B                 mov     esi, [esp+2E0h+hDlg]
  .text:00401062                 mov     [esp+2Dh], eax
  .text:00401066                 xor     ecx, ecx
  .text:00401068                 mov     [esp+2E0h+var_2AF], eax
  .text:0040106C                 xor     edx, edx
  .text:0040106E                 mov     [esp+2E0h+var_2AB], eax
  .text:00401072                 mov     edi, ds:GetDlgItemTextA
  .text:00401078                 mov     [esp+2E0h+var_2A7], ax
  .text:0040107D                 mov     [esp+2E0h+tmp_str1+1], ecx
  .text:00401081                 mov     [esp+0Dh], edx
  .text:00401085                 mov     [esp+2E0h+var_2A5], al
  .text:00401089                 mov     [esp+2E0h+var_2BF], ecx
  .text:0040108D                 mov     dword ptr [esp+2E0h+var_2CF], edx
  .text:00401091                 lea     eax, [esp+2E0h+Name]
  .text:00401098                 mov     [esp+2E0h+var_2BB], ecx
  .text:0040109C                 mov     [esp+2E0h+var_2CB], edx
  .text:004010A0                 push    0C9h            ; nMaxCount
  .text:004010A5                 push    eax             ; lpString
  .text:004010A6                 mov     [esp+2E8h+var_2B7], cx
  .text:004010AB                 mov     [esp+2E8h+var_2C7], dx
  .text:004010B0                 push    3EDh            ; nIDDlgItem
  .text:004010B5                 push    esi             ; hDlg
  .text:004010B6                 mov     [esp+2F0h+tmp_str0], bl
  .text:004010BA                 mov     byte ptr [esp+2F0h+tmp_str1], bl
  .text:004010BE                 mov     [esp+2F0h+var_2B5], cl
  .text:004010C2                 mov     [esp+2F0h+tmp_str2], bl
  .text:004010C6                 mov     [esp+2F0h+var_2C5], dl
  .text:004010CA                 call    edi ; GetDlgItemTextA
  .text:004010CC                 cmp     eax, 2          ; 用户名至少2个字符
  .text:004010CF                 jnb     short loc_4010DD
  .text:004010D1                 pop     edi
  .text:004010D2                 pop     esi
  .text:004010D3                 xor     eax, eax
  .text:004010D5                 pop     ebx
  .text:004010D6                 add     esp, 2D4h
  .text:004010DC                 retn
  .text:004010DD ; ---------------------------------------------------------------------------
  .text:004010DD
  .text:004010DD loc_4010DD:                             ; CODE XREF: OnCheck+CFj
  .text:004010DD                 lea     ecx, [esp+2E0h+Group]
  .text:004010E4                 push    0C9h            ; nMaxCount
  .text:004010E9                 push    ecx             ; lpString
  .text:004010EA                 push    3EEh            ; nIDDlgItem
  .text:004010EF                 push    esi             ; hDlg
  .text:004010F0                 call    edi ; GetDlgItemTextA
  .text:004010F2                 cmp     eax, 2          ; 组织名至少2个字符
  .text:004010F5                 jnb     short loc_401103
  .text:004010F7                 pop     edi
  .text:004010F8                 pop     esi
  .text:004010F9                 xor     eax, eax
  .text:004010FB                 pop     ebx
  .text:004010FC                 add     esp, 2D4h
  .text:00401102                 retn
  .text:00401103 ; ---------------------------------------------------------------------------
  .text:00401103
  .text:00401103 loc_401103:                             ; CODE XREF: OnCheck+F5j
  .text:00401103                 lea     edx, [esp+2E0h+Serial]
  .text:0040110A                 push    0C9h            ; nMaxCount
  .text:0040110F                 push    edx             ; lpString
  .text:00401110                 push    3EFh            ; nIDDlgItem
  .text:00401115                 push    esi             ; hDlg
  .text:00401116                 call    edi ; GetDlgItemTextA
  .text:00401118                 test    eax, eax        ; 注册码不能为空
  .text:0040111A                 jnz     short loc_401126
  .text:0040111C                 pop     edi
  .text:0040111D                 pop     esi
  .text:0040111E                 pop     ebx
  .text:0040111F                 add     esp, 2D4h
  .text:00401125                 retn
  .text:00401126 ; ---------------------------------------------------------------------------
  .text:00401126
  .text:00401126 loc_401126:                             ; CODE XREF: OnCheck+11Aj
  .text:00401126                 lea     edi, [esp+2E0h+Serial]
  .text:0040112D                 or      ecx, 0FFFFFFFFh
  .text:00401130                 xor     eax, eax
  .text:00401132                 repne scasb
  .text:00401134                 not     ecx
  .text:00401136                 dec     ecx
  .text:00401137                 cmp     ecx, 64
  .text:0040113A                 jz      short loc_401146 ; 注册码长度必须是64个字符
  .text:0040113C                 pop     edi
  .text:0040113D                 pop     esi
  .text:0040113E                 pop     ebx
  .text:0040113F                 add     esp, 2D4h
  .text:00401145                 retn
  .text:00401146 ; ---------------------------------------------------------------------------
  .text:00401146
  .text:00401146 loc_401146:                             ; CODE XREF: OnCheck+13Aj
  .text:00401146                 lea     eax, [esp+2E0h+hash_context]
  .text:0040114A                 push    ebp
  .text:0040114B                 push    eax             ; ctx
  .text:0040114C                 call    hash_init
  .text:00401151                 lea     edi, [esp+2E8h+Name]
  .text:00401158                 or      ecx, 0FFFFFFFFh
  .text:0040115B                 xor     eax, eax
  .text:0040115D                 lea     edx, [esp+2E8h+hash_context]
  .text:00401161                 repne scasb
  .text:00401163                 not     ecx
  .text:00401165                 dec     ecx
  .text:00401166                 push    ecx             ; len
  .text:00401167                 lea     ecx, [esp+2ECh+Name]
  .text:0040116E                 push    ecx             ; cstr
  .text:0040116F                 push    edx             ; ctx
  .text:00401170                 call    hash_update
  .text:00401175                 lea     eax, [esp+2F4h+hash_context]
  .text:00401179                 lea     ecx, [esp+2F4h+tmp_str0]
  .text:0040117D                 push    eax             ; ctx
  .text:0040117E                 push    ecx             ; cstr
  .text:0040117F                 call    hash_final
  .text:00401184                 lea     edx, [esp+2FCh+hash_context]
  .text:00401188                 push    edx             ; ctx
  .text:00401189                 call    hash_init
  .text:0040118E                 lea     edi, [esp+300h+Group]
  .text:00401195                 or      ecx, 0FFFFFFFFh
  .text:00401198                 xor     eax, eax
  .text:0040119A                 repne scasb
  .text:0040119C                 not     ecx
  .text:0040119E                 dec     ecx
  .text:0040119F                 lea     eax, [esp+300h+Group]
  .text:004011A6                 push    ecx             ; len
  .text:004011A7                 lea     ecx, [esp+304h+hash_context]
  .text:004011AB                 push    eax             ; cstr
  .text:004011AC                 push    ecx             ; ctx
  .text:004011AD                 call    hash_update
  .text:004011B2                 lea     edx, [esp+30Ch+hash_context]
  .text:004011B6                 lea     eax, [esp+30Ch+tmp_str1]
  .text:004011BA                 push    edx             ; ctx
  .text:004011BB                 push    eax             ; cstr
  .text:004011BC                 call    hash_final
  .text:004011C1                 lea     ecx, [esp+314h+hash_context]
  .text:004011C5                 push    ecx             ; ctx
  .text:004011C6                 call    hash_init
  .text:004011CB                 lea     edx, [esp+318h+Group]
  .text:004011D2                 push    edx             ; char *
  .text:004011D3                 call    __strrev
  .text:004011D8                 mov     edi, eax
  .text:004011DA                 or      ecx, 0FFFFFFFFh
  .text:004011DD                 xor     eax, eax
  .text:004011DF                 lea     edx, [esp+31Ch+Name]
  .text:004011E6                 repne scasb
  .text:004011E8                 not     ecx
  .text:004011EA                 sub     edi, ecx
  .text:004011EC                 mov     esi, edi
  .text:004011EE                 mov     ebp, ecx
  .text:004011F0                 mov     edi, edx
  .text:004011F2                 or      ecx, 0FFFFFFFFh
  .text:004011F5                 repne scasb
  .text:004011F7                 mov     ecx, ebp
  .text:004011F9                 dec     edi
  .text:004011FA                 shr     ecx, 2
  .text:004011FD                 rep movsd
  .text:004011FF                 mov     ecx, ebp
  .text:00401201                 and     ecx, 3
  .text:00401204                 rep movsb
  .text:00401206                 lea     edi, [esp+31Ch+Name]
  .text:0040120D                 or      ecx, 0FFFFFFFFh
  .text:00401210                 repne scasb
  .text:00401212                 not     ecx
  .text:00401214                 dec     ecx
  .text:00401215                 lea     eax, [esp+31Ch+Name]
  .text:0040121C                 push    ecx             ; len
  .text:0040121D                 lea     ecx, [esp+320h+hash_context]
  .text:00401221                 push    eax             ; cstr
  .text:00401222                 push    ecx             ; ctx
  .text:00401223                 call    hash_update
  .text:00401228                 add     esp, 44h
  .text:0040122B                 lea     edx, [esp+2E4h+hash_context]
  .text:0040122F                 lea     eax, [esp+2E4h+tmp_str2]
  .text:00401233                 push    edx             ; ctx
  .text:00401234                 push    eax             ; cstr
  .text:00401235                 call    hash_final
  .text:0040123A                 lea     ecx, [esp+2ECh+tmp_str2]
  .text:0040123E                 push    6               ; size_t
  .text:00401240                 lea     edx, [esp+2F0h+tmp_str3]
  .text:00401244                 push    ecx             ; char *
  .text:00401245                 push    edx             ; char *
  .text:00401246                 call    _strncpy
  .text:0040124B                 lea     eax, [esp+2Ah]
  .text:0040124F                 push    6               ; size_t
  .text:00401251                 lea     ecx, [esp+2FCh+tmp_str4]
  .text:00401255                 push    eax             ; char *
  .text:00401256                 push    ecx             ; char *
  .text:00401257                 call    _strncpy
  .text:0040125C                 lea     edi, [esp+304h+Serial]
  .text:00401263                 or      ecx, 0FFFFFFFFh
  .text:00401266                 xor     eax, eax
  .text:00401268                 lea     edx, [esp+304h+serbytes0]
  .text:0040126F                 repne scasb
  .text:00401271                 not     ecx
  .text:00401273                 dec     ecx
  .text:00401274                 push    edx
  .text:00401275                 lea     eax, [esp+308h+Serial]
  .text:0040127C                 push    ecx
  .text:0040127D                 push    eax
  .text:0040127E                 call    sub_4014E0      ; 关键函数1:检查注册码长度是否是偶数,注册码是否全是16进制字符,
  .text:0040127E                                         ; 然后将注册码字符串串转换为字节串
  .text:00401283                 add     esp, 2Ch
  .text:00401286                 test    eax, eax
  .text:00401288                 pop     ebp
  .text:00401289                 jnz     short loc_401295
  .text:0040128B                 pop     edi
  .text:0040128C                 pop     esi
  .text:0040128D                 pop     ebx
  .text:0040128E                 add     esp, 2D4h
  .text:00401294                 retn
  .text:00401295 ; ---------------------------------------------------------------------------
  .text:00401295
  .text:00401295 loc_401295:                             ; CODE XREF: OnCheck+289j
  .text:00401295                 xor     eax, eax        ; eax = 0
  .text:00401297
  .text:00401297 loc_401297:                             ; CODE XREF: OnCheck+2DAj
  .text:00401297                 lea     esi, [eax+1]    ; for(int i=0; i<3; i++)
  .text:0040129A                 and     eax, 80000001h
  .text:0040129F                 jns     short loc_4012A6
  .text:004012A1                 dec     eax
  .text:004012A2                 or      eax, 0FFFFFFFEh
  .text:004012A5                 inc     eax
  .text:004012A6
  .text:004012A6 loc_4012A6:                             ; CODE XREF: OnCheck+29Fj
  .text:004012A6                 mov     ecx, esi
  .text:004012A8                 and     ecx, 80000001h
  .text:004012AE                 jns     short loc_4012B5
  .text:004012B0                 dec     ecx
  .text:004012B1                 or      ecx, 0FFFFFFFEh
  .text:004012B4                 inc     ecx
  .text:004012B5
  .text:004012B5 loc_4012B5:                             ; CODE XREF: OnCheck+2AEj
  .text:004012B5                 shl     ecx, 4
  .text:004012B8                 lea     edx, [esp+ecx+2E0h+serbytes0]
  .text:004012BC                 lea     ecx, [eax+eax*2]
  .text:004012BF                 shl     eax, 4
  .text:004012C2                 push    edx             ; s3
  .text:004012C3                 lea     edx, [esp+ecx*2+2E4h+tmp_str3]
  .text:004012C7                 lea     eax, [esp+eax+2E4h+serbytes0]
  .text:004012CB                 push    edx             ; s2
  .text:004012CC                 push    eax             ; s1
  .text:004012CD                 call    sub_401320      ; 关键函数2
  .text:004012D2                 mov     eax, esi
  .text:004012D4                 add     esp, 0Ch
  .text:004012D7                 cmp     eax, 3
  .text:004012DA                 jl      short loc_401297
  .text:004012DC                 mov     ecx, 4
  .text:004012E1                 lea     edi, [esp+2E0h+tmp_str0] ; 比较注册码前16个字符
  .text:004012E5                 lea     esi, [esp+2E0h+serbytes0]
  .text:004012E9                 xor     edx, edx
  .text:004012EB                 repe cmpsd
  .text:004012ED                 jz      short loc_4012FB
  .text:004012EF                 pop     edi
  .text:004012F0                 pop     esi
  .text:004012F1                 xor     eax, eax
  .text:004012F3                 pop     ebx
  .text:004012F4                 add     esp, 2D4h
  .text:004012FA                 retn
  .text:004012FB ; ---------------------------------------------------------------------------
  .text:004012FB
  .text:004012FB loc_4012FB:                             ; CODE XREF: OnCheck+2EDj
  .text:004012FB                 mov     ecx, 4
  .text:00401300                 lea     edi, [esp+2E0h+tmp_str1] ; 比较注册码后16个字符
  .text:00401304                 lea     esi, [esp+2E0h+serbytes1]
  .text:00401308                 xor     eax, eax
  .text:0040130A                 repe cmpsd
  .text:0040130C                 pop     edi
  .text:0040130D                 pop     esi
  .text:0040130E                 setz    al
  .text:00401311                 pop     ebx
  .text:00401312                 add     esp, 2D4h
  .text:00401318                 retn
  .text:00401318 OnCheck         endp
  .text:00401318
  .text:00401318 ; ---------------------------------------------------------------------------
  .text:00401319                 align 10h
  .text:00401320
  .text:00401320 ; =============== S U B R O U T I N E =======================================
  .text:00401320
  .text:00401320
  .text:00401320 ; int __cdecl sub_401320(char *s1,char *s2,char *s3)
  .text:00401320 sub_401320      proc near               ; CODE XREF: OnCheck+2CDp
  .text:00401320
  .text:00401320 var_50          = dword ptr -50h
  .text:00401320 var_4B          = dword ptr -4Bh
  .text:00401320 var_47          = dword ptr -47h
  .text:00401320 var_43          = word ptr -43h
  .text:00401320 var_41          = byte ptr -41h
  .text:00401320 var_40          = byte ptr -40h
  .text:00401320 hash_context2   = dword ptr -20h
  .text:00401320 s1              = dword ptr  4
  .text:00401320 s2              = dword ptr  8
  .text:00401320 s3              = dword ptr  0Ch
  .text:00401320
  .text:00401320                 sub     esp, 50h
  .text:00401323                 push    ebx
  .text:00401324                 push    esi
  .text:00401325                 push    edi
  .text:00401326                 xor     dl, dl
  .text:00401328                 mov     ecx, 7
  .text:0040132D                 xor     eax, eax
  .text:0040132F                 lea     edi, [esp+1Dh]
  .text:00401333                 mov     [esp+5Ch+var_40], dl
  .text:00401337                 rep stosd
  .text:00401339                 stosw
  .text:0040133B                 mov     ecx, [esp+5Ch+s1]
  .text:0040133F                 mov     byte ptr [esp+5Ch+var_50], dl
  .text:00401343                 stosb
  .text:00401344                 xor     eax, eax
  .text:00401346                 push    16              ; size_t
  .text:00401348                 mov     [esp+60h+var_50+1], eax
  .text:0040134C                 lea     edx, [esp+60h+var_40]
  .text:00401350                 mov     [esp+60h+var_4B], eax
  .text:00401354                 push    ecx             ; char *
  .text:00401355                 mov     [esp+64h+var_47], eax
  .text:00401359                 push    edx             ; char *
  .text:0040135A                 mov     [esp+68h+var_43], ax
  .text:0040135F                 mov     [esp+68h+var_41], al
  .text:00401363                 call    _strncpy
  .text:00401368                 mov     eax, [esp+68h+s2]
  .text:0040136C                 push    6               ; size_t
  .text:0040136E                 lea     ecx, [esp+6Ch+var_40]
  .text:00401372                 push    eax             ; char *
  .text:00401373                 push    ecx             ; char *
  .text:00401374                 call    _strncat
  .text:00401379                 lea     edx, [esp+74h+hash_context2]
  .text:0040137D                 push    edx             ; ctx
  .text:0040137E                 call    hash_init
  .text:00401383                 lea     eax, [esp+78h+var_40]
  .text:00401387                 push    32              ; len
  .text:00401389                 lea     ecx, [esp+7Ch+hash_context2]
  .text:0040138D                 push    eax             ; cstr
  .text:0040138E                 push    ecx             ; ctx
  .text:0040138F                 call    hash_update
  .text:00401394                 lea     edx, [esp+84h+hash_context2]
  .text:00401398                 lea     eax, [esp+84h+var_50]
  .text:0040139C                 push    edx             ; ctx
  .text:0040139D                 push    eax             ; cstr
  .text:0040139E                 call    hash_final
  .text:004013A3                 mov     eax, [esp+8Ch+s3]
  .text:004013AA                 lea     ecx, [esp+8Ch+var_50]
  .text:004013AE                 add     esp, 30h
  .text:004013B1                 sub     ecx, eax
  .text:004013B3                 mov     esi, 16
  .text:004013B8
  .text:004013B8 loc_4013B8:                             ; CODE XREF: sub_401320+A3j
  .text:004013B8                 mov     dl, [ecx+eax]
  .text:004013BB                 mov     bl, [eax]
  .text:004013BD                 xor     bl, dl
  .text:004013BF                 mov     [eax], bl
  .text:004013C1                 inc     eax
  .text:004013C2                 dec     esi
  .text:004013C3                 jnz     short loc_4013B8
  .text:004013C5                 pop     edi
  .text:004013C6                 pop     esi
  .text:004013C7                 pop     ebx
  .text:004013C8                 add     esp, 50h
  .text:004013CB                 retn
  .text:004013CB sub_401320      endp
  .text:004013CB
  
  
  注册码验证过程:
  1、将用户名、组织、以及用户名和组织的逆串连接起来的字符串分别进行hash运算,得到以下4个字符串。
  s0 = hash(name); s1 = hash(group); s2 = hash(name+ rev(group)); s3 = s2的前12个字符。
  2、检查注册码是否是由64个16进制字符组成,先将它转化为大写,然后将它转化为由32个字节组成的字节串。
  ser_code = str2bytes(serial);
  3、调用函数sub_401320对s3和ser_code进行操作,要调用3次,主要操作是按字节进行异或。
          sub_401320( ser_code, s3, ser_code + 16 );
          sub_401320( ser_code + 16, s3 + 6, ser_code );
          sub_401320( ser_code, s3, ser_code + 16 );
  4、对最后得到的ser_code,如果其前16个字节与s0相同,且后16个字节与s1相同,则注册成功。
  
  函数void  sub_401320( char *s1, char *s2, char *s3 )的操作很简单,取s1的前16个字节和s2的前6个字节,
  进行hash运算,将得到的字符串与s3按字节异或,结果保存到s3中。
  由于异或2次就还原了,所以连续以同样的参数调用sub_401320两次,将不改变s3的值。
  
  可以看出整个验证过程还是比较简单的。
  生成注册码的过程:
  1、将用户名、组织、以及用户名和组织的逆串连接起来的字符串分别进行hash运算,得到以下4个字符串。
  s0 = hash(name); s1 = hash(group); s2 = hash(name+ rev(group)); s3 = s2的前12个字符。
  2、将s0和s1连接起来,构成注册码的初始值,其中s0和s1都是16字节,注册码是32字节。
  ser_code = s0 + s1;
  3、按与验证过程相反的顺序调用函数sub_401320对s3和ser_code进行操作,要调用3次。
          sub_401320( ser_code, tmp_str3, ser_code + 16 );
          sub_401320( ser_code + 16, tmp_str3 + 6, ser_code );
          sub_401320( ser_code, tmp_str3, ser_code + 16 );
  4、将得到的注册码ser_code串转化为其16进制字符串,此即为最终的注册码,长度为64字节。
  
  修改过的hash算法还原比较困难,直接从IDA中提取汇编代码更省事。
  对于与MD5非常类似的hash算法,提取汇编代码的技术已经很成熟,有很多帖子已经详细讲过了,这里就不赘述。
  
  
  以下是一组正确的注册码:
      name:  ylp1332
     group:  abcdefg
    serial:  F7C2C090A074CA0D093842B2D482CF5140E5DAFA3C9E6CAC483830FF4C78FD90
  
  
  以下是keygen的主要代码,不含hash算法的汇编代码。
  在visual c++ 6 with sp6 下编译通过。
  
  /* keygen.c  注册机源码 */
  
  #include <stdio.h>
  #include <string.h>
  
  #define MAXLEN 49
  
  #define HASH_DIGEST_SIZE 16
  typedef unsigned long uint32;
  typedef struct {
          uint32 state[4];
          uint32 count[2];
          unsigned char buffer[64];
  } hash_context;
  void hash_init( hash_context *ctx );
  void hash_update( hash_context *ctx, unsigned char *cstr, unsigned int len );
  void hash_final( unsigned char *cstr, hash_context *ctx );
  
  void bytes2str( unsigned char *in, unsigned int len, unsigned char *out )
  {
          unsigned int i, x, y;
          for( i=0; i<len; i++)
          {
                  y = in[i] >> 4;
                  y += 0x30;
                  if( y > 0x39 )  y += 0x07;
                  x = in[i] & 0x0F;
                  x += 0x30;
                  if( x > 0x39 )  x += 0x07;
                  out[ i << 1 ] = y;
                  out[ (i << 1) + 1 ] = x;
          }
          out[ len << 1 ] = 0x00;
  }
  
  void  sub_401320( char *s1, char *s2, char *s3 )
  {
          int i;
          char buf[ MAXLEN ] = {0};
          char out[ MAXLEN ] = {0};
          hash_context hash_ctx;
  
          strncpy( buf, s1, 16 );
          strncat( buf, s2, 6 );
  
          hash_init( &hash_ctx );
          hash_update( &hash_ctx, buf, 32 );
          hash_final( out, &hash_ctx );
  
          for( i=0; i<16; i++)        s3[i] ^= out[i];
  }
  
  int main(int argc, char **argv)
  {
          char usr_name[ MAXLEN ] = {0};
          char grp_name[ MAXLEN ] = {0};
          char ser_code[ MAXLEN ] = {0};
          char tmp_str0[ MAXLEN ] = {0};
          char tmp_str1[ MAXLEN ] = {0};
          char tmp_str2[ MAXLEN ] = {0};
          char tmp_str3[ MAXLEN ] = {0};
          char buf[ MAXLEN ] = {0};
          char serial[ MAXLEN*2 ] = {0};
  
          hash_context hash_ctx;
  
          // Your Name here, at least 2 chars !
          strcpy( usr_name, "ylp1332" );
          // Your Group here, at least 2 chars !
          strcpy( grp_name, "abcdefg" );
  
          printf("    name:  %s\n", usr_name );
          printf("   group:  %s\n", grp_name );
  
          hash_init( &hash_ctx );
          hash_update( &hash_ctx, usr_name, strlen(usr_name) );
          hash_final( tmp_str0, &hash_ctx );
  
          hash_init( &hash_ctx );
          hash_update( &hash_ctx, grp_name, strlen(grp_name) );
          hash_final( tmp_str1, &hash_ctx );
  
          strcpy( buf, usr_name );
          strcat( buf, _strrev(grp_name));
  
          hash_init( &hash_ctx );
          hash_update( &hash_ctx, buf, strlen(buf) );
          hash_final( tmp_str2, &hash_ctx );
  
          strncpy( tmp_str3, tmp_str2, 12 );
          strncpy( ser_code, tmp_str0, 16 );
          strncpy( ser_code + 16, tmp_str1, 16 );
  
          sub_401320( ser_code, tmp_str3, ser_code + 16 );
          sub_401320( ser_code + 16, tmp_str3 + 6, ser_code );
          sub_401320( ser_code, tmp_str3, ser_code + 16 );
  
          bytes2str( ser_code, 32, serial );
  
          printf("  serial:  %s\n", serial );
  
          return 0;
  }
  
  
--------------------------------------------------------------------------------
【经验总结】
  静态分析与动态调试相结合。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年12月17日 4:23:56


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (4)
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
2
好文章,支持!
2006-12-17 20:14
0
雪    币: 1946
活跃值: (248)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
3
HASH算法,LZ高高手
2006-12-17 20:22
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nsd
4
厉害,学习了!!!
2006-12-18 10:36
0
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
5
不邋,不邋。
恭喜,恭喜!
2006-12-19 19:06
0
游客
登录 | 注册 方可回帖
返回
//