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]

注册事件

image-20241113234938116

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最为简单

image-20241114001042804

RegisterCom.dll patch 点

1\

image-20241114001600780

2\

image-20241114001633432

3\

image-20241114001649334

4\

image-20241114001714660

解决弹窗1==》RegisterCom.dll patch后主程序弹窗

image-20241113230615317

通过spy++ 查看窗口

image-20241113232244204

image-20241113232313292

frm_IUCrakTip

从IDR 中查看窗口信息

image-20241113231856783

窗口间通过消息事件触发,跟踪较复杂,直接从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

image-20241114002930580

解决弹窗2==》CheckSum校验

在修改主程序后弹出

image-20241113215713764

调用栈

image-20241113215956582

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;
}

image-20241113215947712

后续跟踪到

image-20241113230449951

在异常中计算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

image-20241114003117607

测试

缺少网络校验的响应数据,无注册码数据

image-20241114003219465

伪注册

image-20241114003724558

posted @ 2024-11-14 09:17  DirWangK  阅读(24)  评论(0编辑  收藏  举报