> Windows Syscalls
ntoskrnl.exeT1542.001T1014T1542.003

NtModifyDriverEntry

Écrase une EFI_DRIVER_ENTRY existante identifiée par son ID, en réécrivant la variable NVRAM UEFI Driver#### sur place.

Prototype

NTSTATUS NtModifyDriverEntry(
  PEFI_DRIVER_ENTRY DriverEntry
);

Arguments

NameTypeDirDescription
DriverEntryPEFI_DRIVER_ENTRYinPointeur vers une EFI_DRIVER_ENTRY dont le champ `Id` sélectionne l'entrée existante à écraser ; le reste de la structure remplace le contenu actuel.

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x103win10-1507
Win10 16070x108win10-1607
Win10 17030x10Cwin10-1703
Win10 17090x10Dwin10-1709
Win10 18030x10Fwin10-1803
Win10 18090x110win10-1809
Win10 19030x111win10-1903
Win10 19090x111win10-1909
Win10 20040x116win10-2004
Win10 20H20x116win10-20h2
Win10 21H10x116win10-21h1
Win10 21H20x117win10-21h2
Win10 22H20x117win10-22h2
Win11 21H20x11Dwin11-21h2
Win11 22H20x11Ewin11-22h2
Win11 23H20x11Ewin11-23h2
Win11 24H20x120win11-24h2
Server 20160x108winserver-2016
Server 20190x110winserver-2019
Server 20220x11Cwinserver-2022
Server 20250x120winserver-2025

Module noyau

ntoskrnl.exeNtModifyDriverEntry

APIs liées

SetFirmwareEnvironmentVariableW (Driver####)BcdSetElementData (Driver Entry GUID)NtAddDriverEntryNtDeleteDriverEntryNtEnumerateDriverEntries

Stub du syscall

4C 8B D1            mov r10, rcx
B8 20 01 00 00      mov eax, 0x120
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

Miroir de NtModifyBootEntry mais pour l'espace de noms UEFI `Driver####`. L'ID est la clé primaire à l'intérieur de l'EFI_DRIVER_ENTRY ; le noyau le résout, localise la variable firmware correspondante et la réécrit en un seul appel atomique SetVariable. SeSystemEnvironmentPrivilege obligatoire.

Usage courant par les malwares

Utilisé quand un pilote DXE OEM de diagnostic ou de mise à jour firmware existe déjà dans `DriverOrder`. Plutôt que d'enregistrer une nouvelle entrée (suspecte), le malware patche le `DriverFilePath` de l'entrée existante pour pointer vers un binaire `.efi` contrôlé par l'attaquant sur l'ESP, héritant du slot de l'OEM dans DriverOrder et de son FriendlyName plausible. C'est une des techniques documentées dans les analyses LoJax / MosaicRegressor où APT28 exploitait l'infrastructure firmware existante plutôt que de creuser une nouvelle entrée. Les défenseurs qui ne cherchent que les *ajouts* DRIVER_ENTRY inconnus manquent la mutation.

Opportunités de détection

La modification et l'ajout remontent tous deux sur ETW Microsoft-Windows-Kernel-Boot. Le signal diagnostique ici est la **dérive du contenu fichier** : les chemins `Driver####` enregistrés peuvent être énumérés et hachés ; un changement de hash sur disque d'un binaire DXE connu (sans mise à jour firmware signée correspondante de l'OEM) est une preuve haute confiance de détournement de `DriverFilePath`. Eclypsium, CHIPSEC et l'outillage Binarly baselinent tous les hashs des pilotes DXE ; Microsoft Defender for Endpoint remonte la télémétrie des pilotes UEFI sous les rapports « Boot driver and firmware ».

Exemples de syscalls directs

asmx64 direct stub (Win11 24H2, SSN 0x120)

NtModifyDriverEntry PROC
    mov  r10, rcx          ; PEFI_DRIVER_ENTRY (Id inside struct)
    mov  eax, 0120h        ; Win11 24H2
    syscall
    ret
NtModifyDriverEntry ENDP

cRedirect an OEM driver entry to a rogue ESP path

// Defensive analysis: shows the shape of what LoJax-style attackers do.
NTSTATUS hijack_driver(ULONG id, const wchar_t* shim) {
    BYTE buf[1024] = {0};
    PEFI_DRIVER_ENTRY de = (PEFI_DRIVER_ENTRY)buf;
    de->Version = 1;
    de->Length  = sizeof(buf);
    de->Id      = id;                  // existing OEM diagnostic driver
    de->Attributes = LOAD_OPTION_ACTIVE;
    de->BootFilePathOffset = FIELD_OFFSET(EFI_DRIVER_ENTRY, OsOptions);
    // populate FILE_PATH(shim) into buf[BootFilePathOffset..] (omitted)
    return NtModifyDriverEntry(de);
}

rustNaked stub

use std::arch::asm;

#[unsafe(naked)]
unsafe extern "system" fn nt_modify_driver_entry(_entry: *mut u8) -> i32 {
    asm!(
        "mov r10, rcx",
        "mov eax, 0x120",  // Win11 24H2
        "syscall",
        "ret",
        options(noreturn),
    );
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20