DirectX Tweaker Public Beta
spin でおもしろいツールが紹介されていました.
独nonatainmentが、「DirectX Tweaker」のパブリックベータ版をこちらで公開しています。DirectX Tweakerは、このツールから起動したDirect3D使用アプリケーションソフトのDirect3Dのラッパとして働き、アプリのDirect3Dに関する情報を得たり、Direct3Dの設定を動的に変更したりできる大変興味深いツールです。各種機能は、プラグイン形式で提供されます。現在、提供されているプラグインには、例えば、次のようなものがあります
- GetDeviceCaps()でアプリ側が得るCaps情報を自由に設定できるCaps Changer
- テクスチャフェッチのフィルタモードを強制的に設定するAF Control
- バックバッファやZバッファのフォーマット/サイズ/数、マルチサンプリングAAのモードなどを強制的に設定するPresent Changer
- シェーダのバージョン毎に強制的に色を塗り分けるShader Display
- 描画フレーム毎のCPU時刻、描画オブジェクト数(描画コール数?)、描画頂点数をテキストファイルに出力するStatistic
- カラーフォーマット毎にテクスチャを指定の色で塗り分けるTexture Format Display
- テクスチャのサイズ毎にテクスチャを指定の色で塗り分けるTexture Size Display
- ワイヤフレーム描画に強制的に設定するWireframe
- ピクセルシェーダの全命令の演算精度を部分精度(_pp/16bit)に強制的に設定するForce Shader PP
- ピクセルシェーダの全命令の演算精度をフル精度(32bit/24bit)に強制的に設定するForce Shader FP
- nonatainment独自のアルゴリズムでアルファテストの部分にも有効なFSAA処理を行うAlpha Test AA
ざっと見たところ,「DirectX Tweaker」は .NET で書かれた設定ツールと,ネイティブコードによる DirectX Graphics のフック機構からなるようです.プラグインについても実際のフックロジックに関係するものは Win32 DLL で,設定ツールの UI に関係するものは .NET Assembly で作成するようでした.
DebugBreak() を仕掛けたテストプログラムを DirectX Tweaker に食わせて実行時の挙動をデバッガで眺めてみましたが,どうやら「PIX」と同じタイプのフックを行っているようです.WinMain に入った段階で d3d9.dll がロードされていて,かつDirect3DCreate9 の先頭数命令*1 が書き換えられていることが確認できました.恐らく IDirect3D9 のプロキシオブジェクトを返すようなコードに飛ばされているのでしょう*2.
ちなみに DLL が公開する関数のフックと言えば他にも Proxy DLL を利用する方法やインポートセクション書き換える方法もありますが,これらは絶対パスで LoadLibrary を呼び出すタイプのアプリケーションに対してはうまく機能しません.実際最近の SDK に付属するサンプルフレームワークでは,LoadLibrary によって d3d9.dll を絶対パスで読み込んでいるため,以下のような但し書きが追加されています.
現在のサンプルはデバッグ ユーティリティ D3DSpy と一緒には動作しません。\windows\system32 から D3D9.dll を直接ロードするアプリケーションはどれも動作しないでしょう。
一方「PIX」や「DirectX Tweaker」のプログラムローダは,ターゲットの WinMain 開始前に,%WinDir%\System32\d3d9.dll のロードと Direct3DCreate9 の書き換えを行っています.後でアプリケーションが絶対パス指定で LoadLibrary を呼び出しても,実際には DLL の参照カウントが増えるのみで依然として書き換えられた Direct3DCreate9 は有効なまま,という仕組みなんでしょう.
Web で検索してみたところ,アプローチとしては『Advanced Windows 改訂第4版(asin:4756138055)』22.8「CreateProcessを使ったコードの注入」あたりに詳しくまとまっていそうですね.実は未読なんですけど……折角だし買っておくか……