> Windows Syscalls
ntoskrnl.exeT1542.003T1542T1106

NtModifyBootEntry

Ersetzt einen vorhandenen BOOT_ENTRY in der BCD durch einen neuen Deskriptor, identifiziert über seine ID.

Prototyp

NTSTATUS NtModifyBootEntry(
  PBOOT_ENTRY BootEntry
);

Argumente

NameTypeDirDescription
BootEntryPBOOT_ENTRYinZeiger auf einen BOOT_ENTRY, dessen `Id`-Feld den zu überschreibenden Eintrag auswählt. Der Rest der Struktur wird zum neuen Inhalt.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070x102win10-1507
Win10 16070x107win10-1607
Win10 17030x10Bwin10-1703
Win10 17090x10Cwin10-1709
Win10 18030x10Ewin10-1803
Win10 18090x10Fwin10-1809
Win10 19030x110win10-1903
Win10 19090x110win10-1909
Win10 20040x115win10-2004
Win10 20H20x115win10-20h2
Win10 21H10x115win10-21h1
Win10 21H20x116win10-21h2
Win10 22H20x116win10-22h2
Win11 21H20x11Cwin11-21h2
Win11 22H20x11Dwin11-22h2
Win11 23H20x11Dwin11-23h2
Win11 24H20x11Fwin11-24h2
Server 20160x107winserver-2016
Server 20190x10Fwinserver-2019
Server 20220x11Bwinserver-2022
Server 20250x11Fwinserver-2025

Kernel-Modul

ntoskrnl.exeNtModifyBootEntry

Verwandte APIs

BcdSetElementData (bcd.dll)bcdedit.exe /set {bootmgr} pathSetFirmwareEnvironmentVariableWNtAddBootEntryNtDeleteBootEntryNtEnumerateBootEntriesNtSetBootEntryOrder

Syscall-Stub

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

Undokumentierte Hinweise

Anders als NtAddBootEntry hat NtModifyBootEntry keinen Ausgabeparameter `Id` — die ID ist der in der eingehenden BOOT_ENTRY eingebettete *Primärschlüssel*. Der Kernel findet den passenden Firmware-Eintrag (`Boot####`-EFI-Variable auf UEFI, Eintrag in der BCD-Hive auf BIOS) und überschreibt ihn atomar. SeSystemEnvironmentPrivilege erforderlich. Dasselbe opake `OsOptionsLength`-Blob wird übernommen, sodass beliebige BCD-Elemente (BcdLibraryDevice_ApplicationDevice, BcdOSLoaderString_KernelPath usw.) in einem Rutsch gepatcht werden können.

Häufige Malware-Nutzung

Die heimlichste BCD-Persistenzvariante: statt einen *verdächtigen neuen* Eintrag hinzuzufügen, den Verteidiger in `bcdedit /enum` sehen würden, **mutiert die Malware den legitimen `{current}`-Windows-Booteintrag**, sodass dessen `path`-Element auf einen bösartigen bootmgr oder ein verkettetes EFI-Binary zeigt, das anschließend zum echten Loader zurückspringt. Der Nutzer sieht keinen zusätzlichen Menüpunkt; das System bootet einfach durch die Stage-0 des Angreifers. Diese Technik wird ESPecter zugeschrieben (modifiziert das vorhandene Windows-Boot-Manager-BCD-Objekt) sowie der `bcdedit /set {bootmgr} path`-Recon von TrickBoot. BlackLotus patcht ebenfalls den vorhandenen Eintrag, um BitLocker-Integritätsprüfungen vor dem Bootkit-Lauf zu deaktivieren.

Erkennungs­möglichkeiten

BCD-Modifikationen erzeugen dieselbe Telemetrie wie Ergänzungen: ETW Microsoft-Windows-Kernel-Boot, Registry-Deltas auf `HKLM\BCD00000000` und Audit-Event 4673 für SeSystemEnvironmentPrivilege. Insbesondere die Elemente `path`, `device` und `nx` der `{current}`- und `{bootmgr}`-Objekte gegen eine Goldbaseline vergleichen — jede Änderung außerhalb des Patch-Tuesday-Fensters ist verdächtig. Windows Defender Application Control (WDAC) kann den Aufruf nicht verhindern, doch die Durchsetzung von **Boot Integrity** über Measured Boot + einen Remote-Attestation-Dienst (Azure Attestation, Intune-Gerätezustand) erkennt Post-Boot-Drift, weil die TPM-Messungen PCR[4]/PCR[7] von der erwarteten Policy abweichen.

Direkte Syscall-Beispiele

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

NtModifyBootEntry PROC
    mov  r10, rcx          ; PBOOT_ENTRY (Id baked into the struct)
    mov  eax, 11Fh         ; Win11 24H2
    syscall
    ret
NtModifyBootEntry ENDP

cHijack the existing Windows entry path

// Conceptual: rewrite the {current} Windows entry so its bootmgr path becomes our shim.
// Read the existing entry via NtEnumerateBootEntries, mutate the FilePath, write back.
NTSTATUS hijack_current(ULONG id, const wchar_t* shim_path) {
    BYTE buf[1024] = {0};
    PBOOT_ENTRY be = (PBOOT_ENTRY)buf;
    be->Version = 1;
    be->Length  = sizeof(buf);
    be->Id      = id;                 // ID returned by NtEnumerateBootEntries
    be->Attributes = BOOT_ENTRY_ATTRIBUTE_ACTIVE;
    be->BootFilePathOffset = FIELD_OFFSET(BOOT_ENTRY, OsOptions);
    // Build a FILE_PATH(\EFI\evil\shim.efi) here ...
    return NtModifyBootEntry(be);
}

rustNaked stub

use std::arch::asm;

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

MITRE ATT&CK-Mappings

Last verified: 2026-05-20