NtAddDriverEntry
Enregistre une nouvelle EFI_DRIVER_ENTRY dans le firmware pour que l'environnement UEFI charge un pilote avant l'OS.
Prototype
NTSTATUS NtAddDriverEntry( PEFI_DRIVER_ENTRY DriverEntry, PULONG Id );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| DriverEntry | PEFI_DRIVER_ENTRY | in | Pointeur vers une structure EFI_DRIVER_ENTRY décrivant le pilote UEFI à enregistrer (FriendlyName, DriverFilePath, attributs). |
| Id | PULONG | out | Reçoit l'identifiant attribué par le firmware — adossé à une variable NVRAM EFI `Driver####` sur les systèmes UEFI. |
IDs de syscalls par version de Windows
| Version de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x69 | win10-1507 |
| Win10 1607 | 0x69 | win10-1607 |
| Win10 1703 | 0x6A | win10-1703 |
| Win10 1709 | 0x6A | win10-1709 |
| Win10 1803 | 0x6A | win10-1803 |
| Win10 1809 | 0x6A | win10-1809 |
| Win10 1903 | 0x6A | win10-1903 |
| Win10 1909 | 0x6A | win10-1909 |
| Win10 2004 | 0x6B | win10-2004 |
| Win10 20H2 | 0x6B | win10-20h2 |
| Win10 21H1 | 0x6B | win10-21h1 |
| Win10 21H2 | 0x6B | win10-21h2 |
| Win10 22H2 | 0x6B | win10-22h2 |
| Win11 21H2 | 0x6B | win11-21h2 |
| Win11 22H2 | 0x6B | win11-22h2 |
| Win11 23H2 | 0x6B | win11-23h2 |
| Win11 24H2 | 0x6B | win11-24h2 |
| Server 2016 | 0x69 | winserver-2016 |
| Server 2019 | 0x6A | winserver-2019 |
| Server 2022 | 0x6B | winserver-2022 |
| Server 2025 | 0x6B | winserver-2025 |
Module noyau
APIs liées
Stub du syscall
4C 8B D1 mov r10, rcx B8 6B 00 00 00 mov eax, 0x6B F6 04 25 08 03 FE 7F 01 test byte ptr [0x7FFE0308], 1 75 03 jne short +3 0F 05 syscall C3 ret CD 2E int 2Eh C3 ret
Notes non documentées
EFI_DRIVER_ENTRY est structurellement identique à BOOT_ENTRY mais cible l'espace de noms UEFI **DriverOrder** plutôt que BootOrder. UEFI dispatche chaque variable `Driver####` listée dans `DriverOrder` pendant la phase DXE/BDS — *avant* que tout boot manager ne s'exécute. Le noyau atteint le firmware via `HalSetEnvironmentVariableEx` contre le GUID fournisseur `{8BE4DF61-93CA-11d2-AA0D-00E098032B8C}`. SeSystemEnvironmentPrivilege requis et, sur la plupart des firmwares OEM, l'écriture de variable exige aussi que Secure Boot soit désactivé ou accepte la signature du binaire.
Usage courant par les malwares
Encore plus dangereux que la persistance par boot-entry : un pilote UEFI s'exécute dans le **contexte EFI Boot Services**, dans l'environnement firmware CPL0 à mémoire plate, **avant ExitBootServices**, avant que le noyau Windows ne soit chargé, et donc avant PatchGuard, DSE, HVCI ou tout EDR. C'est le vecteur de persistance choisi par MosaicRegressor / LoJax (APT28) qui a enregistré un pilote DXE malveillant via `SetVariable`, et par MoonBounce (APT41) qui a implanté du code dans CORE_DXE. ESPecter et l'implant SPI CosmicStrand persistent en fin de compte aussi comme pilotes DXE. Une DRIVER_ENTRY enregistrée avec succès donne aux attaquants une exécution de code pré-OS permanente qui survit à un wipe de disque et à une réinstallation Windows.
Opportunités de détection
ETW Microsoft-Windows-Kernel-Boot journalise les changements DRIVER_ENTRY au même titre que BOOT_ENTRY. Le contrôle à plus haute valeur unique est **Measured Boot + attestation distante** : chaque pilote DXE UEFI dispatché étend PCR[2], donc un hash de pilote inédit fera échouer l'attestation par rapport à la baseline enregistrée de l'appareil. `tools.uefi.scan_image` et `common.bios_kbrd_buffer` de CHIPSEC ainsi que la surveillance firmware d'Eclypsium détectent les binaires DXE corrompus sur disque. Windows lui-même journalise l'Event ID 1035 (Microsoft-Windows-TPM-WMI) sur les mismatchs PCR quand la récupération BitLocker se déclenche. Auditer 4673 sur l'usage de SeSystemEnvironmentPrivilege pour attraper l'étape de staging en OS.
Exemples de syscalls directs
asmx64 direct stub (Win11 24H2, SSN 0x6B)
NtAddDriverEntry PROC
mov r10, rcx ; PEFI_DRIVER_ENTRY
mov eax, 6Bh ; Win11 24H2
syscall
ret
NtAddDriverEntry ENDPcRegister a DXE driver (defensive analysis only)
// Structurally mirrors NtAddBootEntry but targets DriverOrder.
// Practical use requires SeSystemEnvironmentPrivilege and Secure Boot bypass / disable.
extern NTSTATUS NTAPI NtAddDriverEntry(PEFI_DRIVER_ENTRY, PULONG);
NTSTATUS plant_driver(void) {
BYTE buf[512] = {0};
PEFI_DRIVER_ENTRY de = (PEFI_DRIVER_ENTRY)buf;
de->Version = 1;
de->Length = sizeof(buf);
de->Attributes = 0;
de->FriendlyNameOffset = FIELD_OFFSET(EFI_DRIVER_ENTRY, OsOptions);
wcscpy_s((wchar_t*)(buf + de->FriendlyNameOffset), 32, L"Diagnostic DXE");
ULONG id = 0;
return NtAddDriverEntry(de, &id);
}rustNaked stub
use std::arch::asm;
#[unsafe(naked)]
unsafe extern "system" fn nt_add_driver_entry(_entry: *mut u8, _id: *mut u32) -> i32 {
asm!(
"mov r10, rcx",
"mov eax, 0x6B", // Win11 24H2
"syscall",
"ret",
options(noreturn),
);
}Mappings MITRE ATT&CK
Last verified: 2026-05-20