vovsoft Text Edit Plus v14 离线激活

vovsoft Text Edit Plus v14

程序信息text-edit

Text Edit Plus https://vovsoft.com/software/text-edit-plus/

Version: 14.7

PE32
    操作系统: Windows(2000)[I386, 32 位, GUI]
    链接程序: Turbo Linker(2.25*,Delphi)[GUI32,signed]
    编译器: Embarcadero Delphi(10.3 Rio)[Professional]
    语言: Object Pascal(Delphi)
    签名工具: Windows Authenticode(2.0)[PKCS #7]
    附加: Binary
        证书: WinAuth(2.0)[PKCS #7]
        证书: WinAuth(2.0)[PKCS #7]

Delphi程序,IDR 启动!

程序联网会进行网络校验,联网一定不通过!包括离线注册的时侯

定位按钮事件

NagScreen: TNagScreen

image-20241103192505963

关注‘ok’ 按钮事件

TNagScreen.BitBtn3Click

      object BitBtn3: TSpeedButton
        Left = 1
        Top = 1
        Width = 198
        Height = 37
        Align = alClient
        Caption = 'OK'
        Flat = True
        Font.Charset = DEFAULT_CHARSET
        Font.Color = clWhite
        Font.Height = -12
        Font.Name = 'Tahoma'
        Font.Style = [fsBold]
        ParentFont = False
        OnClick = BitBtn3Click
        ExplicitLeft = 2
        ExplicitTop = 17
        ExplicitWidth = 183
        ExplicitHeight = 39
      end

点击ok后激活计时器

int __fastcall TNagScreen_BitBtn3Click(int a1)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v15 = 0;
  v14 = 0;
  v13 = 0;
  v11 = &savedregs;
  v10 = &loc_9A2CC5;
  ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)&ExceptionList);
  Mask::TCustomMaskEdit::GetText(*(Mask::TCustomMaskEdit **)(a1 + 0x428));
  if ( (unsigned __int8)Siteedit::TSiteActionsListEditorHelper::GetFieldsList(v17, L" ") )
  {
    sub_9A611C((int)L"Activation", (int)&v14);
    v8 = UStrToPWChar(v14);
    sub_9A611C((int)L"Please enter your license key!", (int)&v13);
    v6 = (const WCHAR *)UStrToPWChar(v13);
    TApplication_MessageBox(*Application, v6, v8, 0x10u);
  }
  else
  {
    LOWORD(v2) = 0xFFED;
    sub_67A55C(*Screen, v2, v3, v12, v11, v10, ExceptionList);
    TControl_SetColor(*(_DWORD *)(a1 + 0x42C), 0xFF00000F);
    // mov         eax,dword ptr [ebx+430];TNagScreen.BitBtn3:TSpeedButton
    // …………
    // call        dword ptr [ecx+94];TControl.SetEnabled
    (*(void (__fastcall **)(_DWORD, _DWORD))(**(_DWORD **)(a1 + 0x430) + 0x94))(*(_DWORD *)(a1 + 0x430), 0);
    // license key
    Mask::TCustomMaskEdit::GetText(*(Mask::TCustomMaskEdit **)(a1 + 0x428));
    Trim(v15, &v16);
    UStrAsg(license_key_BB2A20, v16, v4);
    ischecker_created_over_00BACF6C = 0;
    LOBYTE(v5) = 1;
    //  mov         eax,dword ptr [ebx+3EC];TNagScreen.TimerActivator:TTimer
    TTimer_SetEnabled_5F9D74(*(_DWORD *)(a1 + 0x3EC), v5);
  }
  __writefsdword(0, (unsigned int)ExceptionList);
  v11 = (int *)&loc_9A2CCC;
  UStrArrayClr(&v13, 2);
  UStrClr(&v15);
  UStrClr(&v16);
  return UStrClr(&v17);
}

TNagScreen.TimerContinueTimer

Continue

?网络校验时?

TNagScreen.TimerActivatorTimer

负责创建TChecker校验线程和响应激活结果

