winrar-x64-712sc 记录

winrar-x64-712sc 记录

官方个人商业版:WinRAR 7.12 Final 官方正式版WinRAR简体中文版商业版 (2025/06/27)

https://www.win-rar.com/fileadmin/winrar-versions/sc/sc20250627/wrr/winrar-x64-712sc.exe

定位许可验证

如果您使用 WinRAR,您应该把注册 key 文件(rarreg.key)复制到 WinRAR 文件夹或 %APPDATA%\WinRAR 文件夹中。默认的 WinRAR 文件夹是“C:\Program Files\WinRAR”,但是用户能在安装 WinRAR 时修改它。您也可以拖放 rarreg.key 文件到 WinRAR 窗口来注册。

如果这个 key 是 RAR 或 zip 压缩文件,请从压缩文件中解压 rarreg.key 来注册您的 WinRAR。如果压缩文件的名称是 rarkey.rar,安装 key 文件的另一种方法是在 WinRAR 中打开此压缩文件,并在提示时选择“是”来确认。

如果您希望安装程序自动应用 rarreg.key,则可以将其与 WinRAR 安装程序 .exe 文件放在同一文件夹中。仅当找不到以前安装的密钥文件时,才使用此类 rarreg.key 文件。

通过“rarreg.key” 字符串定位到关键函数find_new_regkey_14019A158

通过创建“rarreg.key” 文件并拖放 rarreg.key 文件到 WinRAR 窗口来注册。 得到如下调用栈:

线程 ID      地址               返回到              返回自              大小  方    注释                                                                                        
4848 - 主线程                                                             
           0000001B4713DC28 00007FF73A6A30EF 00007FF73A6AA158 B0  用户模块 winrar.00007FF73A6AA158
           0000001B4713DCD8 00007FF73A6A2F03 00007FF73A6A30EF 30  用户模块 winrar.00007FF73A6A30EF
           0000001B4713DD08 00007FF73A6A2E93 00007FF73A6A2F03 70  用户模块 winrar.00007FF73A6A2F03
           0000001B4713DD78 00007FFC72C7C8BB 00007FF73A6A2E93 60  系统模块 winrar.00007FF73A6A2E93
           0000001B4713DDD8 00007FFC720D7BA3 00007FFC72C7C8BB A0  系统模块 ole32.CPrivDragDrop::PrivDragDrop+13B
           0000001B4713DE78 00007FFC7214180A 00007FFC720D7BA3 660 系统模块 rpcrt4.NdrInterfacePointerMemorySize+393
           0000001B4713E4D8 00007FFC720A6463 00007FFC7214180A 60  系统模块 rpcrt4.NdrClientCall3+225A
           0000001B4713E538 00007FFC71D849BF 00007FFC720A6463 40  系统模块 rpcrt4.NdrStubCall3+D3
           0000001B4713E578 00007FFC71D5671D 00007FFC71D849BF 60  系统模块 combase.CStdStubBuffer_Invoke+6F
           0000001B4713E5D8 00007FFC71D564A8 00007FFC71D5671D 150 系统模块 combase.ObjectMethodExceptionHandlingAction<<lambda_c9f3956a20c9da92a64affc24fdd69ec> >+4D
           0000001B4713E728 00007FFC71D89121 00007FFC71D564A8 40  系统模块 combase.DefaultStubInvoke+268
           0000001B4713E768 00007FFC71D5E84C 00007FFC71D89121 320 系统模块 combase.SyncServerCall::StubInvoke+41
           0000001B4713EA88 00007FFC71D5C209 00007FFC71D5E84C 80  系统模块 combase.ServerCall::ContextInvoke+83C
           0000001B4713EB08 00007FFC71D22619 00007FFC71D5C209 2F0 系统模块 combase.ReentrantSTAInvokeInApartment+1B9
           0000001B4713EDF8 00007FFC71D6A548 00007FFC71D22619 100 系统模块 combase.ComInvokeWithLockAndIPID+9A9
           0000001B4713EEF8 00007FFC71D68D79 00007FFC71D6A548 70  系统模块 combase.ThreadDispatch+468
           0000001B4713EF68 00007FFC712883F1 00007FFC71D68D79 160 系统模块 combase.ThreadWndProc+109
           0000001B4713F0C8 00007FFC71287EB1 00007FFC712883F1 80  系统模块 user32.DispatchMessageW+741
           0000001B4713F148 00007FFC71271884 00007FFC71287EB1 B0  系统模块 user32.DispatchMessageW+201
           0000001B4713F1F8 00007FFC7127157C 00007FFC71271884 60  系统模块 user32.DialogBoxIndirectParamAorW+4F4
           0000001B4713F258 00007FFC712713E2 00007FFC7127157C 40  系统模块 user32.DialogBoxIndirectParamAorW+1EC
           0000001B4713F298 00007FFC712BAF42 00007FFC712713E2 40  系统模块 user32.DialogBoxIndirectParamAorW+52
           0000001B4713F2D8 00007FF73A6B35D4 00007FFC712BAF42 210 用户模块 user32.DialogBoxParamW+72
           0000001B4713F4E8 00007FFC712883F1 00007FF73A6B35D4 160 系统模块 winrar.00007FF73A6B35D4
           0000001B4713F648 00007FFC71287EB1 00007FFC712883F1 80  系统模块 user32.DispatchMessageW+741
           0000001B4713F6C8 00007FF73A6B48FB 00007FFC71287EB1 70  用户模块 user32.DispatchMessageW+201
           0000001B4713F738 00007FF73A6B7658 00007FF73A6B48FB 620 用户模块 winrar.00007FF73A6B48FB
           0000001B4713FD58 00007FF73A6D6B32 00007FF73A6B7658 40  用户模块 winrar.00007FF73A6B7658
           0000001B4713FD98 00007FFC7164257D 00007FF73A6D6B32 30  系统模块 winrar.00007FF73A6D6B32
           0000001B4713FDC8 00007FFC72EAAF08 00007FFC7164257D 80  系统模块 kernel32.BaseThreadInitThunk+1D
           0000001B4713FE48 0000000000000000 00007FFC72EAAF08     用户模块 ntdll.RtlUserThreadStart+28


通过回溯和函数交叉引用,得到拖放注册逻辑在sub_14019C2F4 中通过RegisterDragDrop函数进行注册

HRESULT __fastcall sub_14019C2F4(HWND hWndParent)
{
  IDropTarget *pDropTarget; // rax

  pDropTarget = (IDropTarget *)operator new(8ui64);
  if ( pDropTarget )
    pDropTarget->lpVtbl = &DragDrop_14020BA40;

  pDropTarget = pDropTarget;
  hwnd = (__int64)hWndParent;
  return RegisterDragDrop(hWndParent, pDropTarget);
}

IDropTargetVtbl

rdata:000000014020BA40 ; IDropTargetVtbl DragDrop_14020BA40
.rdata:000000014020BA40 DragDrop_14020BA40 IDropTargetVtbl <offset QueryInterface_14019C290, \
.rdata:000000014020BA40                                         ; DATA XREF: sub_14019C2F4+18↑o
.rdata:000000014020BA40                                  offset AddRef_14018B7F0, offset Release_14019C340, \
.rdata:000000014020BA40                                  offset DragEnter_DragLeave_14003B590, \
.rdata:000000014020BA40                                  offset DragOver_140192630, \
.rdata:000000014020BA40                                  offset DragEnter_DragLeave_14003B590, \
.rdata:000000014020BA40                                  offset Drop_140192E20>

find_new_regkey_14019A158

