首页
论坛
课程
招聘
[旧帖] [原创][申请激活码]某个crackme的详细分析 0.00雪花
2013-9-22 21:30 1696

[旧帖] [原创][申请激活码]某个crackme的详细分析 0.00雪花

2013-9-22 21:30
1696
对一个crackme的详细分析,该crackme 带有MD5算法,还有对Serial进行Base64Decode,大量的运算与比较。不知道有没有人分析过。好吧开始,我一直喜欢IDA,因为F8手指头会累
PS:你喷或者不喷,我就是菜鸟一个,经得起风雨。

IDA代码
.text:00401000 start           proc near
.text:00401000                 call    InitCommonControls
.text:00401005                 push    0               ; lpModuleName
.text:00401007                 call    GetModuleHandleA
.text:0040100C                 mov     hInstance, eax
.text:00401011                 push    0               ; dwInitParam
.text:00401013                 push    offset DialogFunc ; lpDialogFunc    //这里没什么说的
.text:00401018                 push    0               ; hWndParent
.text:0040101A                 push    offset TemplateName ; "MAIN_WINDOW"
.text:0040101F                 push    hInstance       ; hInstance
.text:00401025                 call    DialogBoxParamA
.text:0040102A                 push    0               ; uExitCode
.text:0040102C                 call    ExitProcess
.text:0040102C start           endp
.text:0040102C

.text:00401040 ; INT_PTR __stdcall DialogFunc(HWND, UINT, WPARAM, LPARAM)
.text:00401040 DialogFunc      proc near               ; DATA XREF: start+13o
.text:00401040
.text:00401040 serial          = dword ptr -800h
.text:00401040 Name            = byte ptr -400h
.text:00401040 hWnd            = dword ptr  8
.text:00401040 arg_4           = dword ptr  0Ch
.text:00401040 arg_8           = dword ptr  10h
.text:00401040
.text:00401040                 push    ebp
.text:00401041                 mov     ebp, esp
.text:00401043                 add     esp, 0FFFFF800h
.text:00401049                 push    ebx
.text:0040104A                 push    esi
.text:0040104B                 push    edi
.text:0040104C                 mov     eax, [ebp+arg_4]
.text:0040104F                 cmp     eax, 110h
.text:00401054                 jnz     short loc_40105B
.text:00401056                 jmp     loc_4010FF
.text:0040105B ; ---------------------------------------------------------------------------
.text:0040105B loc_40105B:                             ; CODE XREF: DialogFunc+14j
.text:0040105B                 cmp     eax, 111h
.text:00401060                 jnz     loc_4010F0
.text:00401066                 mov     eax, [ebp+arg_8]
.text:00401069                 cmp     ax, 67h
.text:0040106D                 jnz     loc_4010FF
.text:00401073                 push    400h            ; cchMax
.text:00401078                 lea     eax, [ebp+Name]
.text:0040106D                 jnz     loc_4010FF
.text:00401073                 push    400h            ; cchMax
.text:00401078                 lea     eax, [ebp+Name]   ;name
.text:0040107E                 push    eax             ; lpString
.text:0040107F                 push    65h             ; nIDDlgItem
.text:00401081                 push    [ebp+hWnd]      ; hDlg
.text:00401084                 call    GetDlgItemTextA
.text:00401089                 push    400h            ; cchMax
.text:0040108E                 lea     eax, [ebp+serial]   ;注册码
.text:00401094                 push    eax             ; lpString
.text:00401095                 push    66h             ; nIDDlgItem
.text:00401097                 push    [ebp+hWnd]      ; hDlg
.text:0040109A                 call    GetDlgItemTextA
.text:0040109F                 lea     eax, [ebp+serial]
.text:004010A5                 push    eax             ; serial
.text:004010A6                 lea     eax, [ebp+Name]
.text:004010AC                 push    eax             ; Name
.text:004010AD                 push    [ebp+hWnd]      ; hWnd
.text:004010B0                 call    CheckSerialFunc    ;重要Call
.text:004010B5                 cmp     eax, 1          ; 关键跳 爆破点
.text:004010B8                 jnz     short loc_4010C6
.text:004010BA                 mov     edx, offset Text ; "Serial is OK!"
.text:004010BF                 mov     ecx, 40h
.text:004010C4                 jmp     short loc_4010DF
.text:004010C6 ; ---------------------------------------------------------------------------
.text:004010C6 loc_4010C6:                             ; CODE XREF: DialogFunc+78j
.text:004010C6                 or      eax, eax
.text:004010C8                 jnz     short loc_4010D6
.text:004010CA                 mov     edx, offset aWrongSerial ; "Wrong Serial"
.text:004010CF                 mov     ecx, 40h
.text:004010D4                 jmp     short loc_4010DF
.text:004010D6 ; ---------------------------------------------------------------------------
.text:004010D6 loc_4010D6:                             ; CODE XREF: DialogFunc+88j
.text:004010D6                 xor     eax, eax
.text:004010D8                 pop     edi
.text:004010D9                 pop     esi
.text:004010DA                 pop     ebx
.text:004010DB                 leave
.text:004010DC                 retn    10h
.text:004010DF ; ---------------------------------------------------------------------------
.text:004010DF loc_4010DF:                             ; CODE XREF: DialogFunc+84j
.text:004010DF                                         ; DialogFunc+94j
.text:004010DF                 push    ecx             ; uType
.text:004010E0                 push    offset Caption  ; "Hey Cracker"
.text:004010E5                 push    edx             ; lpText
.text:004010E6                 push    [ebp+hWnd]      ; hWnd
.text:004010E9                 call    MessageBoxA
.text:004010EE                 jmp     short loc_4010FF
.text:004010F0 ; ---------------------------------------------------------------------------
.text:004010F0 loc_4010F0:                             ; CODE XREF: DialogFunc+20j
.text:004010F0                 cmp     eax, 10h
.text:004010F3                 jnz     short loc_4010FF
.text:004010F5                 push    0               ; nResult
.text:004010F7                 push    [ebp+hWnd]      ; hDlg
.text:004010FA                 call    EndDialog
.text:004010FF
.text:004010FF loc_4010FF:                             ; CODE XREF: DialogFunc+16j
.text:004010FF                                         ; DialogFunc+2Dj ...
.text:004010FF                 xor     eax, eax
.text:00401101                 pop     edi
.text:00401102                 pop     esi
.text:00401103                 pop     ebx
.text:00401104                 leave
.text:00401105                 retn    10h
.text:00401105 DialogFunc      endp

现在对CheckSerialFunc函数进行分析,如下(变量我都改了,大家就讲究的看吧,好吧):

 ; int __stdcall CheckSerialFunc(HWND hWnd, LPCSTR Name, int serial)
