KENJI’S BLOG このページをアンテナに追加 RSSフィード

Freezed...

2008-11-22

ローレイヤー勉強会をリアルタイムで実況してみた

ローレイヤー勉強会 第一回

http://www4.big.or.jp/~kanai/MT/archives/000846.html


感想ではなく実況なのでいろいろと雑です。

雰囲気を味わってもらえれば幸いです。


一発目は村上氏のプレゼンで、Linuxカーネルのシステムコールをフックする内容です。例えばwrite関数を呼び出すと、内部でint 80hが呼ばれてカーネルへ処理が移るが、そのときカーネル内でどのような処理が行われるかを説明されてます(開始20分)。

システムコールをフックするためには、どこを書き換える必要があるか? カーネル内にはテーブルが2つあります。IDTを書き換えるか? sys_call_tableを書き換えるか? またカーネルにはどうやってアクセスするか? とりあえずLKM(デバイスドライバ)を書きましょう。もちろん各種カーネルモジュールを使っても大丈夫。また/dev/以下にはデバイスとつながっているファイル群が存在するため、それらを用いてもカーネルへアクセスできるよね。/dev/kmemとか。詳細はman 4 kmemとか見ましょう(開始23分)。

要するにカーネルモジュールを作って、上記のテーブルにパッチを当てると、いろいろと面白いことができるんじゃないか? というわけで、LKMプログラミングを勉強しましょう。ただ、LKMプログラミングは、若干特殊だから、その辺りをまず勉強する必要があります。バグがあればカーネルパニックです。あと、カーネルの場合、コンテキストなどを意識してプログラミングする場合があります(開始27分)。

Linuxカーネルをコンパイルするためのコマンドを解説。CentOS上で環境を構築する。menuconfigとか、makeとか、installkernelとか、vmlinuxとかを紹介。/boot/直下を見ると、vmlinuzというのがあるが、これはカーネル起動時に読み込まれるもの。じゃあ、vmlinuxって何だろう? これはELF形式のカーネルのイメージです。デバッグとかそういうときに使い分けます。あとはrebootするとオーケーです(開始34分)。

ではさっそくオリジナルソースコードをカーネルソースに追加します。自前のカーネルモジュールは、カーネルツリーに含める方法と、カーネルツリーに追加しないでビルドする方法があります。printfの代わりにprintkとか使います。/var/log/以下にログが出ます。ソースコード内の解説。init_moduleはモジュールがロードされたときに実行されます。cleanup_moduleはモジュールがアンロードされたときに実行されます(開始41分)。

まずは、sys_call_tableの場所を特定する必要がある。System.mapを見よう! これはシンボルとアドレスを一致させているとても有用なもの。これで、sys_call_tableのアドレスを特定できる。やり方は他にもある。gdbでカーネルのメモリにアタッチして、直接見よう! gdbでカーネルにアタッチして「p/x &sys_call_table」とか「x/28w &sys_call_table」とかで見れます(開始46分)。

次に偽物(代わりとなる関数)を作成しましょう。とりあえず簡単に、printkでログをだしてオリジナルシステムコールを呼ぶ処理を実装します(開始50分)。

実際にシステムコールをフックするデモンストレーション。自前のモジュールをカーネルへロードすると、ログが表示されます(開始54分)。

以上で1時間目を終了です。とりあえず、自分が認識できたことだけ、可能な限り書きました(自分が聞いた段階での認識間違いがあるかもしれません)。


〜10分休憩〜


二時間は丹田氏のプレゼンです。Linuxの次はWindowsのカーネルです。早速はじまりました(開始2分)。

アンチアクセスチェック、Windowsのアクセスチェックを無効にするツールを作っちゃいました。いきなりそれのデモンストレーションです(ソースコード配布アリ)。このツールを使うと、読み込み専用の共有フォルダに対して、書き込みや削除が可能になります(開始18分)。

カーネルというのは、PID=8が活躍している場所です。実体はntoskrnl.exeです。よって、このファイルを削除するとOSが起動しないです。それで、そもそもカーネルの仕事というのは、システムコールの提供やハードウェアの制御など。でも、プログラマは、カーネルを利用することで、Windows全体に影響を与えることができる。それも、ごく少量のコードで。では、どうやってカーネルにアクセスするか? WinDbgを使いましょう。WinDbgでカーネルをデバッグする場合、2台のマシンが必要ですが、VMを使えば1台でも可能。また、LiveKdなどもツールも便利。WinDbgを利用してWindowsのメモリダンプを取得できる。このツールの利点は、Windowsを停止させる必要がない(開始24分)。

