2008年01月24日

dsound.dllに乗っかる2

WindowsXP からは DLL の検索順序が変わり、それまで簡単だった DLL のすり替えが少し難しくなった。
レジストリを書き換えることで以前の検索順序にする事はできるものの、これを行ってしまうと他のソフトの動作にも支障をきたす可能性があるため別なアプローチで行う方が望ましい。

CreateRemoteThread を使うと任意のプロセスに対してスレッドを注入できる。これを使うと比較的簡単に API フックが実現できるのだが、DirectX は COM が中心になっているためにAPIの差し替えを後々行ってもその効果が現れるタイミングが非常に少ない(インターフェイスを再取得するシーンがくるまでは以前のポインタを使いまわすため)。
なので CreateRemoteThread を使って注入する場合には恐らく CreateProcess でプロセスを立ち上げる時にメインスレッドを一旦サスペンド状態で立ち上げた後、スレッドを注入して API の置換をしなければいけないような気がする(試してないけど!)。
また、CreateRemoteThread はどうも Win9x 系ではサポートされていないらしい。手元には Win9x 系のマシンもないし対応は必須要件ではないけども、すり替え用の dsound.dll は Win9x 系でも動くように作ったつもりなので、せっかくだから CreateRemoteThread は使わずに動くようにしておきたい。

で、これらを踏まえた上で動くものを作るためにはそれなりに泥臭い処理が必要になる事がわかってきたのでそのメモのためにここに書いておく。

この処理でとても参考になったのは gdi++ での API フック手順。
gdi++ でも最初の手順はやはり CreateProcess でメインスレッドをサスペンド状態にして立ち上げる。そして CreateRemoteThread を使うのではなく、exe のエントリポイントのコードを直接書き換えて目的の DLL をロードする処理を注入する。そのプロセス上で DLL がアタッチされてしまえば、後は普通に API フックを行えばいい。
gdi++ の場合はフックした API の元の実装を呼んでいる間に呼ばれる別のフック中のAPIの呼び出しも監視する必要があるために関数本体を書き換えているが、今回の場合はそこまで深い監視は必要ないはずなのでもう少しシンプルなフックだけでいけそうだ。

と、思う。
posted by oov at 08:47| Comment(7) | TrackBack(0) | プログラム | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
いけなかった。全然いけなかった。
プラグインとかで DLL に DirectSound 周辺の機能を盛り込んでいるタイプのソフトが全滅だった。
結局 LoadLibraryA, LoadLibraryW, GetProcAddress を監視して新しく読み込まれたライブラリに対しても読み込んでいく事で対応した。
Posted by oov at 2008年01月24日 13:24
しかもよく考えてみると VirtualAllocEx などを使う必要があったのでこの手法では9x系のサポートはどっちにしろ無理のような気がする。
9x系を視野に入れるならDLLのすり替えが一番現実的なのかも知れない。
Posted by oov at 2008年01月24日 13:45
日本語でおk
Posted by mesosin at 2008年01月28日 15:00
日本語です。
Posted by oov at 2008年01月29日 06:39
(;^ω^)・・・・



日本語でおk

Posted by at 2008年02月03日 18:55
おちこんだりもしたけれど(鯖が)、私は元気です
申し訳ないがいろいろあってしばらく放浪してます
春には戻るかもしれんのでその時はよろしくです
Posted by PA at 2008年02月06日 06:37
あ、了解した。
ちょっと遅い冬眠てところだね。

連絡ありがとう。
俺も何か面白いネタ仕入れたりしておくよ。
Posted by oov at 2008年02月06日 07:18

この記事へのトラックバック