昨天zhengwei同学说他机器上的一个BHO不能正常加载,我把BHO的代码拿过来,在我的两台机器上都验证了一下,一台是Win7+IE8的环境,一台是XP+IE7的环境,都能正常加载。zhengwei的机器是IE6+XP的环境,不能正常加载,升级到IE7后,还是不能加载。排除了是操作系统,以及IE版本的原因。会不会是IE安全设置的原因呢?没有听说过IE安全设置会影响到BHO加载的,还是试了试,同时把他机器上的360也给关了。问题还是没有解决。怎么办?只有上调试器了WinDbg了。

使用WinDbg如何来找查找问题的原因。分析了一下,在我自己的机器上和他的机器上同时开WinDbg,比较能加载和不能加载两个环境下,IE加载BHO的代码执行的路径,就能够找到问题的原因。

因此,第一个问题是,IE是如何加载BHO的?映像中好像没有哪里有文档说这个问题。但是BHO是一个DLL,DLL加载有两种方式,静态加载和动态加载。BHO肯定不是静态加载(为什么?)。动态加载肯定要调用LoadLibrary或者LoadLibraryEx,每个函数又有Ansi和Unicode的两个版本,因为实际上是LoadLibraryA、LoadLibraryW、LoadLibraryExA、LoadLibraryExW四个函数。在这四个函数上设置断点,肯定能够找到断到BHO被加载(当然也可能是别的非BHO的DLL被动态加载)。其实根据经验,只要在LoadLibraryExW设置断点就可以了。好了,可以在WinDbg中开始了。

打开WinDbg,从菜单项File中选择Open Executable…,找到iexplore.exe,打开。这时调试器会断下来,使用命令 bp kernel32!LoadLibraryExW,继续执行。调试器断下后,使用kv命令看调用栈,连着看了几个,都是加载的别的DLL,不是BHO。这样看下去肯定会看到BHO被加载,算了,换个别的思路。

知道的BHO模块的名字叫做test.dll,直接设置模块加载断点就可以了。重新启动WinDbg,加载IE,设置断点 sxe ld:test.dll,继续执行,断下来了,使用kv n 0x100(n 0x100参数是指定调用栈的层数)看调用栈,调用栈如图一。

图一

第06行印证了上面的结论,确实是使用了LoadLibraryExW加载的,至于为什么是KERNELBASE而不是kernel32,是因为这是Win7上的截图,Win7上就是KERNELBASE。另外看行,IE加载BHO使用了一个重要的函数IEFRAME中CShellBrowser2类中的_LoadBrowserHelperObjects函数。好了,可以在出问题的机器上工作了。

在出问题的机器上,在IEFRAME上设置一个断点,不过,WinDbg加载IE启动时,直接bp IEFRAME!CShellBrowser2::_LoadBrowserHelperObjects,你会得到一个如下的错误,0:000> bp IEFRAME!CShellBrowser2::_LoadBrowserHelperObjects

Bp expression 'IEFRAME!CShellBrowser2::_LoadBrowserHelperObjects' could not be resolved, adding deferred bp

为什么?因为这个时候IEFrame还没有加载,WinDbg不知道你设置的是一个什么断点。因此要先通过 sxe ld:ieframe.dll设置dll加载的断点,等到ieframe加载进去后,再在_LoadBrowserHelperObjects函数上设置断点。

断下来后,再在两台机器上都单步执行,比较两台机器上执行的不一样的地方。根据经验,重点是看一下里面调用函数后的返回值。发现_LoadBrowserHelperObjects里会调用几次读注册表,但是两台机器上的返回值是一样的。接着往下看,看到调用了一个函数IEFRAME!IERegGetBoolWithPoliciesW,这个函数的返回值(eax的值)两台机器不一样,正常加载的机器上返回1,不能加载的函数上返回0。问题的范围进一步缩小。

再重新启动,走到IEFRAME!IERegGetBoolWithPoliciesW函数里面,这个函数里也显示调用了几次读注册表的函数,打开注册表看了一下,两台机器上都没有要读的表项。再往下看,调用了一个函数IEFRAME!SHRegGetBoolValueFromHKCUHKLM,从函数的名字看,是要从Current User和Local Machine两个根键下去找要读的键,看看这个函数的参数,参数如下:

很清楚,是要去在Local Machine和Current User下去找Software\Microsoft\Internet Explorer\Main的Enable Browser Extensions的值,看这个注册表项的名字,估计找到原因了。先到正常的机器上去看,Local Machine下没有这个键值,在看Current User,有,值是yes,再看出问题的机器上,值是no,改成yes,问题解决了。

小结:之前不知道有Enable Browser Extensions这样一个值可以影响注册表的加载,知道就用这么折腾了,因此把它记录下来,免得后面的同学继续这样折腾,不过Windbg确实是个好东西,Windows上的很多疑难问题,都能用它来解决,可以好好学下。

