Flash32以上版本无法打开外链问题说明

问题背景

雷霆之怒在微端中无法打开外链,与CP方沟通发现,他们打开URL使用的方式是flash.net.navigateToURL,而从Flash32版本开始,增加了一个安全性控制字段EnableInsecureActiveXNavigateToURL,根据官方Release Note描述,该字段是用于控制打开的外链URL跨域行为的,此次的问题正是由于这个字段引起的。

问题调查

代码层的具体表现为,游戏中点击外链按钮之后,IE控件无法触发NewWindow3事件。根据官方论坛的讨论,可以在系统的flash.ocx目录,创建mms.cfg文件用于对Flash做安全控制,32位进程路径为C:\Windows\SysWOW64\Macromed\Flash\mms.cfg,64位进程路径位C:\Windows\System32\Macromed\Flash\mms.cfg,文件内容为EnableInsecureActiveXNavigateToURL=1,必须要有管理员权限才能写入文件。

直接修改mms.cfg文件最简单,但是由于需要提权,所以在用户双击启动的时候,会弹UAC框,非常影响用户体验。同时,同样的Flash版本下,IE浏览器则不受影响,说明,不止修改mms.cfg文件一条路。

问题解决

暴力方式(Hook)

Flash配置加载流程:

程序加载Flash控件 -> CoreGlobals::Init初始化 -> CreateFileW打开配置文件mms.cfg -> CoreGlobals::ReadSecurityProperty解析配置 -> 保存结果到全局结构体globClass中。

后续需要用到全局配置的时候,直接通过全局函数GetPlatformGlobals即可获取到globClass的指针。32.0.0.387版本的flash.ocx文件中,该指针的FA为0x1398BF8,RVA为0x139b1f8,对应成员变量偏移为0xa234。有了这些信息,即可在运行时,动态修改EnableInsecureActiveXNavigateToURL的值为1,即可绕过跨域的限制,成功收到NewWindow3的响应。

动态改内存的方式虽然可以达到目的,但是兼容性较差,一旦Flash升级了,前面算出来的偏移可能就废了。

分析上面的配置加载流程,我们发现Flash会调用系统API函数CreateFileW打开配置文件,这个API大家都很熟悉了,是导出函数,所以也不用担心偏移地址的问题,直接Hook该API,替换路径为我们本地的mms.cfg文件,这样我们就可以通过程序本地的文件控制Flash的行为了。

上面两种方式都已经实现并且验证可行,但都不算完美,所以只做简要介绍,下面详细说明我们今天的重头戏。

IE方式(白名单)

flash.net.navigateToURL函数最终会调用Flash内部的PlatformPlayer::DoNavigateToURLImpl函数执行真正的逻辑。