カーネルモジュールは.sysファイルです。win32k.sysはWindowsサブシステムです。デバイスドライバの動作イメージは、ざっくり説明すると、カーネルのDLLというイメージ。DLLがプロセスのメモリ空間を自由に参照できるのと同様に、カーネルモジュールもカーネルのメモリ空間を参照できる。なので、カーネルにパッチをあてるときは、カーネルモジュールを作るのは良い(開始27分)。

カーネルモードプログラミングは基本的にコマンドプロンプトでコンパイル。資料もないし結構大変。でもここが一番の障壁であとは楽しい! そしてカーネルモードではRing0を持つことができるため、特権命令が使えます。また、ユーザーへのインターフェースを持たないから、基本入出力はファイルやレジストリを通します。でも、DDKWizardとかDebugViewとかで開発を補助できます(開始33分)。

では、実際にHello Worldを出力するカーネルモジュールをロードするデモをしましょう。実際にコマンドラインからモジュールをロードし、DebugViewで出力を表示された。では、次にデバッグをしてみよう。デバッガでカーネル(モジュール含む)にアタッチすると、アタッチされたカーネルは停止して、デバッグ情報がWinDbgに表示されます。この状態でソースコードレベルでのデバッグも可能。ソースレベルでブレイクポイントも設置できるので、開発はかなり便利(開始43分)。

デモンストレーションはどんどん進むよ。次はmsrのアドレスを出力するデモをやりつつ、カーネルモジュールをロードするためには、サービスマネージャ関数を使います。また、カーネルモジュールはboot直前にロードされたり、ログイン後にロードされたり、任意でロードされたりといったようなロードのタイミングを決められます。また、NtSetSystemInformationを使ってもモジュールをロードできるけど、最近のOSでは使えなくなりました(開始54分)。

システムコールってどうやって呼び出されるかというと、例えば、SHELL32.dllの中にあるShellExecuteExWが呼ばれると、次にkernel32へ進み、次にntdll.dllへ進み、次にnt!KiFastCallEntryへ進みます。このような、どんどんカーネル部分へ進んでいく感じで、最終的にシステムコールへたどり着きます。結局すべてのWin32APIはカーネル内に存在するネイティブAPIへたどりつくため、カーネルをいじればいろんなことができます。そして、カーネルへ進むためには、sysenter命令を呼び出されますから、それをフックしましょう。sysenterフックは要するにmsrを書き換えることなので、ここを書き換えてsysenterフックをします。ただ、すべてのプロセッサ(CPU)に対して書き換えを行わなければならないため、複数のCPUを保持していたら、それら全部を書き換えましょう(開始64分)。

デモンストレーションはどんどん進みます。カーネル内のKiFastCallEntryをフックすることで、すべてのプロセスのシステムコール呼び出しを監視できます。ただ、カーネルモードでいろいろやっているため、ユーザーモードには基本的に感知できないです。KiSystemServiceにシステムコール用の関数ポインタ群が入っているため、それらを変更するだけで、システムコールをフックできます(開始73分)。

以上で2時間目を終了です。同じく、自分が認識できたことだけ、可能な限り書きました(自分が聞いた段階での認識間違いがあるかもしれません)。


二時間目は、本当はもう少し続くんですが、ちょっとマシンのバッテリーがなくなってきたので、ここで止めておきます^^;。あと聞きながらリアルタイムで書いていたので、間違い(スピーカーの間違いではなく、僕の聞き間違いとか)多々あると思います。あとテキスト的にはかなり雑ですが(本当に聞きながら書いていたので)、雰囲気だけでも感じてもらえればと思います。第二回目がいつあるか分かりませんが、このように低レイヤーでコアな勉強会はあまり無いと思いますので、もし興味があれば参加してみてはどうでしょ? ちなみに、どちらも後ほど資料を公開するということでした。皆様、お疲れ様でした。


(追記)資料が公開されています。

http://groups.google.co.jp/group/lowlayer/files

redsoul00redsoul00 2008/11/22 21:10 ぜひ時間があえば勉強会に参加したいです。
資料公開を待ち望んで待ちます。

kenjiaikokenjiaiko 2008/11/23 22:43 資料は後ほど公開されるということだったので見れると思いますよー。でも実際に質問とかコアな話とかもあるのが勉強会なので、できれば行った方が楽しいかもしれないっすー(^^;

トラックバック - http://d.hatena.ne.jp/kenjiaiko/20081122/1227331074