
ブート時に PatchGuard と Driver Signature Enforcement を無効にする
EfiGuardは、ブート時にWindowsブートマネージャー、ブートローダー、カーネルをパッチして、PatchGuardとドライバ署名強制(DSE)を無効にするポータブルなx64 UEFIブートキットです。
EfiGuardを試すだけの場合は、使用方法にスキップしてください。
現在、Vista SP1からWindows 11まで、これまでにリリースされたすべてのEFI互換のWindows x64バージョンをサポートしています。
簡単に使用可能:自動的にWindowsを見つけて起動するローダーを介して、USBスティックまたはWindows EFIパーティションからブートできます。ドライバーは、UEFIシェルまたはローダーを使用して手動でロードおよび構成することもできます。
高速ランタイム命令デコードのためにZydis逆アセンブラライブラリを多用しており、シグネチャマッチングよりも堅牢な分析をサポートします。シグネチャマッチングは新しいOSアップデートで変更が必要になることがよくあります。
受動的に動作:ドライバーはWindowsブートマネージャーをロードまたは起動しません。代わりに、ブート選択メニューまたはローダーなどのEFIアプリケーションを介してファームウェアブートマネージャーによってbootmgfw.efiがロードされたときに動作します。Windows以外のOSがブートされた場合、ドライバーは自動的にアンロードされます。
bootmgfw.efiがwinload.efiではなくbootmgr.efiを起動する場合のために、4段階のパッチングをサポートしています。これは、WinPE、Windowsセットアップ、またはWindows回復モードを起動するためにWIMファイルがロードされた場合です。
グレースフルリカバリ:パッチ失敗時、ドライバーはエラー情報を表示し、ESCキーを押してブートを続行するか再起動するよう促します。これは最終的なカーネルパッチ段階でも同様です。最後のパッチ段階はExitBootServicesが呼び出される前に行われるためです。多くのUEFI WindowsブートキットはOslArchTransferToKernelをフックしますが、これはパターンマッチングで見つけやすいものの、ExitBootServices後にプロテクトモードで実行される関数です。つまり、何か問題が発生したことをユーザーに伝えるためのブートサービスが利用できません。

エラー情報を伴うシミュレートされたパッチ失敗
デバッグ可能:カーネルパッチング段階ではカーネルデバッガおよび画面(バッファリングあり)に、ブートマネージャーおよびブートローダーのパッチング段階ではシリアルポートまたは画面(バッファリングなし)にメッセージを出力できます。ドライバーがPDBデバッグ情報でコンパイルされている場合、仮想DXEドライバーベースを指定して、HAL初期化後の任意の時点でデバッグシンボルをロードし、通常のNTドライバーと同様にデバッグすることが可能です。
DSEバイパス:ブート時の単純なUPGDSEDスタイルのDSE無効化、またはSetVariable() EFIランタイムサービスへのフックとして利用可能です。後者は、WindowsからNtSetSystemEnvironmentValueExを使用して呼び出すことができる任意のカーネルモード読み取り/書き込みバックドアとして機能し、g_CiEnabled/g_CiOptionsを目的の値に設定できます。これを行うためのEfiDSEFix.exeという小さなDSEFixスタイルのアプリケーションが提供されています。DSEを有効のままにしてPatchGuardのみを無効にすることも可能です。ローダーはデフォルトでSetVariableフック方式を使用します。これは、一部のアンチチートおよびアンチウイルスプログラムが、チートやマルウェアと一般的な自己署名ドライバーの違いを理解せず、UPGDSED修正を対象とするためです。
すべての段階でImgpValidateImageHashおよびImgpFilterValidationFailureをパッチすることで、ディスク上の修正されたカーネルとブートローダーをサポートします。ImgpFilterValidationFailureは、一部のクラスの違反をTPMまたはSIログファイルに静かに報告する可能性があります。
Windows 7でセキュアブートを機能させることができます(冗談ではありません!)。Windows 7自体はセキュアブートをサポートしておらず、正式にはCSMなしでのブートもサポートしていないため、セキュアブートを認識しません。これは、WHQLセキュアブートを必要とするロックダウンされたデバイスでWindows 7を使用したい人に役立ちます。これを機能させる方法についてのWikiエントリはこちら。