bool __thiscall PlatformPlayer::DoNavigateToURLImpl(PlatformPlayer *this, struct URLRequest *a2)
{
  CorePlayer *v2; // esi
  char *v3; // ebx
  PlatformFileManager *v4; // eax
  const char **v5; // eax
  bool v6; // bl
  LPCWSTR v8; // esi
  const WCHAR *v9; // eax
  LPCVOID v10; // ecx
  const CHAR *v11; // eax
  unsigned int v12; // ecx
  int v13; // edi
  void *v14; // esp
  WCHAR *v15; // eax
  unsigned int v16; // ecx
  unsigned int v17; // edi
  void *v18; // esp
  const WCHAR *v19; // eax
  WCHAR *v20; // eax
  CorePlayer *v21; // edi
  PlatformFileManager *v22; // eax
  int v23; // eax
  int v24; // eax
  const char *v25; // edx
  char *v26; // ecx
  bool v27; // cf
  bool v28; // zf
  unsigned __int8 v29; // al
  int v30; // ecx
  char *v31; // ecx
  bool v32; // cf
  unsigned __int8 v33; // bl
  int v34; // ecx
  bool v35; // sf
  int v36; // eax
  int v37; // edi
  unsigned __int16 *v38; // eax
  int v39; // eax
  PlatformFileManager *v40; // eax
  struct URLRequest *v41; // edi
  DRM::AVEContentDecryptionCallbacks *v42; // ecx
  const char *v43; // edi
  SAFEARRAY *v44; // edi
  int v45; // ST18_4
  const CHAR *v46; // edi
  int v47; // eax
  int v48; // eax
  struct PlatformGlobals *v49; // eax
  DRM::AVEContentDecryptionCallbacks *v50; // eax
  char *v51; // edi
  char *v52; // edi
  int v53; // eax
  int v54; // eax
  CorePlayer *v55; // ebx
  int v56; // edi
  int v57; // eax
  bool v58; // bl
  IUnknown *v59; // eax
  LPCWSTR v60; // edi
  HRESULT v61; // ebx
  WCHAR *v62; // ST1C_4
  GUID *v63; // [esp+0h] [ebp-B0h]
  GUID *v64; // [esp+4h] [ebp-ACh]
  int *v65; // [esp+8h] [ebp-A8h]
  char *v66; // [esp+Ch] [ebp-A4h]
  BSTR bstrString; // [esp+10h] [ebp-A0h]
  LPCSTR v68; // [esp+14h] [ebp-9Ch]
  int v69; // [esp+18h] [ebp-98h]
  LPCVOID lpMem; // [esp+1Ch] [ebp-94h]
  int v71; // [esp+20h] [ebp-90h]
  LPCWSTR szTargetFrameName; // [esp+24h] [ebp-8Ch]
  struct URLRequest *v73; // [esp+28h] [ebp-88h]
  CorePlayer *v74; // [esp+2Ch] [ebp-84h]
  char v75; // [esp+32h] [ebp-7Eh]
  char v76; // [esp+33h] [ebp-7Dh]
  VARIANTARG v77; // [esp+34h] [ebp-7Ch]
  VARIANTARG v78; // [esp+44h] [ebp-6Ch]
  VARIANTARG pvarg; // [esp+54h] [ebp-5Ch]
  OLECHAR *psz; // [esp+64h] [ebp-4Ch]
  VARIANTARG v81; // [esp+68h] [ebp-48h]
  char *v82; // [esp+78h] [ebp-38h]
  int v83; // [esp+7Ch] [ebp-34h]
  int v84; // [esp+80h] [ebp-30h]
  int v85; // [esp+84h] [ebp-2Ch]
  int v86; // [esp+88h] [ebp-28h]
  _DWORD **v87; // [esp+8Ch] [ebp-24h]
  LPCSTR lpMultiByteStr; // [esp+90h] [ebp-20h]
  int v89; // [esp+94h] [ebp-1Ch]
  int v90; // [esp+98h] [ebp-18h]
  IMoniker *pmkTarget; // [esp+9Ch] [ebp-14h]
  int v92; // [esp+A0h] [ebp-10h]
  int v93; // [esp+A4h] [ebp-Ch]
  int v94; // [esp+A8h] [ebp-8h]

  v2 = this;
  v74 = this;
  v73 = a2;
  v3 = (char *)*((_DWORD *)a2 + 9);
  v94 = *((_DWORD *)a2 + 9);
  if ( !*((_BYTE *)GetPlatformGlobals() + 41524) )
  {
    v4 = CorePlayer::FileMgr(v2);
    v5 = (const char **)PlatformGlobals::GetHostAppInternalName(&v82, v4);
    v6 = PlatformPlayer::RunningInBrowser(*v5) == 0;
    FlashString::Clear((FlashString *)&v82);
    if ( v6 )
      return 0;
    v3 = (char *)v94;
  }
  v8 = 0;
  szTargetFrameName = 0;
  v69 = CorePlayer::CalcCorePlayerVersion(v74);
  if ( v69 > 5 )
  {
    lpMem = CopyUTF8to16(*((const char **)a2 + 8));
    v9 = CopyUTF8to16(v3);
    v10 = lpMem;
    szTargetFrameName = v9;
    goto LABEL_24;
  }
  v11 = (const CHAR *)*((_DWORD *)a2 + 8);
  v68 = v11;
  if ( v11
    && (v12 = strlen(v11),
        v13 = 2 * (v12 + 1),
        v86 = (unsigned __int64)(2i64 * (signed int)(v12 + 1) + 0x80000000i64) >> 32,
        (unsigned __int64)(2i64 * (signed int)(v12 + 1) + 0x80000000i64) <= 0xFFFFFFFF) )
  {
    if ( v13 <= 1024
      && ATL::_ATL_SAFE_ALLOCA_IMPL::_AtlVerifyStackAvailable((ATL::_ATL_SAFE_ALLOCA_IMPL *)v13, (unsigned int)v63) )
    {
      v14 = alloca(v13);
      v15 = (WCHAR *)&v63;
    }
    else
    {
      v15 = (WCHAR *)ATL::_ATL_SAFE_ALLOCA_IMPL::CAtlSafeAllocBufferManager<ATL::CCRTAllocator>::Allocate(v13);
      v8 = szTargetFrameName;
    }
    lpMem = AtlA2WHelper(v15, v68, (unsigned int)v13 >> 1, 3u);
  }
  else
  {
    lpMem = 0;
  }
  if ( v3
    && (v16 = strlen(v3),
        v17 = 2 * (v16 + 1),
        v86 = (unsigned __int64)(2i64 * (signed int)(v16 + 1) + 0x80000000i64) >> 32,
        (unsigned __int64)(2i64 * (signed int)(v16 + 1) + 0x80000000i64) <= 0xFFFFFFFF) )
  {
    if ( (signed int)v17 <= 1024
      && ATL::_ATL_SAFE_ALLOCA_IMPL::_AtlVerifyStackAvailable((ATL::_ATL_SAFE_ALLOCA_IMPL *)v17, (unsigned int)v63) )
    {
      v18 = alloca(v17);
      v19 = AtlA2WHelper((LPWSTR)&v63, v3, v17 >> 1, 3u);
    }
    else
    {
      v20 = (WCHAR *)ATL::_ATL_SAFE_ALLOCA_IMPL::CAtlSafeAllocBufferManager<ATL::CCRTAllocator>::Allocate(v17);
      v8 = szTargetFrameName;
      v19 = AtlA2WHelper(v20, v3, v17 >> 1, 3u);
    }
  }
  else
  {
    v19 = 0;
  }
  v10 = lpMem;
  szTargetFrameName = v19;
  if ( lpMem && v19 )
  {
LABEL_24:
    pmkTarget = 0;
    v71 = -2147467259;
    v21 = v74;
    PlatformPlayer::BuildRelativeMoniker(v10, &pmkTarget);
    if ( !pmkTarget )
    {
      v61 = -2147467259;
      goto LABEL_146;
    }
    v76 = 0;
    if ( !*((_DWORD *)v73 + 10) && v69 < 8 )
    {
      v22 = CorePlayer::FileMgr(v21);
      if ( !PlatformFileManager::IsIE7(v22) )
        goto LABEL_141;
    }
    v23 = *((_DWORD *)v21 + 892);
    v92 = 0;
    v93 = 0;
    ATL::CComQIPtr<IServiceProvider,&_GUID const IID_IServiceProvider>::CComQIPtr<IServiceProvider,&_GUID const IID_IServiceProvider>(*(_DWORD *)(v23 + 16));
    v24 = v93;
    if ( !v93 )
    {
LABEL_137:
      if ( v92 )
        (*(void (__thiscall **)(_DWORD, int))(*(_DWORD *)v92 + 8))(*(_DWORD *)(*(_DWORD *)v92 + 8), v92);
      if ( !v76 )
      {
        v21 = v74;
LABEL_141:
        if ( coreplayer::View::GetFullScreen(*(coreplayer::View **)(*((_DWORD *)v21 + 22) + 628)) )
          coreplayer::View::SetFullScreen(*(coreplayer::View **)(*((_DWORD *)v21 + 22) + 628), 0, 0);
        v59 = (IUnknown *)*((_DWORD *)v21 + 892);
        v60 = szTargetFrameName;
        v61 = HlinkSimpleNavigateToMoniker(pmkTarget, 0, szTargetFrameName, v59 + 27, 0, 0, 0, 0);
        goto LABEL_147;
      }
      v61 = v71;
LABEL_146:
      v60 = szTargetFrameName;
LABEL_147:
      if ( v69 > 5 )
      {
        if ( lpMem )
          MMgc::FixedMalloc::OutOfLineFree(dword_EDCACF8, lpMem);
        if ( v60 )
          MMgc::FixedMalloc::OutOfLineFree(dword_EDCACF8, v60);
      }
      v58 = v61 >= 0;
      goto LABEL_153;
    }
    if ( !v3 )
      goto LABEL_161;
    v25 = "_blank";
    v26 = v3;
    while ( 1 )
    {
      v27 = (unsigned __int8)*v26 < *v25;
      v28 = *v26 == *v25;
      v75 = *v26;
      v24 = v93;
      if ( !v28 )
        break;
      if ( !v75 )
        goto LABEL_35;
      v29 = v26[1];
      v27 = v29 < v25[1];
      v28 = v29 == v25[1];
      v75 = v26[1];
      v24 = v93;
      if ( !v28 )
        break;
      v26 += 2;
      v25 += 2;
      if ( !v75 )
      {
LABEL_35:
        v30 = 0;
        goto LABEL_37;
      }
    }
    v30 = -v27 | 1;
LABEL_37:
    if ( !v30 )
      goto LABEL_162;
    v25 = "_new";
    v31 = v3;
    while ( 1 )
    {
      v32 = (unsigned __int8)*v31 < *v25;
      v28 = *v31 == *v25;
      v75 = *v31;
      v3 = (char *)v94;
      if ( !v28 )
        break;
      if ( !v75 )
        goto LABEL_43;
      v33 = v31[1];
      v32 = v33 < v25[1];
      v28 = v33 == v25[1];
      v75 = v31[1];
      v3 = (char *)v94;
      if ( !v28 )
        break;
      v31 += 2;
      v25 += 2;
      if ( !v75 )
      {
LABEL_43:
        v34 = 0;
        goto LABEL_45;
      }
    }
    v34 = -v32 | 1;
LABEL_45:
    if ( v34 )
    {
LABEL_161:
      v37 = (*(int (__thiscall **)(_DWORD, int, GUID *, GUID *, int *))(*(_DWORD *)v24 + 12))(
              *(_DWORD *)(*(_DWORD *)v24 + 12),
              v24,
              &IID_IWebBrowserApp,
              &IID_IWebBrowser2,
              &v92);
      v71 = v37;
    }
    else
    {
LABEL_162:
      v94 = 0;
      v35 = (*(int (__fastcall **)(_DWORD, const char *, int, SID *, GUID *, int *, GUID *, GUID *, int *))(*(_DWORD *)v24 + 12))(
              *(_DWORD *)(*(_DWORD *)v24 + 12),
              v25,
              v24,
              &SID_STopLevelBrowser,
              &IID_IServiceProvider,
              &v94,
              v63,
              v64,
              v65) < 0;
      v36 = v94;
      v65 = &v92;
      v64 = &IID_IWebBrowser2;
      v63 = &IID_IWebBrowserApp;
      if ( v35 )
        v36 = v93;
      v37 = (*(int (__thiscall **)(_DWORD, int))(*(_DWORD *)v36 + 12))(*(_DWORD *)(*(_DWORD *)v36 + 12), v36);
      v71 = v37;
      ATL::CComPtr<IHTMLLocation>::~CComPtr<IHTMLLocation>(&v94, v63, v64, v65);
    }
    if ( v37 < 0 )
    {
LABEL_135:
      if ( v93 )
        (*(void (__thiscall **)(_DWORD, int))(*(_DWORD *)v93 + 8))(*(_DWORD *)(*(_DWORD *)v93 + 8), v93);
      goto LABEL_137;
    }
    VariantInit(&pvarg);
    if ( v3 )
    {
      pvarg.vt = 8;
      if ( v69 <= 5 )
        v38 = A2BSTR(v3);
      else
        v38 = UTF82BSTR(v3);
      pvarg.lVal = (LONG)v38;
    }
    v71 = ((int (__thiscall *)(HRESULT (__stdcall *)(IMoniker *, IBindCtx *, IMoniker *, LPOLESTR *), IMoniker *, _DWORD, IMoniker *, OLECHAR **))pmkTarget->lpVtbl->GetDisplayName)(
            pmkTarget->lpVtbl->GetDisplayName,
            pmkTarget,
            0,
            pmkTarget,
            &psz);
    if ( v71 < 0 )
    {
LABEL_134:
      VariantClear(&pvarg);
      goto LABEL_135;
    }
    bstrString = SysAllocString(psz);
    CoTaskMemFree(psz);
    VariantInit(&v77);
    lpMultiByteStr = 0;
    v89 = 0;
    v90 = 0;
    v75 = IsWindowsVersion(5u, 0);
    v76 = 0;
    if ( IsWindowsVersion(5u, 1u) )
    {
      v39 = strcmp(CommonPlayer::GetOSLanguage(v69), "ja");
      if ( v39 )
        v39 = -(v39 < 0) | 1;
      if ( !v39 )
      {
        v40 = CorePlayer::FileMgr(v74);
        if ( !PlatformFileManager::IsIE7(v40) )
          v76 = 1;
      }
    }
    v41 = v73;
    v42 = (DRM::AVEContentDecryptionCallbacks *)*((_DWORD *)v73 + 17);
    if ( !v42 )
    {
LABEL_76:
      if ( *((_DWORD *)v41 + 10) )
      {
        FlashString::AppendString((FlashString *)&lpMultiByteStr, "Content-type: ");
        if ( *((_DWORD *)v41 + 12) )
          FlashString::AppendString((FlashString *)&lpMultiByteStr, *((const char **)v41 + 12));
        else
          FlashString::AppendString((FlashString *)&lpMultiByteStr, "application/x-www-form-urlencoded");
        FlashString::AppendString((FlashString *)&lpMultiByteStr, "\r\n");
      }
      if ( v89 )
      {
        v77.vt = 8;
        v77.lVal = (LONG)A2BSTR(lpMultiByteStr);
      }
      VariantInit(&v78);
      if ( *((_DWORD *)v41 + 10) )
      {
        v44 = SafeArrayCreateVector(0x11u, 0, *((_DWORD *)v41 + 11));
        v78.vt = 8209;
        v78.lVal = (LONG)v44;
        SafeArrayLock(v44);
        memcpy(v44->pvData, *((const void **)v73 + 10), *((_DWORD *)v73 + 11));
        SafeArrayUnlock(v44);
        v41 = v73;
      }
      VariantInit(&v81);
      v81.lVal = 0;
      v45 = *((_DWORD *)v41 + 12);
      v81.vt = 3;
      v85 = 0;
      v86 = 0;
      HttpHeaders::HttpHeaders(&v85, v45, 2);
      if ( HttpHeaders::HeadersPresent((HttpHeaders *)&v85) )
        v81.lVal |= 0x8000u;
      if ( !coreplayer::View::GetFullScreen(*(coreplayer::View **)(*((_DWORD *)v74 + 22) + 628)) )
      {
        if ( !SecurityContext::IsPlayerUI(*((SecurityContext **)v41 + 17)) )
          v81.lVal |= 0x100u;
        if ( CommonPlayer::GetWindowsVersion() >= 14
          && (*((_BYTE *)v41 + 77) || CorePlayer::DoesExecutionResultFromUserAction(v74)) )
        {
          v81.lVal &= 0xFFFFFEFF;
          if ( PlatformPlayer::RunningInSpartan() )
            v81.lVal |= 0x400000u;
        }
      }
      v76 = 1;
      v46 = CopyUTF16to8(bstrString, 0);
      v68 = v46;
      if ( !v3 )
        goto LABEL_116;
      v47 = strcmp(v3, &byte_E8C6254);
      if ( v47 )
        v47 = -(v47 < 0) | 1;
      if ( !v47 )
        goto LABEL_116;
      v48 = strcmp(v3, "_self");
      if ( v48 )
        v48 = -(v48 < 0) | 1;
      if ( !v48 )
        goto LABEL_116;
      v66 = *(char **)DRM::AVEContentDecryptionCallbacks::getVideoState(*((DRM::AVEContentDecryptionCallbacks **)v73 + 17));
      v49 = GetPlatformGlobals();
      if ( FlashSecurity::IsScriptingUrl(*((FlashSecurity **)v49 + 6), v46) )
      {
        v50 = (DRM::AVEContentDecryptionCallbacks *)*((_DWORD *)v73 + 20);
        if ( !v50 )
        {
          v50 = (DRM::AVEContentDecryptionCallbacks *)*((_DWORD *)v73 + 17);
          if ( !v50 )
            goto LABEL_116;
        }
        v76 = PlatformPlayer::scriptingTargetIsSecure(v74, v50, v3);
        if ( v76 )
          goto LABEL_116;
        v51 = CopyUTF16to8(pvarg.bstrVal, 0);
        FlashSecurity::ReportDeniedRequest(*(FlashSecurity **)(*((_DWORD *)v74 + 9) + 24), v74, v51, v66, 0);
        StrFree(v51);
      }
      else
      {
        v87 = 0;
        v71 = (*(int (__thiscall **)(_DWORD, int, _DWORD ***))(*(_DWORD *)v92 + 72))(
                *(_DWORD *)(*(_DWORD *)v92 + 72),
                v92,
                &v87);
        if ( v71 >= 0 && v87 )
        {
          v94 = 0;
          v71 = ((int (__thiscall *)(_DWORD, _DWORD **, GUID *, int *))**v87)(**v87, v87, &IID_IHTMLDocument2, &v94);
          if ( v71 >= 0 && v94 )
            v76 = PlatformPlayer::navigationTargetIsSecure(v74, v94, *((_DWORD *)v73 + 17), v3, (int)&pvarg);
          ATL::CComPtr<IHTMLLocation>::~CComPtr<IHTMLLocation>(&v94, v63, v64, v65);
          if ( !v76 )
          {
            v52 = CopyUTF16to8(pvarg.bstrVal, 0);
            FlashSecurity::ReportDeniedRequest(*(FlashSecurity **)(*((_DWORD *)v74 + 9) + 24), v74, v52, v66, 0);
            StrFree(v52);
          }
        }
        ATL::CComPtr<IHTMLLocation>::~CComPtr<IHTMLLocation>(&v87, v63, v64, v65);
      }
      v46 = v68;
LABEL_116:
      if ( v46 )
        MMgc::FixedMalloc::OutOfLineFree(dword_EDCACF8, v46);
      if ( v76 )
      {
        if ( v3 )
        {
          v53 = strcmp(v3, &byte_E8C6254);
          if ( v53 )
            v53 = -(v53 < 0) | 1;
          if ( !v53 )
            goto LABEL_163;
        }
        v54 = strcmp(v3, "_self");
        if ( v54 )
          v54 = -(v54 < 0) | 1;
        if ( v54 )
        {
          v55 = v74;
        }
        else
        {
LABEL_163:
          v55 = v74;
          CorePlayer::UpdateClientSharedObjects(v74);
        }
        (*(void (__thiscall **)(_DWORD, int))(*(_DWORD *)(*((_DWORD *)v55 + 892) + 108) + 4))(
          *(_DWORD *)(*(_DWORD *)(*((_DWORD *)v55 + 892) + 108) + 4),
          *((_DWORD *)v55 + 892) + 108);
        v56 = (*(int (__thiscall **)(_DWORD, int, BSTR, VARIANTARG *, VARIANTARG *, VARIANTARG *, VARIANTARG *))(*(_DWORD *)v92 + 44))(
                *(_DWORD *)(*(_DWORD *)v92 + 44),
                v92,
                bstrString,
                &v81,
                &pvarg,
                &v78,
                &v77);
        v57 = *((_DWORD *)v55 + 892);
        v71 = v56;
        if ( *(_DWORD *)(v57 + 232) == 1 )
        {
          CorePlayer::SetPlayerAbortStatus(v55, 1);
          *((_BYTE *)v55 + 2836) = 1;
          HttpHeaders::~HttpHeaders((HttpHeaders *)&v85);
          FlashString::Clear((FlashString *)&lpMultiByteStr);
          ATL::CComPtr<IHTMLLocation>::~CComPtr<IHTMLLocation>(&v93, v63, v64, v65);
          ATL::CComPtr<IHTMLLocation>::~CComPtr<IHTMLLocation>(&v92, v63, v64, v65);
          v58 = 0;
LABEL_153:
          if ( pmkTarget )
            ((void (__thiscall *)(ULONG (__stdcall *)(IMoniker *), IMoniker *))pmkTarget->lpVtbl->Release)(
              pmkTarget->lpVtbl->Release,
              pmkTarget);
          goto LABEL_156;
        }
        (*(void (__thiscall **)(_DWORD, int))(*(_DWORD *)(v57 + 108) + 8))(
          *(_DWORD *)(*(_DWORD *)(v57 + 108) + 8),
          v57 + 108);
      }
      v76 = 1;
      VariantClear(&v81);
      if ( bstrString )
        SysFreeString(bstrString);
      VariantClear(&v78);
      VariantClear(&v77);
      HttpHeaders::~HttpHeaders((HttpHeaders *)&v85);
      FlashString::Clear((FlashString *)&lpMultiByteStr);
      goto LABEL_134;
    }
    v43 = *(const char **)DRM::AVEContentDecryptionCallbacks::getVideoState(v42);
    if ( v43 )
    {
      if ( StripScheme(v43, "https:") == 0 )
      {
        if ( !StripScheme(v43, "http:") )
          goto LABEL_75;
LABEL_69:
        v82 = 0;
        v83 = 0;
        v84 = 0;
        FlashString::FlashString((FlashString *)&v82, v43);
        if ( v76 )
        {
          FlashString::Truncate((FlashString *)&v82, 0x64u);
        }
        else if ( v75 )
        {
          FlashString::Truncate((FlashString *)&v82, 0x6Eu);
        }
        else
        {
          FlashString::Truncate((FlashString *)&v82, 0x8Cu);
        }
        FlashString::AppendString((FlashString *)&lpMultiByteStr, "Referer: ");
        FlashString::AppendString((FlashString *)&lpMultiByteStr, v82);
        FlashString::AppendString((FlashString *)&lpMultiByteStr, "\r\n");
        FlashString::Clear((FlashString *)&v82);
        goto LABEL_75;
      }
      if ( StripScheme(*((const char **)v73 + 8), "https:") )
        goto LABEL_69;
    }
LABEL_75:
    v41 = v73;
    goto LABEL_76;
  }
  v58 = 0;
LABEL_156:
  while ( v8 )
  {
    v62 = (WCHAR *)v8;
    v8 = *(LPCWSTR *)v8;
    free(v62);
  }
  return v58;
}