int __fastcall TNagScreen_TimerActivatorTimer(Forms::TCustomForm *this)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v24[1] = (unsigned int)&loc_9A4322;
  v24[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)v24);
  if ( ischecker_created_over_00BACF6C )
  {
    if ( *ptr_is_TRIAL_BB2B7C == 1 )
    {
      TTimer_SetEnabled_5F9D74(*((_DWORD *)this + 0xFB), 0);
      if ( *off_BB2698 == 1 )
      {
        gvar_00BACF70 = 1;
        sub_9A611C((int)L"Activation", (int)&v49);
        v23 = UStrToPWChar(v49);
        sub_9A611C((int)L"Thank you!", (int)&v47);
        v22 = v47;
        sub_9A611C((int)L"Product successfully activated.", (int)&v46);
        v17 = v46;
        UStrCatN(&v48, 4);
        v3 = (const WCHAR *)UStrToPWChar(v48);
        TApplication_MessageBox(*Application, v3, v17, (UINT)L"\r");
        if ( *off_BB2694[0] == 1 )
        {
          LOBYTE(v4) = 1;
          TMenuItem_SetVisible(*(_DWORD *)(*gvar_00BB20D4 + 0x694), v4);
          LOBYTE(v5) = 1;
          TMenuItem_SetEnabled(*(_DWORD *)(*gvar_00BB20D4 + 0x694), v5);
          if ( !*gvar_00BB1FC0 )
            TMenuItem_SetChecked(*(_DWORD *)(*gvar_00BB20D4 + 0x694), 0);
        }
        TCustomForm_Close(this);
      }
      else if ( !*ptr_Activation_success_00BB1CBC
             || (*(unsigned __int8 (__fastcall **)(_DWORD))(**((_DWORD **)this + 0xFE) + 0x130))(*((_DWORD *)this + 0xFE)) )
      {
        if ( *ptr_Activation_success_00BB1CBC
          && (*(unsigned __int8 (__fastcall **)(_DWORD))(**((_DWORD **)this + 0xFE) + 0x130))(*((_DWORD *)this + 0xFE)) == 1 )
        {
          sub_9A611C((int)L"Activation", (int)&v32);
          v23 = UStrToPWChar(v32);
          sub_9A611C((int)aActivationFail, (int)&v30);
          v22 = v30;
          sub_9A611C((int)L"License key is invalid!", (int)&v29);
          v19 = v29;
          UStrCatN(&v31, 4);
          v10 = (const WCHAR *)UStrToPWChar(v31);
          TApplication_MessageBox(*Application, v10, v19, (UINT)L"\r");
        }
        else
        {
          sub_9A611C((int)L"Activation", (int)&v28);
          v23 = UStrToPWChar(v28);
          sub_9A611C((int)aActivationFail, (int)&v26);
          v22 = v26;
          sub_9A611C((int)L"License key is invalid!", (int)&v25);
          v20 = v25;
          UStrCatN(&v27, 4);
          v11 = (const WCHAR *)UStrToPWChar(v27);
          TApplication_MessageBox(*Application, v11, v20, (UINT)L"\r");
        }
      }
      else if ( *ptr_RESPONSE_BB1E94 )
      {
        UStrEqual(*ptr_RESPONSE_BB1E94, L"INVALIDSERVERRESPONSE");
        if ( v7 )
        {
          sub_9A611C((int)L"Activation", (int)&v41);
          v23 = UStrToPWChar(v41);
          sub_9A611C((int)aActivationFail, (int)&v39);
          v22 = v39;
          sub_9A611C((int)L"The server returned an invalid response.", (int)&v38);
          v21 = v38;
          sub_9A611C((int)L"Please try again later!", (int)&v37);
          v16 = v37;
          UStrCatN(&v40, 6);
          v8 = (const WCHAR *)UStrToPWChar(v40);
          TApplication_MessageBox(*Application, v8, v16, (UINT)L"\r");
        }
        else
        {
          sub_9A611C((int)L"Activation", (int)&v36);
          v23 = UStrToPWChar(v36);
          sub_9A611C((int)aActivationFail, (int)&v34);
          v22 = v34;
          v21 = L"\r";
          sub_9A611C((int)L"Please check your internet connection!", (int)&v33);
          v15 = *ptr_RESPONSE_BB1E94;
          UStrCatN(&v35, 7);
          v9 = (const WCHAR *)UStrToPWChar(v35);
          TApplication_MessageBox(*Application, v9, v15, (UINT)L"\r");
        }
      }
      else
      {
        sub_9A611C((int)L"Activation", (int)&v45);
        v23 = UStrToPWChar(v45);
        sub_9A611C((int)aActivationFail, (int)&v43);
        v22 = v43;
        sub_9A611C((int)L"Please check your internet connection!", (int)&v42);
        v18 = v42;
        UStrCatN(&v44, 4);
        v6 = (const WCHAR *)UStrToPWChar(v44);
        TApplication_MessageBox(*Application, v6, v18, (UINT)L"\r");
      }
      TControl_SetColor(*((_DWORD *)this + 0x10B), &byte_54B70C);
      LOBYTE(v12) = 1;
      (*(void (__fastcall **)(_DWORD, int))(**((_DWORD **)this + 0x10C) + 0x94))(*((_DWORD *)this + 0x10C), v12);
      sub_67A55C(*Screen, 0, v13, v23, v22, L"\r", v21);
    }
  }
  else
  {
    ischecker_created_over_00BACF6C = 1;
    // call        TThread.Create;TChecker.Create
    v2 = TThread_Create(VMT_9A53C4_TChecker, 1);
    // mov         eax,dword ptr [ebx+3F8];TNagScreen.CheckBox1:TCheckBox
    // …………
    // call        dword ptr [edx+130];TCheckBox.GetChecked
    if ( (*(unsigned __int8 (__fastcall **)(_DWORD))(**((_DWORD **)this + 0xFE) + 0x130))(*((_DWORD *)this + 0xFE)) )
    {
      // 离线激活时
      *(_BYTE *)(v2 + 0x31) = 1;
      // active code
      TControl_GetText(*((Controls::TControl **)this + 0x102), (int)&v50);
    }
    *(_BYTE *)(v2 + 0x31) = 0;
    UStrClr(v2 + 0x34);
    *(_BYTE *)(v2 + 0x30) = 1;
    sub_48F8DC(v2, 1);
  }
  __writefsdword(0, v24[0]);
  v24[2] = (unsigned int)&loc_9A4329;
  UStrArrayClr(&v25, 0x19);
  return UStrClr(&v50);
}