.text:00401108 CheckSerialFunc proc near               ; CODE XREF: DialogFunc+70p
.text:00401108
.text:00401108 newarry1[]      = byte ptr -21Ch
.text:00401108 newarry3[]      = byte ptr -11Ch
.text:00401108 newarry2[]      = byte ptr -1Ch
.text:00401108 newarry[]       = byte ptr -14h
.text:00401108 len_name        = dword ptr -4
.text:00401108 hWnd            = dword ptr  8
.text:00401108 Name            = dword ptr  0Ch
.text:00401108 serial          = dword ptr  10h
.text:00401108
.text:00401108                 push    ebp
.text:00401109                 mov     ebp, esp
.text:0040110B                 add     esp, 0FFFFFDE4h
.text:00401111                 push    [ebp+Name]      ; lpString
.text:00401114                 call    lstrlenA
.text:00401119                 or      eax, eax
.text:0040111B                 jnz     short loc_401137
.text:0040111D                 push    30h             ; uType
.text:0040111F                 push    0               ; lpCaption
.text:00401121                 push    offset aNoNameEntered ; "no name entered"
.text:00401126                 push    [ebp+hWnd]      ; hWnd
.text:00401129                 call    MessageBoxA
.text:0040112E                 mov     eax, 0FFFFFFFFh
.text:00401133                 leave
.text:00401134                 retn    0Ch
.text:00401137 ; ---------------------------------------------------------------------------
.text:00401137 loc_401137:                             ; CODE XREF: CheckSerialFunc+13j
.text:00401137                 mov     [ebp+len_name], eax
.text:0040113A                 push    [ebp+serial]    ; lpString
.text:0040113D                 call    lstrlenA
.text:00401142                 or      eax, eax
.text:00401144                 jnz     short loc_401160 
.text:00401146                 push    30h             ; uType
.text:00401148                 push    0               ; lpCaption
.text:0040114A                 push    offset aNoSerialEntere ; "no serial entered"
.text:0040114F                 push    [ebp+hWnd]      ; hWnd
.text:00401152                 call    MessageBoxA
.text:00401157                 mov     eax, 0FFFFFFFFh
.text:0040115C                 leave
.text:0040115D                 retn    0Ch
.text:00401160 ; ---------------------------------------------------------------------------
.text:00401160 loc_401160:                             ; CODE XREF: CheckSerialFunc+3Cj
.text:00401160                 call    usefull_var_init ; 变量初始化
.text:00401165                 push    offset String2  ; "-diablo2oo2"
.text:0040116A                 push    [ebp+Name]      ; lpString1
.text:0040116D                 call    lstrcatA        ; 链接固定字符串
.text:00401172               add     [ebp+len_name], 0Bh ; len_name+固定字符串的长度,以后len_name就是加上0bh的长度
.text:00401176                 push    [ebp+len_name]  ;len_name
.text:00401179                 push    [ebp+Name]    ;Name
.text:0040117C                call    NameFunc  ; 判断len_name 将name复制给数组 use_byarry_16
.text:00401181                 call    GetNewUse_key   ; 获得新的use_key[]
.text:00401186                 mov     ecx, eax        ; ecx = eax = use_key[]
.text:00401188                 lea     eax, [ebp+newarry[]]
.text:0040118B                 push    eax             ; 新数组,用于接收新数据
.text:0040118C                 push    ecx             ; new_use_key[]
.text:0040118D                 call    ChangeArray     ; 经过一系列运算,复制给新数组newarry[]
.text:00401192                 lea     eax, [ebp+newarry1[]] ; 传递地址 newarry1[] = newarry[]
.text:00401198                 push    eax             ; 新数组newarry1[]
.text:00401199                 push    [ebp+serial]    ; serial
.text:0040119C                 call    SerialFunc      ; 对serial进行运算 和base64运算很相似,
.text:004011A1                 push    8
.text:004011A3                 lea     eax, [ebp+newarry2[]]
.text:004011A6                 push    eax
.text:004011A7                 lea     eax, [ebp+newarry[]]
.text:004011AA                 push    eax
.text:004011AB                 call    ChangeArray1    ; 对newarry[]进行运算赋值给newarry2[]  8为循环数
.text:004011B0                 lea     eax, [ebp+newarry2[]]
.text:004011B3                 push    eax
.text:004011B4                 lea     eax, [ebp+newarry1[]]
.text:004011BA                 push    eax
.text:004011BB                 call    MMXcode      ; 浮点运算 结果放在newarry2[]
.text:004011C0                 push    80h
.text:004011C5                 lea     eax, [ebp+newarry3[]]
.text:004011CB                 push    eax
.text:004011CC                 lea     eax, [ebp+newarry1[]]
.text:004011D2                 push    eax
.text:004011D3                 call    ChangeArray2      ; 对newarry1[]进行运算赋值给newarry3[]  80h为循环数
.text:004011D8                 lea     eax, [ebp+newarry[]]
.text:004011DB                 push    eax
.text:004011DC                 lea     eax, [ebp+newarry3[]]
.text:004011E2                 push    eax
.text:004011E3                 call    cmpArray       ; newarry[]与newarry3[]运算后的相比较,必须相等   eax = 0 证明不同,反之相等
.text:004011E8                 or      eax, eax
.text:004011EA                 jnz     short loc_4011F2 ; 不等于0跳走
.text:004011EC                 xor     eax, eax        ; 等于0 ,清空eax,就完蛋
.text:004011EE                 leave
.text:004011EF                 retn    0Ch
.text:004011F2 ; ---------------------------------------------------------------------------
.text:004011F2
.text:004011F2 loc_4011F2:                             ; CODE XREF: CheckSerialFunc+E2j
.text:004011F2                 lea     eax, [ebp+newarry3[]]
.text:004011F8                 push    eax
.text:004011F9                 call    check_serialFunc ; 再次验证一次
.text:004011FE                 or      eax, eax        ; eax == 0 ?
.text:00401200                 jnz     short loc_401208 ; 不等于跳走
.text:00401202                 xor     eax, eax
.text:00401204                 leave
.text:00401205                 retn    0Ch
.text:00401208 ; ---------------------------------------------------------------------------
.text:00401208
.text:00401208 loc_401208:                             ; CODE XREF: CheckSerialFunc+F8j
.text:00401208                 mov     eax, 1          ; 赋值eax = 1,就是成功
.text:0040120D                 leave
.text:0040120E                 retn    0Ch
.text:0040120E CheckSerialFunc endp

一、usefull_var_init函数进行分析,如下

.text:00404828 usefull_var_init proc near              ; CODE XREF: CheckSerialFunc:loc_401160p
.text:00404828                                         ; check_serialFunc+5Dp ...
.text:00404828                 push    edi
.text:00404829                 xor     eax, eax
.text:0040482B                 mov     dwFlag1, eax     ;标志 后面会用到,赋值 0 
.text:00404830                 xor     eax, eax
.text:00404832                 mov     dwFlag2, eax     ;标志 后面会用到,赋值 0 
.text:00404837                 mov     edi, offset use_byarry_16_ 
.text:0040483C                 mov     ecx, 10h
.text:00404841                 rep stosd     ;将数组use_byarry_16初始化
.text:00404843                 mov     eax, offset use_key__   ;将use_key[]赋值{1,2,3,,,D,E,F}
.text:00404848                 mov     dword ptr [eax], 67452301h
.text:0040484E                 mov     dword ptr [eax+4], 0EFCDAB89h
.text:00404855                 mov     dword ptr [eax+8], 98BADCFEh
.text:0040485C                 mov     dword ptr [eax+0Ch], 10325476h
.text:00404863                 pop     edi
.text:00404864                 retn
.text:00404864 usefull_var_init endp
C代码解释
{
  dwFlag1 = 0;
  dwFlag2 = 0;
  memset(&use_byarry_16_, 0, 0x40u);
  use_key__[0] = 67452301h;
  use_key__[1] = -0EFCDAB89h;
  use_key__[2] = -98BADCFEh;
  use_key__[3] = 10325476h;
}

二、对NameFunc进行分析,分析如下

text:00404868 NameFunc        proc near               ; CODE XREF: CheckSerialFunc+74p
.text:00404868                                         ; check_serialFunc+65p ...
.text:00404868
.text:00404868 name            = dword ptr  8
.text:00404868 len_name        = dword ptr  0Ch
.text:00404868
.text:00404868                 push    ebp
.text:00404869                 mov     ebp, esp
.text:0040486B                 push    esi
.text:0040486C                 push    edi
.text:0040486D                 push    ebx
.text:0040486E                 mov     ebx, [ebp+len_name]
.text:00404871                 mov     esi, [ebp+name]
.text:00404874                 add     dwFlag1, ebx    ; len_name
.text:0040487A                 jmp     short loc_4048BC ; len_name = 0?
.text:0040487C ; ---------------------------------------------------------------------------
.text:0040487C
.text:0040487C loc_40487C:                             ; CODE XREF: NameFunc+56j
.text:0040487C                 mov     eax, dwFlag2    ; (dwFlag1 = 0初始化时)赋值给ecx
.text:00404881                 mov     ecx, 40h
.text:00404886                 sub     ecx, eax        ; ecx = 40h - dwFlag2
.text:00404888                 lea     edi, use_byarry_16_[eax] ; 传递数组地址
.text:0040488E                 cmp     ecx, ebx        ; ecx值与len_name比较大于就跳走
.text:00404890                 ja      short loc_4048B0 ; ecx赋值给ecx
.text:00404892                 sub     ebx, ecx        ; 小于情况  len_name - ecx
.text:00404894                 rep movsb               ; esi->edi esi为name 传递给use_byarry_16_数组
.text:00404896                 call    MD5_HashFunc    ; 大于情况   MD5_hash 算法,利用新的use_byarry_16 获取新的use_key
.text:0040489B                 xor     eax, eax
.text:0040489D                 mov     dwFlag2, eax
.text:004048A2                 mov     edi, offset use_byarry_16_
.text:004048A7                 mov     ecx, 10h
.text:004048AC                 rep stosd  ;; esi->edi esi为name 传递给use_byarry_16_数组
.text:004048AE                 jmp     short loc_4048BC ; len_name = 0?
.text:004048B0 ; ---------------------------------------------------------------------------
.text:004048B0
.text:004048B0 loc_4048B0:                             ; CODE XREF: NameFunc+28j
.text:004048B0                 mov     ecx, ebx        ; ecx赋值给ecx
.text:004048B2                 rep movsb               ; esi->edi esi为name 传递给use_byarry_16_数组
.text:004048B4                 add     dwFlag2, ebx    ; dwFlag2+len_name
.text:004048BA                 jmp     short loc_4048C0
.text:004048BC ; ---------------------------------------------------------------------------
.text:004048BC
.text:004048BC loc_4048BC:                             ; CODE XREF: NameFunc+12j
.text:004048BC                                         ; NameFunc+46j
.text:004048BC                 or      ebx, ebx        ; len_name = 0?
.text:004048BE                 jnz     short loc_40487C ; (dwFlag1 = 0初始化时)赋值给ecx
.text:004048C0
.text:004048C0 loc_4048C0:                             ; CODE XREF: NameFunc+52j
.text:004048C0                 pop     ebx
.text:004048C1                 pop     edi
.text:004048C2                 pop     esi
.text:004048C3                 leave
.text:004048C4                 retn    8
.text:004048C4 NameFunc        endp
小于的时候,很简单就如下
If(40h - (dwFalg1+len_name) )
{
Use_bayarry_16 = name
dwFalg2+= len_name
}
IDA F5出来的好像很正确,嘿嘿
  v2 = len_name;
  v3 = name;
  dwFlag1 += len_name;
  while ( v2 )
  {
    result = dwFlag2;
    v5 = 64 - dwFlag2;
    v6 = &use_byarry_16_[dwFlag2];
    if ( 64 - dwFlag2 > v2 )
    {
      memcpy(v6, v3, v2);
      dwFlag2 += v2;
      return result;
    }
    v2 -= v5;
    memcpy(v6, v3, v5);
    v3 = (char *)v3 + v5;
    MD5_HashFunc();
    result = 0;
    dwFlag2 = 0;
    memset(use_byarry_16_, 0, 0x40u);
  }
  return result;

