2012-11-06 24 views
2

我已经为Internet Explorer编写了一个BHO,它通过将WinInet重定向到内部服务器来修改某些来自IE的HTTP请求。如何用多线程正确挂接WinInet?

它工作正常,当我打开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函数或者我创建的函数的指针不再有效。

+0

你究竟是如何钩住WinInet的,更重要的是,为什么?你究竟想要修改WinInet的请求?请更具体一些。 –

+0

如果你没有在你的hook函数中做任何事情,它会崩溃吗?换句话说,崩溃是与钩住自己的行为有关还是与你在函数中做的事有关? –

+0

@matthew:我会试试。我的假设是因为使用钩子而发生崩溃,但我需要验证。 – Julien

回答

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的销毁中实现一个清理逻辑。只要做构造函数的工作,并返回原始地址。