オブジェクトのメソッドフック

Windowsの世界の「オブジェクト」も、オブジェクト指向型プログラミングの特徴と同じように「メソッド」の概念を持つ。また、プロセスオブジェクトであれば Process.open や Process.close、Jobオブジェクトであれば Job.open や Job.close といった具合に、すべてのオブジェクトが同一のメソッドをもつことで、「オブジェクト」のインターフェースを統一している*1

とまあ、概念の詳細は インサイドWindows(上) あたりを参照してもらうとして、このメソッドがどのように実装されているかというと、OBJECT_TYPE_INITIALIZER 構造体に定義されている。各メソッドは、このカーネル構造体のうんちゃら Procedure フィールドにあたる。よって、こいつを適切なシグネチャの関数に差し替えてあげれば、見事フック完了。


フックに関連する構造体定義は、XP SP2とVista SP1ではシンボルに含まれている。2000 SP4のシンボルには含まれないが、XP SP2用のバイナリで正常動作するようだ。


ProcessオブジェクトのOpenProcedureをフックして、以下のコードを実行すると、画像の中の選択行のようなログが確認できた。Vistaでも使えそうだし、なにか面白いことができないかな。

// __vc9test__.cpp
  DWORD dwPid = 0;
  ::GetWindowThreadProcessId(::FindWindow(_T("ProgMan"), NULL), &dwPid);
  HANDLE process = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);

*1:インターフェースがあっても実装はされていない場合が多い