void __fastcall find_new_regkey_14019A158(LPCWSTR lpExistingFileName)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  n3 = 0;
  v3 = 0xFFFFFFFFFFFFFFFFui64;
  // char is_registed_1400C729C()
  // {
  //   return is_registed_140251170;
  // }
  if ( !is_registed_1400C729C() )               // 爆破可关注is_registed_140251170 变量
    goto LABEL_8;

  if ( byte_14024ED1C )
    goto LABEL_8;

  // "发现新的注册密钥"
  str_14010A934 = get_str_14010A934(1520);
  *(_OWORD *)Caption = 0i64;
  v29 = 0i64;
  v5 = 0xFFFFFFFFFFFFFFFFui64;
  do
    ++v5;
  while ( *((_WORD *)str_14010A934 + v5) );

  wstring_140004168(Caption, (__int64)str_14010A934, v5);
  // "您希望使用新的注册码替换当前的 WinRAR 注册码吗?"
  str_14010A934_1 = get_str_14010A934(1521);
  *(_OWORD *)Text = 0i64;
  v31 = 0i64;
  v7 = 0xFFFFFFFFFFFFFFFFui64;
  do
    ++v7;
  while ( *((_WORD *)str_14010A934_1 + v7) );

  wstring_140004168(Text, (__int64)str_14010A934_1, v7);
  n3 = 3;
  v8 = 1;
  if ( sub_140178D64(hWndParent, Text, Caption, 0x24u) == 6 )