三 、对GetNewUse_key 进行分析

.text:004048C8 GetNewUse_key   proc near               ; CODE XREF: CheckSerialFunc+79p
.text:004048C8                                         ; check_serialFunc+6Ap ...
.text:004048C8                 push    esi
.text:004048C9                 push    edi
.text:004048CA                 mov     ecx, dwFlag2    ; Flag2 = len_name
.text:004048D0                 mov     use_byarry_16_[ecx], 80h ; 数组最后一位 +1 赋值 80h 应该是标记
.text:004048D7                 cmp     ecx, 38h        ; 再次判断len_name > 38h ?小于跳走
.text:004048DA                 jb      short loc_4048F4 ; 此时Flag1 = len_name
.text:004048DC                 call    MD5_HashFunc    ;MD5
.text:004048E1                 xor     eax, eax
.text:004048E3                 mov     dwFlag2, eax
.text:004048E8                 mov     edi, offset use_byarry_16_
.text:004048ED                 mov     ecx, 10h
.text:004048F2                 rep stosd
.text:004048F4
.text:004048F4 loc_4048F4:                             ; CODE XREF: GetNewUse_key+12j
.text:004048F4                 mov     eax, dwFlag1    ; 此时Flag1 = len_name
.text:004048F9                 xor     edx, edx        ; 清空edx
.text:004048FB                 shld    edx, eax, 3     ; 双精度左移位指令
.text:004048FF                 shl     eax, 3          ; 左移3
.text:00404902                 mov     dwVar1, eax     ; 赋值给变量
.text:00404907                 mov     dwVar2, edx     ; 赋值给变量
.text:0040490D                 call    MD5_HashFunc    ; MD5算法 得到新的use_key[]
.text:00404912                 mov     eax, offset use_key__ ; 得到新的use_key 复制给 eax
.text:00404917                 pop     edi
.text:00404918                 pop     esi
.text:00404919                 retn
.text:00404919 GetNewUse_key   endp

上个函数 dwFlag2已将赋值
{
  
  unsigned __int64 v2; // kr08_8@3

  use_byarry_16_[dwFlag2] = -128;
  if ( dwFlag2>= 0x38 )
  {
    MD5_HashFunc();
    dwFlag2 = 0;
    memset(use_byarry_16_, 0, 0x40u);
  }
  mov     eax, dwFlag1 
  xor     edx, edx
  shld    edx, eax, 3
  shl     eax, 3
  mov     dwVar1, eax
  mov     dwVar2, edx 
  MD5_HashFunc();
  mov     eax, offset use_key__
}
最后返回的是改变后的use_key,use_key 是数组,返回的也就是首地址


四、ChangeArray函数进行分析

..text:0040153B ChangeArray     proc near               ; CODE XREF: CheckSerialFunc+85p
.text:0040153B
.text:0040153B var_2           = byte ptr -2
.text:0040153B var_1           = byte ptr -1
.text:0040153B use_key[]       = dword ptr  8
.text:0040153B newarry[]       = dword ptr  0Ch
.text:0040153B
.text:0040153B                 push    ebp
.text:0040153C                 mov     ebp, esp
.text:0040153E                 add     esp, 0FFFFFFFCh
.text:00401541                 push    esi
.text:00401542                 push    edi
.text:00401543                 push    ebx
.text:00401544                 mov     esi, [ebp+use_key[]]
.text:00401547                 mov     edi, [ebp+newarry[]]
.text:0040154A                 xor     ecx, ecx        ; 清空ecx
.text:0040154C                 jmp     short loc_401552 ;  for(i = 0;i!= 16; ++i)
.text:0040154E ; ---------------------------------------------------------------------------
.text:0040154E
.text:0040154E loc_40154E:                             ; CODE XREF: ChangeArray+1Aj
.text:0040154E                 mov     [ecx+edi], cl   ;对newaarry进行赋值
.text:00401551                 inc     ecx
.text:00401552
.text:00401552 loc_401552:                             ; CODE XREF: ChangeArray+11j
.text:00401552                 cmp     ecx, 10h        ; 循环控制 = 10h??
.text:00401555                 jnz     short loc_40154E ; 最后填充newarry[] = {1,2,3...D,E,F}
.text:00401557                 mov     [ebp+var_2], 0  ; 赋值0
.text:0040155B                 jmp     short loc_40158E 
.text:0040155D ; ---------------------------------------------------------------------------
.text:0040155D
.text:0040155D loc_40155D:                             ; CODE XREF: ChangeArray+57j
.text:0040155D                 xor     ecx, ecx        ; ecx清零
.text:0040155F                 jmp     short loc_401586
.text:00401561 ; ---------------------------------------------------------------------------
.text:00401561
.text:00401561 loc_401561:                             ; CODE XREF: ChangeArray+4Ej
.text:00401561                 movzx   eax, byte ptr [ecx+esi] ; 取每一位
.text:00401565                 mov     edx, eax
.text:00401567                 and     al, 0Fh         ; + 0Fh
.text:00401569                 shr     dl, 4           ; 右移 4位
.text:0040156C                 mov     bl, [eax+edi]
.text:0040156F                 mov     [ebp+var_1], bl
.text:00401572                 mov     bl, [edx+edi]
.text:00401575                 mov     [eax+edi], bl
.text:00401578                 mov     bl, [ebp+var_1]
.text:0040157B                 mov     [edx+edi], bl
.text:0040157E                 add     [ecx+esi], bl
.text:00401581                 xor     byte ptr [ecx+esi], 17h ; ^= 0x17u
.text:00401585                 inc     ecx
.text:00401586
.text:00401586 loc_401586:                             ; CODE XREF: ChangeArray+24j
.text:00401586                 cmp     ecx, 10h
.text:00401589                 jnz     short loc_401561 ; 取每一位
.text:0040158B                 inc     [ebp+var_2]     ; ++
.text:0040158E
.text:0040158E loc_40158E:                             ; CODE XREF: ChangeArray+20j
.text:0040158E                 cmp     [ebp+var_2], 10h ; for(i = 0;i!= 16; ++i)
.text:0040158E                                         ; {
.text:0040158E                                         ; for(j = 0;j!= 16; ++j)
.text:0040158E                                         ; {
.text:0040158E                                         ; }
.text:0040158E                                         ; }
.text:00401592                 jnz     short loc_40155D ; ecx清零
.text:00401594                 pop     ebx
.text:00401595                 pop     edi
.text:00401596                 pop     esi
.text:00401597                 leave
.text:00401598                 retn    8
.text:00401598 ChangeArray     endp

C代码解释
 for ( i = 0; i != 16; ++i )
    newarry[i])= i;
for ( i = 0; i != 16; ++i)
  {
    for ( j= 0; j!= 16; ++j )
    {
      var4 =  use_key[i];
      var6 = var4;
      result = v4 & 0xF;
      var6 = var6 >> 4;
      v7 =  newarry[result ];
      newarry[result ])= +newarry[var6];
       newarry[v6] = v7;
      new_use_key[j] += v7;
      use_key[j] ^= 0x17u;
    }
  }


五、SerialFunc函数分析  serialFunc用是的Base64Decode运算,b64table 也就是byte_4060C0这个数组,网上资料应该也很多,这个就不做过多解释