该函数很长,但是目的却很简单,就是打开URL,我们只分析第一个if语句块即可

if ( !*((_BYTE *)GetPlatformGlobals() + 41524) )
  {
    v4 = CorePlayer::FileMgr(v2);
    v5 = (const char **)PlatformGlobals::GetHostAppInternalName(&v82, v4);
    v6 = PlatformPlayer::RunningInBrowser(*v5) == 0;
    FlashString::Clear((FlashString *)&v82);
    if ( v6 )
      return 0;
    v3 = (char *)v94;
  }

前面已经说过GetPlatformGlobals函数用于获取全局配置结构体地址,41524即十六进制的0xa234,就是我们的目标变量偏移,所以这条语句就是判断EnableInsecureActiveXNavigateToURL属性是否为真,如果为真则不会进入if内部,直接进行后续处理,否则进入if内部,准备返回0,而一旦返回,则意味着打开URL失败,在IE控件的表现则为收不到NewWindow3事件。我们如果不进行上面提到的暴力方式的处理,EnableInsecureActiveXNavigateToURL默认为0,则会直接进入if内部,此时,我们就要想办法让v6为假,否则就会失败,而v6的值由v5决定,所以需要看看PlatformGlobals::GetHostAppInternalNamePlatformPlayer::RunningInBrowser这两个函数的实现。