离线校验逻辑

TChecker 类

image-20241103195141955

TChecker.Execute

_Unit180.TChecker.Execute
009A8BC4        mov         byte ptr ds:[0BACF80],0;gvar_00BACF80
009A8BCB        mov         byte ptr ds:[0BACF81],0;gvar_00BACF81
009A8BD2        call        009A6AEC		;关键函数
009A8BD7        ret

check_9A6AEC

由于ida对Delphi 的异常处理未能正确分析,未能完整反编译(如mov fs:[eax], edx 设置SEH就给干傻了)

首先计算“VOVSOFT - Text Edit Plus” 的md5hex (C20297BE5DC4403AA4913F7587535516),作为注册表key

其相关配置将存到

\HKEY_CURRENT_USER\Software\Microsoft\VS\ServiceModules\C20297BE5DC4403AA4913F7587535516\Settings

009A6B5D    | 33C0             | xor eax,eax                                 |
009A6B5F    | 55               | push ebp                                    |
009A6B60    | 68 846B9A00      | push text.9A6B84                            |
009A6B65    | 64:FF30          | push dword ptr fs:[eax]                     |
009A6B68    | 64:8920          | mov dword ptr fs:[eax],esp                  |
009A6B6B    | 8D55 E0          | lea edx,dword ptr ss:[ebp-20]               |
009A6B6E    | A1 6C2ABB00      | mov eax,dword ptr ds:[BB2A6C]               |
009A6B73    | 8B00             | mov eax,dword ptr ds:[eax]                  |
009A6B75    | E8 06EBFFFF      | call <text.calc_md5hex>                     |
009A6B7A    | 33C0             | xor eax,eax                                 |
009A6B7C    | 5A               | pop edx                                     |
009A6B7D    | 59               | pop ecx                                     |
009A6B7E    | 59               | pop ecx                                     |
009A6B7F    | 64:8910          | mov dword ptr fs:[eax],edx                  |
009A6B82    | EB 1C            | jmp text.9A6BA0                             |
009A6B84    | E9 A349A6FF      | jmp text.40B52C                             |
;SEH 异常处理
009A6B89    | 8D45 E0          | lea eax,dword ptr ss:[ebp-20]               |
009A6B8C    | E8 7357A6FF      | call text.40C304                            |
009A6B91    | B8 EC839A00      | mov eax,text.9A83EC                         | 9A83EC:L"Error: MD5 generate problem!"
009A6B96    | E8 25EAFFFF      | call text.9A55C0                            |
009A6B9B    | E8 A84EA6FF      | call text.40BA48                            |

