コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2007年3月8日 >>> 2007年3月8日
link もっと後

2007年3月8日

Win32 APIのフック

研究室の方々が WindowsってAPIのレイヤでフックできないの?って話をしていたのでちょっと考えてみました。DLLの呼び出しをフックする手法は以下のような手法が考えられますが、どれも一長一短です。

フックDLL
概要:フックしたいDLLと同じexportsを持つ偽物DLLを作成して、操作対象プロセスに優先的にロードさせる(カレントディレクトリに配置など)。
長所:比較的簡単に実現できる。
短所:いちいちDLL作るのめんどくさい。いくつかのDLLには効かない。
デバッグ関数
概要:OSのデバッグ機能を用いて、フックしたいAPIの先頭アドレスでデバッグブレークする。
長所:簡単かな?作ったこと無いので良くわからんです。
短所:たぶん遅い。Windowsはデバッガのデタッチができないため、用が済んでもフックプロセスを消せない。これは致命的。
IATパッチ
概要:DLLの関数をcallするときに用いるアドレステーブル(IAT: import address table)を書き換えて、フック処理を呼ばせる。
長所:IATさえ使っていればどんなDLLの関数でもフックできる。
短所:IATの書き換えが大変。スタティックリンクされるとフックできない。
コードインジェクション
概要:DLLの関数の先頭を書き換えフック関数へジャンプさせる命令を入れる。
長所:DLLだけに限らず、どの関数でもフックできる。
短所:関数の先頭アドレスが分かっていないとフックできない(DLLの関数ならたぶん大丈夫)。LoadLibraryとGetProcAddressで動的ロードされたり、スタティックリンクされるとフックできない。

名前は勝手に付けました。下に行くほど実装が面倒くさそう、と勝手に思っています。正式名称(orもっと格好いい名前)や、他の方法をご存じの方は、ご教授いただけると幸いです。

IATパッチングによるDLL呼び出しのフック

以前、フックDLLでwinsockかなんかをフックしたことがあるので、今回はIATを外から無理矢理ぶっ潰してフックを実現してみました。

試しにWindows MessengerのSHELL32.dll!Shell_NotifyIconに割り込んで、ダイアログを表示させてみました(下図)。


Shell_NotifyIconをフック

ちなみにshell32.dllであればフックDLLの方が遙かに楽だと思います。kernel32.dll!CloseHandleなんかもフックしてみたのですが、見た目に呼んでるんだか呼んでないんだかわからんのよね。

課題

ロードされたモジュールは各自のIATを持っています。そのためIATパッチを行う場合は、全てのIATのエントリを虱潰しに見なければなりません。

あるプログラムhoge.exeがkernel32.dllとuser32.dllをロードしていたとしたら、IATは少なくともhogeとkernel32とuser32の3つ分存在するはずです。

その状態でuser32.dll!MessageBoxWをフックしたいと思ったら、全てのIATのエントリからMessageBoxWに関わるエントリを探して書き換えなければ、打ち漏らしが発生してしまいます。IATパッチにおいて、フックをかける処理はかなりヘビーなものになるでしょう。

またDLLはいつロード/アンロードされるかわからないので、フックの設定や解除を徹底しようと思うとかなり難しいです。そのため厳密にフックする必要がある、セキュリティシステムなどには向かない手法です。

あとは…フックを通知する方法も考えないと行けませんね。これはそのうちなんとかなるんじゃないかと思っております。

編集者:すずき(2007/03/08 18:39)

コメント一覧

  • hdkさん(2007/03/08 23:01)
    デバッグ機能とアドレステーブルの書き換えの組み合わせはやったことありますw うまくいったけどあれは遅かった
    http://www.deez.info/sengelha/code/win32-ldpreload/
    これやってみたいんだけどな... 結局やってないや
  • すずきさん(2007/03/09 00:28)
    おお、さすが。でもなぜにIATとデバッグを併用?どちらかで良くない?
  • hdkさん(2007/03/09 01:01)
    詳しくないんで、デバッグ機能使って DLL が読み込まれるタイミングをとらえるようにしたんです。あと、子プロセスを全部フックしたかったというのもあります。

    っていうか IAT パッチングってどうやってるの? プロセス起動直後からとらえることってできる?
  • すずきさん(2007/03/09 12:37)
    なるほど。デバッグ機能のDLLロードイベントは便利ですよね。
    CreateProcess直後は IAT にアドレスが書かれていないので、書き換えできないです。既に動いてるプロセスにフックを引っかけることを考えてました。

    起動直後に止めたいとすれば、一応、PE ヘッダに書いてあるエントリポイント(main の頭とか)にフックを入れておいて、その時点で IAT を根こそぎ書き換えるという方法を考えてました。

    でもこれだとDLLの初期化関数(DllMain)は実行されてしまいますかねえ。
  • IKeJIさん(2007/03/10 20:47)
    LoadLibraryをフックするというのでは駄目でしょうか?
  • IKeJIさん(2007/03/10 20:48)
    ところで、この日記のコメントを書く時に、
    >上記、確かに認めます
    とありますが、何を認めるのでしょうか?
  • すずきさん(2007/03/11 17:11)
    そうするとLoadLibrary以外のロード方法に対して無力という罠が。
  • すずきさん(2007/03/11 17:14)
    > 上記、確かに〜
    ホントは、
    管理者の不適切だと思う物は消します
    とか、
    公序良俗に反する物は書くな
    とか、そんな規定を書く予定が、めんどくさくなってやめたのです。その残骸です。
  • すずきさん(2007/03/13 16:21)
    せっかくなので利用の際のお願い、を追加しました。
open/close この記事にコメントする



link もっと前
2007年3月8日 >>> 2007年3月8日
link もっと後

管理用メニュー

link 記事を新規作成

<2007>
<<<03>>>
----123
45678910
11121314151617
18192021222324
25262728293031

最近のコメント5件

  • link 24年4月22日
    hdkさん (04/24 08:36)
    「うちのHHFZ4310は15年突破しまし...」
  • link 24年4月22日
    すずきさん (04/24 00:37)
    「ちゃんと数えてないですけど蛍光管が10年...」
  • link 24年4月22日
    hdkさん (04/23 20:52)
    「おお... うちのHHFZ4310より後...」
  • link 20年6月19日
    すずきさん (04/06 22:54)
    「ディレクトリを予め作成しておけば良いです...」
  • link 20年6月19日
    斎藤さん (04/06 16:25)
    「「Preferencesというメニューか...」

最近の記事3件

  • link 24年2月7日
    すずき (04/24 02:52)
    「[複数の音声ファイルのラウドネスを統一したい] PCやデジタル音楽プレーヤーで音楽を聞いていると、曲によって音量の大小が激しく...」
  • link 24年4月22日
    すずき (04/23 20:13)
    「[仕事部屋の照明が壊れた] いきなり仕事部屋のシーリングライトが消えました。蛍光管の寿命にしては去年(2022年10月19日の...」
  • link 24年4月17日
    すずき (04/18 22:44)
    「[VSCodeとMarkdownとPlantUMLのローカルサーバー] 目次: LinuxVSCodeのPlantUML Ex...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 04/24 08:36