text:00404920 SerialFunc      proc near               ; CODE XREF: CheckSerialFunc+94p
.text:00404920
.text:00404920 serial          = dword ptr  4
.text:00404920 newarry1[]      = dword ptr  8
.text:00404920
.text:00404920                 push    ebp
.text:00404921                 push    esi
.text:00404922                 push    edi
.text:00404923                 push    ebx
.text:00404924                 mov     edi, [esp+10h+serial]
.text:00404928                 xor     eax, eax        ; 清零
.text:0040492A                 mov     esi, edi        ; esi = serial
.text:0040492C
.text:0040492C loc_40492C:                             ; CODE XREF: SerialFunc+13j
.text:0040492C                 mov     al, [edi]       ; 每一位给al
.text:0040492E                 add     edi, 4
.text:00404931                 test    al, al          ; 判断是否为0?
.text:00404933                 jnz     short loc_40492C ; 等于O跳走
.text:00404935                 lea     ebp, [edi-4]    ; 最后一位
.text:00404938                 mov     eax, 3Dh
.text:0040493D                 sub     ebp, esi        ; 是否相等?
.text:0040493F                 jz      short loc_4049BF ; 等于跳走
.text:00404941                 cmp     al, [ebp+esi-1] ; 最后一位 ==   “=” ???
.text:00404945                 setz    dl              ; 设置dl
.text:00404948                 jnz     short loc_40494E ; 不等于就跳走
.text:0040494A                 mov     [ebp+esi-1], ah ; 倒数第1位 = ah = 0
.text:0040494E
.text:0040494E loc_40494E:                             ; CODE XREF: SerialFunc+28j
.text:0040494E                 cmp     al, [ebp+esi-2] ; 最后2位 ==   “=” ???
.text:00404952                 setz    al              ; 设置al
.text:00404955                 jnz     short loc_40495B ; 不等于跳走
.text:00404957                 mov     [ebp+esi-2], ah ; 倒数第2位 = ah = 0
.text:0040495B
.text:0040495B loc_40495B:                             ; CODE XREF: SerialFunc+35j
.text:0040495B                 add     al, dl          ; al+dl
.text:0040495D                 mov     edi, [esp+10h+newarry1[]]
.text:00404961                 shr     ebp, 2
.text:00404964                 lea     edx, [ebp+ebp*2+0]
.text:00404968                 sub     edx, eax
.text:0040496A                 push    edx
.text:0040496B
.text:0040496B loc_40496B:                             ; CODE XREF: SerialFunc+9Cj
.text:0040496B                 mov     ecx, [esi]
.text:0040496D                 movzx   edx, cl
.text:00404970                 movzx   ebx, ch
.text:00404973                 mov     al, byte_4060C0[edx]
.text:00404979                 mov     ah, byte_4060C0[ebx]
.text:0040497F                 shr     ecx, 10h
.text:00404982                 add     esi, 4
.text:00404985                 movzx   edx, cl
.text:00404988                 movzx   ecx, ch
.text:0040498B                 mov     bl, byte_4060C0[edx]
.text:00404991                 mov     bh, byte_4060C0[ecx]
.text:00404997                 mov     dl, ah
.text:00404999                 mov     dh, bl
.text:0040499B                 shl     al, 2
.text:0040499E                 shr     bl, 2
.text:004049A1                 shl     dh, 6
.text:004049A4                 shl     ah, 4
.text:004049A7                 shr     dl, 4
.text:004049AA                 or      bh, dh
.text:004049AC                 or      al, dl
.text:004049AE                 or      ah, bl
.text:004049B0                 mov     [edi], al
.text:004049B2                 mov     [edi+2], bh
.text:004049B5                 mov     [edi+1], ah
.text:004049B8                 dec     ebp
.text:004049B9                 lea     edi, [edi+3]
.text:004049BC                 jnz     short loc_40496B
.text:004049BE                 pop     eax
.text:004049BF
.text:004049BF loc_4049BF:                             ; CODE XREF: SerialFunc+1Fj
.text:004049BF                 pop     ebx
.text:004049C0                 pop     edi
.text:004049C1                 pop     esi
.text:004049C2                 pop     ebp
.text:004049C3                 retn    8
.text:004049C3 SerialFunc      endp

六、 ChangeArray1   函数分析
text:004014E5 ChangeArray1    proc near               ; CODE XREF: CheckSerialFunc+A3p
.text:004014E5
.text:004014E5 newarry[]       = dword ptr  8
.text:004014E5 newarry2[]      = dword ptr  0Ch
.text:004014E5 var_int8        = dword ptr  10h
.text:004014E5
.text:004014E5                 push    ebp
.text:004014E6                 mov     ebp, esp
.text:004014E8                 push    esi
.text:004014E9                 push    edi
.text:004014EA                 mov     esi, [ebp+newarry[]]
.text:004014ED                 mov     edi, [ebp+newarry2[]]
.text:004014F0                 xor     ecx, ecx        ; 清零
.text:004014F2                 jmp     short loc_401508 ; 参数8
.text:004014F4 ; ---------------------------------------------------------------------------
.text:004014F4
.text:004014F4 loc_4014F4:                             ; CODE XREF: ChangeArray1+26j
.text:004014F4                 mov     al, [esi]       ; newarry[i]给al
.text:004014F6                 mov     dl, [esi+1]     ; newarry[i+1]给dl
.text:004014F9                 shl     al, 4           ; 左移4位
.text:004014FC                 and     dl, 0Fh         ; 与0F异或
.text:004014FF                 add     al, dl          ; 相加
.text:00401501                 mov     [ecx+edi], al   ; newarry2[i]
.text:00401504                 add     esi, 2          ; newarry+2
.text:00401507                 inc     ecx             ; ++
.text:00401508
.text:00401508 loc_401508:                             ; CODE XREF: ChangeArray1+Dj
.text:00401508                 cmp     ecx, [ebp+var_int8] ; 参数8
.text:0040150B                 jnz     short loc_4014F4 ; newarry[i]给al
.text:0040150D                 pop     edi
.text:0040150E                 pop     esi
.text:0040150F                 leave
.text:00401510                 retn    0Ch
.text:00401510 ChangeArray1    endp


C代码解释:
  v4 = newarry[];
  for ( i = 0; i != 8; ++i )
  {
    result = (*(_BYTE *)(v4 + 1) & 0xF) + 16 * *(_BYTE *)v4;
    *(_BYTE *)(i + newarry2[]) = result;
    v4 += 2;
  }
  return result;
将运算的赋值给newarry2数组

MMXcode函数分析
   MMXcode         proc near               ; CODE XREF: CheckSerialFunc+B3p
  .text:00401513
  .text:00401513 newarry1[]      = dword ptr  8
  .text:00401513 newarry2[]      = dword ptr  0Ch
  .text:00401513
  .text:00401513                 push    ebp
  .text:00401514                 mov     ebp, esp
  .text:00401516                 mov     eax, [ebp+newarry2[]]
  .text:00401519                 movq    mm1, qword ptr [eax]
  .text:0040151C                 mov     edx, [ebp+newarry1[]]
  .text:0040151F                 xor     ecx, ecx
  .text:00401521                 jmp     short loc_401530
  .text:00401523 ; ---------------------------------------------------------------------------
  .text:00401523
  .text:00401523 loc_401523:                             ; CODE XREF: MMXcode+20j
  .text:00401523                 movq    mm0, qword ptr [edx]
  .text:00401526                 pxor    mm0, mm1
  .text:00401529                 movq    qword ptr [edx], mm0
  .text:0040152C                 add     edx, 8
  .text:0040152F                 inc     ecx
  .text:00401530
  .text:00401530 loc_401530:                             ; CODE XREF: MMXcode+Ej
  .text:00401530                 cmp     ecx, 10h
  .text:00401533                 jnz     short loc_401523
  .text:00401535                 emms
  .text:00401537                 leave
  .text:00401538                 retn    8
  .text:00401538 MMXcode         endp
  
对 newarry1[]进行浮点运算,扩展值放在newarry2里面


ChangeArray2 函数进行分析