セキュアブートが有効なWindows 7上のWinObjEx64
SetVariableフックはg_CiOptionsへの書き込みに使用されるとSECURE_KERNEL_ERRORバグチェックを引き起こします。EfiGuardを使用するには2つの方法があります:ローダーアプリケーションをブートする方法(ドライバーをロードしてWindowsを起動します)、またはドライバーをUEFIドライバーエントリとしてインストールしてファームウェアが自動的にロードする方法です。
マルチブートなどの高度な構成ではドライバーのインストールが好ましい場合もありますが、ローダーが最も使いやすく、すべての構成で適切に動作するはずです。2つの方法の主な違いについては以下の表を参照してください。不明な場合は、ローダーアプリケーションを選択してください。
| 場所 | インストール | スキップ可能? | どのOSがブートされるか? | |
|---|---|---|---|---|
| UEFIドライバーエントリ | ESP上である必要あり | UEFIシェル経由 | ❌ | 以前と同じ |
| ローダー | どこでも | 不要 |
ローダーとUEFIドライバーエントリの比較
EFI/Boot/Loader.efiをbootx64.efiにリネームします。X:と仮定すると、2つのファイルのパスはX:/EFI/Boot/{bootx64|EfiGuardDxe}.efiになります。SetVariableフック(デフォルト)でブートした場合、ブート後に管理コマンドプロンプトからEfiDSEFix.exe -dを実行してDSEを無効にするか、EfiDSEFix.exeを実行してオプションの完全なリストを表示します。ローダー用に別のドライブを使用する必要はありません。必要に応じて、Windowsが既にインストールされているESPにEfiGuardをインストールできます。ただし、この場合はローダーのUEFIブートエントリを追加する必要があるため、やや複雑になります。
これを行うには、mountvol X: /Sを使用してESPをX:にマウントし、上記の手順に従います。ただし、ローダーをリネームしないで、両方のファイルをX:/EFI/Bootにコピーするだけです。その後、UEFI Shellからbcfg boot addp 0 Loader.efi "EfiGuard"を使用するか、またはefibootmgr(Linux)、EasyUEFI(Windows)などを使用して、手動でUEFIブートエントリを追加する必要があります。
mountvol X: /Sを使用してESPをX:にマウントします。EfiGuardDxe.efiをX:/EFI/Boot/EfiGuardDxe.efiにコピーします。bcfg driver add 0 EfiGuardDxe.efi "EfiGuardDxe"。SetVariableフック(デフォルト)でブートした場合、ブート後に管理コマンドプロンプトからEfiDSEFix.exe -dを実行してDSEを無効にするか、EfiDSEFix.exeを実行してオプションの完全なリストを表示します。注: ファームウェアによっては、手順3で"add"の代わりに"addp"を使用する必要がある場合があります。VirtualBoxではこれが必要であり、一部のマザーボードファームウェアでも必要になる可能性があります。
注: 一部の非常に古いまたは非準拠のファームウェアでは、このインストール方法をまったくサポートしていない場合があります。そのようなシステムでは、代わりにローダーを使用するしかありません。
EfiGuardのビルドにはEDK2が必要です。EDK2がインストールされていない場合は、まずGetting Started with EDK2の手順に従ってください。EDK2ビルドシステムのセットアップはかなり複雑です。このセクションでは、WORKSPACE環境変数が指すworkspaceディレクトリがあり、workspace/edk2にEDK2のチェックアウトがあることを前提としています。サポートされているコンパイラはMSVC、Clang、GCC、ICCです。
workspace/edk2/EfiGuardPkgにクローンします。build -a X64 -t VS2019 -p EfiGuardPkg/EfiGuardPkg.dsc -b RELEASEを実行します。これにより、workspace/Build/EfiGuard/RELEASE_VS2019/X64にEfiGuardDxe.efiとLoader.efiが生成されます。
EfiDSEFixのビルドにはVisual Studioが必要です。
EfiGuard.slnを開き、ソリューションをビルドします。出力バイナリEfiDSEFix.exeはApplication/EfiDSEFix/binにあります。
Visual Studioソリューションには、VisualUefiで使用できるEfiGuardDxe.efiとLoader.efiのプロジェクトも含まれていますが、これらのプロジェクトは追加コードなしではリンクできないためデフォルトではビルドされず、ビルド出力はEDK2が生成するものよりも劣ります(サイズが大きくなります)。Loader.efiは、VisualUefiにUefiBootManagerLibがないためまったくリンクできません。したがって、これらのプロジェクトファイルは開発補助としてのみ意図されており、EFIファイルは引き続きEDK2でコンパイルする必要があります。この目的のためにVisualUefiをセットアップするには、リポジトリをworkspace/VisualUefiにクローンし、EfiGuard.slnを開きます。
EfiGuardはUEFIブートキットですが、最初からそうだったわけではありません。EfiGuardはもともと、PDBシンボルやバージョン固有のシグネチャを使用する代わりに、逆アセンブラベースのアプローチの実現可能性をテストすることを目的とした、NT上で動作するオンディスクパッチャーでした(UPGDSEDに類似)。PatchNtoskrnl.cは今でもこのオリジナルデザインと非常によく似ています。このアプローチが成功し、1年以上のWindowsアップデートでコードの変更が不要であることが証明された後、機能と使いやすさをさらに向上させる方法としてUEFIが登場しました。
ブートキットアプローチによって提供される利点には次のものがあります:
bcdeditを使用したブート構成ストアの変更が不要。ImgpValidateImageHashのパッチが不要(ただし、これはオプションで行うことができます)。dbストアに個人証明書を追加できる場合に、セキュアブートを有効にすることができます。ブートキットとしてのEfiGuardの初期の化身は、dude719のUEFI-Bootkitを最新のWindows 10バージョンで動作させる試みでした。なぜなら、それは時代遅れになり、最新バージョンでは動作しなくなっていたからです(UPGDSEDと同様、バージョン依存のパターンスキャンが原因であることが多い)。最終的には動作するようになりましたが、主にOslArchTransferToKernelをフックする選択に不満がありました。前述のように、この関数はプロテクトモードで実行され、ExitBootServicesが呼び出された後に実行されます。これ以外にも、一部のWindows 10バージョンにしかパッチを適用できないことにも満足していませんでした。私はブートキットが今日までにリリースされたすべてのEFI互換のWindows x64バージョンで動作することを望んでいました。そのため、以下の目標を持ってブートキットをゼロから書き直しました:
最終的なEfiGuardブートフローの全体像は上の図に示されています。個々のコンポーネント固有のフックとパッチについては、ソースファイルのEfiGuardDxe/PatchXxx.cを参照してください。ドライバーの初期化/アンロードおよびEFIブートサービスとランタイムサービスのフックについては、EfiGuardDxe.cを参照してください。
EfiGuardはGPLv3のもとでライセンスされています。EfiGuardDxe/Zydisサブモジュール内のファイルはMITライセンスのもとでライセンスされています。
| ✔️ |
| Windows |