WinDbg解决BHO不加载的更多相关文章

  1. 解决crontab不加载环境变量问题

    公司需要做异构库数据同步,由于之前实际使用过,且字段类型也兼容,满足业务场景,使用了阿里开源数据同步工具:datax,服务器上crontab定时脚本执行. 由于crontab只加载/ect/envir ...

  2. nuxt 头部引入js文件 第一次进入页面不加载js文件的解决方法

    head () { return { title: '', meta: [ { hid: 'description', name: 'description', content: '' } ], sc ...

  3. EasyUI 1.4.4 DataGrid(大数据量) bufferview滚动时不加载下一页数据解决方案

    在使用Easyui DataGrid 过程中,发现若单页数据量超过300,IE浏览器加载速度很慢.也通过网上找寻了很多解决方案,最典型的就是去掉datagrid的自动列宽以及自动行高判断. 1.解决自 ...

  4. Android开源代码解读のOnScrollListener实现ListView滚屏时不加载数据

    使用ListView过程中,如果滚动加载数据的操作比较费时,很容易在滚屏时出现屏幕卡住的现象,一个解决的办法就是不要在滚动时加载数据,而是等到滚动停止后再进行数据的加载.这同样要实现OnScrollL ...

  5. Swift - 表格图片加载优化(拖动表格时不加载,停止时只加载当前页图片)

    列表的单元格中包含有图片在开发中很常见.通常我们可以直接在tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIn ...

  6. 在360、UC等浏览器,img不加载原因

    问题:图片在360浏览器不被加载,在UC浏览器强制不显示. 前言不多说,直接上图. 360浏览器显示情况: UC浏览器显示情况: 由以上两张截图可以看到,在360浏览器,banner图片处根本没有加载 ...

  7. ArcGIS Runtime For Android 100.3天地图不加载问题

    ArcGIS Runtime 100.3 不加载天地图问题 参考这篇帖子:https://community.esri.com/thread/220496-1003-webtiledlayer-can ...

  8. 火狐浏览器返回不加载JS

    火狐浏览器 go(-1),返回后不加载JS,谷歌会加载. 总结: Firefox和Safari在back时不会触发load, ready事件! 解决方法: $(window).unload(funct ...

  9. 使用jquery的load方法设计动态加载,并解决被加载页面JavaScript失效问题

    一.问题分析 对于后台系统,相比大家都有所印象,知道其中的布局结构,如图: 在这种布局中我们需要将header,sidebar,footer分开,而且对于中间部分的content内容需要动态变化,即根 ...

随机推荐

  1. springBoot和MyBatis整合中出现SpringBoot无法启动时处理方式

    在springBoot和Myatis   整合中出现springBoot无法启动   并且报以下错误 Description: Field userMapper in cn.lijun.control ...

  2. 吉首大学校赛 I 滑稽树上滑稽果 (Lucas + 莫队)

    链接:https://ac.nowcoder.com/acm/contest/925/I来源:牛客网 题目描述 n个不同的滑稽果中,每个滑稽果可取可不取,从所有方案数中选取一种,求选取的方案中滑稽果个 ...

  3. AcWing 161. 电话列表 (trie)打卡

    给出一个电话列表,如果列表中存在其中一个号码是另一个号码的前缀这一情况,那么就称这个电话列表是不兼容的. 假设电话列表如下: ·Emergency 911·Alice 97 625 999·Bob 9 ...

  4. [NOIP模拟13]题解

    A.矩阵游戏 其实挺水的? 考场上根本没有管出题人的疯狂暗示(诶这出题人有毛病吧这么简单的东西写一大堆柿子),而且推公式能力近乎没有,所以死掉了. 很显然乘法有交换率结合率所以操作顺序对最终结果没什么 ...

  5. Block 使用总结

    - (void)testBlockWeakObj1 { UILabel *tl = [[UILabelalloc]init];//本地局部变量 __weak UILabel *weakTL = tl; ...

  6. css 导航样式

    html  结构 <div class="nav-menu float-r"> <ul class="menu-item"> <l ...

  7. git回退单个文件

    git原理 Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD. gi ...

  8. Linux权限简析

  9. Lucene字段

    字段是最低单元或索引过程的起点.它代表其中一个键被用于识别要被索引的值的键值对关系.用于表示一个文件的内容的字段中将具有键为“内容”和值,可以包含文本或文档的数字内容的部分或全部. Lucene可以索 ...

  10. nfs下的exportfs命令和nfs客户端重新挂载

    工作中,如果使用了nfs服务器,会遇到修改nfs服务器配置的情况,如果想重新让客户端加载上修改后的配置,但是又不能重启rpcbind服务,我们需要使用export命令了 exportfs命令 常用选项 ...