dll メソッドの呼び出しをインターセプトする方法は?
- そのために利用できるテクニックは何ですか?
- C/C++だけでできますか?
- 実行中のすべてのプロセスから特定の dll へのメソッド呼び出しをインターセプトする方法は?
- 特定のプロセスから特定の dll へのメソッド呼び出しをインターセプトする方法は?
これを行うために私が考えることができる2つの標準的な方法があります
DLL インポート テーブル フック。
このためには、DLL の PE ヘッダーを解析し、インポート テーブルを見つけて、そこに既に書き込まれているものの代わりに独自の関数のアドレスを書き込む必要があります。元の関数のアドレスを保存して、後で呼び出すことができます。このウィキペディアの記事の外部リンクの参照は、これを行うために必要なすべての情報を提供するはずです。
コードの直接変更。フックする関数の実際のコードを見つけて、その最初のオペコードを変更して独自のコードにジャンプします。最終的に実行されるように、そこにあったオペコードを保存する必要があります。これは、思ったよりも簡単です。なぜなら、Microsoft 自身がDetours ライブラリの形で既に実装していたからです。
これは本当にきちんとしたことです。ほんの数行のコードで、たとえば Outlook.exe からの GetSystemMetrics() へのすべての呼び出しを置き換えて、発生する不思議を見ることができます。
一方の方法の利点は、もう一方の方法の欠点です。最初の方法では、必要な DLL にサージカル フックを正確に追加できます。他のすべての DLL はフックされていません。2 番目の方法では、関数を実行するすべての呼び出しをインターセプトする最もグローバルな種類のフックを使用できます。
すべての DLL 関数を事前に知っている場合、1 つの手法は、すべての関数呼び出しを実際の DLL に転送する独自のラッパー DLL を作成することです。この DLL は、C/C++ で作成する必要はありません。元の DLL の関数呼び出し規約に合わせるだけです。
C/C++ API を使用したライブラリについては、Microsoft Detoursを参照してください。ウイルス スキャナー/マルウェア ディテクターをトリガーせずに、他のすべてのプログラムにそれを挿入するのは、少し難しいことです。しかし、あなた自身のプロセスは公正なゲームです。
Linux では、これは LD_PRELOAD 環境変数で実行できます。オーバーライドしたいシンボルを含む共有ライブラリを指すようにこの変数を設定してから、アプリを起動します。