2

我为 Internet Explorer 编写了一个 BHO,它钩住 WinInet,通过将来自 IE 的一些 HTTP 请求重定向到内部服务器来修改它们。

当我在 IE 中打开前 3 个选项卡时它工作正常,因为为每个选项卡创建了一个新的 iexplore.exe 进程,每个选项卡都加载 BHO。

超过 4 个选项卡时会出现问题:不是创建新的 iexplore.exe 进程,而是在不同的线程中重新使用现有进程。我可以多次挂钩同一进程(每个线程 1 个),也可以只挂钩一次。在这两种情况下,关闭选项卡时都会发生崩溃。

示例:打开选项卡 1(单独的 iepxlore.exe)、2(单独的 iepxlore.exe)、3(单独的 iepxlore.exe)和 4(与选项卡 1 共享 iexplore)。关闭选项卡 1. 刷新选项卡 4,IE 在 NDTDLL.DLL 内崩溃。如果我在挂钩的 WinInet.ddl 内不执行任何操作(只需调用旧函数),就会发生崩溃

如果每个 iexplore.exe 进程只挂接一次 WinInet,我将无法拦截所有选项卡中的请求。

我想知道最好的方法是什么。到目前为止,我发现的所有示例都假设每个选项卡有 1 个 iexpolore.exe 进程。

WinInet 挂钩代码基于代码项目示例,我只是挂钩较少的功能。

看起来指向旧 WinInet 函数或我创建的函数的指针不再有效。

4

1 回答 1

0

假设您从 codeproject.com 获取了大部分示例代码,那么您有一个严重的清理问题。

所以这就是发生的事情:

  1. 当您打开选项卡时,您的 BHO 会被加载。
  2. g_oHook 对象(静态)被初始化。它的初始化在所有模块中设置了钩子(即在当前进程中的所有其他 DLL 中)。
  3. 通过设置挂钩,我的意思是修改 IAT(导入地址表)中的条目。它们现在指向您在 DLL 中的函数(请记住:当您从一个 DLL 调用另一个 DLL 时,您会通过 IAT(
  4. 然后关闭选项卡。正在卸载您的 DLL。
  5. ntdll.dll的IAT中的地址仍然指向你自己DLL的旧位置的内存空间,现在不存在了。在 IE 第一次尝试调用其中一个函数时,您会遇到错误

为了修复,您需要在 CWininetHook::~CWininetHook 的销毁中实现清理逻辑。只需执行构造函数的操作,并返回原始地址。

于 2013-01-09T08:24:51.383 回答