_DWORD *__cdecl PlatformGlobals::GetHostAppInternalName(_DWORD *a1, PlatformFileManager *a2)
{
  const char *v2; // edi
  const char *v3; // eax
  const void *v4; // esi
  unsigned __int16 *v5; // esi
  const char *v6; // eax
  char *v7; // esi
  char *v8; // eax
  LPCVOID pBlock; // [esp+28h] [ebp-130h]
  __int16 v11; // [esp+2Eh] [ebp-12Ah]
  LPVOID lpBuffer; // [esp+30h] [ebp-128h]
  LPVOID v13; // [esp+34h] [ebp-124h]
  unsigned int puLen; // [esp+38h] [ebp-120h]
  int v15; // [esp+3Ch] [ebp-11Ch]
  int v16; // [esp+40h] [ebp-118h]
  int v17; // [esp+44h] [ebp-114h]
  int v18; // [esp+48h] [ebp-110h]
  char v19; // [esp+4Ch] [ebp-10Ch]
  CHAR SubBlock[4]; // [esp+50h] [ebp-108h]
  char v21; // [esp+60h] [ebp-F8h]
  char v22; // [esp+64h] [ebp-F4h]
  int v23; // [esp+68h] [ebp-F0h]
  __int16 v24; // [esp+74h] [ebp-E4h]

  *a1 = 0;
  a1[1] = 0;
  a1[2] = 0;
  v19 = aStringfileinfo[16];
  strcpy((char *)&v11, "e");
  v15 = 0;
  v16 = 0;
  v17 = 0;
  v18 = 0;
  FlashFileString::FlashFileString((FlashFileString *)&v15);
  v2 = 0;
  pBlock = 0;
  v13 = 0;
  if ( PlatformFileManager::FileGetModuleFileName(a2, 0, (struct FlashFileString *)&v15) )
  {
    v3 = FlashFileString::getMBCS((FlashFileString *)&v15);
    v2 = CreateStr(v3);
    v4 = PlatformFileManager::FileGetFileVersionInfo(a2, (const struct FlashFileString *)&v15);
    pBlock = v4;
    if ( v4 )
    {
      if ( VerQueryValueA(v4, "\\VarFileInfo\\Translation", &lpBuffer, &puLen) )
      {
        v5 = (unsigned __int16 *)lpBuffer;
        qmemcpy(SubBlock, "\\StringFileInfo\\", 16);
        FourCharacterHexCodeFromWord(&v21, *(unsigned __int16 *)lpBuffer);
        FourCharacterHexCodeFromWord(&v22, v5[1]);
        qmemcpy(&v23, "\\InternalNam", 12);
        v24 = v11;
        if ( VerQueryValueA(pBlock, SubBlock, &v13, &puLen) )
          FlashString::operator=((char *)v13);
      }
    }
  }
  if ( !a1[1] )
  {
    if ( v2 )
    {
      if ( *v2 )
      {
        v6 = FlashStrRChr(v2, 92);
        if ( v6 )
        {
          v7 = (char *)(v6 + 1);
          v8 = (char *)FlashStrChr(v6 + 1, 46);
          if ( v8 )
          {
            if ( v8 > v7 )
            {
              *v8 = 0;
              FlashString::operator=(v7);
            }
          }
        }
      }
    }
  }
  if ( pBlock )
    MMgc::FixedMalloc::OutOfLineFree(dword_EDCACF8, pBlock);
  if ( v2 )
    MMgc::FixedMalloc::OutOfLineFree(dword_EDCACF8, v2);
  FlashFileString::~FlashFileString((FlashFileString *)&v15);
  return a1;
}
char __cdecl PlatformPlayer::RunningInBrowser(const char *a1)
{
  char v1; // bl
  int v2; // esi
  char result; // al
  char *v4; // [esp+Ch] [ebp-30h]
  const char *v5; // [esp+10h] [ebp-2Ch]
  const char *v6; // [esp+14h] [ebp-28h]
  const char *v7; // [esp+18h] [ebp-24h]
  const char *v8; // [esp+1Ch] [ebp-20h]
  const char *v9; // [esp+20h] [ebp-1Ch]
  const char *v10; // [esp+24h] [ebp-18h]
  const char *v11; // [esp+28h] [ebp-14h]
  const char *v12; // [esp+2Ch] [ebp-10h]
  const char *v13; // [esp+30h] [ebp-Ch]
  const char *v14; // [esp+34h] [ebp-8h]
  const char *v15; // [esp+38h] [ebp-4h]

  v1 = 0;
  v4 = "explorer";
  v5 = "iexplore";
  v6 = "AOL";
  v7 = "netscape";
  v8 = "excel";
  v9 = "powerpnt";
  v10 = "pptview";
  v11 = "winword";
  v12 = "ybrowser";
  v13 = "msn";
  v14 = "msn6";
  v15 = "iepreview.exe";
  if ( a1 )
  {
    v2 = 0;
    while ( FlashStrICmp(a1, (&v4)[v2]) )
    {
      if ( (unsigned int)++v2 >= 0xC )
        goto LABEL_5;
    }
    return 1;
  }
LABEL_5:
  if ( byte_EDABB0C )
  {
    if ( !byte_EDABB0D )
      return v1;
    result = 1;
  }
  else
  {
    byte_EDABB0C = 1;
    if ( CommonPlayer::isWin10()
      && PlatformGlobals::platformInstance
      && PlatformGlobals::IsMetroMode(PlatformGlobals::platformInstance) )
    {
      byte_EDABB0D = 1;
      result = 1;
    }
    else
    {
      result = 0;
      byte_EDABB0D = 0;
    }
  }
  return result;
}

GetHostAppInternalName逻辑比较简单,就是取进程名,这里有一点要注意的是,它取的是InternalNam,即我们在rc文件中配置的InternalName

RunningInBrowser就是判断进程是否在浏览器中运行,参数a1就是前面取到的InternalName,我们期望该函数返回1,才能使得DoNavigateToURLImpl中的v6为0,从而可以继续执行后续逻辑。首先,如果a1在代码中列的12个名单中(即白名单),则无条件返回1,所以,我们只需要修改rc文件中的InternalName为白名单中的任意一项即可。

360方式(Hook+白名单)

360安全浏览器Hook了GetModuleFileNameW这个API,把自己伪装成IE浏览器,从而实现白名单效果。


flash

4670 Words

2020-08-12 10:48