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.

浙公网安备 33010602011771号