> Windows Syscalls
ntoskrnl.exeT1014T1622T1106

NtSystemDebugControl

Leitet Kerneldebugger-artige Anfragen weiter (Kernel-R/W, Control Space, Breakpoints, Profiler), ausgewählt über die SysDbgCommand-Enum.

Prototyp

NTSTATUS NtSystemDebugControl(
  SYSDBG_COMMAND Command,
  PVOID          InputBuffer,
  ULONG          InputBufferLength,
  PVOID          OutputBuffer,
  ULONG          OutputBufferLength,
  PULONG         ReturnLength
);

Argumente

NameTypeDirDescription
CommandSYSDBG_COMMANDinOperations-Selektor: SysDbgReadVirtual, SysDbgWriteVirtual, SysDbgReadPhysical, SysDbgWritePhysical, SysDbgReadControlSpace, SysDbgGetTriageDump, SysDbgBreakPoint usw.
InputBufferPVOIDinBefehlsspezifischer Eingabepuffer (üblicherweise ein SYSDBG_VIRTUAL- oder SYSDBG_PHYSICAL-Deskriptor mit Address/Buffer/Request).
InputBufferLengthULONGinGröße von InputBuffer in Bytes.
OutputBufferPVOIDoutBefehlsspezifischer Ausgabepuffer (z. B. empfängt Daten für SysDbgReadVirtual).
OutputBufferLengthULONGinGröße von OutputBuffer in Bytes.
ReturnLengthPULONGoutOptional. Erhält die Anzahl tatsächlich in OutputBuffer geschriebener Bytes.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070x1A1win10-1507
Win10 16070x1AAwin10-1607
Win10 17030x1B0win10-1703
Win10 17090x1B3win10-1709
Win10 18030x1B5win10-1803
Win10 18090x1B6win10-1809
Win10 19030x1B7win10-1903
Win10 19090x1B7win10-1909
Win10 20040x1BDwin10-2004
Win10 20H20x1BDwin10-20h2
Win10 21H10x1BDwin10-21h1
Win10 21H20x1BFwin10-21h2
Win10 22H20x1BFwin10-22h2
Win11 21H20x1C9win11-21h2
Win11 22H20x1CDwin11-22h2
Win11 23H20x1CDwin11-23h2
Win11 24H20x1D0win11-24h2
Server 20160x1AAwinserver-2016
Server 20190x1B6winserver-2019
Server 20220x1C5winserver-2022
Server 20250x1D0winserver-2025

Kernel-Modul

ntoskrnl.exeNtSystemDebugControl

Verwandte APIs

KdSystemDebugControlDebugActiveProcessNtSetDebugFilterStateNtQuerySystemInformationNtCreateDebugObject

Syscall-Stub

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

NtSystemDebugControl ist ein Multiplexer für debuggerartige Kerneloperationen. Die Command-Enum (SYSDBG_COMMAND / SysDbgCommand) wählt zwischen virtuellem/physikalischem Speicher lesen und schreiben, Control-Space-Zugriff, MSR-Lesen, Profiler-Steuerung, Breakpoint-Installation, Triage-Dump-Abruf und mehreren Legacy-Befehlen. *Entscheidend*: auf Free-/Retail-Builds hat Microsoft die wirklich mächtigen Befehle schrittweise eingeschränkt: SysDbgReadVirtual, SysDbgWriteVirtual, SysDbgReadPhysical und SysDbgWritePhysical liefern STATUS_NOT_IMPLEMENTED zurück, sofern das System nicht einen Debug-(Checked-)Kernel ausführt oder mit `/DEBUG` und aktivem Kernel-Debugger gestartet wurde. Auf einem normalen Win10-/Win11-Desktop sind diese Bytes wirkungslos. Der Aufrufer benötigt zusätzlich SeDebugPrivilege.

Häufige Malware-Nutzung

Historisch — Windows XP und frühes Vista — bot NtSystemDebugControl mit SysDbgReadVirtual/WriteVirtual eine saubere Userland-zu-Kernel-R/W-Primitive, die mehrere Rootkits ausnutzten. Rustock und der Kernel-Treiber von BlackEnergy 2 werden oft als Beispiele genannt; zahlreiche Forschungs-PoCs derselben Ära nutzten sie für SSDT-Patching und Manipulation an Kernelstrukturen. Seit Vista x64 + PatchGuard + Free-Build-Restriktion ist dieser Weg auf modernen Systemen praktisch geschlossen. Moderne Malware missbraucht NtSystemDebugControl nicht mehr für Kernel-R/W — der Pfad ist zu. Indirekte Nutzungen halten sich: SysDbgGetTriageDump kann von Anti-Analyse-Code aufgerufen werden, um die Anwesenheit eines Kernel-Debuggers oder aktiven Profilers zu erkennen.

Erkennungs­möglichkeiten

Auf einem modernen System ist *jeder* erfolgreiche Aufruf von NtSystemDebugControl aus einem Nicht-Debugger-Prozess verdächtig. ETW Microsoft-Windows-Kernel-Audit-API-Calls deckt die privilegierte Debugger-Oberfläche ab, und die Nutzung von SeDebugPrivilege erscheint in der Sicherheitsauditierung (Event ID 4673). EDR-seitig ntdll!NtSystemDebugControl hooken, den Befehl dekodieren und SysDbgReadVirtual / SysDbgWriteVirtual / SysDbgReadControlSpace / SysDbgReadMsr unabhängig vom Rückgabestatus als hochkonfidente Indikatoren behandeln. Aufrufe, die STATUS_NOT_IMPLEMENTED zurückliefern, sind selbst ein loggenswertes Sondierungssignal.

Direkte Syscall-Beispiele

asmx64 direct stub (Win11 24H2 SSN)

; Direct syscall stub for NtSystemDebugControl (SSN 0x1D0 on Win11 24H2 / Server 2025)
NtSystemDebugControl PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 1D0h         ; SSN for win11-24h2
    syscall
    ret
NtSystemDebugControl ENDP

cSysDbgReadVirtual sketch (gated on free builds)

// Read N bytes from a kernel virtual address.
// On a stock Win10/Win11 system this returns STATUS_NOT_IMPLEMENTED.
// Only works against a checked kernel or with the system booted /DEBUG.
typedef enum _SYSDBG_COMMAND {
    SysDbgReadVirtual           = 8,
    SysDbgWriteVirtual          = 9,
    SysDbgReadPhysical          = 10,
    SysDbgWritePhysical         = 11,
    SysDbgReadControlSpace      = 12,
    SysDbgGetTriageDump         = 29,
} SYSDBG_COMMAND;

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

// caller must have SeDebugPrivilege enabled
BYTE buf[16] = { 0 };
SYSDBG_VIRTUAL in = {
    .Address = (PVOID)0xfffff80000000000ULL,  // some kernel VA
    .Buffer  = buf,
    .Request = sizeof(buf),
};
ULONG returned = 0;
NTSTATUS s = NtSystemDebugControl(SysDbgReadVirtual,
                                  &in, sizeof(in),
                                  NULL, 0,
                                  &returned);
// On a free build: s == STATUS_NOT_IMPLEMENTED (0xC0000002).

rustwindows-sys + naked syscall stub

// Cargo: windows-sys = "0.59"
use std::arch::asm;

#[unsafe(naked)]
unsafe extern "system" fn nt_system_debug_control_stub() {
    asm!(
        "mov r10, rcx",
        "mov eax, 0x1D0",   // Win11 24H2; resolve dynamically for other builds
        "syscall",
        "ret",
        options(noreturn),
    );
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20