2

WinInet をフックして IE からの一部の HTTP 要求を内部サーバーにリダイレクトすることで変更する Internet Explorer 用の BHO を作成しました。

IE で最初の 3 つのタブを開くと、タブごとに新しい iexplore.exe プロセスが作成され、それぞれが BHO をロードするため、正常に動作します。

4 つ以上のタブがある場合に問題が発生します。新しい iexplore.exe プロセスを作成する代わりに、既存のプロセスが別のスレッドで再利用されます。同じプロセスを複数回 (スレッドごとに 1 つ) フックすることも、1 回だけフックすることもできます。どちらの場合も、タブを閉じるとクラッシュが発生します。

例: タブ 1 (別の iepxlore.exe)、2 (別の iepxlore.exe)、3 (別の iepxlore.exe)、および 4 (タブ 1 で iexplore を共有) を開きます。タブ 1 を閉じます。タブ 4 を更新すると、NDTDLL.DLL 内で IE がクラッシュします。フックされた WinInet.ddl 内で何もしないと、クラッシュが発生します (古い関数を呼び出すだけです)。

WinInet を iexplore.exe プロセスごとに 1 回だけフックすると、すべてのタブで要求をインターセプトできなくなります。

どのように進めていくのがベストなのか悩んでいます。これまでに見つけたすべての例では、タブごとに 1 つの iexpolore.exe プロセスがあると想定しています。

WinInet フック コードは、コード プロジェクトの例に基づいています。フックする関数を減らしただけです。

古い W​​inInet 関数へのポインタ、または私が作成した関数へのポインタが無効になっているようです。

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 がこれらの関数の 1 つを初めて呼び出そうとすると、エラーが発生します。

修正するには、CWininetHook::~CWininetHook の破棄にクリーンアップ ロジックを実装する必要があります。コンストラクターが行うことを実行して、元のアドレスを返します。

于 2013-01-09T08:24:51.383 に答える