获取 MachineGuid

计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography

MachineGuid

009A6BA2    | 55               | push ebp                                    |
009A6BA3    | 68 C06B9A00      | push text.9A6BC0                            |
009A6BA8    | 64:FF30          | push dword ptr fs:[eax]                     |
009A6BAB    | 64:8920          | mov dword ptr fs:[eax],esp                  |
009A6BAE    | 8D45 E4          | lea eax,dword ptr ss:[ebp-1C]               |
009A6BB1    | E8 FAFCFFFF      | call <text.get__MachineGuid>                |
009A6BB6    | 33C0             | xor eax,eax                                 |
009A6BB8    | 5A               | pop edx                                     |
009A6BB9    | 59               | pop ecx                                     |
009A6BBA    | 59               | pop ecx                                     |
009A6BBB    | 64:8910          | mov dword ptr fs:[eax],edx                  |
009A6BBE    | EB 1C            | jmp text.9A6BDC                             |
009A6BC0    | E9 6749A6FF      | jmp text.40B52C                             |
009A6BC5    | 8D45 E4          | lea eax,dword ptr ss:[ebp-1C]               |
009A6BC8    | E8 3757A6FF      | call text.40C304                            |
009A6BCD    | B8 34849A00      | mov eax,text.9A8434                         | 9A8434:L"Error: GUID generate problem!"
009A6BD2    | E8 E9E9FFFF      | call text.9A55C0                            |
009A6BD7    | E8 6C4EA6FF      | call text.40BA48                            |

判断是否存在key.txt,存在时读取并保存到注册表\HKEY_CURRENT_USER\Software\Microsoft\VS\ServiceModules\C20297BE5DC4403AA4913F7587535516\Settings

LicenseKey

image-20241103200849419

后面初始化某些配置

未联网、未激活时

image-20241103205621006

联网校验过、未激活时有如下配置

image-20241103201340503

该程序会进行网络校验,发送的相关字符:

image-20241103201854819

image-20241103202014692

网络请求失败时,校验Parity