text:004014B7 ChangeArray2    proc near               ; CODE XREF: CheckSerialFunc+CBp
.text:004014B7
.text:004014B7 newarry1[]      = dword ptr  8
.text:004014B7 newarry3[]      = dword ptr  0Ch
.text:004014B7 var_int80h      = dword ptr  10h
.text:004014B7
.text:004014B7                 push    ebp
.text:004014B8                 mov     ebp, esp
.text:004014BA                 push    esi
.text:004014BB                 push    edi
.text:004014BC                 mov     esi, [ebp+newarry1[]] ; 源地址
.text:004014BF                 mov     edi, [ebp+newarry3[]] ; 目的地址
.text:004014C2                 xor     ecx, ecx
.text:004014C4                 jmp     short loc_4014DA ; 参数三 80H次循环
.text:004014C6 ; ---------------------------------------------------------------------------
.text:004014C6
.text:004014C6 loc_4014C6:                             ; CODE XREF: ChangeArray2+26j
.text:004014C6                 movzx   eax, byte ptr [ecx+esi] ; newarry1[i]
.text:004014CA                 mov     edx, eax        ; 给edx
.text:004014CC                 and     al, 0Fh         ; al^0fh
.text:004014CE                 shr     dl, 4           ; 右移4位
.text:004014D1                 mov     [edi], dl       ; 给newarry3
.text:004014D3                 mov     [edi+1], al     ; 给newarry3[1]
.text:004014D6                 add     edi, 2          ; +2
.text:004014D9                 inc     ecx
.text:004014DA
.text:004014DA loc_4014DA:                             ; CODE XREF: ChangeArray2+Dj
.text:004014DA                 cmp     ecx, [ebp+var_int80h] ; 参数三 80H次循环
.text:004014DD                 jnz     short loc_4014C6 ; newarry1[i]
.text:004014DF                 pop     edi
.text:004014E0                 pop     esi
.text:004014E1                 leave
.text:004014E2                 retn    0Ch
.text:004014E2 ChangeArray2    endp

C代码解释   F5就是强悍
  v4 = newarry3[];
  for ( i = 0; i != 80h; ++i )
  {
    v6 =  newarry1[i];
    V5 = v6;
    *(_BYTE *)v4 = v6 >> 4;
    *(_BYTE *)(v4 + 1) = V5 & 0xF;
    v4 += 2;
  }
cmpArray 函数分析 newarry和运算后的newarry3比较

.text:00401486 cmpArray        proc near               ; CODE XREF: CheckSerialFunc+DBp
.text:00401486
.text:00401486 newarry3[]      = dword ptr  8
.text:00401486 newarry[]       = dword ptr  0Ch
.text:00401486
.text:00401486                 push    ebp
.text:00401487                 mov     ebp, esp
.text:00401489                 push    edi
.text:0040148A                 mov     edi, [ebp+newarry[]]
.text:0040148D                 xor     ecx, ecx
.text:0040148F                 jmp     short loc_4014A8 ; 10h次循环
.text:00401491 ; ---------------------------------------------------------------------------
.text:00401491
.text:00401491 loc_401491:                             ; CODE XREF: cmpArray+25j
.text:00401491                 push    ecx
.text:00401492                 push    ecx
.text:00401493                 push    [ebp+newarry3[]]
.text:00401496                 call    changevar      ; 函数运算为 eax = newarry3[] + ecx + 16 * ecx
.text:0040149B                 cmp     al, [ecx+edi]   ; 返回值放在eax里面 然后与newarry[]相比
.text:0040149E                 jz      short loc_4014A7 ; 相等再继续
.text:004014A0                 xor     eax, eax        ; 不等 清空eax
.text:004014A2                 pop     edi
.text:004014A3                 leave
.text:004014A4                 retn    8
.text:004014A7 ; ---------------------------------------------------------------------------
.text:004014A7
.text:004014A7 loc_4014A7:                             ; CODE XREF: cmpArray+18j
.text:004014A7                 inc     ecx
.text:004014A8
.text:004014A8 loc_4014A8:                             ; CODE XREF: cmpArray+9j
.text:004014A8                 cmp     ecx, 10h        ; 10h次循环
.text:004014AB                 jnz     short loc_401491
.text:004014AD                 mov     eax, 1
.text:004014B2                 pop     edi
.text:004014B3                 leave
.text:004014B4                 retn    8
.text:004014B4 cmpArray        endp


C代码解释
v3 = 0
  for ( i = 0; i != 16; i = v3 + 1 )
  {
    v4 = changevar(newarry3[], i, i);
    if ( v4 != *(_BYTE *)(v3 + newarry[]) )
      return 0;
  }
  return 1;

Changevar函数更简单
text:0040146E changevar       proc near               ; CODE XREF: check_serialFunc+42p
.text:0040146E                                         ; check_serialFunc+DEp ...
.text:0040146E
.text:0040146E newarry3[]      = dword ptr  8
.text:0040146E arg_4           = dword ptr  0Ch
.text:0040146E arg_8           = dword ptr  10h
.text:0040146E
.text:0040146E                 push    ebp
.text:0040146F                 mov     ebp, esp
.text:00401471                 mov     eax, 10h
.text:00401476                 mul     [ebp+arg_8]
.text:00401479                 add     eax, [ebp+arg_4]
.text:0040147C                 add     eax, [ebp+newarry3[]]   ;eax = newarry3[] + ecx + 16 * ecx
.text:0040147F                 movzx   eax, byte ptr [eax]
.text:00401482                 leave
.text:00401483                 retn    0Ch
.text:00401483 changevar       endp

十  check_serialFunc进行分析此函数为重要call,前面的运算各种运算得到newarry3作为参数传入。

