オブジェクト ハンドル
ドライバーとユーザー モード コンポーネントは、ハンドルを通じてほとんどのシステム定義オブジェクトにアクセスします。 ハンドルは、不透明なデータ型である HANDLE で表現されます (デバイス オブジェクトやドライバー オブジェクトへのアクセスにハンドルは使用されません)。
ほとんどの種類のオブジェクトについて、そのオブジェクトを作成したか開いたカーネル モード ルーチンが呼び出し元にハンドルを提供します。 呼び出し元は、そのハンドルを使用して、オブジェクトに対する以降の操作を実行します。
ドライバーで多く使用されるオブジェクトの種類と、その種類のオブジェクトにハンドルを提供するルーチンの一覧を次に示します。
アセチルサリチル酸アクロレイン | オブジェクトを作成するか開くルーチン |
---|---|
ファイル |
|
レジストリ キー |
IoOpenDeviceInterfaceRegistryKey、IoOpenDeviceRegistryKey、ZwCreateKey、ZwOpenKey |
Threads |
|
Events |
|
シンボリック リンク |
|
ディレクトリ オブジェクト |
|
セクション オブジェクト |
オブジェクトにアクセスする必要がなくなったドライバーは ZwClose ルーチンを呼び出し、そのオブジェクトのハンドルを閉じます。 上記の表に示したすべての種類のオブジェクトに対し、この処理が機能します。
ハンドルを提供するルーチンのほとんどは、パラメーターとして OBJECT_ATTRIBUTES 構造体をとります。 この構造体を使用してハンドルの属性を指定できます。
ドライバーでは、次のハンドル属性を指定できます。
OBJ_KERNEL_HANDLE
カーネル モードでのみハンドルにアクセスできます。
OBJ_INHERIT
現在のプロセスのすべての子は、作成されたときにハンドルのコピーを受け取ります。
OBJ_FORCE_ACCESS_CHECK
この属性は、ハンドルに対してすべてのアクセス チェックを実行することを指定します。 既定では、カーネル モードで作成されたハンドルに対してはアクセス チェックがすべて省略されます。
InitializeObjectAttributes を使用して、これらの属性を OBJECT_ATTRIBUTES 構造体に設定します。
オブジェクト ハンドルの検証の詳細については「オブジェクト ハンドルの検証失敗」を参照してください。
プライベート オブジェクトのハンドル
ドライバーは、自身がプライベートで使用するオブジェクト ハンドルを作成するたびに OBJ_KERNEL_HANDLE 属性を指定する必要があります。 これにより、ユーザー モード アプリケーションからは、そのハンドルにアクセスできなくなります。
共有オブジェクトのハンドル
カーネル モードとユーザー モードで同じオブジェクト ハンドルを使用するドライバーは、誤ってセキュリティ ホールが発生しzないように注意して作成する必要があります。 ガイドラインを次に示します。
ハンドルは、カーネル モードで作成してユーザー モードに渡します。ユーザー モードで作成したハンドルをカーネル モードに渡さないようにします。 ユーザー モード コンポーネントで作成されてドライバーに渡されたハンドルを信頼すべきではありません。
ユーザー モード アプリケーションの代わりにドライバーでハンドルを操作する必要がある場合は、OBJ_FORCE_ACCESS_CHECK 属性を使用して、所要のアクセス権がアプリケーションにあることを確認します。
ObReferenceObjectByPointer を使用して、共有ハンドル上でカーネル モードへの参照を保持します。 そのようにしない場合、ユーザー モード コンポーネント側でそのハンドルを閉じると参照カウントがゼロになるので、ドライバー側でそのハンドルを使用するか閉じようとするとシステムがクラッシュします。
ユーザー モード アプリケーションでイベント オブジェクトが作成された場合、そのアプリケーションから IOCTL を通じてイベント オブジェクトへのハンドルがドライバーに渡されていれば、ドライバーではそのイベントが通知されるまで安全に待機できます。 ドライバーでは、イベントを作成したプロセスのコンテキストで IOCTL を取り扱い、ObReferenceObjectByHandle を呼び出して、渡されたハンドルがイベント ハンドルであることを検証する必要があります。