怎样写一个与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?的更多相关文章

  1. 怎样写一个与Windows10 IE11兼容的标准BHO?

    p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; f ...

  2. 写一个trim函数,兼容IE firefox chrome(正则)

    因为在获取输入框内容时,常常trim下多余的空格.而IE部分低端浏览器里的JavaScript版本不内置trim()这个清楚空格函数,而流行的浏览器里都兼容了,比如chrome,FF等.为了不让IE下 ...

  3. 写一个ajax程序就是如此简单

    写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发 ...

  4. 操刀 requirejs,自己动手写一个

    前沿 写在文章的最前面 这篇文章讲的是,我怎么去写一个 requirejs . 去 github 上fork一下,顺便star~ requirejs,众所周知,是一个非常出名的js模块化工具,可以让你 ...

  5. 写一个兼容性比较好的拖拽DEMO

    写一个兼容性比较好的拖拽DEMO 查看Demo 思路 div盒子 鼠标按下事件onmousedown 鼠标移动事件onmousemove,获得鼠标的坐标,将div移动至鼠标的当前坐标 鼠标抬起事件om ...

  6. 『练手』手写一个独立Json算法 JsonHelper

    背景: > 一直使用 Newtonsoft.Json.dll 也算挺稳定的. > 但这个框架也挺闹心的: > 1.影响编译失败:https://www.cnblogs.com/zih ...

  7. 用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载

    用java写一个servlet,可以将放在tomcat项目根目录下的文件进行下载,将一个完整的项目进行展示,主要有以下几个部分: 1.servlet部分   Export 2.工具类:TxtFileU ...

  8. 一起学习造轮子(一):从零开始写一个符合Promises/A+规范的promise

    本文是一起学习造轮子系列的第一篇,本篇我们将从零开始写一个符合Promises/A+规范的promise,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Pr ...

  9. 通过用jQuery写一个页面,我学到了什么

    概述 前几天面试,hr发来一个测试文件,让我做做看.我一看,其实就是根据PSD需求写一个页面,再加上一些互动效果即可. 刚好我之前学了切图,jquery等知识还没练手过,于是高兴的答应了. 最后花了3 ...

随机推荐

  1. 使用java操作HDFS

    新建Java Project; 1,右击项目,属性,Java Build Path,Libraries,Add External JARs(haddopp根目录下的所以jar): 2,做一下项目关联, ...

  2. ROS(indigo) 语音工具 科大讯飞 百度 pocketsphinx julius rospeex 16.11.22更新 ROS中文语音

    ROS语音工具汇总,目前先给出链接,只用过一些简单的命令. 中文语音: 参考链接:使用科大讯飞库 1 http://www.ncnynl.com/archives/201611/1069.html 2 ...

  3. 实现memmove函数

    分析:memmove函数是<string.h>的标准函数,其作用是把从source开始的num个字符拷贝到destination.最简单的方法是直接复制,但是由于它们可能存在内存的重叠区, ...

  4. 非负矩阵分解NMF

    http://blog.csdn.net/pipisorry/article/details/52098864 非负矩阵分解(NMF,Non-negative matrix factorization ...

  5. Cocos2d-x 添加iOS7默认分享/AirDrop

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=530 下午添加分享的时候,看着这 ...

  6. Android中JNI编程详解

    前几天在参加腾讯模拟考的时候,腾讯出了一道关于JNI的题,具体如下: JNI本身是一个非常复杂的知识,但是其实对于腾讯的这道题而言,如果你懂JNI,那么你可能会觉得这道题非常简单,就相当于C语言中的h ...

  7. 部署Openfire3.9.3源码部署

    1,下载Openfire3.9.3源码代码:http://www.igniterealtime.org/downloads/index.jsp 2,具体的配置请参考http://blog.csdn.n ...

  8. 北大青鸟Asp.net之颗粒归仓

    自从小编走进编程的世界以来,学习的编程知识都是和C/S这个小伙伴握手,直到做完牛腩老师的新闻发布系统,才开始了小编的B/S学习生涯,和B/S初次谋面,小宇宙瞬间爆发了,看着自己的第一个B/S系统,牛腩 ...

  9. [Python]django使用多进程连接msyql错误

    问题 mysql 查询出现错误 error: (2014, "Commands out of sync; you can't run this command now") 查询 m ...

  10. 今天我成为了CSDN博客专家

    刚刚收到了来自CSDN的回复,正如我的期待: 我随即回到自己的博客页面,欣喜地看到"专家"勋章被点亮了.Oh, yeah~ Q:我为什么要申请这个"专家"称号? ...