NtSetSystemInformation
Generischer Kernel-Setter, ausgewählt über SYSTEM_INFORMATION_CLASS — Zugang zu SystemDebugControl, GDI-Treiberladen und mehr.
Prototyp
NTSTATUS NtSetSystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| SystemInformationClass | SYSTEM_INFORMATION_CLASS | in | Enum, der die Operation auswählt, z. B. SystemLoadGdiDriverInformation (26), SystemDebugControl (37), SystemRegistryQuotaInformation. |
| SystemInformation | PVOID | in | Klassenspezifischer Eingabepuffer (z. B. SYSTEM_GDI_DRIVER_INFORMATION, SYSTEM_LOAD_GDI_DRIVER_INFORMATION). |
| SystemInformationLength | ULONG | in | Größe des SystemInformation-Puffers in Bytes. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x18E | win10-1507 |
| Win10 1607 | 0x197 | win10-1607 |
| Win10 1703 | 0x19D | win10-1703 |
| Win10 1709 | 0x1A0 | win10-1709 |
| Win10 1803 | 0x1A2 | win10-1803 |
| Win10 1809 | 0x1A3 | win10-1809 |
| Win10 1903 | 0x1A4 | win10-1903 |
| Win10 1909 | 0x1A4 | win10-1909 |
| Win10 2004 | 0x1AA | win10-2004 |
| Win10 20H2 | 0x1AA | win10-20h2 |
| Win10 21H1 | 0x1AA | win10-21h1 |
| Win10 21H2 | 0x1AC | win10-21h2 |
| Win10 22H2 | 0x1AC | win10-22h2 |
| Win11 21H2 | 0x1B5 | win11-21h2 |
| Win11 22H2 | 0x1B9 | win11-22h2 |
| Win11 23H2 | 0x1B9 | win11-23h2 |
| Win11 24H2 | 0x1BC | win11-24h2 |
| Server 2016 | 0x197 | winserver-2016 |
| Server 2019 | 0x1A3 | winserver-2019 |
| Server 2022 | 0x1B2 | winserver-2022 |
| Server 2025 | 0x1BC | winserver-2025 |
Kernel-Modul
Verwandte APIs
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
Undokumentierte Hinweise
Anders als die meisten Nachbarn driftet die SSN von NtSetSystemInformation mit jedem Feature-Release: `0x18E` in 1507, `0x1A4` in 1903/1909, `0x1AA` in 2004-21H1, `0x1AC` in 21H2/22H2, dann `0x1B5`/`0x1B9`/`0x1BC` unter Win11. Jeder hartkodierte Stub *muss* mit Build-Prüfung oder dynamischer Auflösung kombiniert werden. Die Funktion ist das Schreibpendant zu NtQuerySystemInformation; die Zugriffskontrollen hängen von der gewählten `SYSTEM_INFORMATION_CLASS` ab: die meisten Klassen erfordern SeTcbPrivilege, SeLoadDriverPrivilege oder SeDebugPrivilege.
Häufige Malware-Nutzung
Zwei nennenswerte Missbräuche. (1) **`SystemLoadGdiDriverInformation` (26)** lud historisch einen Kernelmode-GDI-Treiber aus einem vom Aufrufer gelieferten UNICODE_STRING-Pfad — der klassische Vektor zum Laden unsignierter/verwundbarer Treiber vor KMCS. Modernes Windows blockt den unsignierten Pfad unter HVCI/Vulnerable Driver Blocklist, doch Akteure rufen ihn weiterhin in BYOVD-Ketten, in denen der Treiber selbst signiert ist. (2) **`SystemDebugControl` (37)** mit den Unterbefehlen `SysDbgReadVirtual` / `SysDbgWriteVirtual` erlaubt einem Aufrufer mit `SeDebugPrivilege` beliebigen Kernel-Speicher zu lesen oder zu schreiben — ohne einen Treiber zu laden. Wird von einigen Rootkits und Red-Team-Tools für leise Kernel-Patches genutzt, wenn das EDR die offensichtliche Treiber-Lade-Oberfläche bereits zugemacht hat. Manche Familien manipulieren auch `SystemRegistryQuotaInformation`, um die Registry aufzublähen und Windows-Komponenten, die von Quotas abhängen, lahmzulegen.
Erkennungsmöglichkeiten
Aufrufe von `NtSetSystemInformation` sind außerhalb des OS selten — Volumen-Heuristiken funktionieren. Die hochwertigste Quelle ist das ETW-Event `ImageLoad` von Microsoft-Windows-Kernel-General kombiniert mit dem Kernel-Callback PsSetLoadImageNotifyRoutine, der feuert, sobald via Klasse 26 ein Kernel-Treiber geladen wird — Defender Application Control und die Microsoft Vulnerable Driver Blocklist konsumieren ihn, um bekannte Treiber wie `gdrv.sys`, `RTCore64.sys`, `dbutil_2_3.sys` zu blocken. `Audit Privilege Use` (Event ID 4673) für SeLoadDriverPrivilege und SeDebugPrivilege auditieren, unerwartete Aufrufer (nicht System, nicht services.exe) von NtSetSystemInformation beobachten. Direkter Syscall-Aufruf kann die Treiber-Lade-Benachrichtigung unabhängig von der User-Mode-Cleverness nicht unterdrücken.
Direkte Syscall-Beispiele
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 ENDPcKernel 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