ELAM ドライバーの要件
ドライバーのインストールでは、オンラインおよびオフライン インストール用の既存のツールを使用して、通常の INF 処理を通じてドライバーを登録する必要があります。 ELAM ドライバのサンプルコードについては、https://github.com/Microsoft/Windows-driver-samples/tree/main/security/elam を参照してください:
AM ドライバーのインストール
ドライバーのインストールの互換性を確保するために、ELAM ドライバーは、他のすべてのブート開始ドライバーと同様に、ブート開始ドライバーとして自身をアドバタイズします。 INF は、起動の種類を "SERVICE_BOOT_START (0)" に設定しますが、これは、ドライバーをブート ローダーによって読み込み、カーネルの初期化中に初期化する必要があることを示します。 ELAM ドライバーは、そのグループを "早期起動" としてアドバタイズします。 このグループのドライバーの早期起動動作は、次のセクションで説明するように、Windows に実装されます。
ELAM ドライバー INF のドライバー インストール セクションの例を次に示します。
[SampleAV.Service]
DisplayName = %SampleAVServiceName%
Description = %SampleAVServiceDescription%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 0 ; SERVICE_BOOT_START
ErrorControl = 3 ; SERVICE_ERROR_CRITICAL
LoadOrderGroup = “Early-Launch”
AM ドライバーはデバイスを所有していないため、ドライバーが、サービスとしてレジストリにのみ追加されるように、AM ドライバーを、レガシとしてインストールする必要があります。 (AM ドライバーが、通常の PNP ドライバーとしてインストールされている場合、レジストリの enum セクションに追加されるため、PDO 参照があり、ドライバーをアンロードするときに望ましくない動作が発生します。)
また、ELAM ドライバーの INF ファイルに SignatureAttributes Section を含める必要があります。
バックアップ ドライバーのインストール
ELAM ドライバーが誤って破損した場合の回復メカニズムを提供するために、ELAM インストーラーは、ドライバーのコピーをバックアップ場所にインストールします。 これにより、WinRE はクリーン コピーを取得し、インストールを回復できます。
インストーラーは、以下に格納されている BackupPath キーからバックアップ ファイルの場所を読み取ります。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\EarlyLaunch
その後、インストーラーは、regkey で指定されたフォルダーにバックアップ コピーを配置します。
AM ドライバーの初期化
Windows ブート ローダー Winload は、Windows カーネルにハンドオフする前に、すべてのブート開始ドライバーと、その依存 DLL を、メモリに読み込みます。 ブート開始ドライバーは、ディスク スタックが初期化される前に初期化する必要があるデバイス ドライバーを表します。 これらのドライバーには、特に、ディスク スタック、ボリューム マネージャー、オペレーティング システム デバイス用のファイル システム ドライバーとバス ドライバーが含まれます。
AM ドライバー コールバック インターフェイス
ELAM ドライバーは、コールバックを使用して、すべてのブート開始ドライバーと依存 DLL の説明を PnP マネージャーに提供し、すべてのブート イメージを、既知の正常なバイナリ、既知の不良バイナリ、不明なバイナリとして分類できます。
既定のオペレーティング システム ポリシーでは、既知の不良ドライバーと DLL は初期化されません。 ポリシーは設定可能であり、ブート証明の一部としてWinloadによって測定されます。
PnP は、AM ドライバーによって提供されるポリシーと分類を使用して、各ブート イメージを初期化するかどうかを決定します。
レジストリ コールバック
早期起動ドライバーは、レジストリまたはブート ドライバーのコールバックを使用して、各ブート開始ドライバーの入力として使用される構成データを、監視および検証できます。 構成データは、Winload によって読み込まれてブート ドライバーの初期化時に使用できるシステム レジストリ ハイブに格納されます。
Note
ELAM レジストリ ハイブへの変更は、システムが起動する前に破棄されます。 その結果、ELAM ドライバーは、レジストリに書き込むのではなく、標準の Windows イベント トレーシング (ETW) ログを使用する必要があります。
これらのコールバックは、ELAM ドライバーの有効期間中有効であり、ドライバーがアンロードされると登録解除されます。 For more info, see:
ブート ドライバーのコールバック
IoRegisterBootDriverCallback と IoUnRegisterBootDriverCallback を使用して、BOOT_DRIVER_CALLBACK_FUNCTION を登録および登録解除します。
このコールバックは、すべてのブート開始ドライバーが初期化され、コールバック機能が機能しなくなった場合など、Windows から ELAM ドライバーに状態の更新を提供します。
コールバック タイプ
BDCB_CALLBACK_TYPE 列挙体は、次の 2 種類のコールバックを記述します。
- ELAM ドライバーに状態の更新を提供するコールバック (BdCbStatusUpdate)
- イメージを初期化する前に、ブート開始ドライバーと依存 DLL を分類するために AM ドライバーによって使用されるコールバック (BdCbInitializeImage)
この 2 つのコールバックの種類には、コールバックに固有の追加情報を提供する一意のコンテキスト構造が含まれています。
状態更新コールバックのコンテキスト構造には、Windows コールアウトを記述する 1 つの列挙型が含まれています。
イメージ初期化コールバックのコンテキスト構造は、より複雑であり、読み込まれた各イメージのハッシュと証明書の情報が含まれています。 この構造体には、AM ドライバーがドライバーの分類の種類を格納する出力パラメーターであるフィールドが、追加で含まれています。
状態更新コールバックから返されるエラーは致命的なエラーとして扱われ、システム バグ チェックにつながります。 これにより、ELAM ドライバーは、AM ポリシーの範囲外の状態に達したことを示すことができます。 たとえば、AM ランタイム ドライバーが読み込まれず、初期化されていない場合、早期起動ドライバーは、Windows が AM ドライバーが読み込まれていない状態にならないように、アンロード準備コールバックを失敗させることができます。
イメージは、イメージの初期化コールバックからエラーが返されると、不明として扱われます。 不明なドライバーは、OS ポリシーに基づいて初期化されるか、初期化がスキップされます。
マルウェア署名
マルウェアの署名データは AM ISV によって決定されますが、少なくとも、ドライバー ハッシュの承認された一覧を含める必要があります。 署名データは、Winload によって読み込まれる HKLM の下の新しい "Early Launch Drivers" ハイブ内のレジストリに格納されます。 各 AM ドライバーには、署名バイナリ ラージ オブジェクト (BLOB) を格納するための一意のキーがあります。 レジストリのパスとキーの形式は、次のとおりです。
HKLM\ELAM\<VendorName>\
キー内では、ベンダーは、任意の値を自由に定義して使用できます。 メジャー ブートによって測定される 3 つの定義済みバイナリ BLOB 値があり、ベンダーはそれぞれを使用できます。
- 測定済み
- ポリシー
- 構成
ELAM ハイブは、パフォーマンスのために早期起動マルウェア対策によって使用された後にアンロードされます。 ユーザー モード サービスで署名データを更新する場合は、ファイルの場所 \Windows\System32\config\ELAM から、ハイブ ファイルをマウントする必要があります。 例えば、ユーザーは、UUID を生成して文字列に変換し、それをハイブをマウントできる一意のキーとして使用することができます。 これらのデータ BLOB の格納と取得の形式は ISV に任されていますが、AM ドライバーが、データの整合性を検証できるように、署名データに署名する必要があります。
マルウェア署名の検証
マルウェア署名データの整合性を検証する方法は、各 AM ISV に委ねられています。 CNG 暗号化プリミティブ関数は、マルウェア署名データのデジタル署名と証明書の検証を支援するのに有効です。
マルウェア署名の失敗
ELAM ドライバーが署名データの整合性をチェックし、そのチェックが失敗した場合、または、署名データがない場合、ELAM ドライバーの初期化は成功します。 この場合、ブート ドライバーごとに、ELAM ドライバーは初期化コールバックごとに "unknown" を返す必要があります。 さらに、ELAM ドライバーは、起動後に、この情報をランタイム AM コンポーネントに渡す必要があります。
AM ドライバーのアンロード
コールバック StatusType が BdCbStatusPrepareForUnload の場合は、これは、すべてのブート ドライバーが初期化され、AM ドライバーがアンロードの準備をする必要があることを AM ドライバーに示しています。 アンロードする前に、早期起動 AM ドライバーはコールバックの登録を解除する必要があります。 登録解除は、コールバック中には発生しません。代わりに、ドライバーが DriverEntry 中に指定できる DriverUnload 関数で発生する必要があります。
マルウェア対策の継続性を維持し、適切なハンドオフを確保するには、早期起動 AM ドライバーがアンロードされる前に、ランタイム AM エンジンを開始する必要があります。 つまり、ランタイム AM エンジンは、早期起動 AM ドライバーによって検証されるブート ドライバーである必要があります。
パフォーマンス
ドライバーは、次の表で定義されているパフォーマンス要件を満たす必要があります。
シナリオ |
開始時間 |
終了時間 |
上限 |
初期化を許可する前に、読み込まれた起動に不可欠なドライバーを評価します。 これには、状態更新のコールバックも含まれます。 |
カーネルはマルウェア対策ドライバーにコールバックして、読み込まれた起動に不可欠なドライバーを評価します。 |
マルウェア対策ドライバーは、評価結果を返します。 |
0.5 ミリ秒 |
読み込まれたすべての起動に不可欠なドライバーを評価する |
カーネルはマルウェア対策ドライバーにコールバックして、最初に読み込まれたブートに不可欠なドライバーを評価します。 |
マルウェア対策ドライバーは、最後の起動に不可欠なドライバーの評価結果を返します。 |
50 ミリ秒 |
フットプリント (ドライバー + メモリ内の構成データ) |
該当なし |
該当なし |
128kB |
ドライバーの初期化
ブート ドライバーが ELAM ドライバーによって評価されると、カーネルは ELAM によって返された分類を使用して、ドライバーを初期化するかどうかを決定します。 この決定はポリシーによって決定され、レジストリの次の場所に格納されます。
HKLM\System\CurrentControlSet\Control\EarlyLaunch\DriverLoadPolicy
これは、ドメインに参加しているクライアントのグループ ポリシーを使用して構成できます。 マルウェア対策ソリューションでは、管理されていないシナリオで、この機能をエンド ユーザーに公開できます。 DriverLoadPolicy には、次の値が定義されています。
PNP_INITIALIZE_DRIVERS_DEFAULT 0x0 (initializes known Good drivers only)
PNP_INITIALIZE_UNKNOWN_DRIVERS 0x1
PNP_INITIALIZE_BAD_CRITICAL_DRIVERS 0x3 (this is the default setting)
PNP_INITIALIZE_BAD_DRIVERS 0x7
ブートの失敗
初期化ポリシーが原因でブート ドライバーがスキップされた場合、カーネルは、リスト内の次のブート ドライバーの初期化を試行し続けます。 これは、ドライバーがすべて初期化されるか、スキップされたブート ドライバーが、ブートに不可欠であったためにブートが失敗するまで続きます。 ディスク スタックの起動後にクラッシュが発生した場合は、クラッシュ ダンプがあり、かつ、不足しているドライバーに関する情報を含む、理由またはクラッシュに関する情報が含まれています。 これを WinRE で使用して、エラーの原因を特定し、修復を試みることができます。
ELAM と測定されたブート
ELAM ドライバーが、ポリシー違反 (ルートキットなど) を検出した場合は、すぐに Tbsi_Revoke_Attestation を呼び出して、システムが良好な状態であったことを示す PCR を無効にする必要があります。 この関数は、システムに TPM がないなどの、測定されたブートに問題がある場合にエラーを返します。
Tbsi_Revoke_Attestation は、カーネル モードから呼び出すことができます。 PCR[12] を未指定の値で拡張し、TPM のイベント カウンターをインクリメントします。 どちらのアクションも必要であるため、今後作成されるすべての引用符で信頼が壊れます。 その結果、TPM の電源が投入されている残りの時間、測定されたブート ログには TPM の現在の状態が反映されず、リモート システムは、システムのセキュリティ状態を信頼できなくなります。