如何使用多个线程正确挂钩WinInet?

时间:2012-11-06 04:53:30

标签: c++ internet-explorer-9 hook bho

我为Internet Explorer编写了一个BHO,它通过将WinInet重定向到内部服务器来挂钩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钩子代码基于Code Project example,我只是挂钩了更少的函数。

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

1 个答案:

答案 0 :(得分:0)

假设您从codeproject.com获取了大部分示例代码,则会出现严重的清理问题。

所以这就是:

  1. 当您打开标签页时,您的BHO会被加载。
  2. 初始化g_oHook对象(静态)。它的初始化在所有模块中设置挂钩(即在当前进程中的所有其他DLL中)。
  3. 通过设置挂钩,我的意思是修改IAT(导入地址表)中的条目。它们现在指向DLL中的函数(记住:当你从一个DLL调用另一个DLL时,你会通过IAT(
  4. 然后关闭标签。正在卸载您的DLL。
  5. ntdll.dll的IAT中的地址仍然指向您自己的DLL旧位置的内存空间,现在不存在。 IE第一次尝试调用其中一个函数时出现错误
  6. 为了修复,你需要在销毁CWininetHook :: ~CWininetHook时实现清理逻辑。只需执行构造函数的操作,并返回原始地址。