text:00401211 check_serialFunc proc near              ; CODE XREF: CheckSerialFunc+F1p
.text:00401211
.text:00401211 var_118         = dword ptr -118h
.text:00401211 var_114         = dword ptr -114h
.text:00401211 var_110         = dword ptr -110h
.text:00401211 var_10C         = dword ptr -10Ch
.text:00401211 var_108         = dword ptr -108h
.text:00401211 var_104         = dword ptr -104h
.text:00401211 var_100         = byte ptr -100h
.text:00401211 newarry3[]      = dword ptr  8
.text:00401211
.text:00401211                 push    ebp
.text:00401212                 mov     ebp, esp
.text:00401214                 add     esp, 0FFFFFEE8h
.text:0040121A                 push    edi
.text:0040121B                 lea     edi, [ebp+var_100]
.text:00401221                 mov     [ebp+var_108], 0 ; var_108 赋值 0
.text:0040122B                 jmp     loc_4012B0      ; 10h 次循环
.text:00401230 ; ---------------------------------------------------------------------------
.text:00401230
.text:00401230 loc_401230:                             ; CODE XREF: check_serialFunc+A6j
.text:00401230                 push    10h
.text:00401232                 push    edi             ; 清空var_100
.text:00401233                 call    RtlZeroMemory
.text:00401238                 mov     [ebp+var_104], 0 ; var_104赋值 0
.text:00401242                 jmp     short loc_401265 ; 10h循环
.text:00401244 ; ---------------------------------------------------------------------------
.text:00401244
.text:00401244 loc_401244:                             ; CODE XREF: check_serialFunc+5Bj
.text:00401244                 push    [ebp+var_108]
.text:0040124A                 push    [ebp+var_104]
.text:00401250                 push    [ebp+newarry3[]]
.text:00401253                 call    changevar       ; 函数运算为 eax = newarry3[] + var_104 + 16 * var_108
.text:00401258                 cmp     al, 0Fh         ; al > 0Fh  ???
.text:0040125A                 ja      short loc_40125F ; 大于跳走
.text:0040125C                 mov     [eax+edi], al   ; 小于 将al给edi[eax]
.text:0040125F
.text:0040125F loc_40125F:                             ; CODE XREF: check_serialFunc+49j
.text:0040125F                 inc     [ebp+var_104]   ; ++
.text:00401265
.text:00401265 loc_401265:                             ; CODE XREF: check_serialFunc+31j
.text:00401265                 cmp     [ebp+var_104], 10h ; 10h循环
.text:0040126C                 jnz     short loc_401244
.text:0040126E                 call    usefull_var_init
.text:00401273                 push    10h
.text:00401275                 push    edi             ; 新的var_100[]数组
.text:00401276                 call    NameFunc
.text:0040127B                 call    GetNewUse_key
.text:00401280                 cmp     dword ptr [eax], 1EFC11Ah ; 获得的新的key与这固定的数组比较不等于就跳走就over 了
.text:00401286                 jnz     short loc_4012A3
.text:00401288                 cmp     dword ptr [eax+4], 1BAF6CE9h
.text:0040128F                 jnz     short loc_4012A3
.text:00401291                 cmp     dword ptr [eax+8], 3329D3E0h
.text:00401298                 jnz     short loc_4012A3
.text:0040129A                 cmp     dword ptr [eax+0Ch], 0A8C24F1Ah
.text:004012A1                 jz      short loc_4012AA ; ++
.text:004012A3
.text:004012A3 loc_4012A3:                             ; CODE XREF: check_serialFunc+75j
.text:004012A3                                         ; check_serialFunc+7Ej ...
.text:004012A3                 xor     eax, eax
.text:004012A5                 pop     edi
.text:004012A6                 leave
.text:004012A7                 retn    4
.text:004012AA ; ---------------------------------------------------------------------------
.text:004012AA
.text:004012AA loc_4012AA:                             ; CODE XREF: check_serialFunc+90j
.text:004012AA                 inc     [ebp+var_108]   ; ++
.text:004012B0
.text:004012B0 loc_4012B0:                             ; CODE XREF: check_serialFunc+1Aj
.text:004012B0                 cmp     [ebp+var_108], 10h ; 10h 次循环
.text:004012B7                 jnz     loc_401230
.text:004012BD                 mov     [ebp+var_104], 0 ; var_104 清零
.text:004012C7                 jmp     loc_40134C      ; 再来一次和上面的一样
.text:004012CC ; ---------------------------------------------------------------------------
.text:004012CC
.text:004012CC loc_4012CC:                             ; CODE XREF: check_serialFunc+142j
.text:004012CC                 push    10h
.text:004012CE                 push    edi
.text:004012CF                 call    RtlZeroMemory
.text:004012D4                 mov     [ebp+var_108], 0 ; 清零
.text:004012DE                 jmp     short loc_401301 ; 再来一次,和上面的一样
.text:004012E0 ; ---------------------------------------------------------------------------
.text:004012E0
.text:004012E0 loc_4012E0:                             ; CODE XREF: check_serialFunc+F7j
.text:004012E0                 push    [ebp+var_108]
.text:004012E6                 push    [ebp+var_104]
.text:004012EC                 push    [ebp+newarry3[]]
.text:004012EF                 call    changevar       ; 函数运算为 eax = newarry3[] + var_104 + 16 * var_108
.text:004012F4                 cmp     al, 0Fh
.text:004012F6                 ja      short loc_4012FB
.text:004012F8                 mov     [eax+edi], al
.text:004012FB
.text:004012FB loc_4012FB:                             ; CODE XREF: check_serialFunc+E5j
.text:004012FB                 inc     [ebp+var_108]
.text:00401301
.text:00401301 loc_401301:                             ; CODE XREF: check_serialFunc+CDj
.text:00401301                 cmp     [ebp+var_108], 10h
.text:00401308                 jnz     short loc_4012E0
.text:0040130A                 call    usefull_var_init
.text:0040130F                 push    10h
.text:00401311                 push    edi
.text:00401312                 call    NameFunc
.text:00401317                 call    GetNewUse_key
.text:0040131C                 cmp     dword ptr [eax], 1EFC11Ah
.text:00401322                 jnz     short loc_40133F
.text:00401324                 cmp     dword ptr [eax+4], 1BAF6CE9h
.text:0040132B                 jnz     short loc_40133F
.text:0040132D                 cmp     dword ptr [eax+8], 3329D3E0h
.text:00401334                 jnz     short loc_40133F
.text:00401336                 cmp     dword ptr [eax+0Ch], 0A8C24F1Ah
.text:0040133D                 jz      short loc_401346
.text:0040133F
.text:0040133F loc_40133F:                             ; CODE XREF: check_serialFunc+111j
.text:0040133F                                         ; check_serialFunc+11Aj ...
.text:0040133F                 xor     eax, eax
.text:00401341                 pop     edi
.text:00401342                 leave
.text:00401343                 retn    4
.text:00401346 ; ---------------------------------------------------------------------------
.text:00401346
.text:00401346 loc_401346:                             ; CODE XREF: check_serialFunc+12Cj
.text:00401346                 inc     [ebp+var_104]
.text:0040134C
.text:0040134C loc_40134C:                             ; CODE XREF: check_serialFunc+B6j
.text:0040134C                 cmp     [ebp+var_104], 10h ; 循环10h次
.text:00401353                 jnz     loc_4012CC
.text:00401359                 mov     [ebp+var_110], 0
.text:00401363                 jmp     loc_401457
.text:00401368 ; ---------------------------------------------------------------------------
.text:00401368
.text:00401368 loc_401368:                             ; CODE XREF: check_serialFunc+24Dj
.text:00401368                 mov     [ebp+var_10C], 0
.text:00401372                 jmp     loc_401444      ; 这次是循环4次
.text:00401377 ; ---------------------------------------------------------------------------
.text:00401377
.text:00401377 loc_401377:                             ; CODE XREF: check_serialFunc+23Aj
.text:00401377                 mov     [ebp+var_118], 0
.text:00401381                 push    10h
.text:00401383                 push    edi
.text:00401384                 call    RtlZeroMemory
.text:00401389                 jmp     short loc_4013F9 ; 这次是循环4次
.text:0040138B ; ---------------------------------------------------------------------------
.text:0040138B
.text:0040138B loc_40138B:                             ; CODE XREF: check_serialFunc+1EFj
.text:0040138B                 mov     [ebp+var_114], 0
.text:00401395                 jmp     short loc_4013EA ; 循环 4 次
.text:00401397 ; ---------------------------------------------------------------------------
.text:00401397
.text:00401397 loc_401397:                             ; CODE XREF: check_serialFunc+1E0j
.text:00401397                 mov     eax, [ebp+var_10C]
.text:0040139D                 mov     ecx, 4
.text:004013A2                 mul     ecx
.text:004013A4                 add     eax, [ebp+var_114]
.text:004013AA                 mov     [ebp+var_104], eax
.text:004013B0                 mov     eax, [ebp+var_110]
.text:004013B6                 mov     ecx, 4
.text:004013BB                 mul     ecx
.text:004013BD                 add     eax, [ebp+var_118]
.text:004013C3                 mov     [ebp+var_108], eax
.text:004013C9                 push    [ebp+var_108]
.text:004013CF                 push    [ebp+var_104]
.text:004013D5                 push    [ebp+newarry3[]]
.text:004013D8                 call    changevar       ; 函数运算为 eax = newarry3[] + var_104 + 16 * var_108
.text:004013DD                 cmp     al, 0Fh
.text:004013DF                 ja      short loc_4013E4
.text:004013E1                 mov     [eax+edi], al
.text:004013E4
.text:004013E4 loc_4013E4:                             ; CODE XREF: check_serialFunc+1CEj
.text:004013E4                 inc     [ebp+var_114]
.text:004013EA
.text:004013EA loc_4013EA:                             ; CODE XREF: check_serialFunc+184j
.text:004013EA                 cmp     [ebp+var_114], 4 ; 循环 4 次
.text:004013F1                 jnz     short loc_401397
.text:004013F3                 inc     [ebp+var_118]
.text:004013F9
.text:004013F9 loc_4013F9:                             ; CODE XREF: check_serialFunc+178j
.text:004013F9                 cmp     [ebp+var_118], 4 ; 这次是循环4次
.text:00401400                 jnz     short loc_40138B
.text:00401402                 call    usefull_var_init
.text:00401407                 push    10h
.text:00401409                 push    edi
.text:0040140A                 call    NameFunc
.text:0040140F                 call    GetNewUse_key
.text:00401414                 cmp     dword ptr [eax], 1EFC11Ah
.text:0040141A                 jnz     short loc_401437
.text:0040141C                 cmp     dword ptr [eax+4], 1BAF6CE9h
.text:00401423                 jnz     short loc_401437
.text:00401425                 cmp     dword ptr [eax+8], 3329D3E0h
.text:0040142C                 jnz     short loc_401437
.text:0040142E                 cmp     dword ptr [eax+0Ch], 0A8C24F1Ah
.text:00401435                 jz      short loc_40143E
.text:00401437
.text:00401437 loc_401437:                             ; CODE XREF: check_serialFunc+209j
.text:00401437                                         ; check_serialFunc+212j ...
.text:00401437                 xor     eax, eax
.text:00401439                 pop     edi
.text:0040143A                 leave
.text:0040143B                 retn    4
.text:0040143E ; ---------------------------------------------------------------------------
.text:0040143E
.text:0040143E loc_40143E:                             ; CODE XREF: check_serialFunc+224j
.text:0040143E                 inc     [ebp+var_10C]
.text:00401444
.text:00401444 loc_401444:                             ; CODE XREF: check_serialFunc+161j
.text:00401444                 cmp     [ebp+var_10C], 4 ; 这次是循环4次
.text:0040144B                 jnz     loc_401377
.text:00401451                 inc     [ebp+var_110]
.text:00401457
.text:00401457 loc_401457:                             ; CODE XREF: check_serialFunc+152j
.text:00401457                 cmp     [ebp+var_110], 4
.text:0040145E                 jnz     loc_401368
.text:00401464                 mov     eax, 1
.text:00401469                 pop     edi
.text:0040146A                 leave
.text:0040146B                 retn    4
.text:0040146B check_serialFunc endp

其实里面就是3个大循环,有规律,得到的use_key[]和固定的值相比较不相等就over,大量for循环
C源码看其真面目

