FineArt News

APIフックとドライバフック

一般的なアプリケーションはソフトウェア会社がコンパイルした実行ファイルであり、機能や特性は固定されています。メーカーのサポート以外に機能を変更することはできません。フック技術は、第三者のソフトウェアエンジニアがこれらのメーカープログラムを「修正」するためのソリューションです。例えば、Windows上で外部ディスクを直接使用できますが、ファイルを外部ディスクにコピーする際に自動的にバックアップを取得することが必要な場合、Windowsを「修正」するためにフック技術を使用する必要があります。

Windowsのメモリを理解する

一般的に、フック技術には上層のAPIフックと下層のドライバフックがあります。APIフックとドライバフックの違いで上層と下層とは何かを明確に区別するためには、まずWindowsのメモリ配置について理解する必要があります。Windowsなどのオペレーティングシステムは仮想メモリ技術を使用しており、すべての人が見ているメモリ位置は仮想的であり、プログラムが実行されるとオペレーティングシステムがいくつかのアルゴリズムでリアルメモリに対応させます。

Windowsは仮想メモリを上下2つに分けています。上層部分はユーザ空間であり、私たちがよく知っているアプリケーションがここにあります。下図から分かるように、各アプリケーションは自分がメモリ全体を所有していると認識しています。このようなアプリケーションベースの隔離方式により、異なるプログラム間で干渉し合うことはありません。例えば、下図の(1)は、WINWORD.EXE、EXCEL.EXEともに仮想位置"0000 1000 0000 0000"のメモリを所有していると認識しています。WINWORD.EXEがこの領域のメモリを自由に変更しても、Excelのこの領域のメモリは影響を受けません。

仮想メモリの下層部分は、オペレーティングシステムのカーネルであり、よく知る各種ドライバ・共有メモリ・Windowsカーネルなどが存在します。この部分のメモリ空間は実際に共有されているため、仮に仮想位置"8000 1000 0000 0000"のメモリを修正した場合、すべてのプログラムに影響が及びます。例えば、下図(2)でネットワークパケットフィルタドライバを変更し、ネットワークのパケットをフィルタリングする場合、WINWORD.EXEやEXCEL.EXEなどすべてのアプリケーションのネットワークパケットがフィルタリングされます。

APIフック

Windowsのメモリ配置を理解できれば、APIフック技術について説明することができます。上図に続き、MyApp.EXEがWINWORD.EXEにAPIフックをかける場合を考えてみます。

この過程にはいくつかの課題があります。まず、2つのプログラムは異なるメモリ空間にあるため、別々の世界にいるようなものです。そのため、他の世界に侵入する方法が必要です。これはWindowsが提供するDLLフック(例えば、マウスフック・キーボードフック・CBTフックなど)を使用することで簡単に実現できます。または、CreateProcess、CreateThreadなどの高度な技術を使用して、フックプログラム(例えばmyHook)を他のプログラムのメモリ空間に「注入」することができます。

次に、注入が成功した後、注入されたプログラム内でホストプログラムの重要なAPIを見つけて、これらのAPIを置き換える必要があります。

例:「MyAPP.EXEでOfficeのファイルを開く動作をキャプチャしたい」場合

下図(1)のように、注入でWINWORD.EXEおよびEXCEL.EXEなどのOfficeプログラムに個別に侵入する必要があります。成功すればmyHookを侵入されたプログラムのメモリ空間に配置できます。

下図(2)のように、それぞれのプログラムの「OpenFile」APIを見つけてAPIを置き換えることで、APIフックを完了します。

APIフックの設計が悪い場合、しばしばアプリケーションのクラッシュを引き起こすので、Windows 10からは対応策としてCFG(Control Flow Guard)とCIG(Code Integrity Guard)のメカニズムが新たに追加されています。

ドライバフック

ドライバフックにはいろんな実装案がありますが、一般的なミニドライバを例に説明します。ミニドライバとは、ドライバを1から実装するのは効率が悪くて制御も難しくなり問題も起こりやすいため、その対応策としてWindows自体が大部分の機能を実装して、重要な部分をミニドライバにコールアウトするソリューションです。

下図から分かるように、ネットワークパケットをインターセプトするにはWFPのマイミニドライバを作成するだけで良くなります。

通常、同じタイプのミニドライバを一緒にフックできます。例えば、ネットワークパケットをインターセプトするプログラムは1つとは限らず、通常はウイルス対策ソフトウェアもネットワークパケットをインターセプトするので、ミニドライバ間の順序が重要になります。例えば、上層のミニドライバがインターセプトしたネットワークパケットを下に流さない場合、下層のドライバではパケットを見ることができなくなります。

また、ミニドライバはWindowsのコアの一部であるため、通常WindowsはミニドライバにMicrosoftのデジタル署名を要求します。Microsoftのデジタル署名が付いたミニドライバのみがコアにロードされます。

カクテル式の多階層セキュリティ

実際のアプリケーション運用はより複雑で、セキュリティ対策をするにも単一の技術では到底対応しきれません。そのため、カクテルのように異なる技術を混ぜて多層的に組み合わせることでセキュリティを確保する必要があります。

URLの保護を例に説明すると、ユーザのインターネット活動を検出したい場合、ブラウザなどのソフトウェアのインターフェースを対象に上層のAPIフック技術を使用してフィルタリングすることができます。このようにして、ユーザがブラウザで操作するURLや送信内容を取得できます。

しかし、このような設計だけでは不十分です。例えば、特定のネットワーク接続プログラムを使用した場合はブラウザを経由しません。または上層のメインプログラムが削除された場合(上層のAPIフック主体のメインプログラムが削除された場合、多くのAPIフックが無効になります)、これらの操作でAPIフック技術によるインターネット活動のフィルタリングが回避されることがあります。一般的に、成熟したセキュリティソフトウェアは第2層または第3層以上の保護を設置する必要があります。多層保護ですべての卵が同じ籠に盛られるようなことを回避できます。例えば、第2層でドライバフックを使用してインターネット活動をフィルタリングし、APIフックと共同で対処できます。

TSFシステムを使用する場合、より多層の防御機能があります。さながらカクテルのように交差する保護でより安全なシステムを実現します。例えば、ユーザの操作ログを記録したり、ブラウザなどのソフトウェア実行を録画したり、アプリケーション制御を使用してハッカーの攻撃からPCを保護することができます。

まとめ

本文は、APIフックとドライバフックの違い、開発の大まかな流れおよびWindowsがこれら2つの技術に対して制限を課す方法について説明しました。現実世界でのアプリケーションにおいて、情報セキュリティ問題は単一の技術によって対応できるものではなく、TSFも異なる制御機能を多層的に組み合わせることで効果的に制御を行っています。