怎样写一个与Win8 IE11兼容的标准BHO?
怎样写一个与Win8 IE11兼容的标准BHO?
环境:Windows8.1 x86 IE11(其它环境未讨论)
作者:magictong
日期:2014/02/02
概述
微软在2013年6月份推出了Windows8.1并且带上了IE11,在一个不起眼的地方,偷偷的勾上了“启动增强保护模式”功能(最新消息,11月份的时候微软发了个更新又取消了这个勾,但是说不定哪天又发个更新给勾上)。然后你会发现一大批的IE插件沦陷了(迅雷,QQ下载助手等等,都无法生效了)。
等等!我大微软不是号称兼容做得最好的吗……难道一棍子把所有的插件全部打死了?!
现象
我们看看自己的BHO插件的情况,找一个在老的浏览器下面工作的很好的BHO插件,然后在Windows8.1IE11下面注册使用,慢着,BHO是啥?怎么写一个BHO,这……参考[1]和[2]吧,只能帮助你到这里了。
注册之后打开IE11,发现IE11的下面有这样的提示。
某某插件与增强安全功能不兼容。打开这个详细信息看看,发现是告诉你怎么关闭这个增强安全功能。
查看管理加载项里面的状态,也是“不兼容”。
这下用户心里开始纠结了,从这个描述上看你的增强保护模式是加强安全保护的,如果关闭了是不是我就不安全了?如果不关闭,以前的一些好用的插件都无效了,这要用户怎么选?!当然更多的用户是不知道发生了神马,嗯!而对于我们这些软件厂商来说,这是更大的负担,看似一个小小的改动,又得忙活几天了,对于软件开发者来说,当然希望用户不关闭增强保护功能(既不能帮助用户关闭,也不能提示用户关闭,这毕竟是一种不负责任的行为),那么要想我们的插件在用户的机器上生效,看来得做点什么……
解决方案
解铃还须系铃人,当然得去问问微软在这个增强保护模式上面做了什么,参考[3],前面主要讲IE11下面对Web访问的影响等等,可以快速浏览下。和插件相关的在后半部分,需要仔细研究下。
这里面提到,如果你的插件(不管是BHO,Axtivex还是其它插件)想兼容EPM(增强保护模式),需要在注册时标明本插件是增强保护模式兼容的,具体来说就是要把插件注册到一个特殊的Com组件类型库中,这个特殊的组件类型库就是CATID_AppContainerCompatible,OK,注册组件类型库是不难的,我们试一下,在BHO的注册代码里面添加下面的代码。
DEFINE_GUID(CATID_AppContainerCompatible, 0x59fb2056, 0xd625,0x48d0,
0xa9, 0x44, 0x1a, 0x85, 0xb5, 0xab, 0x26, 0x40);
//DllRegisterServer - Adds entries to the system registry
STDAPIDllRegisterServer(void)
{
HRESULThr =_AtlModule.DllRegisterServer();
ICatRegister*pcr =NULL;
HRESULThrRegCat =CoCreateInstance(CLSID_StdComponentCategoriesMgr,NULL,CLSCTX_INPROC_SERVER,IID_ICatRegister,
(void**)&pcr);
if(SUCCEEDED(hrRegCat)&&pcr)
{
CATIDrgcatid[1];
rgcatid[0] =CATID_AppContainerCompatible;
pcr->RegisterClassImplCategories(CLSID_AdPromotionImp,
1,rgcatid);
}
if(pcr)
pcr->Release();
returnhr;
}
看起来很简单,但是行不行呢?试一下(注意:要重新注册BHO,直接只替换文件是不行的!上面这种是动态注册的方法,还有一种静态注册的方法(等下说),这种动态注册的方法要注意的是,如果是用向导生成的BHO代码,那么DllRegisterServer里面会有一段(_AtlModule.DllRegisterServer();)代码,你的组件注册代码要放在它后面,否则注册会被覆盖掉而不生效,静态注册的方法没有这种问题)。
是不是看到了熟悉“启用”不“不启用”提示?!果断“启用”。现在BHO是不是加载了,并且大部分功能都正常了呢?
有人说,我想那个启动不启用提示也没有是否可以呢?答案是肯定的,但是过程却是曲折的,如果你的BHO永远只想当一个良民(标准BHO),还真的很困难,你得修改HKCU\Software\Microsoft\InternetExplorer\Approved
Extensions\{05F5F404-7C24-4B39-B5CC-340CEDEB9C0D}这个注册表下面的二进制值,这个里面存储的是微软IE下的某个插件获取到用户信任(也就是用户主动点了启用)的数据,而这个值微软是加密的,难以轻易破解,否则微软架构的这套安全机制轻易就完蛋了。那只能走其它的路子,做一个不标准的BHO,主要体现在不注册COM,也不在标准BHO的注册表位置注册(IE通过枚举这个位置来加载BHO),然后我们通过其它方式注入(消息钩子,驱动,远程线程……),这不是本文重点,可以参考[4]。
之前提到,还有一种静态注册COM组件类型库的方法,也很简单,只需要在RGS文件里面添加如下的内容就可以了。
其实原理都是类似的(不过要注意的是静态添加的方法无法区分系统版本,而在低于win8的系统环境下面上面的rgs代码是会注册失败的,除非你确信你的BHO只会在win8上存在,否则慎用)。。
更多问题
事情完全搞定了吗?No,No,No!万里长征才走了第一步,我想有些人可能已经注意到了我在上面提到现在大部分功能已经正常了,也就是说还有很多功能是不正常的,这就牵扯出了IE11增强保护模式下的特殊权限问题,你会发现虽然IE加载了你的BHO,但是很多API都调用失败了,很多IPC通信也无法完成,原因不外乎,读\写文件,读\写注册表失败,打开某内核对象失败,而且都是权限问题,这又是另外一个自IE下保护模式出现以来就有的兼容性问题了,但是因为这个和本文关系不是特别大,而且网上介绍保护模式的文件汗牛充栋[5],因此就不详细介绍了。这里仅仅点到即止,说明一下IE11下增强保护下出现的新问题,在增强保护模式下IE运行在一种特殊的完整性权限下,叫AppContainer,在[3]里面有提到,在这种情况下BHO或者插件需要访问的资源的用户组权限需要在一个特殊的组里面,这个组叫ALL_APPLICATION_PACKAGES,这个组的SID是“S-1-15-2-1”(当然Low完整性权限也是必须要的),你给BHO所有要访问的资源,内核对象通过权限控制API,添加上这个用户组,基本上BHO就都可以访问了,另外就是建议你的BHO不要去直接操作文件注册表这些敏感资源,一来是一般没权限不被系统允许,二来是风险很高,建议你通过IPC告知高权限进程去进行这些敏感操作。
参考资料
[1]如何使用BHO定制你的Internet Explorer浏览器http://www.vckbase.com/index.php/wv/1145
[2]用VisualStudio2005生成浏览器帮助对象http://www.cnblogs.com/jcss2008/archive/2009/06/06/1497518.html
[3] UnderstandingEnhanced Protected Modehttp://blogs.msdn.com/b/ieinternals/archive/2012/03/23/understanding-ie10-enhanced-protected-mode-network-security-addons-cookies-metro-desktop.aspx
[4] BHO强制注入IE技术方案简述http://km.oa.com/group/QQPCMGR_tech/articles/show/165005
[5]面对IE保护模式的开发者生存之道http://tech.it168.com/msoft/2007-12-04/200712041740771.shtml
怎样写一个与Win8 IE11兼容的标准BHO?的更多相关文章
- 怎样写一个与Windows10 IE11兼容的标准BHO?
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...
- 写一个trim函数,兼容IE firefox chrome(正则)
因为在获取输入框内容时,常常trim下多余的空格.而IE部分低端浏览器里的JavaScript版本不内置trim()这个清楚空格函数,而流行的浏览器里都兼容了,比如chrome,FF等.为了不让IE下 ...
- 写一个ajax程序就是如此简单
写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发 ...
- 操刀 requirejs,自己动手写一个
前沿 写在文章的最前面 这篇文章讲的是,我怎么去写一个 requirejs . 去 github 上fork一下,顺便star~ requirejs,众所周知,是一个非常出名的js模块化工具,可以让你 ...
- 写一个兼容性比较好的拖拽DEMO
写一个兼容性比较好的拖拽DEMO 查看Demo 思路 div盒子 鼠标按下事件onmousedown 鼠标移动事件onmousemove,获得鼠标的坐标,将div移动至鼠标的当前坐标 鼠标抬起事件om ...
- 『练手』手写一个独立Json算法 JsonHelper
背景: > 一直使用 Newtonsoft.Json.dll 也算挺稳定的. > 但这个框架也挺闹心的: > 1.影响编译失败:https://www.cnblogs.com/zih ...
- 用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载
用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载,将一个完整的项目进行展示,主要有以下几个部分: 1.servlet部分 Export 2.工具类:TxtFileU ...
- 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise
本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...
- 通过用jQuery写一个页面,我学到了什么
概述 前几天面试,hr发来一个测试文件,让我做做看.我一看,其实就是根据PSD需求写一个页面,再加上一些互动效果即可. 刚好我之前学了切图,jquery等知识还没练手过,于是高兴的答应了. 最后花了3 ...
随机推荐
- 集群技术(三)MySQL集群深度解析
什么是MySQL集群 MySQL集群是一个无共享的(shared-nothing).分布式节点架构的存储方案,其目的是提供容错性和高性能. 数据更新使用读已提交隔离级别(read-committedi ...
- 最大熵模型The Maximum Entropy
http://blog.csdn.net/pipisorry/article/details/52789149 最大熵模型相关的基础知识 [概率论:基本概念CDF.PDF] [信息论:熵与互信息] [ ...
- Android通过WebService实现图片的上传和下载(一)
这篇文章将讲解Android如果通过访问WebService接口实现图片的上传和下载,当然这不但需要大家懂得Android还要懂得WebService技术,安卓属于客户端,而webservice则属于 ...
- Apache shiro集群实现 (一) shiro入门介绍
近期在ITOO项目中研究使用Apache shiro集群中要解决的两个问题,一个是Session的共享问题,一个是授权信息的cache共享问题,官网上给的例子是Ehcache的实现,在配置说明上不算很 ...
- 打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(二解决思路3)
续前一篇:打开Voice Over时,CATextLayer的string对象兼容NSString和NSAttributedString导致的Crash(二解决思路2)ok,到这里已经能够锁定范围了, ...
- 详解EBS接口开发之库存事务处理采购接收和退货
(一)接收&退货常用标准表简介 1.1 常用标准表 如下表中列出了与采购接收&退货导入相关的表和说明: 表名 说明 其他信息 RCV_TRANSACTIONS 采购接收事务表 事务 ...
- BeanUtils Exception 之 FastHashMap
这里仅仅是为了记录一件十分奇怪的事情,在使用BeanUtils的过程中,所有的依赖包都添加了, common logging common collections ··· 在为boolean 这种基本 ...
- 安卓6.0新特性在Fragment申请运行时权限
今天在Fragment申请权限时代码如下: public void getContacts(){ int flag = ActivityCompat.checkSelfPermission(getAc ...
- 2.7、Android Studio使用翻译编辑器本地化UI
如果你的应用支持多语言,你需要合理的管理你的翻译的string资源.Android Studio 提供了翻译编辑器来使查看和管理翻译的资源更加容易. 关于翻译编辑器 翻译后的资源在你的项目里保存在不同 ...
- 1081. Rational Sum (20) -最大公约数
题目如下: Given N rational numbers in the form "numerator/denominator", you are supposed to ca ...