char v16[256];
  for ( i = 0; i != 16; ++i )
  {
    RtlZeroMemory(v16, 16);
    for ( j = 0; j != 16; ++j )
    {
      v1 = changevar(newarry3[], j, i);
      if ( (_BYTE)v1 <= 0xFu )
        v16[v1] = v1;
    }
    usefull_var_init(); //初始化变量
    NameFunc(v16, 0x10u);  //获取 use_byarry_16数组
    v2 = GetNewUse_key();  //根据use_byarry_16数组 得到的use_key 和这些比较不相等就失败
    if ( *(_DWORD *)v2 != 1EFC11Ah
      || *(_DWORD *)(v2 + 4) != 1BAF6CE9h
      || *(_DWORD *)(v2 + 8) != 3329D3E0h
      || *(_DWORD *)(v2 + 12) != 0A8C24F1Ah )
      return 0;
  }
  for ( k = 0; k != 16; ++k )
  {
    RtlZeroMemory(v16, 16);
    for ( l = 0; l != 16; ++l )
    {
      v4 = changevar(newarry3[], k, l);
      if ( (_BYTE)v4 <= 0xFu )
        v16[v4] = v4;
    }
    usefull_var_init();  //初始化变量
    NameFunc(v16, 0x10u);   //获取 use_byarry_16数组
    v5 = GetNewUse_key();//根据use_byarry_16数组 得到的use_key 和这些比较不相等就失败
    if ( *(_DWORD *)v5 != 1EFC11Ah
      || *(_DWORD *)(v5 + 4) != 1BAF6CE9h
      || *(_DWORD *)(v5 + 8) != 3329D3E0h
      || *(_DWORD *)(v5 + 12) != 0A8C24F1Ah )
      return 0;
  }
  for ( m = 0; m != 4; ++m )
  {
    for ( n = 0; n != 4; ++n )
    {
      v8 = 0;
      RtlZeroMemory(v16, 16);
      while ( v8 != 4 )
      {
        for ( ii = 0; ii != 4; ++ii )
        {
          v6 = changevar(newarry3[], ii + 4 * n, v8 + 4 * m);
          if ( (_BYTE)v6 <= 0xFu )
            v16[v6] = v6;
        }
        ++v8;
      }
      usefull_var_init();  //初始化变量
      NameFunc(v16, 0x10u);  //获取 use_byarry_16数组
      v7 = GetNewUse_key(); ////根据use_byarry_16数组 得到的use_key 和这些比较不相等就失败
      if ( *(_DWORD *)v7 != 1EFC11Ah
        || *(_DWORD *)(v7 + 4) != 1BAF6CE9h
        || *(_DWORD *)(v7 + 8) != 3329D3E0h
        || *(_DWORD *)(v7 + 12) != 0A8C24F1Ah )
        return 0;
    }
  }
  return 1;
}

