> Windows Syscalls
ntoskrnl.exeT1112T1547.001T1106

NtRenameKey

Renomme une clé de registre existante en place — pas de wrapper Win32, accessible uniquement via l'API NT.

Prototype

NTSTATUS NtRenameKey(
  HANDLE          KeyHandle,
  PUNICODE_STRING NewName
);

Arguments

NameTypeDirDescription
KeyHandleHANDLEinHandle vers la clé à renommer, ouverte avec l'accès KEY_WRITE.
NewNamePUNICODE_STRINGinNouveau nom de feuille (pas un chemin). Ne doit pas contenir d'antislash et doit être unique parmi ses voisins.

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x158win10-1507
Win10 16070x15Fwin10-1607
Win10 17030x165win10-1703
Win10 17090x168win10-1709
Win10 18030x16Awin10-1803
Win10 18090x16Bwin10-1809
Win10 19030x16Cwin10-1903
Win10 19090x16Cwin10-1909
Win10 20040x172win10-2004
Win10 20H20x172win10-20h2
Win10 21H10x172win10-21h1
Win10 21H20x174win10-21h2
Win10 22H20x174win10-22h2
Win11 21H20x17Cwin11-21h2
Win11 22H20x17Fwin11-22h2
Win11 23H20x17Fwin11-23h2
Win11 24H20x181win11-24h2
Server 20160x15Fwinserver-2016
Server 20190x16Bwinserver-2019
Server 20220x17Awinserver-2022
Server 20250x181winserver-2025

Module noyau

ntoskrnl.exeNtRenameKey

APIs liées

NtSetValueKeyNtSaveKeyNtRestoreKeyRegRenameKey (no Win32 export — emulated)

Stub du syscall

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

NtRenameKey n'est pas documenté sur MSDN — Win32 n'expose aucun équivalent et Reflection.RegistryKey ne peut pas l'atteindre. L'opération est atomique dans CmRenameKey, qui appelle CmpDuplicateKeyValueInformation sur un KCB fraîchement créé puis détache l'ancien nom de la HHIVE du parent. Verrous tenus : HiveLock + verrou KCB du parent. Renvoie STATUS_OBJECT_NAME_COLLISION si un voisin avec NewName existe déjà.

Usage courant par les malwares

Rare en offensif. La niche plausible est l'*évasion d'allowlist* : les schémas de persistance qui font tourner le nom d'une valeur `Run` (ou le nom d'une clé sous `Image File Execution Options`) pour contourner des allowlists défenseurs qui cherchent des noms précis. On peut aussi l'utiliser pour renommer temporairement une clé liée à la sécurité pendant qu'une autre modification est en cours puis la renommer en arrière — mais ce motif se fait plus proprement avec NtSaveKey/NtRestoreKey. Signal honnête : la plupart des rapports publics de rotation registre utilisent NtSetValueKey pour changer un nom de valeur plutôt que NtRenameKey sur la clé elle-même.

Opportunités de détection

Bruit de fond réellement faible — pratiquement aucun logiciel légitime n'appelle NtRenameKey. ETW Microsoft-Windows-Kernel-Registry émet un événement de tâche RenameKey. Sysmon Event 12 (RegistryEvent CreateKey/DeleteKey) ne distingue pas proprement les renommages — cela apparaît comme un DeleteKey sur l'ancien chemin suivi d'un CreateKey sur le nouveau, avec le même KCB. CmRegisterCallbackEx livre RegNtPreRenameKey / RegNtPostRenameKey, ce qui est le point de hook le plus propre. Un seul RenameKey sous HKLM\SYSTEM\CurrentControlSet\Services ou HKLM\Software\Microsoft\Windows\CurrentVersion\Run mérite toujours enquête.

Exemples de syscalls directs

cRotate a Run subkey name

// Rotate the leaf name of HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Updater
// to evade trivial 'name == Updater' allowlists.
UNICODE_STRING newName;
RtlInitUnicodeString(&newName, L"WindowsUpdateHelper");
NTSTATUS st = NtRenameKey(hRunSubkey, &newName);
if (st == STATUS_OBJECT_NAME_COLLISION) {
    // sibling exists — pick a different rotated name
}

asmx64 direct stub (Win11 24H2 SSN 0x181)

NtRenameKey PROC
    mov  r10, rcx
    mov  eax, 181h
    syscall
    ret
NtRenameKey ENDP

rustntapi binding

// Cargo: ntapi = "0.4", widestring = "1"
let name = U16CString::from_str("WindowsUpdateHelper")?;
let mut us = UNICODE_STRING {
    Length: (name.len() * 2) as u16,
    MaximumLength: ((name.len() + 1) * 2) as u16,
    Buffer: name.as_ptr() as _,
};
let status = unsafe { NtRenameKey(h_key, &mut us) };

Mappings MITRE ATT&CK

Last verified: 2026-05-20