Browse Source

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

master
lniwn 5 years ago
parent
commit
a78a561c9c
  1. 823
      content/posts/2020/Flash32以上版本无法打开外链问题说明.md

823
content/posts/2020/Flash32以上版本无法打开外链问题说明.md

@ -1,9 +1,824 @@
--- ---
title: "Flash32以上版本无法打开外链问题说明" title: "Flash32以上版本无法打开外链问题说明"
date: 2020-08-12T10:48:22+08:00 date: 2020-08-12T10:48:22+08:00
draft: true draft: false
toc: true toc: true
images: images:
tags: [untagged] tags: [flash]
categories: categories: windows
--- ---
## 问题背景
雷霆之怒在微端中无法打开外链,与CP方沟通发现,他们打开URL使用的方式是`flash.net.navigateToURL`,而从Flash32版本开始,增加了一个安全性控制字段`EnableInsecureActiveXNavigateToURL`,根据官方[Release Note](https://helpx.adobe.com/flash-player/release-note/fp_32_air_32_release_notes.html)描述,该字段是用于控制打开的外链URL跨域行为的,此次的问题正是由于这个字段引起的。
## 问题调查
代码层的具体表现为,游戏中点击外链按钮之后,IE控件无法触发`NewWindow3`事件。根据官方论坛的[讨论](https://community.adobe.com/t5/flash-player/issue-with-navigatetourl/td-p/10641531?page=1),可以在系统的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`函数执行真正的逻辑。
```c++
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`语句块即可
```c++
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::GetHostAppInternalName`和`PlatformPlayer::RunningInBrowser`这两个函数的实现。
```c++
_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;
}
```
```c++
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浏览器,从而实现白名单效果。
Loading…
Cancel
Save