LABEL_8:
    v8 = 0;

  if ( (n3 & 2) != 0 )
  {
    n3 &= ~2u;
    std::wstring::~wstring((std::wstring *)Text);
  }

  if ( (n3 & 1) != 0 )
    std::wstring::~wstring((std::wstring *)Caption);

  if ( !v8 )
  {
    v32 = 0i64;
    si128 = 0i64;
    wstring_140004168(&v32, (__int64)L"rarreg.key", 0xAui64);
    sub_1400F5460(&lpNewFileName, &v32);
    if ( si128.m128i_i64[1] > 7ui64 )
    {
      v9 = (void *)v32;
      if ( (unsigned __int64)(2 * si128.m128i_i64[1] + 2) >= 0x1000 )
      {
        v9 = *(void **)(v32 - 8);
        if ( (unsigned __int64)(v32 - (_QWORD)v9 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(v9);
    }

    si128 = _mm_load_si128((const __m128i *)&xmmword_1401F32B0);
    LOWORD(v32) = 0;
    p_lpNewFileName = &lpNewFileName;
    if ( lpNewFileName._Myres > 7 )
      p_lpNewFileName = (std_wstring *)lpNewFileName.u._Ptr;

    lpExistingFileName_1 = lpExistingFileName;
    if ( *((_QWORD *)lpExistingFileName + 3) > 7ui64 )
      lpExistingFileName_1 = *(const WCHAR **)lpExistingFileName;

    v12 = CopyFileW(lpExistingFileName_1, p_lpNewFileName->u._Buf, 0);
    _Ptr_.u = 0i64;
    *(__m128i *)&_Ptr_._Mysize = _mm_load_si128((const __m128i *)&xmmword_1401F32B0);
    _Ptr_.u._Buf[0] = 0;
    LOBYTE(v13) = 1;
    sub_1400F54A4(&_Ptr_, v13);
    sub_1400F34BC(&_Ptr_);
    sub_140006F14(&_Ptr_, (__int64)L"rarreg.key", 0xAui64);
    if ( v12 )
    {
      sub_1400DD4E0(_Ptr_.u._Buf);
    }
    else
    {
      Ptr = &_Ptr_;
      if ( _Ptr_._Myres > 7 )
        Ptr = (std_wstring *)_Ptr_.u._Ptr;

      if ( *((_QWORD *)lpExistingFileName + 3) > 7ui64 )
        lpExistingFileName = *(LPCWSTR *)lpExistingFileName;

      CopyFileW(lpExistingFileName, Ptr->u._Buf, 0);
      wstring_1400048E8(&lpNewFileName, &_Ptr_, v15);
    }

    SetForegroundWindow(hWndParent);
    FlashWindow(hWndParent, 1);
    v16 = load_and_check_1400C62CC((LPCWSTR *)&lpNewFileName, 1);
    set_registed_1400C7684(v16);
    FlashWindow(hWndParent, 0);
    sub_140099420((WPARAM)&wParam_, v17, v18);
    if ( is_registed_1400C729C() )
    {
      // "注册已成功完成"
      str_14010A934_2 = get_str_14010A934(872);
      *(_OWORD *)Text = 0i64;
      v31 = 0i64;
      v20 = 0xFFFFFFFFFFFFFFFFui64;
      do
        ++v20;
      while ( *((_WORD *)str_14010A934_2 + v20) );

      wstring_140004168(Text, (__int64)str_14010A934_2, v20);
      // "这份 WinRAR 已经成功注册。谢谢您!"
      str_14010A934_3 = get_str_14010A934(0x367);
      *(_OWORD *)Caption = 0i64;
      v29 = 0i64;
      do
        ++v3;
      while ( *((_WORD *)str_14010A934_3 + v3) );

      wstring_140004168(Caption, (__int64)str_14010A934_3, v3);
      sub_140178D64(hWndParent, Caption, Text, 0x40u);
      if ( v29.m128i_i64[1] > 7ui64 )
      {
        v22 = *(void **)Caption;
        if ( (unsigned __int64)(2 * v29.m128i_i64[1] + 2) >= 0x1000 )
        {
          v22 = *(void **)(*(_QWORD *)Caption - 8i64);
          if ( (unsigned __int64)(*(_QWORD *)Caption - (_QWORD)v22 - 8i64) > 0x1F )
            invalid_parameter_noinfo_noreturn();
        }

        j_j_free(v22);
      }

      v23 = _mm_load_si128((const __m128i *)&xmmword_1401F32B0);
      v29 = v23;
      Caption[0] = 0;
      if ( v31.m128i_i64[1] > 7ui64 )
      {
        v24 = *(void **)Text;
        if ( (unsigned __int64)(2 * v31.m128i_i64[1] + 2) >= 0x1000 )
        {
          v24 = *(void **)(*(_QWORD *)Text - 8i64);
          if ( (unsigned __int64)(*(_QWORD *)Text - (_QWORD)v24 - 8i64) > 0x1F )
            invalid_parameter_noinfo_noreturn();
        }

        j_j_free(v24);
        v23 = _mm_load_si128((const __m128i *)&xmmword_1401F32B0);
      }

      v31 = v23;
      Text[0] = 0;
    }
    else
    {
      sub_1400DD4E0(lpNewFileName.u._Buf);
      // "注册失败"
      str_14010A934_4 = get_str_14010A934(870);
      sub_14018179C((__int64)str_14010A934_4);
      v23 = _mm_load_si128((const __m128i *)&xmmword_1401F32B0);
    }

    if ( _Ptr_._Myres > 7 )
    {
      _Ptr = _Ptr_.u._Ptr;
      if ( 2 * _Ptr_._Myres + 2 >= 0x1000 )
      {
        _Ptr = (wchar_t *)*((_QWORD *)_Ptr_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)((char *)_Ptr_.u._Ptr - (char *)_Ptr - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr);
      v23 = _mm_load_si128((const __m128i *)&xmmword_1401F32B0);
    }

    *(__m128i *)&_Ptr_._Mysize = v23;
    _Ptr_.u._Buf[0] = 0;
    std::wstring::~wstring((std::wstring *)&lpNewFileName);
  }
}

load_and_check_1400C62CC

char __fastcall load_and_check_1400C62CC(LPCWSTR *lpNewFileName, char flag)
{
  bool v4; // al
  char v5; // bl
  char *buf; // rax
  char *data; // rdi
  int sz; // eax
  char RarReg[112]; // [rsp+20h] [rbp-88h] BYREF

  RarReg_1400DB4E8((WrapFile *)RarReg);
  v4 = fopen_1400DBC10((WrapFile *)RarReg, (std_wstring *)lpNewFileName, 0);
  v5 = 0;
  if ( v4 )
  {
    buf = (char *)j__malloc_base(0x2000ui64);
    data = buf;
    if ( buf )
    {
      sz = fread_1400DC050((WrapFile *)RarReg, (__int64)buf, 0x2000ui64);
      if ( sz > 0 && check_data_1400C6390(data, sz, flag) )
        v5 = 1;

      free(data);
    }
  }

  sub_1400DB548((WrapFile *)RarReg);
  return v5;
}

关键校验check_data_1400C6390

当第三个参数不为0时,将对rarkey进行完整校验,否则只校验crc32

char __fastcall check_data_1400C6390(char *data, __int64 sz, char flag)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  data_1 = data;
  sz_1 = sz;
  if ( (unsigned int)x_crc32_1400CCF28(
                       0xFFFFFFFF,
                       "70c2441db366d92ea7be1342b3bf629026ba92bb675f06e684bdd34511097434",//内置ecc 公钥
                       0x40ui64) != 0x26E831B8 )
    return 0;

  memset(temp, 0, sizeof(temp));
  memmove(lic_data_140251180, temp, 0x604ui64);
  // RAR registration data
  while ( get_line_1400C71F4(&data_1, &sz_1, temp, 0x100ui64) && temp[0] == '#' )
    ;

  // 获取用户名
  get_line_1400C71F4(&data_1, &sz_1, username, 0x100ui64);
  // 许可类型
  get_line_1400C71F4(&data_1, &sz_1, lictype, 0x100ui64);
  // UID
  get_line_1400C71F4(&data_1, &sz_1, temp, 0x100ui64);
  memset(&lic_data, 0, 0x18);
  lic_data._Myres = 0xFi64;
  LOBYTE(lic_data.u._Buf[0]) = 0;
  n7 = 7i64;
  Size_5 = 0xFFFFFFFFFFFFFFFFui64;
  v6 = 1;
  do
  {
    get_line_1400C71F4(&data_1, &sz_1, temp, 0x100ui64);
    Size = 0xFFFFFFFFFFFFFFFFui64;
    do
      ++Size;
    while ( temp[Size] );
	//获取lic_data(RegisterData),一共7行,进行拼接
    wstr_add_140040AF8(&lic_data, temp, Size);
    --n7;
  }
  while ( n7 );

  if ( lic_data._Mysize < 0xA )
    goto LABEL_170;

  Ptr_10 = &lic_data;
  if ( lic_data._Myres > 0xF )
    Ptr_10 = (std_wstring *)lic_data.u._Ptr;

  // lic_data[:2] str转int,表示RegisterData[0]的长度
  number0_64 = (unsigned int)stoi_1400C768C((char *)Ptr_10, 2ui64);
  Ptr_1 = (__int64)&lic_data;
  if ( lic_data._Myres > 0xF )
    Ptr_1 = (__int64)lic_data.u._Ptr;

  // lic_data[2:2+3] str转int,表示RegisterData[1]的长度
  number1_122 = (unsigned int)stoi_1400C768C((char *)(Ptr_1 + 2), 3ui64);
  Ptr_2 = (__int64)&lic_data;
  if ( lic_data._Myres > 0xF )
    Ptr_2 = (__int64)lic_data.u._Ptr;

  // lic_data[5:5+3] str转int,表示RegisterData[2]的长度
  number2_122 = (unsigned int)stoi_1400C768C((char *)(Ptr_2 + 5), 3ui64);
  Ptr_3 = (__int64)&lic_data;
  if ( lic_data._Myres > 0xF )
    Ptr_3 = (__int64)lic_data.u._Ptr;

  // lic_data[8:8+2] str转int,表示RegisterData[3]的长度
  number3_50 = (unsigned int)stoi_1400C768C((char *)(Ptr_3 + 8), 2ui64);
  number = (char *)(number0_64 + number1_122 + number2_122 + number3_50);
    //RegisterData的长度+0xb 不能超出总数据大小// 0xb 对应后面checksum值的最大长度
  if ( (unsigned __int64)(number + 0xB) > lic_data._Mysize )
  {
LABEL_170:
    v6 = 0;
  }
  else
  {
    RegisterData0_.u = 0i64;
    si128 = _mm_load_si128((const __m128i *)&Mysize);
    *(__m128i *)&RegisterData0_._Mysize = si128;
    RegisterData0_.u._Buf[0] = 0;
    RegisterData1_.u = 0i64;
    *(__m128i *)&RegisterData1_._Mysize = si128;
    RegisterData1_.u._Buf[0] = 0;
    RegisterData2_.u = 0i64;
    *(__m128i *)&RegisterData2_._Mysize = si128;
    RegisterData2_.u._Buf[0] = 0;
    RegisterData3_.u = 0i64;
    *(__m128i *)&RegisterData3_._Mysize = si128;
    RegisterData3_.u._Buf[0] = 0;
    memset(&temp_1, 0, sizeof(temp_1));
    if ( lic_data._Mysize < 0xA )
      unknown_libname_8();

    Size_1 = (unsigned int)number0_64;
    if ( lic_data._Mysize - 0xA < number0_64 )
      Size_1 = lic_data._Mysize - 0xA;

    Ptr_4 = (__int64)&lic_data;
    if ( lic_data._Myres > 0xF )
      Ptr_4 = (__int64)lic_data.u._Ptr;

    string_14001371C((std_wstring *)&temp_1, (wchar_t *)(Ptr_4 + 0xA), Size_1);
    if ( RegisterData0_._Myres > 0xF )
    {
      Ptr = RegisterData0_.u._Ptr;
      if ( RegisterData0_._Myres + 1 >= 0x1000 )
      {
        Ptr = (char *)*((_QWORD *)RegisterData0_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData0_.u._Ptr - Ptr - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(Ptr);
    }

    RegisterData0_ = temp_1;
    *(__m128i *)&temp_1._Mysize = si128;
    temp_1.u._Buf[0] = 0;
    _Mysize = number0_64 + 0xA;
    memset(&temp_2, 0, sizeof(temp_2));
    if ( lic_data._Mysize < _Mysize )
      unknown_libname_8();

    Size_2 = number1_122;
    if ( lic_data._Mysize - _Mysize < number1_122 )
      Size_2 = lic_data._Mysize - _Mysize;

    Ptr_5 = (__int64)&lic_data;
    if ( lic_data._Myres > 0xF )
      Ptr_5 = (__int64)lic_data.u._Ptr;

    string_14001371C((std_wstring *)&temp_2, (wchar_t *)(_Mysize + Ptr_5), Size_2);
    if ( RegisterData1_._Myres > 0xF )
    {
      _Ptr_1 = RegisterData1_.u._Ptr;
      if ( RegisterData1_._Myres + 1 >= 0x1000 )
      {
        _Ptr_1 = (char *)*((_QWORD *)RegisterData1_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData1_.u._Ptr - _Ptr_1 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr_1);
    }

    RegisterData1_ = temp_2;
    *(__m128i *)&temp_2._Mysize = si128;
    temp_2.u._Buf[0] = 0;
    _Mysize_1 = number1_122 + _Mysize;
    memset(&temp_1, 0, sizeof(temp_1));
    if ( lic_data._Mysize < _Mysize_1 )
      unknown_libname_8();

    Size_3 = number2_122;
    if ( lic_data._Mysize - _Mysize_1 < number2_122 )
      Size_3 = lic_data._Mysize - _Mysize_1;

    Ptr_6 = (__int64)&lic_data;
    if ( lic_data._Myres > 0xF )
      Ptr_6 = (__int64)lic_data.u._Ptr;

    // RegisterData[2]
    string_14001371C((std_wstring *)&temp_1, (wchar_t *)(_Mysize_1 + Ptr_6), Size_3);
    if ( RegisterData2_._Myres > 0xF )
    {
      _Ptr_2 = RegisterData2_.u._Ptr;
      if ( RegisterData2_._Myres + 1 >= 0x1000 )
      {
        _Ptr_2 = (char *)*((_QWORD *)RegisterData2_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData2_.u._Ptr - _Ptr_2 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr_2);
    }

    RegisterData2_ = temp_1;
    *(__m128i *)&temp_1._Mysize = si128;
    temp_1.u._Buf[0] = 0;
    _Mysize_2 = number2_122 + _Mysize_1;
    memset(&temp_2, 0, sizeof(temp_2));
    if ( lic_data._Mysize < _Mysize_2 )
      unknown_libname_8();

    Size_4 = number3_50;
    if ( lic_data._Mysize - _Mysize_2 < number3_50 )
      Size_4 = lic_data._Mysize - _Mysize_2;

    Ptr_7 = (__int64)&lic_data;
    if ( lic_data._Myres > 0xF )
      Ptr_7 = (__int64)lic_data.u._Ptr;

    // RegisterData[3]
    string_14001371C((std_wstring *)&temp_2, (wchar_t *)(_Mysize_2 + Ptr_7), Size_4);
    if ( RegisterData3_._Myres > 0xF )
    {
      _Ptr_3 = RegisterData3_.u._Ptr;
      if ( RegisterData3_._Myres + 1 >= 0x1000 )
      {
        _Ptr_3 = (char *)*((_QWORD *)RegisterData3_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData3_.u._Ptr - _Ptr_3 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr_3);
    }

    RegisterData3_ = temp_2;
    *(__m128i *)&temp_2._Mysize = si128;
    temp_2.u._Buf[0] = 0;
    v32 = number3_50 + _Mysize_2;
    Ptr_8 = &lic_data;
    if ( lic_data._Myres > 0xF )
      Ptr_8 = (std_wstring *)lic_data.u._Ptr;
	//RegisterData 后面的数据表示checksum
    checksum = stoi_1400C768C((char *)Ptr_8 + v32, lic_data._Mysize - v32);
    i_1 = 0xFFFFFFFFFFFFFFFFui64;
    do
      ++i_1;
    while ( lictype[i_1] );
	//计算lictype 校验和
    v36 = x_crc32_1400CCF28(0xFFFFFFFF, lictype, i_1);
    i_2 = 0xFFFFFFFFFFFFFFFFui64;
    do
      ++i_2;
    while ( username[i_2] );
	//计算username 校验和
    v38 = x_crc32_1400CCF28(v36, username, i_2);
    Ptr_9 = &lic_data;
    if ( lic_data._Myres > 0xF )
      Ptr_9 = (std_wstring *)lic_data.u._Ptr;

    // 校验xcrc32,lic_data+0xa 对应RegisterData 数据,0xa为lic_data开头对应的4个RegisterData长度(2+3+3+2)的字符串大小
    //这里的xcrc32 为crc32值取反,//^0xffffffff
    if ( (unsigned int)x_crc32_1400CCF28(v38, (char *)&Ptr_9->u._Ptr + 0xA, (unsigned __int64)number) == checksum )
    {
      get_utf8_str_1400C719C(username, lic_data_140251180, 0x100i64);
      get_utf8_str_1400C719C(lictype, lic_data_140251180_, 0x100i64);
      sz_2 = 0;
      LODWORD(sz_1) = 0;
      if ( lictype[0] )
      {
        Str_1 = lictype;
        sz_3 = 0i64;
        while ( 1 )
        {
          if ( (unsigned int)str_cmp_140112C70(Str_1, "Version: ", 9ui64)
            && (unsigned int)str_cmp_140112C70(Str_1, "VersMax: ", 9ui64) )
          {
            goto LABEL_96;
          }

          for ( i = &lictype[sz_3 + 9]; ; ++i )
          {
            if ( !*i )
              goto LABEL_143;

            if ( i[0xFFFFFFFF] == ' ' && IsDigitChar_1401126C0(*i) )
              break;
          }

          n7_1 = sub_1401D5830();
          v45 = strchr(i, '.');
          v46 = v45;
          if ( !v45 )
            goto LABEL_81;

          v47 = v45 + 1;
          if ( v45[1] == '*' )
            break;

          n0xC = sub_1401D5830();
          if ( IsDigitChar_1401126C0(*v47) )
          {
            Size_5 = 0xFFFFFFFFFFFFFFFFui64;
            if ( !IsDigitChar_1401126C0(v46[2]) )
              n0xC *= 0xA;
          }
          else
          {
            Size_5 = 0xFFFFFFFFFFFFFFFFui64;
          }

LABEL_83:
          n0xC_1 = 0;
          if ( n0xC > 0 )
            n0xC_1 = n0xC;

          dword_140251780 = 0x64 * n7_1 + n0xC_1;
          v50 = n7_1 == 7 && (n0xC == 0xFFFFFFFF || (unsigned int)(n0xC - 0xA) < 0xA);
          sz_2 = sz_1;
          if ( lictype[(unsigned int)(sz_1 + 4)] == 0x4D && (n7_1 > 7 || n7_1 == 7 && n0xC >= 0xC) )
            v50 = 1;

          if ( !v50 )
          {
            sprintf_s(DstBuf, 0x32ui64, L"WinRAR %d.%d", (unsigned int)n7_1, n0xC);
            LODWORD(v73) = 0xC;
            sprintf_s(DstBuf_1, 0x32ui64, L"WinRAR %d.%d", 7i64, v73);
            // "可用的许可证密钥的有效期仅有 %s"
            str_14010A934 = get_str_14010A934(961);
            sub_140112F78((__int64)&stub, (__int64)str_14010A934, DstBuf);
            _Ptr_4 = &stub;
            if ( stub._Myres > 7 )
              _Ptr_4 = (std_string *)stub.u._Ptr;

            sub_140112F30(&unk_140251580, _Ptr_4, 0x100i64);
            sub_14018179C((__int64)L"%s. %s", DstBuf_1, &unk_140251580);
            std::wstring::~wstring((std::wstring *)&stub);
            goto LABEL_143;
          }

LABEL_96:
          if ( !(unsigned int)str_cmp_140112C70(Str_1, "DateMax: ", 9ui64) )
          {
            for ( j = &lictype[sz_3 + 9]; ; ++j )
            {
              if ( !*j )
                goto LABEL_143;

              if ( j[0xFFFFFFFF] == 0x20 && IsDigitChar_1401126C0(*j) )
                break;
            }

            v52 = 1;
            v53 = 1;
            v54 = sub_1401D5830();
            v55 = strchr(j, 0x2E);
            if ( v55 )
            {
              v56 = v55 + 1;
              v52 = sub_1401D5830();
              if ( strchr(v56, 0x2E) )
                v53 = sub_1401D5830();
            }

            number = 0i64;
            sub_140115084(&number);
            sub_140114D38(&number, (unsigned int *)&stub);
            if ( v54 <= *(_DWORD *)stub.u._Buf
              && (v54 != *(_DWORD *)stub.u._Buf
               || v52 <= HIDWORD(stub.u._Ptr) && (v52 != HIDWORD(stub.u._Ptr) || v53 < *((_DWORD *)&stub.u._Ptr + 2))) )
            {
              goto LABEL_143;
            }
          }

          LODWORD(sz_1) = ++sz_2;
          sz_3 = sz_2;
          Str_1 = &lictype[sz_2];
          if ( !*Str_1 )
            goto LABEL_112;
        }

        Size_5 = 0xFFFFFFFFFFFFFFFFui64;

LABEL_81:
        n0xC = 0xFFFFFFFF;
        goto LABEL_83;
      }

LABEL_112:
      if ( flag )
      {
        memset(&stub, 0, sizeof(stub));
        string_14001371C(
         &stub,
          "70c2441db366d92ea7be1342b3bf629026ba92bb675f06e684bdd34511097434",
          0x40ui64);
        memset(&str_lictype, 0, sizeof(str_lictype));
        do
          ++Size_5;
        while ( lictype[Size_5] );

        string_14001371C(&str_lictype, lictype, Size_5);
        //ECC 签名验证,参数1:msg 参数2:公钥,参数3:签名
        //1、取RegisterData[1] 作为签名数据,lic_type作为msg,使用内置公钥(winrar_pubkey_key,70c2441db366d92ea7be1342b3bf629026ba92bb675f06e684bdd34511097434)验证lic_type 的签名(RegisterData[1])
        args_3___sig = Verify_1400CF02C(&str_lictype, &stub, &RegisterData1_);
        if ( str_lictype._Myres > 0xF )
        {
          _Ptr_6 = str_lictype.u._Ptr;
          if ( str_lictype._Myres + 1 >= 0x1000 )
          {
            _Ptr_6 = (char *)*((_QWORD *)str_lictype.u._Ptr + 0xFFFFFFFF);
            if ( (unsigned __int64)(str_lictype.u._Ptr - _Ptr_6 - 8) > 0x1F )
              invalid_parameter_noinfo_noreturn();
          }

          j_j_free(_Ptr_6);
        }

        *(__m128i *)&str_lictype._Mysize = si128;
        str_lictype.u._Buf[0] = 0;
        if ( stub._Myres > 0xF )
        {
          _Ptr_7 = stub.u._Ptr;
          if ( stub._Myres + 1 >= 0x1000 )
          {
            _Ptr_7 = (char *)*((_QWORD *)stub.u._Ptr + 0xFFFFFFFF);
            if ( (unsigned __int64)(stub.u._Ptr - _Ptr_7 - 8) > 0x1F )
              invalid_parameter_noinfo_noreturn();
          }

          j_j_free(_Ptr_7);
        }

        *(__m128i *)&stub._Mysize = si128;
        stub.u._Buf[0] = 0;
        if ( !args_3___sig )
          goto LABEL_143;


        str_add_1400C6250(&temp_1, username, &RegisterData0_);
        memset(&stub, 0, sizeof(stub));
        string_14001371C(
          (std_wstring *)&stub,
          (wchar_t *)"70c2441db366d92ea7be1342b3bf629026ba92bb675f06e684bdd34511097434",
          0x40ui64);
        //2、取RegisterData[2] 作为签名数据, username+RegisterData[0]作为msg,使用内置公钥验证签名
        v60 = Verify_1400CF02C(&temp_1, &stub, &RegisterData2_);
        if ( stub._Myres > 0xF )
        {
          _Ptr_8 = stub.u._Ptr;
          if ( stub._Myres + 1 >= 0x1000 )
          {
            _Ptr_8 = (char *)*((_QWORD *)stub.u._Ptr + 0xFFFFFFFF);
            if ( (unsigned __int64)(stub.u._Ptr - _Ptr_8 - 8) > 0x1F )
              invalid_parameter_noinfo_noreturn();
          }

          j_j_free(_Ptr_8);
        }

        *(__m128i *)&stub._Mysize = si128;
        stub.u._Buf[0] = 0;
        if ( !v60 )
          goto LABEL_135;

        temp_2.u = 0i64;
        *(__m128i *)&temp_2._Mysize = si128;
        temp_2.u._Buf[0] = 0;
         //3、username+RegisterData[0] 作为msg ,通过RegisterData[3]生成私钥(公钥对应RegisterData[0]),msg签名得到temp_Signature,
          //参数1:msg 参数2:data 参数3:Signature
        gen_key_and_Signature_1400CECC4(&temp_1, &RegisterData3_, &temp_2);
        //4、使用RegisterData[0] (通过RegisterData[3]生成的公钥)作为公钥,验证temp_1(username+RegisterData[0])的签名temp_Signature
        if ( !(unsigned int)Verify_1400CF02C(&temp_1, &RegisterData0_, &temp_2) )
        {
          if ( temp_2._Myres <= 0xF )
          {
LABEL_134:
            *(__m128i *)&temp_2._Mysize = si128;
            temp_2.u._Buf[0] = 0;

LABEL_135:
            if ( temp_1._Myres <= 0xF )
            {
LABEL_139:
              *(__m128i *)&temp_1._Mysize = si128;
              temp_1.u._Buf[0] = 0;
              goto LABEL_143;
            }

            _Ptr_9 = temp_1.u._Ptr;
            if ( temp_1._Myres + 1 < 0x1000
              || (_Ptr_9 = (char *)*((_QWORD *)temp_1.u._Ptr + 0xFFFFFFFF),
                  (unsigned __int64)(temp_1.u._Ptr - _Ptr_9 - 8) <= 0x1F) )
            {
              j_j_free(_Ptr_9);
              goto LABEL_139;
            }

LABEL_189:
            invalid_parameter_noinfo_noreturn();
          }

          _Ptr_10 = temp_2.u._Ptr;
          if ( temp_2._Myres + 1 < 0x1000
            || (_Ptr_10 = (char *)*((_QWORD *)temp_2.u._Ptr + 0xFFFFFFFF),
                (unsigned __int64)(temp_2.u._Ptr - _Ptr_10 - 8) <= 0x1F) )
          {
            j_j_free(_Ptr_10);
            goto LABEL_134;
          }

LABEL_190:
          invalid_parameter_noinfo_noreturn();
        }

        if ( temp_2._Myres > 0xF )
        {
          _Ptr_12 = temp_2.u._Ptr;
          if ( temp_2._Myres + 1 >= 0x1000 )
          {
            _Ptr_12 = (char *)*((_QWORD *)temp_2.u._Ptr + 0xFFFFFFFF);
            if ( (unsigned __int64)(temp_2.u._Ptr - _Ptr_12 - 8) > 0x1F )
              goto LABEL_190;
          }

          j_j_free(_Ptr_12);
        }

        *(__m128i *)&temp_2._Mysize = si128;
        temp_2.u._Buf[0] = 0;
        if ( temp_1._Myres > 0xF )
        {
          _Ptr_13 = temp_1.u._Ptr;
          if ( temp_1._Myres + 1 >= 0x1000 )
          {
            _Ptr_13 = (char *)*((_QWORD *)temp_1.u._Ptr + 0xFFFFFFFF);
            if ( (unsigned __int64)(temp_1.u._Ptr - _Ptr_13 - 8) > 0x1F )
              goto LABEL_189;
          }

          j_j_free(_Ptr_13);
        }

        *(__m128i *)&temp_1._Mysize = si128;
        temp_1.u._Buf[0] = 0;
      }
    }
    else
    {
LABEL_143:
      v6 = 0;
    }

    if ( RegisterData3_._Myres > 0xF )
    {
      _Ptr_14 = RegisterData3_.u._Ptr;
      if ( RegisterData3_._Myres + 1 >= 0x1000 )
      {
        _Ptr_14 = (char *)*((_QWORD *)RegisterData3_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData3_.u._Ptr - _Ptr_14 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr_14);
    }

    *(__m128i *)&RegisterData3_._Mysize = si128;
    RegisterData3_.u._Buf[0] = 0;
    if ( RegisterData2_._Myres > 0xF )
    {
      _Ptr_15 = RegisterData2_.u._Ptr;
      if ( RegisterData2_._Myres + 1 >= 0x1000 )
      {
        _Ptr_15 = (char *)*((_QWORD *)RegisterData2_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData2_.u._Ptr - _Ptr_15 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr_15);
    }

    *(__m128i *)&RegisterData2_._Mysize = si128;
    RegisterData2_.u._Buf[0] = 0;
    if ( RegisterData1_._Myres > 0xF )
    {
      _Ptr_16 = RegisterData1_.u._Ptr;
      if ( RegisterData1_._Myres + 1 >= 0x1000 )
      {
        _Ptr_16 = (char *)*((_QWORD *)RegisterData1_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData1_.u._Ptr - _Ptr_16 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr_16);
    }

    *(__m128i *)&RegisterData1_._Mysize = si128;
    RegisterData1_.u._Buf[0] = 0;
    if ( RegisterData0_._Myres > 0xF )
    {
      _Ptr_17 = RegisterData0_.u._Ptr;
      if ( RegisterData0_._Myres + 1 >= 0x1000 )
      {
        _Ptr_17 = (char *)*((_QWORD *)RegisterData0_.u._Ptr + 0xFFFFFFFF);
        if ( (unsigned __int64)(RegisterData0_.u._Ptr - _Ptr_17 - 8) > 0x1F )
          invalid_parameter_noinfo_noreturn();
      }

      j_j_free(_Ptr_17);
    }

    *(__m128i *)&RegisterData0_._Mysize = si128;
    RegisterData0_.u._Buf[0] = 0;
  }

  if ( lic_data._Myres > 0xF )
  {
    _Ptr_18 = lic_data.u._Ptr;
    if ( lic_data._Myres + 1 >= 0x1000 )
    {
      _Ptr_18 = (wchar_t *)*((_QWORD *)lic_data.u._Ptr + 0xFFFFFFFF);
      if ( (unsigned __int64)((char *)lic_data.u._Ptr - (char *)_Ptr_18 - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }

    j_j_free(_Ptr_18);
  }

  lic_data._Mysize = 0i64;
  lic_data._Myres = 0xFi64;
  LOBYTE(lic_data.u._Buf[0]) = 0;
  return v6;
}

RegisterData验证流程

1、取RegisterData[1] 作为签名数据,lic_type作为msg,使用内置公钥(winrar_pubkey_key,70c2441db366d92ea7be1342b3bf629026ba92bb675f06e684bdd34511097434)验证lic_type 的签名(RegisterData[1])

2、取RegisterData[2] 作为签名数据, username+RegisterData[0]作为msg,使用内置公钥验证签名(RegisterData[2])

3、username+RegisterData[0] 作为msg ,通过RegisterData[3]生成私钥(公钥对应RegisterData[0]),msg签名得到temp_Signature,

4、使用RegisterData[0] (通过RegisterData[3]生成的公钥)作为公钥,验证msg(username+RegisterData[0])的签名temp_Signature

生成私钥gen_key_and_Signature_1400CECC4

void __fastcall gen_key_and_Signature_1400CECC4(std_string *msg, std_string *data, std_string *Signature)
{
  // [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]

  memset(&generator, 0, sizeof(generator));
  sha1_get_generator_1400D0888(&generator, data);// 得到generator
  // get_private_key,15次循环中,生成私钥
  sha1_get_private_key_1400D0908(&generator, &privateKey);
  Mysize = msg->_Mysize;
  if ( msg->_Myres > 0xF )
    msg = (std_string *)msg->u._Ptr;

  // def get_hash_and_rand(s: str, generator: bytes):
  //     sha1 = hashlib.sha1()
  //     sha1.update(s.encode())
  //     generator += (
  //         b"".join([sha1.digest()[i * 4 : (i + 1) * 4][::-1] for i in range(5)])
  //         + b"\x43\x8d\xfd\x0f\x7c\x3c\xe3\xb4\xd1\x1b\x46\x53\x46\xa5\x27\x0f\x0d\xd9\x50\x10"
  //     )
  //     print(generator[20:50].hex())
  //     hash = int.from_bytes(generator[20:50], "little")
  //     rand = b""
  //     for i in range(16, 31):
  //         sha1 = hashlib.sha1()
  //         sha1.update(i.to_bytes(4, "little") + generator)
  //         rand += sha1.digest()[3:1:-1]
  //     rand = int.from_bytes(rand, "little")
  //     return hash, rand

  // msg==>
  x_sha1_1400D0758(&generator, msg, Mysize, 2i64);//生成msg的hash
  hex2bignumb_1400D0660(generator.msg_hash_numb, &hash);//转大数,只取30字节
  clear_1400CFF20();
  do
  {
    sha1_get_private_key_1400D0908(&generator, &rand);// rand
    ECC_GenerateSignature_1400CF368(&privateKey, &rand, &hash, &signature);//签名
  }
  while ( !signature.r.numbSize );

  memset(&a3__1, 0, 0x18);
  a3__1._Myres = 0xFi64;
  a3__1.u._Buf[0] = 0;
  a3_.u = 0i64;
  *(__m128i *)&a3_._Mysize = _mm_load_si128((const __m128i *)&::Mysize);
  a3_.u._Buf[0] = 0;
  sub_1400D094C(signature.s.number, 19ui64, &a3__1);
  sub_1400D094C(&signature.r.numbSize, 19ui64, &a3_);
  sprintf_s_0(DstBuf, 0xAui64, "%02u", LODWORD(a3__1._Mysize));
  Size = 0xFFFFFFFFFFFFFFFFui64;
  do
    ++Size;
  while ( DstBuf[Size] );

  _Mysize_1 = a3__1._Mysize;
  if ( 0x7FFFFFFFFFFFFFFFi64 - a3__1._Mysize < Size )
    unknown_libname_7();

  a3__2 = &a3__1;
  if ( a3__1._Myres > 0xF )
    a3__2 = (std_string *)a3__1.u._Ptr;

  LOBYTE(_Mysize_1) = v16;
  str_add_2_14003F53C(&Ptr_, _Mysize_1, (wchar_t **)&a3__1, DstBuf, Size, a3__2, a3__1._Mysize);
  a2_ = str_add_1400CEC4C(&v20, &Ptr_, &a3_);
  str_140069B30(Signature, a2_);
  if ( v20._Myres > 0xF )
  {
    Ptr = v20.u._Ptr;
    if ( v20._Myres + 1 >= 0x1000 )
    {
      Ptr = (char *)*((_QWORD *)v20.u._Ptr + 0xFFFFFFFF);
      if ( (unsigned __int64)(v20.u._Ptr - Ptr - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }

    j_j_free(Ptr);
  }

  si128 = _mm_load_si128((const __m128i *)&::Mysize);
  *(__m128i *)&v20._Mysize = si128;
  v20.u._Buf[0] = 0;
  if ( Ptr_._Myres > 0xF )
  {
    _Ptr_1 = Ptr_.u._Ptr;
    if ( Ptr_._Myres + 1 >= 0x1000 )
    {
      _Ptr_1 = (char *)*((_QWORD *)Ptr_.u._Ptr + 0xFFFFFFFF);
      if ( (unsigned __int64)(Ptr_.u._Ptr - _Ptr_1 - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }

    j_j_free(_Ptr_1);
    si128 = _mm_load_si128((const __m128i *)&::Mysize);
  }

  *(__m128i *)&Ptr_._Mysize = si128;
  Ptr_.u._Buf[0] = 0;
  sub_1400D03E4();
  memset(&generator, 0, sizeof(generator));
  if ( a3_._Myres > 0xF )
  {
    _Ptr_2 = a3_.u._Ptr;
    if ( a3_._Myres + 1 >= 0x1000 )
    {
      _Ptr_2 = (char *)*((_QWORD *)a3_.u._Ptr + 0xFFFFFFFF);
      if ( (unsigned __int64)(a3_.u._Ptr - _Ptr_2 - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }

    j_j_free(_Ptr_2);
  }

  *(__m128i *)&a3_._Mysize = _mm_load_si128((const __m128i *)&::Mysize);
  a3_.u._Buf[0] = 0;
  if ( a3__1._Myres > 0xF )
  {
    _Ptr = a3__1.u._Ptr;
    if ( a3__1._Myres + 1 >= 0x1000 )
    {
      _Ptr = (char *)*((_QWORD *)a3__1.u._Ptr + 0xFFFFFFFF);
      if ( (unsigned __int64)(a3__1.u._Ptr - _Ptr - 8) > 0x1F )
        invalid_parameter_noinfo_noreturn();
    }

    j_j_free(_Ptr);
  }

  a3__1._Mysize = 0i64;
  a3__1._Myres = 0xFi64;
  a3__1.u._Buf[0] = 0;
}

相关结构

struct XHashNumber
{
  int allSz;
  int index;
  int generator_sha1_numb[5];
  int msg_hash_numb[11];
};

struct  XNumber
{
  unsigned int numbSize;
  unsigned int number[17];
};

struct SHA1_CTX
{
  _DWORD state_0[5];
  __int64 count_18;
  unsigned __int8 buffer_20[64];
};

sha1_get_generator_1400D0888

//sha1 计算结果 时:将state[5]数组按大端序转bytes,(表现为标准sha1值每4字节倒序)

void __fastcall sha1_get_generator_1400D0888(XHashNumber *Dst, std_string *Ptr)
{
  unsigned __int64 Mysize; // r8
  SHA1_CTX SHA1_; // [rsp+20h] [rbp-78h] BYREF

  rage::Sha1::Init(&SHA1_);
  Mysize = Ptr->_Mysize;
  if ( Ptr->_Myres > 0xF )
    Ptr = (std_string *)Ptr->u._Ptr;

  sha1_update_140111248(&SHA1_, Ptr->u._Buf, Mysize);
  sha1_done(&SHA1_, (unsigned int *)Dst->generator_sha1_numb);
  Dst->allSz = 6;
}

sha1_get_private_key_1400D0908

struct XHashNumber
{
  int allSz;
  int index;
  int generator_sha1_numb[5];
  int msg_hash_numb[11];
};
int __fastcall sha1_get_private_key_1400D0908(XHashNumber *generator, XNumber *privateKey)
{
  __int64 i; // rbx
  int v; // eax

  // def get_private_key(generator: bytes):
  //     private_key = b""
  //     for i in range(1, 16):
  //         sha1 = hashlib.sha1()
  //         sha1.update(i.to_bytes(4, "little") + generator)
  //         private_key += sha1.digest()[3:1:-1] //只保留前2字节,对应标准sha1结果的[2:4]
  //     return int.from_bytes(private_key, "little")
  privateKey->numbSize = 0xF;
  for ( i = 1i64; i < 0x10; ++i )
  {
    v = sha1_numb_1400D068C(generator);
     //只保留前2字节,对应标准sha1结果的[2:4]
    *(&privateKey->numbSize + i) = v;
  }

  return v;
}

WORD __fastcall sha1_numb_1400D068C(XHashNumber *Dst)
{
  int *number_ptr; // r8
  unsigned int bitSize; // er9
  int v4; // er11
  unsigned int i; // er10
  __int64 v6; // rax
  unsigned int v7; // edx
  SHA1_CTX context; // [rsp+20h] [rbp-E8h] BYREF
  char digest[20]; // [rsp+80h] [rbp-88h] BYREF
  char data[80]; // [rsp+A0h] [rbp-68h] BYREF

  number_ptr = &Dst->index;
  bitSize = 0;
  ++Dst->index;
  if ( Dst->allSz )
  {
    do
    {
      v4 = 0;
      for ( i = 0; i < 0x20; i += 8 )
      {
        v6 = 4 * bitSize + v4++;
        v7 = (unsigned int)*number_ptr >> i;
        data[v6] = v7;
      }

      ++bitSize;
      ++number_ptr;
    }
    while ( bitSize < Dst->allSz );
  }

  rage::Sha1::Init(&context);
  sha1_update_140111248(&context, data, (unsigned int)(4 * Dst->allSz));
  sha1_done(&context, (unsigned int *)digest);
  // 这里只取前2字节,对应标准sha1结果的[2:4]
  return *(_WORD *)digest;
}

消息hash算法

__int64 __fastcall x_sha1_1400D0758(XHashNumber *Dst, _QWORD *msg, __int64 msg_size, __int64 n2)
{
  unsigned __int8 v4; // di
  __int64 n2_1; // rbx
  int n2_2; // eax
  char v10; // al
  SHA1_CTX *context; // rsi
  __int64 n2_3; // r14
  __int64 numbSize; // rax
  char data[16]; // [rsp+20h] [rbp-B9h] BYREF
  SHA1_CTX context_[2]; // [rsp+30h] [rbp-A9h] BYREF

  v4 = 0;
  n2_1 = (unsigned int)n2;
  data[0] = 0;
  if ( (int)n2 > 0 )
  {
    LOBYTE(n2_2) = 0;
    do
    {
      rage::Sha1::Init(&context_[(unsigned __int8)n2_2]);
      v10 = data[0];
      if ( data[0] == 1 )
      {
        sha1_update_140111248(&context_[1], data, 1ui64);
        v10 = data[0];
      }

      n2_2 = (unsigned __int8)(v10 + 1);
      data[0] = n2_2;
    }
    while ( n2_2 < (int)n2_1 );

    context = context_;
    n2_3 = n2_1;
    do
    {
      sha1_update_140111248(context++, (char *)msg, msg_size);
      --n2_3;
    }
    while ( n2_3 );

    data[0] = 0;
    do
    {
      sha1_done(context_, (unsigned int *)&Dst->msg_hash_numb[4 * v4 + v4]);
      rage::Sha1::Init(context_);
      v4 = ++data[0];
      // 第二次时,清空status计算空xsha1值:438DFD0F7C3CE3B4D11B465346A5270F0DD95010
      //对应标准sha1值:0ffd8d43b4e33c7c53461bd10f27a5461050d90d
      memset(context_, 0, 0x14);
    }
    while ( (unsigned __int8)data[0] < (int)n2_1 );
  }

  numbSize = (unsigned int)(n2_1 + 4 * n2_1 + 6);
  Dst->allSz = numbSize;
  return numbSize;
}

rarkey.key

飘云阁WinRAR中文版_v7.12_官方正式注册商业版+注册文件

RAR registration data
State Grid Corporation Of China
50000 PC usage license
UID=5827a0bd1c43525d0a5d
64122122500a5d3d56f784f3a440ac3fb632d34e08bbaa37fc7712
6acaeb8eb044810272e86042cb7c79b1da0eaf88c79f8a7c6dd77b
dba335e27a109997ac90fb0e10e4129e79f46c42b4ee1832fa5113
7443fcc1124840d4dd36f3af84a5c915a760b18c6394f938168227
fbf29edbc4b34ef85ee53fbfca71814a82afadf073876b4b033451
b6292a7cc7975b3ff3cc73404abbf7c126787344169eeae4609f62
c9ffbc159bf2640ad5d9b88f8fa9d9cbf2b7e5b022a21938465244

RAR registration data
UserName
LicenseType
UID=
strlen(RegisterData[0])strlen(RegisterData[1])strlen(RegisterData[2])strlen(RegisterData[3])RegisterData[0]RegisterData[1]RegisterData[2]RegisterData[3]checksum
64
122
122
50

//RegisterData[0]==》RegisterData[3] 生成的公钥
0a5d3d56f784f3a440ac3fb632d34e08bbaa37fc77126acaeb8eb044810272e8

//RegisterData[1]==》LicenseType_Signature 使用(LicenseType)进行签名==>“60” s r
60
42cb7c79b1da0eaf88c79f8a7c6dd77bdba335e27a109997ac90fb0e10e4
129e79f46c42b4ee1832fa51137443fcc1124840d4dd36f3af84a5c915a7

//s
{
0x0000000F, 0x000010E4, 0x0000FB0E, 0x0000AC90, 0x00009997, 0x00007A10, 0x000035E2, 0x0000DBA3,
 0x0000D77B, 0x00007C6D, 0x00009F8A, 0x000088C7, 0x00000EAF, 0x0000B1DA, 0x00007C79, 0x000042CB
};
//r
{
0x0000000F, 0x000015A7, 0x0000A5C9, 0x0000AF84, 0x000036F3, 0x0000D4DD, 0x00004840, 0x0000C112,
 0x000043FC, 0x00001374, 0x0000FA51, 0x00001832, 0x0000B4EE, 0x00006C42, 0x000079F4, 0x0000129E
};


//RegisterData[2]==>UserName_Signature 使用(UserName+RegisterData[0]进行签名) ==> "60" s r
60b18c6394f938168227fbf29edbc4b34ef85ee53fbfca71814a82afadf073876b4b033451b6292a7cc7975b3ff3cc73404abbf7c126787344169eeae4

//RegisterData[3]==》'60'+ UserName 生成的公钥[:48]
609f62c9ffbc159bf2640ad5d9b88f8fa9d9cbf2b7e5b022a2

//checksum
1938465244

winrar_pubkey_key:70c2441db366d92ea7be1342b3bf629026ba92bb675f06e684bdd34511097434

70c2441db366d92ea7be1342b3bf629026ba92bb675f06e684bdd34511097434

{
0x00000010, 0x00007434, 0x00001109, 0x0000D345, 0x000084BD, 0x000006E6, 0x0000675F, 0x000092BB,
 0x000026BA, 0x00006290, 0x0000B3BF, 0x00001342, 0x0000A7BE, 0x0000D92E, 0x0000B366, 0x0000441D,
 0x000070C2
};

winrar ECC 椭圆曲线信息

y² + xy = x³ + ax² + b (a=0, b=0xa1)

GF((215)17)

curveOrder_n_140205A40= 0x1026DD85081B82314691CED9BBEC30547840E4BF72D8B5E0D258442BBCD31

.rdata:0000000140205A40 ; const XNumber curveOrder_n_140205A40
.rdata:0000000140205A40 curveOrder_n_140205A40 dd 10h                  ; numbSize
.rdata:0000000140205A40                                         ; DATA XREF: ECC_GenerateSignature_1400CF368+CC↑o
.rdata:0000000140205A40                                         ; ECC_GenerateSignature_1400CF368+E0↑o ...
.rdata:0000000140205A40                 dd 0CD31h, 42BBh, 2584h, 5E0Dh, 2D8Bh, 4BF7h, 840Eh, 547h; number
.rdata:0000000140205A40                 dd 0BEC3h, 0ED9Bh, 691Ch, 2314h, 81B8h, 0D850h, 26Dh, 1; number
.rdata:0000000140205A40                 dd 0                    ; number


.rdata:0000000140205A90 ; XNumber G_X_140205A90
.rdata:0000000140205A90 G_X_140205A90   dd 11h                  ; numbSize
.rdata:0000000140205A90                                         ; DATA XREF: ECC_GenerateSignature_1400CF368+27↑r
.rdata:0000000140205A90                                         ; VerifySignature_1400CF4C0+28↑r
.rdata:0000000140205A90                 dd 38CCh, 52Fh, 2510h, 45AAh, 1B89h, 4468h, 4882h, 0D67h; number
.rdata:0000000140205A90                 dd 4FEBh, 55CEh, 25h, 4CB7h, 0CC2h, 59DCh, 289Eh, 65E3h; number
.rdata:0000000140205A90                 dd 56FDh                ; number


.rdata:0000000140205B20 ; XNumber G_Y_140205B20
.rdata:0000000140205B20 G_Y_140205B20   dd 11h                  ; numbSize
.rdata:0000000140205B20                                         ; DATA XREF: ECC_GenerateSignature_1400CF368+88↑r
.rdata:0000000140205B20                                         ; VerifySignature_1400CF4C0+8A↑r
.rdata:0000000140205B20                 dd 31A7h, 65F2h, 18C4h, 3412h, 7388h, 54C1h, 539Bh, 4A02h; number
.rdata:0000000140205B20                 dd 4D07h, 12D6h, 7911h, 3B5Eh, 4F0Eh, 216Fh, 2BF2h, 1974h; number
.rdata:0000000140205B20                 dd 20DAh                ; number


逆推生成

1、生成RegisterData[1],需要lic_type 以及winrar 的ECC私钥

2、需要RegisterData[3]的生成方式,

3、生成RegisterData[0],通过RegisterData[3]计算得到公钥

4、生成RegisterData[2],通过winrar的ecc私钥对username+RegisterData[0]进行签名得到。

5、UID 数据未知

难点1、winrar 的ECC私钥

根据keygen 知道 winrar 私钥先由sha1_get_generator_1400D0888 得到generator:81b73eeb29532650a3f45edcd5b947684c3be4cd (标准sha1值: eb3eb78150265329dc5ef4a36847b9d5cde43b4c,data未知),然后经sha1_get_private_key_1400D0908 生成

私钥为:0x59fe6abcca90bdb95f0105271fa85fb9f11f467450c1ae9044b7fd61d65e

难点2、RegisterData[3]

根据keygen 知道 RegisterData[3] 由 username 计算得到的公钥temp_public_key,'60'与temp_public_key_hexstr[:48] 拼接得到。

难点3、UID

并未验证,

uid = temp_public_key_hexstr[48:] + RegisterData[0][:4]

//8字节+2字节

参考链接

windows-system-management-tools-standalone/WinRAR-keygen.py

winrar-keygen/README.HOW_DOES_IT_WORK.zh-CN.md at master · bitcookies/winrar-keygen

obaby/winrar-keygen:WinRAR 的密钥生成器。 --- obaby/winrar-keygen: A keygen for WinRAR.

posted @ 2025-07-13 18:35  DirWangK  阅读(237)  评论(0)    收藏  举报