iobituninstaller v14 分析
iobituninstaller v14 分析
v14.0.1.19 版本
PE32
操作系统: Windows(2000)[I386, 32 位, GUI]
链接程序: Turbo linker(2.25)
编译器: Embarcadero Object Pascal(Delphi)(20.0)
语言: Object Pascal(Delphi)
库: Visual Component Library
工具: Embarcadero Delphi(2009)
签名工具: Windows Authenticode(2.0)[PKCS #7]
附加: Binary
证书: Windows Authenticode(2.0)[PKCS #7]
注册事件
TForm_Activate_RdImgBtnRegNowClick_00854A3C
int __fastcall TForm_Activate_RdImgBtnRegNowClick(void *a1)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v39 = a1;
v32 = &savedregs;
v31[1] = (unsigned int)&loc_8550AB;
v31[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v31);
TControl_GetText(*((_DWORD *)a1 + 0xFD), &v38);
UStrAsg((volatile __int32 *)(*gvar_TIUPro_009D6CF4[0] + 0x2C), v38);
TControl_GetText(v39[0xFD], &v37);
replace_and_insert_84B788(v37, &result);
if ( !*(_DWORD *)(*gvar_TIUPro_009D6CF4[0] + 4) )
goto LABEL_58;
if ( !DirectoryExists(*(void **)(*gvar_TIUPro_009D6CF4[0] + 4), v2) )
{
v30 = &savedregs;
v29 = &loc_854AEA;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
ForceDirectories(*(_DWORD *)(*gvar_TIUPro_009D6CF4[0] + 4));
__writefsdword(0, (unsigned int)ExceptionList);
}
(*(void (__fastcall **)(_DWORD, _DWORD))(*(_DWORD *)v39[0xE9] + 0x64))(v39[0xE9], 0);
(*(void (__fastcall **)(_DWORD, _DWORD))(*(_DWORD *)v39[0xED] + 0x64))(v39[0xED], 0);
(*(void (__fastcall **)(_DWORD, _DWORD))(*(_DWORD *)v39[0xFD] + 0x64))(v39[0xFD], 0);
v30 = &savedregs;
v29 = &loc_85506F;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
StrPCopy_0(*gvar_009D7CFC, *(_DWORD *)(*gvar_TIUPro_009D6CF4[0] + 4));
if ( !*gvar_009D7CFC )
{
LABEL_57:
v24 = ExceptionList;
__writefsdword(0, (unsigned int)ExceptionList);
v30 = (int *)&loc_855076;
LOBYTE(v24) = 1;
// 'TControl.SetEnabled'
(*(void (__fastcall **)(void *, void *))(*(_DWORD *)v39[0xE9] + 0x64))((void *)v39[0xE9], v24);
LOBYTE(v25) = 1;
// 'TControl.SetEnabled'
(*(void (__fastcall **)(_DWORD, int))(*(_DWORD *)v39[0xED] + 0x64))(v39[0xED], v25);
LOBYTE(v26) = 1;
// 'TControl.SetEnabled'
(*(void (__fastcall **)(_DWORD, int))(*(_DWORD *)v39[0xFD] + 0x64))(v39[0xFD], v26);
goto LABEL_58;
}
v4 = UStrToPWChar(result, v3);
UStrFromPWChar((int)&v36, v4);
v5 = check_84B680(v36);
v7 = v5 < 2;
v8 = v5 - 2;
if ( v7 || (v9 = v8 - 1, v7 = v9 < 3, v10 = v9 - 3, v7) || v10 == 4 )
{
// // [0, 5] ∪ {10}
// 产品不对应
licensemessage_851144((int)v39, 7, (__int32)result);// type 7
*off_9D77F8 = 1;
TryFinallyExit(ExceptionList, v29, v30);
goto LABEL_58;
}
// TYPE 为6,7,8,9
v11 = UStrToPWChar(result, v6);
UStrFromPWChar((int)&v35, v11);
if ( check_84B680(v35) != 8 )
goto LABEL_31;
// 当倒数第二位在[B,P,Q,R,S,T]中
// 且最后一位不为D==》 失败
// 其它情况 ok
if ( (unsigned __int8)sub_84B9EC((char *)result, (int)v4) )
{
// L"%s 是免费赠送的只能用在特定的版本。请访问 <a>这里</a> 购买一个新的注册码来激活IObit Uninstaller %s PRO。"
licensemessage_851144((int)v39, 8, (__int32)result);
*off_9D77F8 = 1;
TryFinallyExit(ExceptionList, v29, v30);
goto LABEL_58;
}
// last D 免费版本 v14
// 倒数第二位不为F,最后一位为D
if ( !(unsigned __int8)sub_84BBA8((wchar_t *)result, (wchar_t *)&v41) )
{
LABEL_31:
if ( ClientCheckKey_60F2C8((int)v4, 14) != 1 )// 需要==1
{
// 非法
(*(void (__fastcall **)(_DWORD, _DWORD))(*(_DWORD *)v39[0xF9] + 0x64))(v39[0xF9], 0);
TControl_SetColor(v39[0xFD], v39[0x106]);
TControl_SetText(v39[0xEA], v39[0x109]);
v14 = sub_587E38((int)VMT_58684C_TResource, (int)L"word.red", 0, 1);
TFont_SetColor(*(_DWORD *)(v39[0xEA] + 0x64), v14);
*off_9D77F8 = 1;
TryFinallyExit(ExceptionList, v29, v30);
goto LABEL_58;
}
LOBYTE(v13) = 1;
TControl_SetVisible(v39[0xFF], v13);
LOBYTE(v15) = 1;
TCustomEdit_SetReadOnly(v39[0xFD], v15);
LOBYTE(v16) = 1;
TRdTimer_SetEnabled(v39[0xEB], v16);
v17 = 0x64;
do
{
TApplication_ProcessMessages(*Application);
kernel32_Sleep_1(0xAu);
--v17;
}
while ( v17 );
v19 = UStrToPWChar(result, v18);
v20 = call_ActiveApp_60ED0C(v19, v1); // 返回1
TControl_SetVisible(v39[0xFF], 0);
TRdTimer_SetEnabled(v39[0xEB], 0);
IntToStr(v20, &v33);
UStrCat3(&v34, L"ActiveApp end ::");
log_5814E4(VMT_58032C_TIULogHelper, (char)L"E6C7", v34, 0, 0, 0);
TForm_Activate_pnlFormMouseMove(0, 0);
if ( v20 <= 0 ) // 《=0时错误
{
switch ( v20 )
{
case 0xFFFFFFFB:
(*(void (__fastcall **)(_DWORD, _DWORD))(*(_DWORD *)v39[0xF9] + 0x64))(v39[0xF9], 0);
TControl_SetColor(v39[0xFD], v39[0x106]);
TControl_SetText(v39[0xEA], v39[0x109]);
v23 = sub_587E38((int)VMT_58684C_TResource, (int)L"word.red", 0, 1);
TFont_SetColor(*(_DWORD *)(v39[0xEA] + 0x64), v23);
break;
case 0xFFFFFFF7:
// :L"注册码 %s 在您所在的地区或国家无效。 请单击“确定”购买有效的注册码。"
licensemessage_851144((int)v39, 0x11, (__int32)result);
*off_9D77F8 = 3;
break;
case 0xFFFFFFFE:
// L"注册码 %s 已经过期。点击 <a>这里</a> 享受折扣续费!"
licensemessage_851144((int)v39, 2, (__int32)result);
*off_9D77F8 = 4;
break;
case 0xFFFFFFFD:
// Driver Booster
licensemessage_851144((int)v39, 4, (__int32)result);
*off_9D77F8 = 3;
break;
case 0:
case 0xFFFFFFFF:
case 0xFFFFFFFC:
// invalid
licensemessage_851144((int)v39, 0, (__int32)result);
*off_9D77F8 = 3;
break;
case 0xFFFFFFF8:
// L"连接接不到注册服务器, 请检查您的网络和代理设置, 稍后再重试激活您的注册码."
licensemessage_851144((int)v39, 6, (__int32)result);
v39[0xA9] = 1;
break;
default:
// IObit Malware Fighter
licensemessage_851144((int)v39, 5, (__int32)result);
*off_9D77F8 = 1;
break;
}
}
else
{
// this way
v21 = CheckLicenseLocatin_60EDC4(*gvar_009D7CFC);// 3 永久许可
sub_6B0B30(*gvar_TIUPro_009D6CF4[0], v21);
if ( !(unsigned __int8)sub_60F0DC(*gvar_009D7CFC, v20) || v20 == 3 )
{
// this way
licensemessage_851144((int)v39, 1, 0);
*off_9D77F8 = 2;
v39[0xA9] = 1;
sub_6B0928(*gvar_TIUPro_009D6CF4[0], 0xFFFFFFFF);
v22 = v21 - 1;
if ( !v22 || v22 == 2 )
sub_6B0854();
}
}
TCustomEdit_SetReadOnly(v39[0xFD], 0);
goto LABEL_57;
}
UStrEqual(v41, L"6");
if ( v12 )
{
// 终身许可证代码,仅对IObit Uninstaller v6
licensemessage_851144((int)v39, 9, (__int32)result);
}
else
{
UStrEqual(v41, L"7");
if ( v12 )
{
// 终身许可证代码,仅对IObit Uninstaller v7
licensemessage_851144((int)v39, 0xA, (__int32)result);
}
else
{
UStrEqual(v41, L"8");
if ( v12 )
{
// 终身许可证代码,仅对IObit Uninstaller v8
licensemessage_851144((int)v39, 0xB, (__int32)result);
}
else
{
UStrEqual(v41, L"9");
if ( v12 )
{
// 终身许可证代码,仅对IObit Uninstaller v8
licensemessage_851144((int)v39, 0xC, (__int32)result);
}
else
{
UStrEqual(v41, L"0");
if ( v12 )
{
// 终身许可证代码,仅对IObit Uninstaller v10
licensemessage_851144((int)v39, 0xD, (__int32)result);
}
else
{
UStrEqual(v41, L"A");
if ( v12 )
{
// 终身许可证代码,仅对IObit Uninstaller v11
licensemessage_851144((int)v39, 0xE, (__int32)result);
}
else
{
UStrEqual(v41, L"B");
if ( v12 )
{
// 终身许可证代码,仅对IObit Uninstaller v12
licensemessage_851144((int)v39, 0xF, (__int32)result);
}
else
{
UStrEqual(v41, L"C");
if ( v12 )
// 终身许可证代码,仅对IObit Uninstaller v13
licensemessage_851144((int)v39, 0x10, (__int32)result);
else
// L"无效注册码! 请输入一个有效的注册码!"
licensemessage_851144((int)v39, 3, 0);
}
}
}
}
}
}
}
*off_9D77F8 = 1;
TryFinallyExit(ExceptionList, v29, v30);
LABEL_58:
__writefsdword(0, v31[0]);
UStrArrayClr(&loc_8550B2);
UStrArrayClr(v32);
return UStrArrayClr(v32);
}
key8类型check函数
各类型check函数大同小异,
特定长度分组,MD5,比较
int __fastcall check8_84D1A0(_WORD *a1)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v11 = &savedregs;
v10[1] = (unsigned int)&loc_84D4DF;
v10[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v10);
UStrFromPWChar((int)&v34, a1);
StringReplace(v34, L"-", 0, (void *)(unsigned __int8)gvar_0084D4F0, &v28);
UStrLAsg(&v34, v28);
StringReplace(v34, L" ", 0, (void *)(unsigned __int8)gvar_0084D4F0, &v27);
UStrLAsg(&v34, v27);
LowerCase(v34, &v26);
UStrLAsg(&v34, v26);
v1 = v34;
if ( v34 )
v1 = (wchar_t *)*((_DWORD *)v34 + 0xFFFFFFFF);
if ( v1 == (wchar_t *)0x14 )
{
StringReplace(v34, L"o", L"0", (void *)(unsigned __int8)gvar_0084D4F0, &v25);
UStrLAsg(&v34, v25);
StringReplace(v34, L"i", L"1", (void *)(unsigned __int8)gvar_0084D4F0, &v24);
UStrLAsg(&v34, v24);
UStrLAsg(&part0, 0);
UStrLAsg(&part1, 0);
UStrLAsg(&part2, 0);
UStrLAsg(&part3, 0);
UStrLAsg(part4, 0);
for ( i = 1; i != 5; ++i )
{
UStrFromWChar(&v23, v34[i - 1]);
UStrCat(&part0, v23);
}
for ( j = 5; j != 10; ++j )
{
UStrFromWChar(&v22, v34[j - 1]);
UStrCat(&part1, v22);
}
for ( k = 10; k != 14; ++k )
{
UStrFromWChar(&v21, v34[k - 1]);
UStrCat(&part2, v21);
}
for ( m = 14; m != 19; ++m )
{
UStrFromWChar(&v20, v34[m - 1]);
UStrCat(&part3, v20);
}
for ( n = 0x13; n != 21; ++n )
{
UStrFromWChar(&v19, v34[n - 1]);
UStrCat(part4, v19);
}
LStrFromUStr(&v15, part2);
md5_4721FC(v15, v16);
hexdight_4726E8(v16, v17);
LowerCase(*(_DWORD *)v17, &v18);
UStrLAsg(&part2, v18);
LStrFromUStr(&v12, part3);
md5_4721FC(v12, v16);
hexdight_4726E8(v16, v13);
LowerCase(*(_DWORD *)v13, &v14);
UStrLAsg(&part3, v14);
v7 = part2[28] == *part0 && part2[29] == part0[1] && part2[30] == part0[2] && part2[31] == part0[3];
v8 = *part3 == *part1
&& part3[1] == part1[1]
&& part3[2] == part1[2]
&& part3[3] == part1[3]
&& part3[4] == part1[4];
if ( v7 && v8 )
LOBYTE(n) = 1;
else
n = 0;
}
else
{
n = 0;
}
__writefsdword(0, v10[0]);
LStrClr(&loc_84D4E6);
UStrArrayClr(v11);
LStrClr(v11);
UStrArrayClr(v11);
return n;
}
初步校验后调用RegisterCom.dll中的导出函数进行验证
RegisterCom.dll 验证
ClientCheckKey 需返回1
ActiveApp 网络校验,需返回1 ??3
CheckLicenseLocatin 许可文件校验,3:永久 1:时限,2(未分析)
ClientCheckKey
int __stdcall ClientCheckKey(wchar_t *key, int a2)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v11 = 0;
v10 = 0;
v9 = 0;
*(_DWORD *)v8 = 0;
v7 = v2;
v6 = &savedregs;
v5[1] = (unsigned int)&loc_509367;
v5[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v5);
v3 = 0;
UStrFromPWChar(&v10, key);
LowerCase(v10, &a1);
if ( (unsigned __int8)sub_507550(a1) )
{
sub_509290(a2, (int)&v11);
WStrFromUStr(v8, a1);
last_copy_40A018(*(int *)v8, 2, (int)&v9);
UStrFromWStr(&v12, v9);
v3 = (unsigned __int8)sub_508E70(v12, v11) != 0;
}
__writefsdword(0, v5[0]);
v6 = (int *)&loc_50936E;
WStrArrayClr(v8, 2);
UStrArrayClr(&v10, 4);
return v3;
}
sub_507550
int __fastcall sub_507550(wchar_t *a1)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
key = a1;
UStrAddRef(a1);
v11 = &savedregs;
v10[1] = (unsigned int)&loc_507B1F;
v10[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v10);
v1 = 0;
LowerCase(key, &v56);
UStrLAsg(&key, v56);
StringReplace(key, (wchar_t *)L" ", 0, (void *)(unsigned __int8)gvar_00507B34, v55);
UStrLAsg(&key, *(_DWORD *)v55);
StringReplace(key, (wchar_t *)L" ", 0, (void *)(unsigned __int8)gvar_00507B34, v54);
UStrLAsg(&key, *(_DWORD *)v54);
StringReplace(key, (wchar_t *)L"o", (wchar_t *)L"0", (void *)(unsigned __int8)gvar_00507B34, v53);
UStrLAsg(&key, *(_DWORD *)v53);
StringReplace(key, (wchar_t *)L"l", (wchar_t *)L"1", (void *)(unsigned __int8)gvar_00507B34, v52);
UStrLAsg(&key, *(_DWORD *)v52);
StringReplace(key, (wchar_t *)L"i", (wchar_t *)L"1", (void *)(unsigned __int8)gvar_00507B34, v51);
UStrLAsg(&key, *(_DWORD *)v51);
StringReplace(key, (wchar_t *)L"z", (wchar_t *)L"2", (void *)(unsigned __int8)gvar_00507B34, v50);
UStrLAsg(&key, *(_DWORD *)v50);
StringReplace(key, (wchar_t *)L"-", 0, (void *)(unsigned __int8)gvar_00507B34, v49);
UStrLAsg(&key, *(_DWORD *)v49);
v2 = key;
if ( key )
v2 = (wchar_t *)*((_DWORD *)key + 0xFFFFFFFF);
if ( v2 == (wchar_t *)0x14 )
{
v3 = 1;
while ( 1 )
{
v4 = key[v3 - 1];
if ( v4 >= 0x100u || !_bittest(&gvar_00507BD8, (unsigned __int8)v4) )
break;
if ( ++v3 == 19 )
{
WStrFromUStr(v47, key);
copy_409FFC(*(int *)v47, 4, (int)&v48);
UStrFromWStr(&part0, v48);
WStrFromUStr(v45, key);
last_copy_40A018(*(int *)v45, 16, (int)&v46);
UStrFromWStr(&key, v46);
WStrFromUStr(v43, key);
copy_409FFC(*(int *)v43, 5, (int)&v44);
UStrFromWStr(&part1, v44);
WStrFromUStr(v41, key);
last_copy_40A018(*(int *)v41, 11, (int)&v42);
UStrFromWStr(&key, v42);
WStrFromUStr(v39, key);
copy_409FFC(*(int *)v39, 4, (int)&v40);
UStrFromWStr(&part2, v40);
WStrFromUStr(v37, key);
last_copy_40A018(*(int *)v37, 7, (int)&v38);
UStrFromWStr(&key, v38);
WStrFromUStr(v35, key);
copy_409FFC(*(int *)v35, 5, (int)&v36);
UStrFromWStr(&part3, v36);
LStrFromUStr(&v32, part0, 0);
md5_5071D0(v32, v33);
hexdight_507248(v33, v34);
part0_md5 = *(_DWORD *)v34;
LStrFromUStr(&v25, part2, 0);
md5_5071D0(v25, v33);
hexdight_507248(v33, v26);
LowerCase(*(_DWORD *)v26, &v27);
WStrFromUStr(part2_md5, v27);
last_copy_40A018(*(int *)part2_md5, 4, (int)&v29);
LStrFromWStr((int)&v30, v29, 0);
md5_5071D0(v30, v33);
hexdight_507248(v33, v31);
UStrEqual(part0_md5, *(_DWORD *)v31);
if ( v6 )
{
LStrFromUStr(&v21, part1, 0);
md5_5071D0(v21, v33);
hexdight_507248(v33, v22);
LStrFromUStr(&v23, *(_DWORD *)v22, 0);
md5_5071D0(v23, v33);
hexdight_507248(v33, v24);
part1_md5_md5 = *(_DWORD *)v24;
LStrFromUStr(&v12, part3, 0);
md5_5071D0(v12, v33);
hexdight_507248(v33, v13);
LowerCase(*(_DWORD *)v13, &v14);
WStrFromUStr(v15, v14);
copy_409FFC(*(int *)v15, 5, (int)&v16);
LStrFromWStr((int)&v17, v16, 0);
md5_5071D0(v17, v33);
hexdight_507248(v33, v18);
LStrFromUStr(&v19, *(_DWORD *)v18, 0);
md5_5071D0(v19, v33);
hexdight_507248(v33, v20);
UStrEqual(part1_md5_md5, *(_DWORD *)v20);
if ( v6 )
LOBYTE(v1) = 1;
}
break;
}
}
}
__writefsdword(0, v10[0]);
v11 = (int *)&loc_507B29;
LStrClr(&v12);
UStrArrayClr(v13, 2);
WStrArrayClr(v15, 2);
LStrClr(&v17);
UStrClr(v18);
LStrClr(&v19);
UStrClr(v20);
LStrClr(&v21);
UStrClr(v22);
LStrClr(&v23);
UStrClr(v24);
LStrClr(&v25);
UStrArrayClr(v26, 2);
WStrArrayClr(part2_md5, 2);
LStrClr(&v30);
UStrClr(v31);
LStrClr(&v32);
UStrClr(v34);
WStrArrayClr(v35, 0xE);
UStrArrayClr(v49, 0xD);
return v1;
}
对应的py脚本
key虽然可推生成器,但关键点在于生成的key无法过网络校验,
import hashlib
def md5_hex_lower(x:str):
if isinstance(x,str):
x=x.encode()
h=hashlib.md5()
h.update(x)
return h.hexdigest().lower()
def key_replace3(key:str):
key=key.lower()
translation_table = str.maketrans({
'o': '0',
'i': '1',
'l': '1',
'z': '2',
'-': '',
' ': '',
})
x=key.translate(translation_table)
return x
def ClientCheckKey(input_key):
# 字符串预处理
result = key_replace3(input_key)
# # 确认处理后的字符串长度
# if len(result) != 20:
# return 0
# 将字符串拆分成多段
part0 = result[:4]
part1 = result[4:9]
part2 = result[9:13]
part3 = result[13:18]
# 对各段计算 MD5
# 计算每一部分的MD5哈希值
part0_md5 = md5_hex_lower(part0)
part2_md5 = md5_hex_lower(md5_hex_lower(part2)[-4:])
part1_md5 = md5_hex_lower(md5_hex_lower(part1))
part3_md5 = md5_hex_lower(md5_hex_lower(md5_hex_lower(part3)[:5]))
print('cmp1:',part0_md5 , part2_md5)
print('cmp2:',part1_md5 , part3_md5)
# 验证哈希值的条件
if part0_md5 == part2_md5 and part1_md5 == part3_md5:
return True
else:
return False
ActiveApp
todo
网络验证
CheckLicenseLocatin
todo
int __stdcall CheckLicenseLocatin(_DWORD *iob_dir)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v40 = &loc_50BF1D;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
v81 = 0;
v38 = &savedregs;
v37 = &loc_50BEC9;
v36 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v36);
// eax:L"C:\\Program Files (x86)\\Common Files\\IObit\\IObit Uninstaller\\"
if ( iob_dir )
{
sub_509290(iob_dir[0x28F], (int)&v85);
UStrFromWArray(&System__AnsiString, iob_dir, 0x100, v40, ExceptionList, v38, v37, v36);
IncludeTrailingPathDelimiter(System__AnsiString);
UStrLAsg(&System__AnsiString, v75[2]);
sub_509750(System__AnsiString, (int)&v88);
if ( (unsigned __int8)FileExists(v88) )
goto LABEL_7;
UStrCat3((int)&v88, (void *)System__AnsiString, L"appscription.dat");
if ( (unsigned __int8)FileExists(v88)
|| (ParamStr(0, v75),
ExtractFilePath(v75[0]),
v35 = v75[1],
v34 = L"LicensePath\\",
v33 = L"license.dat",
UStrCatN(&v88, 3),
ExtractFilePath(v88),
(unsigned __int8)FileExists(v88)) )
{
LABEL_7:
v32 = (const wchar_t *)&savedregs;
v31 = (int *)&loc_50B831;
v30 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v30);
LOBYTE(v3) = 1;
v77 = (Inifiles::TMemIniFile *)TExtIniFile_Create(VMT_439EB4_TExtIniFile, v3);
LOBYTE(v4) = 1;
v78 = (Classes::TStream *)TObject_Create(VMT_422150_TMemoryStream, v4);
v80 = (System::TObject *)TZLBArc2_Create(VMT_434688_TZLBArc2);
LOBYTE(v5) = 1;
v79 = (System::TObject *)TObject_Create(VMT_5061A4_TzibDecryptAndEncrypt, v5);
v6 = v80;
*((_DWORD *)v80 + 0x39) = v79;
*((_DWORD *)v6 + 0x38) = sub_506560;
v7 = v80;
*((_DWORD *)v80 + 0x37) = v79;
*((_DWORD *)v7 + 0x36) = sub_50629C;
ParamStr(0, v74);
ExtractFilePath(v74[0]);
UStrAsg((char *)v80 + 0x88, v74[1]);
UStrAsg((char *)v80 + 0x8C, L"registercm-2016");
v29 = &savedregs;
v28 = (const wchar_t *)&loc_50B79A;
v27 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v27);
sub_434AD8(v80, v88);
__writefsdword(0, (unsigned int)v27);
sub_435B54((int)v80);
TStream_SetPosition(v78, 0i64);
sub_43A7A4(v77);
__writefsdword(0, (unsigned int)v30);
v32 = L"N/A";
v31 = &v73;
(**(void (__fastcall ***)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *, int, const wchar_t *, const wchar_t *, const wchar_t *, int *))v77)(
v77,
L"main",
L"Code",
v35,
v34,
v33,
L"N/A",
&v73);
StrPCopy_0(iob_dir + 0x199);
v30 = (struct _EXCEPTION_REGISTRATION_RECORD *)L"N/A";
v29 = &v72;
(**(void (__fastcall ***)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *, const wchar_t *, int *))v77)(
v77,
L"main",
L"FingerPrint",
L"N/A",
&v72);
StrPCopy_0((char *)iob_dir + 0x6CA);
v28 = L"Personal";
v27 = (struct _EXCEPTION_REGISTRATION_RECORD *)&v71;
(**(void (__fastcall ***)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *, const wchar_t *, int *))v77)(
v77,
L"main",
L"LicenseType",
L"Personal",
&v71);
StrPCopy_0((char *)iob_dir + 0x8CA);
v26 = 0;
iob_dir[0x23D] = -((*(unsigned __int8 (__fastcall **)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *, _DWORD))(*(_DWORD *)v77 + 0x10))(
v77,
L"main",
L"Expried",
0) != 0);
v25 = L"1";
v24 = &v70;
(**(void (__fastcall ***)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *, const wchar_t *, int *))v77)(
v77,
L"main",
L"Seat",
L"1",
&v70);
StrPCopy_0((char *)iob_dir + 0x95E);
v23 = L"N/A";
v22 = &v69;
(**(void (__fastcall ***)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *, const wchar_t *, int *))v77)(
v77,
L"main",
L"ExpDate",
L"N/A",
&v69);
StrPCopy_0(iob_dir + 0x23E);
v21 = 0;
iob_dir[0x25B] = -((*(unsigned __int8 (__fastcall **)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *))(*(_DWORD *)v77 + 0x10))(
v77,
L"main",
L"OverSeat") != 0);
v20 = L"N/A";
v19 = &v68;
(**(void (__fastcall ***)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *))v77)(
v77,
L"main",
L"LastValidate");
StrPCopy_0(iob_dir + 0x25C);
v18 = 0;
p_a1 = &a1;
v8 = *(_DWORD *)v77;
(**(void (__fastcall ***)(Inifiles::TMemIniFile *, const wchar_t *, const wchar_t *))v77)(
v77,
L"main",
L"LastServerDate");
StrPCopy_0((char *)iob_dir + 0x9D6);
TObject_Free(v78);
TObject_Free(v77);
TObject_Free(v80);
TObject_Free(v79);
UStrFromWArray(&v66, iob_dir + 0x199, 0x33, v21, L"N/A", &v68, 0, &a1);
UStrEqual(v66, L"N/A");
if ( !v9 && (UStrFromWArray(&v64, iob_dir + 0x199, 0x33, v21, v20, v19, v18, p_a1), Trim(v64, &v65), v65) )
{
UStrFromWArray(&v63, iob_dir + 0x199, 0x33, v21, v20, v19, v18, p_a1);
if ( (unsigned __int8)sub_507550(v63) )
{
UStrFromWArray(&v86, iob_dir + 0x199, 0x33, v21, v20, v19, v18, p_a1);
WStrFromUStr(v61, v86);
last_copy_40A018(*(int *)v61, 2, (int)&v62);
UStrFromWStr(&v82, v62);
if ( !(unsigned __int8)sub_508E70(v82, v85) || !(unsigned __int8)sub_508A48(v86, v8, v2) )
{
v81 = 0xFFFFFFFF;
__writefsdword(0, (unsigned int)p_a1);
goto LABEL_49;
}
UStrFromWArray(&v60, (char *)iob_dir + 0x8CA, 0x15, v21, v20, v19, v18, p_a1);
UStrEqual(v60, L"Invalid");
if ( v9 )
{
v81 = 0xFFFFFFFF;
}
else
{
sub_4FF7F4((int)&v59);
Trim(v59, &v84);
sub_4FF904((int)&v58, v8, v1, v2);
Trim(v58, &v83);
UStrFromWArray(&v57, (char *)iob_dir + 0x6CA, 0x100, v21, v20, v19, v18, p_a1);
UStrEqual(v57, L"N/A");
if ( v9
|| (UStrFromWArray(&v56, (char *)iob_dir + 0x6CA, 0x100, v21, v20, v19, v18, p_a1), Pos(v84, v56))
|| (UStrFromWArray(&v55, (char *)iob_dir + 0x6CA, 0x100, v21, v20, v19, v18, p_a1), Pos(v83, v55)) )
{
if ( iob_dir[0x23D] != 0 )
{
if ( iob_dir[0x25B] != 0 )
{
v81 = 0xFFFFFFFD;
}
else
{
UStrFromWArray(&v54, iob_dir + 0x199, 0x33, v21, v20, v19, v18, p_a1);
if ( (unsigned __int8)sub_50905C(v54, v85) == 1 )
{
v81 = 0xFFFFFFFE;
}
else
{
UStrFromWArray(&v53, iob_dir + 0x199, 0x33, v21, v20, v19, v18, p_a1);
if ( (unsigned __int8)sub_509378(v53, v85, v8) == 1 )
v81 = 3;
else
v81 = 0xFFFFFFFE;
}
}
}
else
{
UStrFromWArray(&v52, iob_dir + 0x23E, 0x33, v21, v20, v19, v18, p_a1);
UStrEqual(v52, L"N/A");
if ( !v9
&& (UStrFromWArray(&v50, iob_dir + 0x23E, 0x33, v21, v20, v19, v18, p_a1), Trim(v50, &v51), v51) )
{
UStrFromWArray(&v47, iob_dir + 0x23E, 0x33, v21, v20, v19, v18, p_a1);
v76 = sub_4FF30C(v47);
v16 = &savedregs;
v15 = &loc_50BEAE;
v14 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v14);
UStrFromWArray(
&v46,
(char *)iob_dir + 0x9D6,
0x33,
&loc_50BEAE,
v14,
HIDWORD(v76),
LODWORD(v76),
&savedregs);
v10 = sub_50B4BC(v12);
if ( (unsigned __int8)sub_4176F4(v10, v13) == 0xFF )
{
UStrFromWArray(&v45, iob_dir + 0x199, 0x33, v18, p_a1, v16, v15, v14);
if ( (unsigned __int8)sub_50905C(v45, v85) == 1 )
{
v81 = 0xFFFFFFFE;
}
else
{
UStrFromWArray(&v44, iob_dir + 0x199, 0x33, v18, p_a1, v16, v15, v14);
if ( (unsigned __int8)sub_509378(v44, v85, v8) == 1 )
v81 = 3;
else
v81 = 0xFFFFFFFE;
}
}
else
{
UStrFromWArray(&v43, iob_dir + 0x199, 0x33, v18, p_a1, v16, v15, v14);
if ( (unsigned __int8)sub_50905C(v43, v85) == 1 )
{
v81 = 2;
}
else
{
UStrFromWArray(&v42, iob_dir + 0x199, 0x33, v18, p_a1, v16, v15, v14);
if ( (unsigned __int8)sub_509378(v42, v85, v8) == 1 )
v81 = 3;
else
v81 = 1;
}
}
__writefsdword(0, (unsigned int)v14);
}
else
{
UStrFromWArray(&v49, iob_dir + 0x199, 0x33, v21, v20, v19, v18, p_a1);
if ( (unsigned __int8)sub_50905C(v49, v85) == 1 )
{
v81 = 2;
}
else
{
UStrFromWArray(&v48, iob_dir + 0x199, 0x33, v21, v20, v19, v18, p_a1);
if ( (unsigned __int8)sub_509378(v48, v85, v8) == 1 )
v81 = 3;
else
v81 = 1;
}
}
}
}
else
{
v81 = 0xFFFFFFFB;
}
}
}
else
{
v81 = 0xFFFFFFFF;
}
}
else
{
v81 = 0;
}
__writefsdword(0, (unsigned int)p_a1);
goto LABEL_49;
}
__writefsdword(0, (unsigned int)v33);
}
else
{
__writefsdword(0, (unsigned int)v36);
}
LABEL_49:
__writefsdword(0, (unsigned int)ExceptionList);
v41 = &loc_50BF24;
UStrArrayClr(&v42, 0x13);
WStrArrayClr(v61, 2);
UStrArrayClr(&v63, 0x10);
UStrArrayClr(&v82, 7);
return v81;
}
ValidateThreadLicense
todo
返回值需为0
int __stdcall ValidateThreadLicense(LPDWORD lpThreadId, int a2, int a3, int a4, HWND a5)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v22 = &loc_50D45C;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
v42 = 0;
v40 = 0;
dword_51DB08 = a5;
v39 = 0x1E;
v20 = &savedregs;
v19 = &loc_50D410;
v18 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v18);
if ( lpThreadId && a4 >= 1 )
{
HIDWORD(v17) = &savedregs;
LODWORD(v17) = &loc_50D154;
v16 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v16);
ParamStr(0, System__AnsiString);
ExtractFilePath(System__AnsiString[0]);
UStrCat3((int)&v43, (void *)System__AnsiString[1], L"update\\update.ini");
LOBYTE(v5) = 1;
v6 = (System::TObject *)TSafeIniFile_Create(VMT_43A9D4_TSafeIniFile, v5);
sub_43B674(v6, v43);
v39 = (*(int (__fastcall **)(System::TObject *, const wchar_t *, const wchar_t *, int))(*(_DWORD *)v6 + 8))(
v6,
L"RegOption",
L"LD",
0x1E);
TObject_Free(v6);
__writefsdword(0, (unsigned int)v16);
UStrFromWArray(&v44, lpThreadId + 0x199, 0x33, v22, ExceptionList, v20, v19, v18);
if ( !(unsigned __int8)sub_509430(v44)
|| (UStrFromWArray(&v36, lpThreadId + 0x23E, 0x33, v22, ExceptionList, v20, v19, v18), Trim(v36, &v37), v37) )
{
UStrFromWArray(&v32, lpThreadId + 0x23E, 0x33, v22, ExceptionList, v20, v19, v18);
UStrEqual(v32, L"N/A");
if ( !v8
&& (UStrFromWArray(&v30, lpThreadId + 0x23E, 0x33, v22, ExceptionList, v20, v19, v18), Trim(v30, &v31), v31) )
{
UStrFromWArray(&v29, lpThreadId + 0x23E, 0x33, v22, ExceptionList, v20, v19, v18);
v9 = sub_4FF30C(v29);
sub_4175B8(v9);
v34 = v9;
Now();
sub_4175B8(v9);
if ( v9 > v34 )
goto LABEL_15;
UStrFromWArray(&v28, lpThreadId + 0x25C, 0x33, v22, ExceptionList, v20, v19, v18);
v10 = sub_4FF30C(v28);
sub_4175B8(v10);
v27 = v10;
Now();
sub_4175B8(v10);
if ( v10 == v27
|| (UStrFromWArray(&v26, lpThreadId + 0x23E, 0x33, v22, ExceptionList, v20, v19, v18),
v11 = sub_4FF30C(v26),
v17 = v11,
Now(),
v12 = sub_4175DC(v11, v17),
v12 >= v39) )
{
LABEL_15:
UStrFromWArray(&v25, lpThreadId + 0x25C, 0x33, v22, ExceptionList, v20, v19, v18);
v13 = sub_4FF30C(v25);
sub_4175B8(v13);
v34 = v13;
Now();
sub_4175B8(v13);
if ( v13 != v34 )
{
UStrFromWArray(&v24, (char *)lpThreadId + 0x9D6, 0x33, v22, ExceptionList, v20, v19, v18);
if ( sub_50C190(v24, a2) == 1 )
v40 = 1;
}
}
else
{
v40 = 1;
}
}
else
{
v40 = 1;
kernel32_OutputDebugStringW(L"ValidateThreadLicense N/A");
}
}
else
{
UStrFromWArray(&v35, lpThreadId + 0x25C, 0x33, v22, ExceptionList, v20, v19, v18);
v7 = sub_4FF30C(v35);
sub_4175B8(v7);
v34 = v7;
Now();
sub_4175B8(v7);
if ( v7 != v34 )
{
UStrFromWArray(&v33, (char *)lpThreadId + 0x9D6, 0x33, v22, ExceptionList, v20, v19, v18);
if ( sub_50C190(v33, a2) == 1 )
v40 = 1;
}
}
if ( v40 )
{
StrPCopy_0((char *)lpThreadId + 0x8CA);
v42 = 0xFFFFFFFF;
v14 = (void *)BeginThread(0, 0, sub_50C35C, lpThreadId, 0, &v41);
kernel32_CloseHandle_0(v14);
}
}
__writefsdword(0, (unsigned int)v18);
__writefsdword(0, (unsigned int)ExceptionList);
v23 = &loc_50D463;
UStrArrayClr(&v24, 3);
UStrArrayClr(&v28, 6);
UStrArrayClr(&v35, 5);
UStrArrayClr(&v43, 2);
return v42;
}
patch方案
1、分析ActiveApp ,修补响应数据或许可行
2、分析CheckLicenseLocatin ,构造license.dat 或许可行(??license.dat 使用zlib 加密“registercm-2016"压缩)
3、patch dll
因为许可校验基本都放到了RegisterCom.dll ,直接patch最为简单
RegisterCom.dll patch 点
1\
2\
3\
4\
解决弹窗1==》RegisterCom.dll patch后主程序弹窗
通过spy++ 查看窗口
frm_IUCrakTip
从IDR 中查看窗口信息
窗口间通过消息事件触发,跟踪较复杂,直接从api入手
通过定位WinVerifyTrust
最终确定
TCVCheckThread_Execute_008C4948
CrackVerify
int __fastcall TCVCheckThread_Execute(void *a1)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v8 = a1;
v2 = TObject_Create(VMT_8C2424_TCVDeleteHelper, 1);
*((_BYTE *)v8 + 0x40) = exists_hijack_8C248C(v2);
TObject_Free(v2);
if ( *((_BYTE *)v8 + 0x40) )
// 存在特定dll时进行签名验证,确定是否为劫持补丁
// 以及RegisterCom.dll完整性校验
TCVCheckThread_CrackVerify_8C4A04((int)v8, v2, v1);
result = *((_DWORD *)v8 + 0x11);
if ( !result )
return result;
v7 = &savedregs;
v6 = &loc_8C49B3;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
reg_Verification_8C45BC(result, *((_BYTE *)v8 + 0x40));
__writefsdword(0, (unsigned int)ExceptionList);
result = (int)v8;
if ( *((_BYTE *)v8 + 0x40) )
return result;
v7 = &savedregs;
v6 = &loc_8C49F3;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
v4 = *((_DWORD *)v8 + 0x11);
if ( *(_WORD *)(v4 + 0x22) )
(*(void (__fastcall **)(_DWORD))(*((_DWORD *)v8 + 0x11) + 0x20))(*(_DWORD *)(v4 + 0x24));
result = 0;
__writefsdword(0, (unsigned int)ExceptionList);
return result;
}
exists_hijack_8C248C
int __fastcall exists_hijack_8C248C(int a1)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v20 = a1;
v12 = &savedregs;
v11 = (struct _EXCEPTION_REGISTRATION_RECORD *)&loc_8C26BB;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
v19 = 1;
TApplication_GetExeName(*Application, &v15);
ExtractFilePath(v15, &v16);
v14 = v16;
IncludeTrailingPathDelimiter(v16, &v21);
UStrLAsg(&result, v21);
LOBYTE(v1) = 1;
v18 = (_DWORD *)TStringList_Create(VMT_4946FC_TStringList, v1);
// TStringList.Add'
(*(void (__fastcall **)(_DWORD *, const wchar_t *, _DWORD))(*v18 + 0x38))(v18, L"msimg32", *v18);
(*(void (__fastcall **)(_DWORD *, const wchar_t *, void *))(*v18 + 0x38))(v18, L"PYG", (void *)*v18);
(*(void (__fastcall **)(_DWORD *, const wchar_t *, void *))(*v18 + 0x38))(v18, L"uxtheme", (void *)*v18);
(*(void (__fastcall **)(_DWORD *, const wchar_t *, void *))(*v18 + 0x38))(v18, L"version", (void *)*v18);
(*(void (__fastcall **)(_DWORD *, const wchar_t *, void *))(*v18 + 0x38))(v18, L"winmm", (void *)*v18);
v17 = (_DWORD *)sub_4992E4(v18);
v13 = &savedregs;
v12 = (int *)&loc_8C2684;
v11 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v11);
while ( (unsigned __int8)TStringsEnumerator_MoveNext(v17) )
{
TStringsEnumerator_GetCurrent(v17, &v24);
UStrCatN(L".dll", v24, result);
if ( (unsigned __int8)FileExists(v22) )
{
v19 = 0;
ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)&savedregs;
v9 = &loc_8C25B1;
v8 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v8);
v3 = (const WCHAR *)UStrToPWChar(v22, v2);
kernel32_DeleteFileW(v3);
__writefsdword(0, (unsigned int)v8);
ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)&savedregs;
v9 = &loc_8C25F8;
v8 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v8);
if ( (unsigned __int8)FileExists(v22) )
{
UStrToPWChar(v22, v4);
sub_8C28D8(1);
}
__writefsdword(0, (unsigned int)v8);
}
UStrCatN(L"_IObitDel.dll", v24, result);
if ( (unsigned __int8)FileExists(v22) )
{
ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)&savedregs;
v9 = &loc_8C264C;
v8 = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&v8);
v6 = (const WCHAR *)UStrToPWChar(v22, v5);
kernel32_DeleteFileW(v6);
__writefsdword(0, (unsigned int)v8);
}
}
__writefsdword(0, (unsigned int)v11);
v13 = (int *)&loc_8C268B;
if ( v17 )
(*(void (__cdecl **)(int *))(*v17 - 4))(v13);
TObject_Free(v18);
__writefsdword(0, (unsigned int)v11);
UStrArrayClr(&loc_8C26C2);
UStrArrayClr(v13);
return v19;
}
解决方案:patch 主程序TCVCheckThread_Execute_008C4948
直接ret
解决弹窗2==》CheckSum校验
在修改主程序后弹出
调用栈
EntryPoint--》InitExe--》StartExe--》InitUnits 触发异常
sub_9A9188 异常处理
int sub_9A9188()
{
int v1; // eax
int v2; // eax
int v3; // eax
int result; // eax
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // [esp-Ch] [ebp-Ch] BYREF
void *v6; // [esp-8h] [ebp-8h]
v6 = &loc_9A922E;
ExceptionList = NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)&ExceptionList);
if ( dword_9DBCC8-- == 0 )
{
*IsMultiThread = 1;
sub_4361A0(ExceptionList, v6);
sub_46A3D4(&gvar_009B0684, gvar_009B06C8);
v1 = sub_46A3D4(&gvar_009B0688, gvar_009B06C8);
if ( gvar_009B064C )
v1 = sub_46A26C(gvar_009B06C8, (unsigned __int8)byte_9B0650);
if ( gvar_009B0648 )
v1 = sub_46A088(gvar_009B06C8, 0);
v2 = sub_41C838(v1);
v3 = sub_46A2B4(v2);
sub_436DD4(v3);
gvar_009B06D8 = 1;
sub_46ADBC(); // box
gvar_009B06D8 = 0;
}
result = 0;
__writefsdword(0, (unsigned int)ExceptionList);
return result;
}
后续跟踪到
在异常中计算checksum并与pe中checksum字段比较
calc_checksum_46A4C4
int __fastcall calc_checksum_46A4C4(HMODULE hModule)
{
// [COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL-"+" TO EXPAND]
v16 = 0;
v18 = 0;
v17 = 0;
result = 0;
v15 = &savedregs;
v14[1] = (unsigned int)&loc_46A724;
v14[0] = (unsigned int)NtCurrentTeb()->NtTib.ExceptionList;
__writefsdword(0, (unsigned int)v14);
v2 = 0;
if ( (kernel32_GetVersion_0() & 0x80000000) != 0 )
{
kernel32_GetModuleFileNameA(hModule, (LPSTR)Filename, 0x104u);
FileA = kernel32_CreateFileA((LPCSTR)Filename, 0x80000000, 3u, 0, 3u, 0, 0);
}
else
{
kernel32_GetModuleFileNameW_1(hModule, Filename, 0x104u);
FileA = kernel32_CreateFileW_1(Filename, 0x80000000, 3u, 0, 3u, 0, 0);
}
if ( FileA != (HANDLE)0xFFFFFFFF )
{
FileMappingW = kernel32_CreateFileMappingW(FileA, 0, 2u, 0, 0, 0);
v5 = FileMappingW;
if ( FileMappingW )
{
lpBaseAddress = kernel32_MapViewOfFile(FileMappingW, 4u, 0, 0, 0);
if ( lpBaseAddress )
{
v6 = sub_41B6D0(lpBaseAddress);
if ( v6 )
{
// add eax, 18h ;sizeof Signature + fileheader
// add eax, 40h ; '@' op_header +0x40 checksum
v21 = (char *)(v6 + 0x58);
if ( *(_DWORD *)(v6 + 0x58) ) // checksum
{
// https://www.cnblogs.com/concurrency/p/3926698.html
// uint32_t calc_checksum(uint32_t checksum, void *data, int length) {
// if (length && data != nullptr) {
// uint32_t sum = 0;
// do {
// sum = *(uint16_t *)data + checksum;
// checksum = (uint16_t)sum + (sum >> 16);
// data = (char *)data + 2;
// } while (--length);
// }
// return checksum + (checksum >> 16);
// }
// uint32_t generate_pe_checksum(void *file_base, uint32_t file_size) {
// uint32_t file_checksum = 0;
// PIMAGE_NT_HEADERS nt_headers = ImageNtHeader(file_base);
// if (nt_headers) {
// uint32_t header_size = (uintptr_t)nt_headers - (uintptr_t)file_base +
// ((uintptr_t)&nt_headers->OptionalHeader.CheckSum -
// (uintptr_t)nt_headers);
// uint32_t remain_size = (file_size - header_size - 4) >> 1;
// void *remain = &nt_headers->OptionalHeader.Subsystem;
// uint32_t header_checksum = calc_checksum(0, file_base, header_size >> 1);
// file_checksum = calc_checksum(header_checksum, remain, remain_size);
// if (file_size & 1){
// file_checksum += (uint16_t)*((char *)file_base + file_size - 1);
// }
// }
// return (file_size + file_checksum);
// }
FileSize_0 = kernel32_GetFileSize_0(FileA, 0);
v7 = sub_46A468(lpBaseAddress, v21 - (_BYTE *)lpBaseAddress, 0);
v8 = sub_46A468(v21 + 4, FileSize_0 - (v21 - (_BYTE *)lpBaseAddress) - 4, v7);
if ( FileSize_0 + v8 != *(_DWORD *)v21 )
LOBYTE(v2) = 1;
}
}
kernel32_UnmapViewOfFile(lpBaseAddress);
}
kernel32_CloseHandle_0(v5);
}
kernel32_CloseHandle_0(FileA);
}
if ( (_BYTE)v2 )
{
if ( (kernel32_GetVersion_0() & 0x80000000) != 0 )
{
(*(void (__fastcall **)(int, int *))(*(_DWORD *)gvar_009B0F0C + 0x2A0))(gvar_009B0F0C, &v17);
LStrFromUStr(&v18, v17);
v11 = (const CHAR *)LStrToPChar(v18);
user32_MessageBoxA_0(0, v11, 0, 0x10u);
}
else
{
(*(void (__fastcall **)(int, void **))(*(_DWORD *)gvar_009B0F0C + 0x2A0))(gvar_009B0F0C, &result);
v10 = (const WCHAR *)UStrToPWChar(result, v9);
user32_MessageBoxW_0(0, v10, 0, 0x10u);
}
if ( kernel32_GetModuleHandleW_1(0) == gvar_009B06C8 )
kernel32_ExitProcess_0(0);
IntfClear(&gvar_009B0F0C);
(*(void (__fastcall **)(int, int *))(*(_DWORD *)gvar_009B0F0C + 0x2A0))(gvar_009B0F0C, &v16);
v12 = sub_40BBD4(VMT_40BB5C_MadException, v16);
RaiseExcept(v12);
}
__writefsdword(0, v14[0]);
UStrArrayClr(&loc_46A72B);
LStrClr(v15);
UStrClr(v15);
return v2;
}
解决方案:
方法1:修正CheckSum
方法2:patch calc_checksum_46A4C4
测试
缺少网络校验的响应数据,无注册码数据
伪注册