009A80DE    | 8B85 78FFFFFF    | mov eax,dword ptr ss:[ebp-88]                   |
009A80E4    | 83E8 04          | sub eax,4                                       |
009A80E7    | 8B00             | mov eax,dword ptr ds:[eax]                      |
009A80E9    | 8985 78FFFFFF    | mov dword ptr ss:[ebp-88],eax                   |
009A80EF    | 8B85 78FFFFFF    | mov eax,dword ptr ss:[ebp-88]                   |
009A80F5    | 85C0             | test eax,eax                                    |
009A80F7    | 7E 16            | jle text.9A810F                                 |
009A80F9    | BA 01000000      | mov edx,1                                       |
009A80FE    | 8B0D A4CFBA00    | mov ecx,dword ptr ds:[<LicenseKey_BACFA4>]      |
009A8104    | 0FB74C51 FE      | movzx ecx,word ptr ds:[ecx+edx*2-2]             |
009A8109    | 03D9             | add ebx,ecx                                     |
009A810B    | 42               | inc edx                                         |
009A810C    | 48               | dec eax                                         |
009A810D    | 75 EF            | jne text.9A80FE                                 |
009A810F    | 33F6             | xor esi,esi                                     |
009A8111    | 8B45 E4          | mov eax,dword ptr ss:[ebp-1C]                   |
009A8114    | 8985 74FFFFFF    | mov dword ptr ss:[ebp-8C],eax                   |
009A811A    | 83BD 74FFFFFF 00 | cmp dword ptr ss:[ebp-8C],0                     |
009A8121    | 74 11            | je text.9A8134                                  |
009A8123    | 8B85 74FFFFFF    | mov eax,dword ptr ss:[ebp-8C]                   |
009A8129    | 83E8 04          | sub eax,4                                       |
009A812C    | 8B00             | mov eax,dword ptr ds:[eax]                      |
009A812E    | 8985 74FFFFFF    | mov dword ptr ss:[ebp-8C],eax                   |
009A8134    | 8B85 74FFFFFF    | mov eax,dword ptr ss:[ebp-8C]                   |
009A813A    | 85C0             | test eax,eax                                    |
009A813C    | 7E 13            | jle text.9A8151                                 |
009A813E    | BA 01000000      | mov edx,1                                       | get key checksum
009A8143    | 8B4D E4          | mov ecx,dword ptr ss:[ebp-1C]                   |
009A8146    | 0FB74C51 FE      | movzx ecx,word ptr ds:[ecx+edx*2-2]             |
009A814B    | 03F1             | add esi,ecx                                     |
009A814D    | 42               | inc edx                                         |
009A814E    | 48               | dec eax                                         |
009A814F    | 75 F2            | jne text.9A8143                                 |
009A8151    | 8B45 C4          | mov eax,dword ptr ss:[ebp-3C]                   | esi==> MachineGuid checksum
009A8154    | 83C0 34          | add eax,34                                      | eax+34h Activate code
009A8157    | B9 14000000      | mov ecx,14                                      |
009A815C    | BA 01000000      | mov edx,1                                       |
009A8161    | E8 9255A6FF      | call <text.@UStrDelete>                         | 删除长度14h
009A8166    | 8B45 C4          | mov eax,dword ptr ss:[ebp-3C]                   |
009A8169    | 8B40 34          | mov eax,dword ptr ds:[eax+34]                   |
009A816C    | E8 3F5DA8FF      | call <text.StrToInt>                            | 即激活码[20:] 为int_str
009A8171    | 2BF3             | sub esi,ebx                                     |
009A8173    | 3BC6             | cmp eax,esi                                     | int_str == MachineGuid_checksum - key_checksum
009A8175    | 0F85 CE000000    | jne text.9A8249                                 |
009A817B    | 8B45 C4          | mov eax,dword ptr ss:[ebp-3C]                   | int_str 存储到 注册表Parity
009A817E    | 8B40 34          | mov eax,dword ptr ds:[eax+34]                   |
009A8181    | 50               | push eax                                        |
009A8182    | B9 CC869A00      | mov ecx,text.9A86CC                             | 9A86CC:L"Parity"
009A8187    | BA 5C859A00      | mov edx,text.9A855C                             | 9A855C:L"Settings"
009A818C    | A1 20EBBC00      | mov eax,dword ptr ds:[BCEB20]                   |
009A8191    | E8 7AA5B9FF      | call <text.reg_set_>                            |
009A8196    | B8 24EBBC00      | mov eax,<text.LicenseOwner>                     |
009A819B    | BA B48B9A00      | mov edx,text.9A8BB4                             | 9A8BB4:L"Offline"
009A81A0    | E8 3F45A6FF      | call <text.@UStrAsg>                            |
009A81A5    | 8D85 5CFEFFFF    | lea eax,dword ptr ss:[ebp-1A4]                  |
009A81AB    | 8B15 24EBBC00    | mov edx,dword ptr ds:[<LicenseOwner>]           |
009A81B1    | E8 CA51A6FF      | call <text.@WStrFromUStr>                       |
009A81B6    | 8B85 5CFEFFFF    | mov eax,dword ptr ss:[ebp-1A4]                  |
009A81BC    | 8D8D 60FEFFFF    | lea ecx,dword ptr ss:[ebp-1A0]                  |
009A81C2    | 66:BA BA00       | mov dx,BA                                       |
009A81C6    | E8 45E4FFFF      | call <text.xor_enc>                             |
009A81CB    | 8B85 60FEFFFF    | mov eax,dword ptr ss:[ebp-1A0]                  | 设置注册表LicenseOwner 值为Offline xor加密的hexstr
009A81D1    | 50               | push eax                                        |
009A81D2    | B9 A4869A00      | mov ecx,text.9A86A4                             | 9A86A4:L"LicenseOwner"
009A81D7    | BA 5C859A00      | mov edx,text.9A855C                             | 9A855C:L"Settings"
009A81DC    | A1 20EBBC00      | mov eax,dword ptr ds:[BCEB20]                   |
009A81E1    | E8 2AA5B9FF      | call <text.reg_set_>                            |

