-1

SetWindowsHookExを使用して WH_GETMESSAGE、WH_CALLWNDPROC、および WH_CALLWNDPROCRET をフックするグローバル フックを作成しました。
フック dll は、フックされたプロセスに新しいスレッドを作成します。このスレッドは、とりわけ、プロセスのオーディオ状態をチェックし、IAudioSessionManager2::GetSessionEnumerator()を呼び出します。

ここで興味深いのは、フック ホストからUnhookWindowsHookEx()を呼び出していて、dll のワーカー スレッドがIAudioSessionManager2::GetSessionEnumerator()への呼び出しを実行している間に呼び出していたことです。その呼び出しは、 DLL_PROCESS_DETACH を持つ DllMainが呼び出された同じスレッドの呼び出しスタックにありました。その理由は、GetSessionEnumerator()がどこかでGetMessage()関数を呼び出し、後者が再入可能であるためだと思います。残念ながら正確には覚えていませんが、コール スタックで確認したと思います。

しかし、私が疑問に思っている重要なことや不明な点が複数あります。だからここに私の関連する質問があります:

  1. DLL_PROCESS_DETACH を指定した DllMain は、現在アンロードされている dll から関数を実行するスレッドであっても、いつでも呼び出すことができますか?
  2. DllMain DLL_PROCESS_DETACH が終了すると、関数のスタックはどうなりますか? 呼び出しスタックの上の関数のコードは最終的に実行されますか?
  3. これらの関数が終了しない場合はどうなりますか? dll はいつアンロードされますか?
  4. DllMain DLL_PROCESS_DETACH は、WH_GETMESSAGE、WH_CALLWNDPROC、および WH_CALLWNDPROCRET フックのコールバック中に同様に呼び出すことができますか? あまり頻繁ではありませんが、これらの関数は再入可能であるため、前の呼び出しがまだ同じスタックで実行されている間にこれらの関数への呼び出しを挿入できることを知っており、実験的に確認しましたが、次の呼び出しも行うかどうかはわかりませんDllMain も同様の方法で注入できます。
  5. 正確に DllMain をスレッドで呼び出すことができる場合 - 呼び出す必要がある特定の Windows API 関数がいくつかあり、それが DllMain DLL_PROCESS_DETACH 呼び出しにつながる可能性がありますか、または任意の命令で発生する可能性がありますか?
  6. DllMain DLL_PROCESS_DETACH 呼び出しをいつでも「注入」でき、コール スタックの上位の関数が実行されなくなった場合、コール スタックの上位の関数が中断された場所を正確に知るにはどうすればよいでしょうか? したがって、DllMain 内で関数によって割り当てられたハンドルまたはリソースをスタック上で解放することができます。
  7. DllMain DLL_PROCESS_DETACH への呼び出しを一時的に防止/延期する方法はありますか? 呼び出し/割り込みが同じスタックで発生した場合、ロックは明らかに役に立ちません。

残念ながら、フック解除中に DllMain でこのような状況が発生する前に、フック (およびフック解除) コードを複数のコンピューターで数か月実行していたため、これらの質問を実験的に解決することはおそらくできません。なんらかの理由で、4つの異なるプログラムで同時に発生しました...


また、十分な評判を持っている人が「再入可能」と「再入可能」のタグをマージしてくれませんか?

4

1 に答える 1

0

Hansのおかげで、ポイント (4) に関して、DllMain DLL_PROCESS_DETACH はフック プロシージャで再入可能ではないことがわかりました。

フックが作成したスレッドに関して、私のログ ファイルは現在、DllMain DLL_PROCESS_DETACH がこのスレッドのスタックに注入された場合、そのスレッドは DllMain の終了後に実際に終了し、完了まで実行されないことを示しています。それはポイント(2)と(3)に答えるはずです。質問自体は暗黙のうちにポイント (1) に答えます。

しかし、フックが作成したそのスレッドの問題を解決するために、DllMain DLL_PROCESS_DETACH を呼び出すことで防止できると思います

GetModuleHandleEx
(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
    (LPCTSTR)DllMain,
    &hModule_thread
)

およびスレッド終了呼び出しの前

FreeLibraryAndExitThread(hModule_thread, 0)

したがって、GetModuleHandleExを使用すると、ポイント (7) に答える必要があり、これにより、他のすべてのポイントが無関係になります。もちろん、フックされたプロセスでスレッドの終了をトリガーするには、IPCを使用する必要があります。

残りの興味深い質問はポイント (5) ですが、それは単なる好奇心からです:
「DllMain DLL_PROCESS_DETACH をスレッドで正確に呼び出すことができる場合、呼び出す必要がある特定の Windows API 関数がいくつかあり、それが次につながる可能性があります。 DllMain DLL_PROCESS_DETACH 呼び出し、または任意の命令で発生する可能性がありますか?"

于 2013-11-29T06:33:05.967 に答える