ShadowDefender 註冊碼 分析

DirWangK發表於2024-08-17

目錄
  • ShadowDefender
    • CRegisterDlg
      • 定位虛表
      • 定位AFX_MSGMAP_ENTRY
      • 定位訊息事件
    • do_register_check_14001BFC4
      • check_140002FF4
      • hash_14000328C
  • py

ShadowDefender

Version: 1.5.0.726

MFC 程式,

CRegisterDlg

定位虛表

image-20240817231732470

定位AFX_MSGMAP_ENTRY

image-20240817231852169

定位訊息事件

根據AFX_MSGMAP_ENTRY和 ResourceHacker 註冊框控制元件分析,定位關鍵函式register_check_14001BC88和register_ok_14001BA88

image-20240817232004642

do_register_check_14001BFC4

註冊碼5*5;‘-’進行分隔

校驗流程:

1、註冊碼去除‘-’(記為data),判斷長度是否為25

2、data拼接版本字串("V100" 或者 "V110" ),前16位與 hash_14000328C(data[16:]) 進行比較

__int64 __fastcall do_register_check_14001BFC4(CWnd *this)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v2 = sub_1400279A4();
  if ( !v2 )
    unknown_libname_72(0x80004005i64);
  registration_code = ((__int64 (__fastcall *)(void ***))(*v2)[3])(v2) + 0x18;
  DlgItem = CWnd::GetDlgItem(this, 1);
  CWnd::EnableWindow(DlgItem, 0);
  v4 = CWnd::GetDlgItem(this, 1016);            // registration code
  CWnd::GetWindowTextW(v4, &registration_code);
  Source = (wchar_t *)(ATL::CSimpleStringT<wchar_t,0>::CloneData((volatile signed __int32 *)(registration_code - 0x18))
                     + 0x18);
  ATL::CStringT<wchar_t,StrTraitMFC<wchar_t,ATL::ChTraitsCRT<wchar_t>>>::Remove(&Source, '-');
  v5 = Source;
  if ( *((_DWORD *)Source + 0xFFFFFFFC) == 0x19
    && ((unsigned int)check_140002FF4(Source, L"V100", 0i64) || (unsigned int)check_140002FF4(v5, L"V110", 0i64)) )
  {
    v6 = CWnd::GetDlgItem(this, 1);
    CWnd::EnableWindow(v6, 1);
  }
  if ( _InterlockedDecrement((volatile signed __int32 *)v5 + 0x7FFFFFFE) <= 0 )
    (*(void (__fastcall **)(_QWORD))(**((_QWORD **)v5 + 0xFFFFFFFD) + 8i64))(*((_QWORD *)v5 + 0xFFFFFFFD));
  v7 = (_QWORD *)(registration_code - 0x18);
  result = (unsigned int)_InterlockedDecrement((volatile signed __int32 *)(registration_code - 0x18 + 0x10));
  if ( (int)result <= 0 )
    return (*(__int64 (__fastcall **)(_QWORD))(*(_QWORD *)*v7 + 8i64))(*v7);
  return result;
}

check_140002FF4

__int64 __fastcall check_140002FF4(wchar_t *Source, LPCWCH version, _DWORD *a3)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v16 = 0xFFFFFFFFFFFFFFFEui64;
  wcsncpy_s(code, 0x20ui64, Source, 0x19ui64);
  code[0x19] = 0;
  wcsupr_s(code, 0x20ui64);
  if ( wcslen(code) == 25 )
  {
    sub_140064220((__int64)temp, 0, 0x20ui64);
    WideCharToMultiByte(0, 0x200u, code, 0xFFFFFFFF, str_code, 0x20, 0i64, 0i64);
    // V100  or V110
    WideCharToMultiByte(0, 0x200u, version, 0xFFFFFFFF, (LPSTR)temp, 0x20, 0i64, 0i64);
    strcat_s(str_code, 0x20ui64, (const char *)temp);
    md5_init_140001370((__int64)v18);
    v5 = strlen(str_code);
    md5_update_140001DF8((__int64)v18, (__int64)&str_code[0x10], v5 - 0x10);// 16位之後計算hash
    md5_final_1400014BC((__int64)v18, (__int64)hash);
    v6 = 0;
    for ( i = 0i64; i < 0x10; ++i )
    {
      if ( (unsigned __int16)hash_14000328C((unsigned __int8)hash[i]) != code[i] )
        break;
      ++v6;
    }
    sub_1400013CC(v18);
    if ( v6 >= 0x10 )
      return 1i64;
  }
  if ( !a3 )
    return 0i64;
  *a3 = 0;
  pcbData = 0x10;
  if ( SHGetValueW(
         HKEY_CLASSES_ROOT,
         L"CLSID\\{78C3F4BC-C7BC-48E4-AD72-2DD16F6704A9}",
         &Default,
         &pdwType,
         &pvData,
         &pcbData) )
  {
    return 0i64;
  }
  GetSystemTime(temp);
  SystemTimeToFileTime(&pvData, &FileTime);
  SystemTimeToFileTime(temp, &v14);
  v9 = *(unsigned __int64 *)&FileTime / 10000000;
  FileTime = (struct _FILETIME)v9;
  v10 = *(unsigned __int64 *)&v14 / 10000000;
  v14 = (struct _FILETIME)v10;
  if ( v10 <= v9 )
    return 0i64;
  v11 = v10 - v9;
  if ( v11 < 2592000 )
    *a3 = 30 - v11 / 86400;
  return 0i64;
}

