> Windows Syscalls
ntoskrnl.exeT1497T1106

NtQueryBootOptions

Liest den BCD-Boot-Optionen-Blob des Systems — Debug-Flags, OS-Load-Options, Hypervisor-Einstellungen, Test-Signing.

Prototyp

NTSTATUS NtQueryBootOptions(
  PBOOT_OPTIONS BootOptions,
  PULONG        BootOptionsLength
);

Argumente

NameTypeDirDescription
BootOptionsPBOOT_OPTIONSoutVom Aufrufer bereitgestellte BOOT_OPTIONS-Struktur (variable Länge), die die aktuellen Boot-Optionen empfängt.
BootOptionsLengthPULONGin/outEingang: Kapazität in Bytes. Ausgang: geschriebene Bytes; STATUS_BUFFER_TOO_SMALL liefert die nötige Größe.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070x129win10-1507
Win10 16070x12Fwin10-1607
Win10 17030x134win10-1703
Win10 17090x136win10-1709
Win10 18030x138win10-1803
Win10 18090x139win10-1809
Win10 19030x13Awin10-1903
Win10 19090x13Awin10-1909
Win10 20040x140win10-2004
Win10 20H20x140win10-20h2
Win10 21H10x140win10-21h1
Win10 21H20x141win10-21h2
Win10 22H20x141win10-22h2
Win11 21H20x147win11-21h2
Win11 22H20x149win11-22h2
Win11 23H20x149win11-23h2
Win11 24H20x14Bwin11-24h2
Server 20160x12Fwinserver-2016
Server 20190x139winserver-2019
Server 20220x146winserver-2022
Server 20250x14Bwinserver-2025

Kernel-Modul

ntoskrnl.exeNtQueryBootOptions

Verwandte APIs

NtSetBootOptionsNtQueryBootEntryOrderNtEnumerateBootEntriesbcdedit /enum {current}

Syscall-Stub

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

Liefert den BOOT_OPTIONS-Blob, den der OS-Loader erfasst und in den laufenden Kernel weiterreicht. Die Struktur enthält Version, Length, Timeout, CurrentBootEntryId, NextBootEntryId und eine HeaderId, gefolgt von der Optionstext-Region. Beispiele für hier vorkommende Strings: `DEBUG`, `TESTSIGNING`, `HYPERVISORLAUNCHTYPE=AUTO`, `BOOTLOG`, `WINPE`, `NOEXECUTE=OPTIN`. Erfordert SeSystemEnvironmentPrivilege. Hauptsächlich verwendet von Recovery-/Setup-Tools und einigen defensiven Produkten, die erkennen wollen, ob der Host in einem entwicklerfreundlichen Boot-Modus läuft.

Häufige Malware-Nutzung

Geringes Offensiv-Signal. Manche Malware (insbesondere Anti-Analyse-Routinen in Commodity-Loadern) ruft dies auf, um debugger-freundliche Boot-Zustände (`DEBUG`, `TESTSIGNING`, `BOOTLOG`) zu erkennen und Verhalten abzubrechen oder zu ändern, um Sandbox-/Lab-Umgebungen auszuweichen. Das ist das dominante Missbrauchsmuster — Environmental Keying statt direkter Kompromittierung. Boot-Optionen zu lesen, eskaliert per se keine Privilegien und persistiert nicht.

Erkennungs­möglichkeiten

Das Volumen legitimer Aufrufe ist moderat (Recovery-Tools, OEM-Diagnose-Agenten, einige Endpoint-Schutzprodukte). ETW Microsoft-Windows-Kernel-General protokolliert den Zugriff. Das interessante Signal ist *Korrelation*: ein Binary, das gerade eskalierte, SeSystemEnvironmentPrivilege aktivierte und dann BootOptions unmittelbar vor der Entscheidung las, weitere Payload auszuliefern, ist die klassische Anti-Analyse-Form. Sandbox-Anbieter reagieren typischerweise mit Spoofing des zurückgegebenen Blobs, um `DEBUG`/`TESTSIGNING` unsichtbar zu machen.

Direkte Syscall-Beispiele

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtQueryBootOptions (SSN 0x14B, Win11 24H2)
NtQueryBootOptions PROC
    mov  r10, rcx
    mov  eax, 14Bh
    syscall
    ret
NtQueryBootOptions ENDP

cAnti-analysis: refuse to run under DEBUG/TESTSIGNING boot

// Demonstrative environmental-keying check used by commodity loaders.
// In production the loader fingerprints additional artefacts before deciding.
#pragma pack(push,4)
typedef struct _BOOT_OPTIONS {
    ULONG  Version;
    ULONG  Length;
    ULONG  Timeout;
    ULONG  CurrentBootEntryId;
    ULONG  NextBootEntryId;
    WCHAR  HeaderId[1]; // variable
} BOOT_OPTIONS, *PBOOT_OPTIONS;
#pragma pack(pop)

BOOLEAN was;
RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE, FALSE, &was);

UCHAR buf[1024];
ULONG len = sizeof(buf);
NTSTATUS s = NtQueryBootOptions((PBOOT_OPTIONS)buf, &len);
if (NT_SUCCESS(s)) {
    // Naive substring scan of the trailing options region.
    PCWSTR opts = (PCWSTR)(buf + sizeof(BOOT_OPTIONS));
    if (wcsstr(opts, L"DEBUG") || wcsstr(opts, L"TESTSIGNING")) {
        ExitProcess(0); // bail — looks like an analyst's machine
    }
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20