14.7 版本check函数的局部变量

## check函数的局部变量

[ebp-18h] string==> LastUpdateCheck


[ebp-4Ch]  int==》 LastUpdateCheckCount



[ebp-0BCh] string==>InstalledVersion

​					

[ebp-3ch]  ==>obj  

​					[+30h] 判断是否设置InstalledVersion

​					obj+34h==>Activate code


[ebp-0C0h] string==> CurrentVersion


[ebp-0C4h] string==>CurrentURL

BACF90:&L"http://vovsoft.com/software/text-edit-plus/"

BACF90:&L"6810A868ADD9651ABAB1AC6CD56621708492E4E0605911074FDF754F05F4B503A6DADFF038CCB31C72640C"


[ebp-0CCh] string ==>CurrentPrice


[ebp-0D4h]  ==> license_key (原始)



[ebp-0D8h]  string ==> LicenseKey (xor_enc_license_key)


[ebp-0DCh] ==》LicenseKey  xor dec  -->原始


[ebp-0E0h] string==> LicenseOwner


[ebp-8] string ==>Parity


[ebp-1Ch]  machineGuid

other

某些配置项通过xor加密存储,如 CurrentURL、LicenseKey、LicenseOwner

xor_enc_9A6610

// bad sp value at call has been detected, the output may be wrong!
void __fastcall xor_enc_9A6610(int a1, __int16 a2, int a3)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  v20 = 0;
  v18 = 0;
  v19 = a3;
  v14 = &savedregs;
  v13 = &loc_9A66D8;
  ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)&ExceptionList);
  UStrClr(a3);
  UTF8Encode(a1, &v20, v5, v17, v16, v15, v14, v13, ExceptionList);
  v6 = (int)v20;
  if ( v20 )
    v6 = *((_DWORD *)v20 + 0xFFFFFFFF);
  if ( v6 - 1 >= 0 )
  {
    v7 = v6;
    v8 = 0;
    do
    {
      v20[v8] ^= HIBYTE(a2);
      a2 = 0xD201 * ((unsigned __int8)v20[v8++] + a2) + 0x7F6A;
      --v7;
    }
    while ( v7 );
  }
  v9 = (int)v20;
  if ( v20 )
    v9 = *((_DWORD *)v20 + 0xFFFFFFFF);
  if ( v9 - 1 >= 0 )
  {
    v10 = v9;
    v11 = 0;
    do
    {
      IntToHex((unsigned __int8)v20[v11], 2, &v18);
      UStrCat(v19, v18);
      ++v11;
      --v10;
    }
    while ( v10 );
  }
  __writefsdword(0, v19);
  savedregs = &dword_9A66DF;
  UStrClr(&v18);
  ((void (__fastcall *)(char **))LStrClr)(&v20);
  JUMPOUT(0x9A66DF);
}

xor_dec sub_9A66E8

