hail2u.net の同名エントリを受けて、僕もちょっと書いてみました。てか IRC で出来そうとかつぶやいたら kyo さん速攻エントリ書いててびびったり。暇人だな!!
dll と ini をセットで googletalk.exe と同じディレクトリに放り込むだけ。使用したいブラウザのパスを ini ファイル内で指定します。
デフォルトブラウザで OK という人は ini 不要。
あと開く URL を https に修正する、ってこともしてます。というかこれがしたくて作りました。
いろいろ手抜きなソースはここら辺に置いてます。
追記
いちお、解説を書いておく。苦手な分野で、よく知らないことも Blog に書き公開することで何かプラスになるかもしれないという(ハテナオヤメソッド)
まずWindowsでは、あるアプリのメモリやなんかをいじろうと思ったらそのアプリと同じプロセス内にいる必要がある。そのためにはDLLインジェクションという技を使って自作DLLを目的のアプリケーションのプロセス内に挿入する。
これにはいろんな方法(レジストリ、グローバルフック、プロクシDLL、CreateRemoteThread)なんかがあるが、NT限定なら後ろ二つが楽チン。今回はそのうちのプロクシDLL方式を使った。
一般にWindowsアプリケーションはシステムディレクトリにあるDLLをロードする。そのときのDLLの探索順はPerlのライブラリと同じようにカレントディレクトリからとなっている。なので、システムディレクトリにあるDLLと同じ名前のDLLをアプリケーションと同じディレクトリに置けばシステムディレクトリにあるものの代わりにカレントディレクトリのDLLがロードされる。何もせずにアプリ側からロードしてくれるわけ。
ただもちろん、本来のシステムディレクトリ内のDLLとしての機能も果たす必要があるので、自作DLLの中で本来のDLLをロードし関数をマッピングする必要はある。これはちよクロシステムで配布されているlistexpというツールを使うと雛形を作ってくれて便利!
目的のアプリケーションのプロセス内に進入することができたら、今度は関数テーブルを書き換え、本来呼び出されるAPI関数の代わりに自分のDLL内の関数が呼び出されるようにする。今回はgoogletalkがブラウザを起動するのに使っているShellExecuteW関数を自分のものに書き換えた。
プロクシDLLの場合、乗っ取りたい関数がそのDLL内にあれば関数をマップする際にちょこっと書き換えるだけでOKだが、今回のっとるShellExecuteW関数はshell32.dll内にあり、これはレジストリでシステムディレクトリのものが読み込まれるように定義されていてこの方式は使えない。
なのでCode Projectなんかで解説されているHookImportedFunctionというのを利用した。これは関数のインポートテーブルに書かれている目的の関数のアドレスを自分のものに書き換えるということをしている。
大体そんな感じ。VCとか一年に数回しか立ち上げないから使うたびにいろいろ忘れていて大変。どんどんC書けなくなる。。