> Windows Syscalls
ntoskrnl.exeT1497T1106

NtQueryBootOptions

Reads the system's BCD boot options blob — debug flags, OS load options, hypervisor settings, test signing.

Prototype

NTSTATUS NtQueryBootOptions(
  PBOOT_OPTIONS BootOptions,
  PULONG        BootOptionsLength
);

Arguments

NameTypeDirDescription
BootOptionsPBOOT_OPTIONSoutCaller-allocated BOOT_OPTIONS structure (variable length) that receives the current boot options.
BootOptionsLengthPULONGin/outOn input: capacity in bytes. On output: bytes written; STATUS_BUFFER_TOO_SMALL returns the required size.

Syscall IDs by 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 module

ntoskrnl.exeNtQueryBootOptions

Related 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

Undocumented notes

Returns the BOOT_OPTIONS blob captured by the OS loader and surfaced into the running kernel. The structure includes Version, Length, Timeout, CurrentBootEntryId, NextBootEntryId, and an HeaderId followed by the option-string region. Examples of strings present here: `DEBUG`, `TESTSIGNING`, `HYPERVISORLAUNCHTYPE=AUTO`, `BOOTLOG`, `WINPE`, `NOEXECUTE=OPTIN`. Requires SeSystemEnvironmentPrivilege. Mostly used by recovery / setup tooling and by some defensive products that want to detect whether the host is running in a developer-friendly boot mode.

Common malware usage

Low offensive signal. Some malware (notably anti-analysis routines in commodity loaders) call this to detect debugger-friendly boot states (`DEBUG`, `TESTSIGNING`, `BOOTLOG`) and abort or modify behaviour to evade sandbox / lab environments. That is the dominant abuse pattern — environmental keying rather than direct compromise. Reading boot options does not itself escalate privilege or persist.

Detection opportunities

Volume of legitimate calls is moderate (recovery tooling, OEM diagnostic agents, some endpoint protection products). Microsoft-Windows-Kernel-General ETW logs the access. The interesting signal is *correlation*: a binary that just elevated, enabled SeSystemEnvironmentPrivilege, and then read BootOptions immediately before deciding whether to deploy further payload is the textbook anti-analysis shape. Sandbox vendors typically respond by spoofing the returned blob to make `DEBUG`/`TESTSIGNING` invisible.

Direct syscall examples

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