// bad sp value at call has been detected, the output may be wrong!
int __usercall sub_9A66E8@<eax>(
        int a1@<eax>,
        __int16 value@<dx>,
        int a3@<ecx>,
        int a4@<ebx>,
        int a5@<edi>,
        int a6@<esi>)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  cchWideChar = 0;
  v26 = 0;
  v25 = 0;
  temp = 0;
  v22[1] = 0;
  v22[0] = 0;
  v21 = 0;
  v20[5] = a4;
  v20[4] = a6;
  v20[3] = a5;
  v24 = a3;
  v20[2] = &savedregs;
  v20[1] = System::__linkproc__ HandleFinally;
  v20[0] = NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)v20);
  UpperCase(a1, &v26);
  v7 = (int)v26;
  if ( v26 )
    v7 = *((_DWORD *)v26 + 0xFFFFFFFF);
  LStrSetLength((int)&cchWideChar, v7 / 2);
  v19 = &savedregs;
  v18 = (int (__cdecl *)(int, int))&loc_9A67BC;
  ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)&ExceptionList);
  v9 = (int)v26;
  if ( v26 )
    v9 = *((_DWORD *)v26 + 0xFFFFFFFF);
  if ( v9 > 1 )
    UStrFromPWCharLen_3512(v22, *v26, v8, ExceptionList, &byte_9A68AC);
  __writefsdword(0, (unsigned int)ExceptionList);
  v10 = cchWideChar;
  if ( cchWideChar )
    v10 = (char *)*((_DWORD *)cchWideChar + 0xFFFFFFFF);
  v11 = (int)(v10 + 0xFFFFFFFF);
  if ( v11 >= 0 )
  {
    size = v11 + 1;
    index = 0;
    do
    {
      temp = (unsigned __int8)cchWideChar[index];
      cchWideChar[index] ^= HIBYTE(value);
      value = 0xD201 * (temp + value) + 0x7F6A;
      ++index;
      --size;
    }
    while ( size );
  }
  v19 = &savedregs;
  v18 = System::__linkproc__ HandleFinally;
  ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
  __writefsdword(0, (unsigned int)&ExceptionList);
  UStrClr(&v25);
  UTF8ToUnicodeString((int)cchWideChar);
  UStrAsg(v24, v25, v14);
  __writefsdword(0, (unsigned int)ExceptionList);
  v19 = (int (__fastcall **)(_DWORD))&loc_9A685F;
  UStrClr(&v25);
  __writefsdword(0, (unsigned int)v26);
  savedregs = sub_9A6896;
  UStrArrayClr(&v21, 3);
  UStrArrayClr(&v25, 2);
  v15 = ((int (__fastcall *)(char **))LStrClr)(&cchWideChar);
  return sub_9A6896(v15);
}

py

import random
import string

# xor_dec
def xor_dec_9A66E8(data:bytes,value:int=0xba):
    out=bytearray(data)
    for i in range(len(data)):
        temp = data[i]  
        out[i] ^= (value >> 8) & 0xFF 
        value =0xD201 * (temp + value) + 0x7F6A
    return out

# xor_enc
def xor_enc_9A6610(data:bytes,value:int=0xba):
    out=bytearray(data)
    for i in range(len(data)):
        out[i] ^= (value >> 8) & 0xFF  
        value =0xD201 * (out[i] + value) + 0x7F6A
    return out

def checksum32(data:bytes):
    n=0
    for x in data:
        n+=x
    return n&0xffffffff

def gen(machineGuid:bytes,key:bytes=b'AAAAA-AAAAA-AAAAA'):

    if isinstance(machineGuid,str):
        machineGuid=machineGuid.encode()
    if isinstance(key,str):
        key=key.encode()

    machineGuid=machineGuid.lower()
    key=key.upper()
    licensekey_checksum=checksum32(key)
    # print('licensekey_checksum:%08x'%licensekey_checksum)
    mid_checksum=checksum32(machineGuid)
    # print('mid_checksum:%08x'%mid_checksum)
    Parity=mid_checksum-licensekey_checksum
    print('Parity:',Parity)
    stub=''.join(random.choices(string.ascii_uppercase,k=20))
    code=stub+str(Parity)
    print(f'Activate code:\n{code}')
    return code

image-20241103205213207

14.7、14.8 离线测试可用,程序联网便会进行网络校验,联网一定不通过!

image-20241103205236963

如果想修改名字可手动修改注册表项:

image-20241103210347976

如ikun 经过xor_enc_9A6610 加密后hexstr为 695DDF6E

image-20241103210329499

posted @ 2024-11-03 21:27  DirWangK  阅读(32)  评论(0编辑  收藏  举报