hash_14000328C

{ 0:0x41, 1:0x42, 2:0x43, 3:0x44, 4:0x45, 5:0x46, 6:0x47, 7:0x48, 8:0x4a, 9:0x4b, 10:0x4d, 11:0x4e, 12:0x50, 13:0x51, 14:0x52, 15:0x53, 16:0x54, 17:0x55, 18:0x56, 19:0x57, 20:0x58, 21:0x59, 22:0x5a, 23:0x32, 25:0x34, 26:0x35, 27:0x36, 28:0x37, 29:0x38, 30:0x39, }  #other:0x33
__int64 __fastcall hash_14000328C(int a1)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v1 = a1 % 0x1F;
  if ( v1 > 15 )
  {
    if ( v1 > 23 )
    {
      v20 = v1 - 24;
      if ( v20 )                                // >24
      {
        v21 = v20 - 1;
        if ( !v21 )                             // 25
          return 0x34i64;
        v22 = v21 - 1;
        if ( !v22 )
          return 0x35i64;
        v23 = v22 - 1;
        if ( !v23 )
          return 0x36i64;
        v24 = v23 - 1;
        if ( !v24 )
          return 0x37i64;
        v25 = v24 - 1;
        if ( !v25 )
          return 0x38i64;
        if ( v25 == 1 )
          return 0x39i64;
      }
    }
    else
    {
      if ( v1 == 23 )
        return 0x32i64;
      v14 = v1 - 0x10;
      if ( !v14 )                               // 16
        return 0x54i64;
      v15 = v14 - 1;
      if ( !v15 )
        return 0x55i64;
      v16 = v15 - 1;
      if ( !v16 )
        return 0x56i64;
      v17 = v16 - 1;
      if ( !v17 )
        return 0x57i64;
      v18 = v17 - 1;
      if ( !v18 )
        return 0x58i64;
      v19 = v18 - 1;
      if ( !v19 )
        return 0x59i64;
      if ( v19 == 1 )
        return 0x5Ai64;
    }
  }
  else
  {
    if ( v1 == 15 )
      return 0x53i64;
    if ( v1 > 7 )
    {
      v8 = v1 - 8;
      if ( !v8 )                                // 8
        return 0x4Ai64;
      v9 = v8 - 1;
      if ( !v9 )                                // 9
        return 0x4Bi64;
      v10 = v9 - 1;
      if ( !v10 )                               // 10
        return 0x4Di64;
      v11 = v10 - 1;
      if ( !v11 )                               // 11
        return 0x4Ei64;
      v12 = v11 - 1;
      if ( !v12 )                               // 12
        return 0x50i64;
      v13 = v12 - 1;
      if ( !v13 )                               // 13
        return 0x51i64;
      if ( v13 == 1 )                           // 14
        return 0x52i64;
    }
    else
    {
      if ( v1 == 7 )
        return 0x48i64;
      if ( !v1 )
        return 0x41i64;
      v2 = v1 - 1;
      if ( !v2 )
        return 0x42i64;
      v3 = v2 - 1;
      if ( !v3 )
        return 0x43i64;
      v4 = v3 - 1;
      if ( !v4 )
        return 0x44i64;
      v5 = v4 - 1;
      if ( !v5 )
        return 0x45i64;
      v6 = v5 - 1;
      if ( !v6 )
        return 0x46i64;
      if ( v6 == 1 )
        return 0x47i64;
    }
  }
  return 0x33i64;
}

py


import hashlib

import random

S_TABLE='ABCDEFGHJKMNPQRSTUVWXYZ24567893'

def hash_14000328C(a1):
    v1 = a1 % 0x1F   # 31

    lookup_map={ 0:0x41, 1:0x42, 2:0x43, 3:0x44, 4:0x45, 5:0x46, 6:0x47, 7:0x48, 8:0x4a, 9:0x4b, 10:0x4d, 11:0x4e, 12:0x50, 13:0x51, 14:0x52, 15:0x53, 16:0x54, 17:0x55, 18:0x56, 19:0x57, 20:0x58, 21:0x59, 22:0x5a, 23:0x32, 25:0x34, 26:0x35, 27:0x36, 28:0x37, 29:0x38, 30:0x39, }
    return lookup_map.get(v1,0x33)


def split_string(s, length):
    return [s[i:i+length] for i in range(0, len(s), length)]


def gen(version='V110',part2=random.choices(S_TABLE,k=9)):
    # version='V100'  # 'V110'

    part2_str=''.join(part2)
    # print('[+]part2:',part2_str)
    x=part2_str+version
    hash=hashlib.md5(x.encode()).digest()
    # print('[-]md5hash:',hash.hex())
    part1=[hash_14000328C(hash[i]) for i in range(16) ]
    # print('[+]part1:',bytes(part1))
    
    
    data=''.join(map(chr,part1))+part2_str
    code='-'.join(split_string(data,5))
    print('[#]code:',code)
    return code




if __name__=='__main__':
    gen()
    

image-20240817233311397

相關文章