就剩下一个MD4_HASH函数了,其实很有规律,汇编代码就不写了,直接上C代码一目了然。

  v0 = (int)use_key__;
  v1 = use_key__[1];
  v2 = use_key__[2];
  v3 = use_key__[3];
  v4 = __ROL__(*(_DWORD *)use_byarry_16_ + use_key__[0] + (v3 ^ v1 & (v3 ^ use_key__[2])) - 680876936, 7);
  v5 = v1 + v4;
  v6 = __ROL__(*(_DWORD *)&use_byarry_16_[4] + v3 + (v2 ^ v5 & (v2 ^ use_key__[1])) - 389564586, 12);
  v7 = v5 + v6;
  v8 = __ROL__(*(_DWORD *)&use_byarry_16_[8] + v2 + (v1 ^ v7 & (v1 ^ v5)) + 606105819, 17);
  v9 = v7 + v8;
  v10 = __ROL__(*(_DWORD *)&use_byarry_16_[12] + v1 + (v5 ^ v9 & (v5 ^ v7)) - 1044525330, 22);
  v11 = v9 + v10;
  v12 = __ROL__(*(_DWORD *)&use_byarry_16_[16] + v5 + (v7 ^ v11 & (v7 ^ v9)) - 176418897, 7);
  v13 = v11 + v12;
  v14 = __ROL__(*(_DWORD *)&use_byarry_16_[20] + v7 + (v9 ^ v13 & (v9 ^ v11)) + 1200080426, 12);
  v15 = v13 + v14;
  v16 = __ROL__(*(_DWORD *)&use_byarry_16_[24] + v9 + (v11 ^ v15 & (v11 ^ v13)) - 1473231341, 17);
  v17 = v15 + v16;
  v18 = __ROL__(*(_DWORD *)&use_byarry_16_[28] + v11 + (v13 ^ v17 & (v13 ^ v15)) - 45705983, 22);
  v19 = v17 + v18;
  v20 = __ROL__(*(_DWORD *)&use_byarry_16_[32] + v13 + (v15 ^ v19 & (v15 ^ v17)) + 1770035416, 7);
  v21 = v19 + v20;
  v22 = __ROL__(*(_DWORD *)&use_byarry_16_[36] + v15 + (v17 ^ v21 & (v17 ^ v19)) - 1958414417, 12);
  v23 = v21 + v22;
  v24 = __ROL__(*(_DWORD *)&use_byarry_16_[40] + v17 + (v19 ^ v23 & (v19 ^ v21)) - 42063, 17);
  v25 = v23 + v24;
  v26 = __ROL__(*(_DWORD *)&use_byarry_16_[44] + v19 + (v21 ^ v25 & (v21 ^ v23)) - 1990404162, 22);
  v27 = v25 + v26;
  v28 = __ROL__(*(_DWORD *)&use_byarry_16_[48] + v21 + (v23 ^ v27 & (v23 ^ v25)) + 1804603682, 7);
  v29 = v27 + v28;
  v30 = __ROL__(*(_DWORD *)&use_byarry_16_[52] + v23 + (v25 ^ v29 & (v25 ^ v27)) - 40341101, 12);
  v31 = v29 + v30;
  v32 = __ROL__(*(_DWORD *)&use_byarry_16_[56] + v25 + (v27 ^ v31 & (v27 ^ v29)) - 1502002290, 17);
  v33 = v31 + v32;
  v34 = __ROL__(*(_DWORD *)&use_byarry_16_[60] + v27 + (v29 ^ v33 & (v29 ^ v31)) + 1236535329, 22);
  v35 = v33 + v34;
  v36 = __ROL__(*(_DWORD *)&use_byarry_16_[4] + v29 + (v33 ^ v31 & (v35 ^ v33)) - 165796510, 5);
  v37 = v35 + v36;
  v38 = __ROL__(*(_DWORD *)&use_byarry_16_[24] + v31 + (v35 ^ v33 & (v37 ^ v35)) - 1069501632, 9);
  v39 = v37 + v38;
  v40 = __ROL__(*(_DWORD *)&use_byarry_16_[44] + v33 + (v37 ^ v35 & (v39 ^ v37)) + 643717713, 14);
  v41 = v39 + v40;
  v42 = __ROL__(*(_DWORD *)use_byarry_16_ + v35 + (v39 ^ v37 & (v41 ^ v39)) - 373897302, 20);
  v43 = v41 + v42;
  v44 = __ROL__(*(_DWORD *)&use_byarry_16_[20] + v37 + (v41 ^ v39 & (v43 ^ v41)) - 701558691, 5);
  v45 = v43 + v44;
  v46 = __ROL__(*(_DWORD *)&use_byarry_16_[40] + v39 + (v43 ^ v41 & (v45 ^ v43)) + 38016083, 9);
  v47 = v45 + v46;
  v48 = __ROL__(*(_DWORD *)&use_byarry_16_[60] + v41 + (v45 ^ v43 & (v47 ^ v45)) - 660478335, 14);
  v49 = v47 + v48;
  v50 = __ROL__(*(_DWORD *)&use_byarry_16_[16] + v43 + (v47 ^ v45 & (v49 ^ v47)) - 405537848, 20);
  v51 = v49 + v50;
  v52 = __ROL__(*(_DWORD *)&use_byarry_16_[36] + v45 + (v49 ^ v47 & (v51 ^ v49)) + 568446438, 5);
  v53 = v51 + v52;
  v54 = __ROL__(*(_DWORD *)&use_byarry_16_[56] + v47 + (v51 ^ v49 & (v53 ^ v51)) - 1019803690, 9);
  v55 = v53 + v54;
  v56 = __ROL__(*(_DWORD *)&use_byarry_16_[12] + v49 + (v53 ^ v51 & (v55 ^ v53)) - 187363961, 14);
  v57 = v55 + v56;
  v58 = __ROL__(*(_DWORD *)&use_byarry_16_[32] + v51 + (v55 ^ v53 & (v57 ^ v55)) + 1163531501, 20);
  v59 = v57 + v58;
  v60 = __ROL__(*(_DWORD *)&use_byarry_16_[52] + v53 + (v57 ^ v55 & (v59 ^ v57)) - 1444681467, 5);
  v61 = v59 + v60;
  v62 = __ROL__(*(_DWORD *)&use_byarry_16_[8] + v55 + (v59 ^ v57 & (v61 ^ v59)) - 51403784, 9);
  v63 = v61 + v62;
  v64 = __ROL__(*(_DWORD *)&use_byarry_16_[28] + v57 + (v61 ^ v59 & (v63 ^ v61)) + 1735328473, 14);
  v65 = v63 + v64;
  v66 = __ROL__(*(_DWORD *)&use_byarry_16_[48] + v59 + (v63 ^ v61 & (v65 ^ v63)) - 1926607734, 20);
  v67 = v65 + v66;
  v68 = __ROL__((v67 ^ v63 ^ v65) + *(_DWORD *)&use_byarry_16_[20] + v61 - 378558, 4);
  v69 = v67 + v68;
  v70 = __ROL__((v69 ^ v65 ^ v67) + *(_DWORD *)&use_byarry_16_[32] + v63 - 2022574463, 11);
  v71 = v69 + v70;
  v72 = __ROL__((v71 ^ v67 ^ v69) + *(_DWORD *)&use_byarry_16_[44] + v65 + 1839030562, 16);
  v73 = v71 + v72;
  v74 = __ROL__((v73 ^ v69 ^ v71) + *(_DWORD *)&use_byarry_16_[56] + v67 - 35309556, 23);
  v75 = v73 + v74;
  v76 = __ROL__((v75 ^ v71 ^ v73) + *(_DWORD *)&use_byarry_16_[4] + v69 - 1530992060, 4);
  v77 = v75 + v76;
  v78 = __ROL__((v77 ^ v73 ^ v75) + *(_DWORD *)&use_byarry_16_[16] + v71 + 1272893353, 11);
  v79 = v77 + v78;
  v80 = __ROL__((v79 ^ v75 ^ v77) + *(_DWORD *)&use_byarry_16_[28] + v73 - 155497632, 16);
  v81 = v79 + v80;
  v82 = __ROL__((v81 ^ v77 ^ v79) + *(_DWORD *)&use_byarry_16_[40] + v75 - 1094730640, 23);
  v83 = v81 + v82;
  v84 = __ROL__((v83 ^ v79 ^ v81) + *(_DWORD *)&use_byarry_16_[52] + v77 + 681279174, 4);
  v85 = v83 + v84;
  v86 = __ROL__((v85 ^ v81 ^ v83) + *(_DWORD *)use_byarry_16_ + v79 - 358537222, 11);
  v87 = v85 + v86;
  v88 = __ROL__((v87 ^ v83 ^ v85) + *(_DWORD *)&use_byarry_16_[12] + v81 - 722521979, 16);
  v89 = v87 + v88;
  v90 = __ROL__((v89 ^ v85 ^ v87) + *(_DWORD *)&use_byarry_16_[24] + v83 + 76029189, 23);
  v91 = v89 + v90;
  v92 = __ROL__((v91 ^ v87 ^ v89) + *(_DWORD *)&use_byarry_16_[36] + v85 - 640364487, 4);
  v93 = v91 + v92;
  v94 = __ROL__((v93 ^ v89 ^ v91) + *(_DWORD *)&use_byarry_16_[48] + v87 - 421815835, 11);
  v95 = v93 + v94;
  v96 = __ROL__((v95 ^ v91 ^ v93) + *(_DWORD *)&use_byarry_16_[60] + v89 + 530742520, 16);
  v97 = v95 + v96;
  v98 = __ROL__((v97 ^ v93 ^ v95) + *(_DWORD *)&use_byarry_16_[8] + v91 - 995338651, 23);
  v99 = v97 + v98;
  v100 = __ROL__(*(_DWORD *)use_byarry_16_ + v93 + (v97 ^ (v99 | ~v95)) - 198630844, 6);
  v101 = v99 + v100;
  v102 = __ROL__(*(_DWORD *)&use_byarry_16_[28] + v95 + (v99 ^ (v101 | ~v97)) + 1126891415, 10);
  v103 = v101 + v102;
  v104 = __ROL__(*(_DWORD *)&use_byarry_16_[56] + v97 + (v101 ^ (v103 | ~v99)) - 1416354905, 15);
  v105 = v103 + v104;
  v106 = __ROL__(*(_DWORD *)&use_byarry_16_[20] + v99 + (v103 ^ (v105 | ~v101)) - 57434055, 21);
  v107 = v105 + v106;
  v108 = __ROL__(*(_DWORD *)&use_byarry_16_[48] + v101 + (v105 ^ (v107 | ~v103)) + 1700485571, 6);
  v109 = v107 + v108;
  v110 = __ROL__(*(_DWORD *)&use_byarry_16_[12] + v103 + (v107 ^ (v109 | ~v105)) - 1894986606, 10);
  v111 = v109 + v110;
  v112 = __ROL__(*(_DWORD *)&use_byarry_16_[40] + v105 + (v109 ^ (v111 | ~v107)) - 1051523, 15);
  v113 = v111 + v112;
  v114 = __ROL__(*(_DWORD *)&use_byarry_16_[4] + v107 + (v111 ^ (v113 | ~v109)) - 2054922799, 21);
  v115 = v113 + v114;
  v116 = __ROL__(*(_DWORD *)&use_byarry_16_[32] + v109 + (v113 ^ (v115 | ~v111)) + 1873313359, 6);
  v117 = v115 + v116;
  v118 = __ROL__(*(_DWORD *)&use_byarry_16_[60] + v111 + (v115 ^ (v117 | ~v113)) - 30611744, 10);
  v119 = v117 + v118;
  v120 = __ROL__(*(_DWORD *)&use_byarry_16_[24] + v113 + (v117 ^ (v119 | ~v115)) - 1560198380, 15);
  v121 = v119 + v120;
  v122 = __ROL__(*(_DWORD *)&use_byarry_16_[52] + v115 + (v119 ^ (v121 | ~v117)) + 1309151649, 21);
  v123 = v121 + v122;
  v124 = __ROL__(*(_DWORD *)&use_byarry_16_[16] + v117 + (v121 ^ (v123 | ~v119)) - 145523070, 6);
  v125 = v123 + v124;
  v126 = __ROL__(*(_DWORD *)&use_byarry_16_[44] + v119 + (v123 ^ (v125 | ~v121)) - 1120210379, 10);
  v127 = v125 + v126;
  v128 = __ROL__(*(_DWORD *)&use_byarry_16_[8] + v121 + (v125 ^ (v127 | ~v123)) + 718787259, 15);
  v129 = v127 + v128;
  v130 = __ROL__(*(_DWORD *)&use_byarry_16_[36] + v123 + (v127 ^ (v129 | ~v125)) - 343485551, 21);
  use_key__[0] += v125;
  *(_DWORD *)(v0 + 4) += v129 + v130;
  *(_DWORD *)(v0 + 8) += v129;
  *(_DWORD *)(v0 + 12) += v127;
}


对use_byarry_16进行大量的算法,最后赋值给use_key[] {第一位,第二位,第三位,第四位}
Use_byarry_16决定use_key[]的值。

到此已经把每个函数都分析完毕,不对的地方求指导。
代码量太大,总结一下吧
1、注册码 链接固定字符串-"-diablo2oo2” ,长度加0Bh
2、在NameFunc函数中运算得到 use_byarry_16数组
3、在GetNewUse_key函数中根据use_byarry_16数组获取use_key[]
4、ChangeArray函数use_key[]一系列运算结果给newarry
5、SerialFunc函数 serial base64运算,放在newarry1中
6、ChangeArray1函数中 对newarry[]进行运算赋值给newarry2[]  8为循环
7、MMXcode 函数中 浮点运算 对newarry1扩展结果放在newarry2[]
8、 ChangeArray2 函数中 对newarry1[]进行运算赋值给newarry3[]  80h为循环
9、 cmpArray  函数中  newarry[]与newarry3[]运算后的相比较,必须相等 不相等就over
A、 check_serialFunc  函数中 16+16+16 = 48 次  use_key[]验证,有一次不相等就Over

闲得无聊我把改程序还原了一下,不敢说是逆向,怕笑掉大家的大牙。注册机不会写,没有头绪,运算太多了。
附上还原的Radasm工程文件和源代码还有IDA分析的idb文件
PS其实不敢上传IDB文件因为变量写的太烂了,请不要喷的太厉害。

【公告】 [2022大礼包]《看雪论坛精华22期》发布!收录近1000余篇精华优秀文章!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回