> Windows Syscalls
ntoskrnl.exeT1068T1014T1562.001

NtSetSystemInformation

Generic kernel setter selected by SYSTEM_INFORMATION_CLASS — gateway to SystemDebugControl, GDI driver loading and more.

Prototype

NTSTATUS NtSetSystemInformation(
  SYSTEM_INFORMATION_CLASS SystemInformationClass,
  PVOID                    SystemInformation,
  ULONG                    SystemInformationLength
);

Arguments

NameTypeDirDescription
SystemInformationClassSYSTEM_INFORMATION_CLASSinEnum selecting the operation, e.g. SystemLoadGdiDriverInformation (26), SystemDebugControl (37), SystemRegistryQuotaInformation (37 set).
SystemInformationPVOIDinClass-specific input buffer (e.g. SYSTEM_GDI_DRIVER_INFORMATION, SYSTEM_LOAD_GDI_DRIVER_INFORMATION).
SystemInformationLengthULONGinSize in bytes of the SystemInformation buffer.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 15070x18Ewin10-1507
Win10 16070x197win10-1607
Win10 17030x19Dwin10-1703
Win10 17090x1A0win10-1709
Win10 18030x1A2win10-1803
Win10 18090x1A3win10-1809
Win10 19030x1A4win10-1903
Win10 19090x1A4win10-1909
Win10 20040x1AAwin10-2004
Win10 20H20x1AAwin10-20h2
Win10 21H10x1AAwin10-21h1
Win10 21H20x1ACwin10-21h2
Win10 22H20x1ACwin10-22h2
Win11 21H20x1B5win11-21h2
Win11 22H20x1B9win11-22h2
Win11 23H20x1B9win11-23h2
Win11 24H20x1BCwin11-24h2
Server 20160x197winserver-2016
Server 20190x1A3winserver-2019
Server 20220x1B2winserver-2022
Server 20250x1BCwinserver-2025

Kernel module

ntoskrnl.exeNtSetSystemInformation

Related APIs

NtQuerySystemInformationNtSystemDebugControlNtLoadDriverNtUnloadDriverSetSystemFileCacheSize

Syscall stub

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

Unlike most of its neighbours, the SSN for NtSetSystemInformation drifts on every feature release: `0x18E` on 1507, `0x1A4` on 1903/1909, `0x1AA` on 2004-21H1, `0x1AC` on 21H2/22H2, then `0x1B5`/`0x1B9`/`0x1BC` across Win11. Any hardcoded stub *must* be paired with a build check or dynamic resolution. The function is the write-side counterpart of NtQuerySystemInformation and is gated by access checks tied to the chosen `SYSTEM_INFORMATION_CLASS`: most classes require SeTcbPrivilege, SeLoadDriverPrivilege, or SeDebugPrivilege.

Common malware usage

Two notable abuses. (1) **`SystemLoadGdiDriverInformation` (26)** historically loaded a kernel-mode GDI driver from a caller-supplied UNICODE_STRING image path — the classic vector for unsigned/exploit-vulnerable driver loading prior to KMCS. Modern Windows blocks the unsigned path under HVCI/Vulnerable Driver Blocklist, but actors still call it as part of bring-your-own-vulnerable-driver (BYOVD) chains where the driver itself is signed. (2) **`SystemDebugControl` (37)** with sub-commands `SysDbgReadVirtual` / `SysDbgWriteVirtual` lets a caller holding `SeDebugPrivilege` read or write arbitrary kernel memory without ever loading a driver — used by some rootkits and red-team tooling for stealthy kernel patches when EDR has already neutered the obvious driver-load surface. Also occasionally seen tampering with `SystemRegistryQuotaInformation` to bloat the registry and disable Windows components that depend on quota limits.

TurlaRobbinHoodBlackByte (BYOVD via RTCore64.sys)Scattered Spider (BYOVD tooling)LazyScripter / FIN7 (BYOVD chains)

Detection opportunities

Calls to `NtSetSystemInformation` itself are uncommon outside the OS, so volume-based heuristics work. The single highest-value source is Microsoft-Windows-Kernel-General `ImageLoad` ETW combined with the kernel image-load notify callback (PsSetLoadImageNotifyRoutine), which fires whenever a kernel driver is loaded via class 26 — Defender Application Control and the Microsoft Vulnerable Driver Blocklist consume this to block known-bad drivers like `gdrv.sys`, `RTCore64.sys`, `dbutil_2_3.sys`. Audit `Audit Privilege Use` (Event ID 4673) for SeLoadDriverPrivilege and SeDebugPrivilege use, and watch for unexpected callers (non-System, non-services.exe) invoking NtSetSystemInformation. Direct-syscall callers cannot suppress the driver-load notification regardless of how clever the user-mode is.

Direct syscall examples

cBYOVD: load a signed-but-vulnerable driver via class 26

// SystemLoadGdiDriverInformation == 26
typedef struct _SYSTEM_GDI_DRIVER_INFORMATION {
    UNICODE_STRING DriverName;
    PVOID ImageAddress;
    PVOID SectionPointer;
    PVOID EntryPoint;
    PIMAGE_EXPORT_DIRECTORY ExportSectionPointer;
    ULONG ImageLength;
} SYSTEM_GDI_DRIVER_INFORMATION, *PSYSTEM_GDI_DRIVER_INFORMATION;

SYSTEM_GDI_DRIVER_INFORMATION info = {0};
RtlInitUnicodeString(&info.DriverName,
    L"\\??\\C:\\ProgramData\\vuln.sys");

// Caller must hold SeLoadDriverPrivilege (enabled, not just present).
NTSTATUS s = NtSetSystemInformation(
    26 /* SystemLoadGdiDriverInformation */,
    &info,
    sizeof(info));

asmDirect stub for Win11 24H2 (SSN 0x1BC)

; Build-pinned to Win11 24H2 / Server 2025. Use dynamic resolution
; (Hell's Gate / Halo's Gate / Tartarus' Gate) for portable stubs —
; this SSN moves on every feature update.
NtSetSystemInformation_24H2 PROC
    mov  r10, rcx
    mov  eax, 1BCh
    syscall
    ret
NtSetSystemInformation_24H2 ENDP

cKernel write via SystemDebugControl (privileged)

// SystemDebugControl == 37 (Set-variant accepts SysDbgWriteVirtual etc.)
typedef enum _SYSDBG_COMMAND {
    SysDbgReadVirtual  = 8,
    SysDbgWriteVirtual = 9,
} SYSDBG_COMMAND;

typedef struct _SYSDBG_VIRTUAL {
    PVOID Address;
    PVOID Buffer;
    ULONG Request;
} SYSDBG_VIRTUAL, *PSYSDBG_VIRTUAL;

// Enable SeDebugPrivilege first.
SYSDBG_VIRTUAL v = {
    .Address = (PVOID)0xfffff80000000000ULL, // kernel target
    .Buffer  = patchBytes,
    .Request = patchLen,
};
NtSystemDebugControl(SysDbgWriteVirtual, &v, sizeof(v), NULL, 0, NULL);
// (Note: ntoskrnl exposes both NtSystemDebugControl and SystemDebugControl
//  via NtSetSystemInformation; modern builds prefer the dedicated syscall.)

MITRE ATT&CK mappings

Last verified: 2026-05-20