解决插件在IE增强保护模式下无法运行的问题

    这篇博客本来去年底就应该写的了,但是,可能因为懒,或者就是觉得内容不太重要,所以,一直没有写。

IE的增强保护模式(Enhanced Protected Mode

    EPM是在IE10中出现的,是以前的保护模式的加强版,提供“深度的保护”,以防止攻击者安装恶意软件,或者修改系统设置。保护模式基于最小权限的原则——通过限制Internet Explorer所拥有的能力,使得入侵代码所获得的能力也相应地受到了限制。当然,这也会让大部分正常的插件不能使用。

解决插件在IE增强保护模式下无法运行的问题_第1张图片


    EPMIE10中是默认关闭的,而在IE11中则默认开启(后来又变回关闭了)。在程序中可以通过IEIsProtectedModeProcess(BOOL *pVal)来判断IE是否启用了EMP

    EPM开启后,会将IE运行在APPContainer中,以限制其能力。所以在IE11中,插件会因为权限原因,无法正常使用。

    解决办法就是将插件添加在APPContainer中。在插件注册的方法DllRegisterServer中添加下面代码即可:

ICatRegister* pcr = NULL ;
class __declspec(uuid("{59FB2056-D625-48D0-A944-1A85B5AB2640}")) AppContainerCompatible;
hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
CATID rgcatid[1] ;
rgcatid[0] = __uuidof(AppContainerCompatible);
hr = pcr->RegisterClassImplCategories(CLSID_AtiveX, 1, rgcatid);//CLSID_AtiveX为插件的CLSID

    其作用是:在注册表中,添加

HKEY_CLASSES_ROOT\CLSID\(插件的CLSID)\Implemented Categories\{59FB2056-D625-48D0-A944-1A85B5AB2640},表示将这个控件添加到AppContainer

    完成上述操作后,发现插件的部分功能恢复正常了,不过使用RPC与系统服务通信的模块依旧出问题。接下来,需要创建COM组件(EXE类型,假设为RPCBroker.exe)来充当RPC通信的桥梁,也就是将调用RPC的方法,移植到RPCBroker.exe中执行(如NdrClientCall2方法)。这里主要比较纠结的地方,就是参数的传递,因为有些参数类型,ATL中并不支持。

    创建COM组件 http://www.cnblogs.com/xiaokang088/archive/2011/05/16/2047376.html 文中是创建的COMdll类型的,我们应该选择可执行文件(EXE)类型。

    COM组件需要注册才能使用,因此要在插件的DllRegisterServer中注册COM组件:RpcBroker.exe /RegServer。另外卸载COM组件:RPCBroker.exe /UnRegServer

解决插件在IE增强保护模式下无法运行的问题_第2张图片

    使用RPCBroker.exe后,RPC通信也正常了。不过,在IE中启用控件的时候,会出现下面的警告。

解决插件在IE增强保护模式下无法运行的问题_第3张图片

    这是由于RPCBroker.exe打破了APPContainer的限制,提高了插件的权限。所以我们需要在注册表项(HKLM\Software\Microsoft\Internet Explorer\Low Rights\ElevationPolicy)中配置RPCBroker.exePolicy(DWORD),AppName(REG_SZ),AppPath(REG_SZ)等信息。其中Policy有四个数值,我们需要将其设置为3

解决插件在IE增强保护模式下无法运行的问题_第4张图片

    关于EMP的详细介绍: http://msdn.microsoft.com/en-us/library/bb250462(v=vs.85).aspx


注册部分代码:

static void ShellProcess(LPSTR pszFile, LPSTR pszParameters)
{
	SHELLEXECUTEINFO ShExecInfo = {0};
	ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
	ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
	ShExecInfo.hwnd = NULL;
	ShExecInfo.lpVerb = NULL;
	ShExecInfo.lpFile = pszFile;
	ShExecInfo.lpParameters = pszParameters;
	ShExecInfo.lpDirectory = NULL;
	ShExecInfo.nShow = SW_HIDE;
	ShExecInfo.hInstApp = NULL;
	ShellExecuteEx(&ShExecInfo);

	WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
}
void RegisterBroker()
{
	HKEY hKey;
	HKEY hSubKey;
	
	char exeDir[_MAX_PATH];
	char exeFullPath[_MAX_PATH];

	memset(exeFullPath,0,sizeof(exeFullPath));

	GetModuleFileName((HMODULE)_hInstance, exeDir, _MAX_PATH);	
	char *p = strrchr(exeDir, '\\');
	p[1] = 0;

	strcat_s(exeFullPath,sizeof(exeFullPath), exeDir);
	strcat_s(exeFullPath,sizeof(exeFullPath), g_szQQCertBrokerName);
	
	ShellProcess(exeFullPath, "/Regserver");

	//注册IE低权限
	HRESULT hr;
	hr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("SOFTWARE\\Microsoft\\Internet Explorer\\Low Rights\\ElevationPolicy"),0,KEY_ALL_ACCESS,&hKey);
	if(ERROR_SUCCESS == hr){
		if(ERROR_SUCCESS == RegCreateKeyEx(hKey,"{COM组件的CLSID}",0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hSubKey,NULL)){
			RegSetValueEx(hSubKey,_T("AppName"),0,REG_SZ,(BYTE *)g_szQQCertBrokerName,sizeof(g_szQQCertBrokerName));

			RegSetValueEx(hSubKey,_T("AppPath"),0,REG_SZ,(BYTE *)exeDir,sizeof(exeDir));

			DWORD dwValue = 0x3;
			RegSetValueEx(hSubKey,_T("Policy"),0,REG_DWORD,(BYTE *)&dwValue,sizeof(DWORD));
			RegCloseKey(hSubKey);
		}
		RegCloseKey(hKey);
	}
	
}



补充:浏览器插件结合COM组件的使用方式,可以突破较多的限制。比如在Win8系统中,插件加载驱动程序出现Access Denied的问题~










你可能感兴趣的:(web插件)