NtAddDriverEntry
Registers a new EFI_DRIVER_ENTRY in the firmware so the UEFI environment loads a driver before the OS.
Prototype
NTSTATUS NtAddDriverEntry( PEFI_DRIVER_ENTRY DriverEntry, PULONG Id );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| DriverEntry | PEFI_DRIVER_ENTRY | in | Pointer to an EFI_DRIVER_ENTRY structure describing the UEFI driver to register (FriendlyName, DriverFilePath, attributes). |
| Id | PULONG | out | Receives the firmware-assigned identifier — backed by an EFI `Driver####` NVRAM variable on UEFI systems. |
Syscall IDs by Windows version
| Windows version | Syscall ID | 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 |
Kernel module
Related APIs
Syscall stub
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
Undocumented notes
EFI_DRIVER_ENTRY is structurally identical to BOOT_ENTRY but addresses the UEFI **DriverOrder** namespace rather than BootOrder. UEFI dispatches every `Driver####` variable listed in `DriverOrder` during the DXE/BDS phase — *before* any boot manager runs. The kernel reaches the firmware via `HalSetEnvironmentVariableEx` against vendor GUID `{8BE4DF61-93CA-11d2-AA0D-00E098032B8C}`. SeSystemEnvironmentPrivilege is required and, on most OEM firmware, the variable write also requires Secure Boot to be either disabled or to accept the binary's signature.
Common malware usage
Even more dangerous than boot-entry persistence: a UEFI driver runs in **EFI Boot Services context**, in the firmware's flat-memory CPL0 environment, **before ExitBootServices**, before the Windows kernel loads, and therefore before PatchGuard, DSE, HVCI or any EDR has any execution. This is the persistence vector chosen by MosaicRegressor / LoJax (APT28) which registered a malicious DXE driver via `SetVariable`, and by MoonBounce (APT41) which planted code into CORE_DXE. ESPecter and the CosmicStrand SPI implant ultimately persist as DXE drivers as well. A successfully registered DRIVER_ENTRY gives attackers permanent pre-OS code execution that survives disk wipe and Windows reinstall.
Detection opportunities
ETW Microsoft-Windows-Kernel-Boot logs DRIVER_ENTRY changes alongside BOOT_ENTRY ones. The single highest-value control is **Measured Boot + remote attestation**: every UEFI DXE driver dispatched extends PCR[2], so a previously unseen driver hash will cause attestation to fail against the device's recorded baseline. CHIPSEC's `tools.uefi.scan_image` and `common.bios_kbrd_buffer` plus Eclypsium's firmware monitoring detect rogue DXE binaries on disk. Windows itself logs Event ID 1035 (Microsoft-Windows-TPM-WMI) on PCR mismatches when BitLocker recovery is triggered. Audit 4673 on SeSystemEnvironmentPrivilege use to catch the in-OS staging step.
Direct syscall examples
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),
);
}MITRE ATT&CK mappings
Last verified: 2026-05-20