> Windows Syscalls
ntoskrnl.exeT1112T1547.001T1106

NtRenameKey

Benennt einen bestehenden Registry-Schlüssel an Ort und Stelle um — kein Win32-Wrapper, nur über die NT-API erreichbar.

Prototyp

NTSTATUS NtRenameKey(
  HANDLE          KeyHandle,
  PUNICODE_STRING NewName
);

Argumente

NameTypeDirDescription
KeyHandleHANDLEinHandle auf den umzubenennenden Schlüssel, geöffnet mit KEY_WRITE-Zugriff.
NewNamePUNICODE_STRINGinNeuer Blattname (kein Pfad). Darf keinen Backslash enthalten und muss unter Geschwistern eindeutig sein.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
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

Kernel-Modul

ntoskrnl.exeNtRenameKey

Verwandte APIs

NtSetValueKeyNtSaveKeyNtRestoreKeyRegRenameKey (no Win32 export — emulated)

Syscall-Stub

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

Undokumentierte Hinweise

NtRenameKey ist auf MSDN nicht dokumentiert — Win32 bietet kein Äquivalent und Reflection.RegistryKey kann es nicht erreichen. Die Operation läuft atomar in CmRenameKey, das CmpDuplicateKeyValueInformation auf einen frisch erzeugten KCB anwendet und anschließend den alten Namen aus dem HHIVE des Eltern-Knotens aushängt. Gehaltene Locks: HiveLock + KCB-Lock des Elternknotens. Liefert STATUS_OBJECT_NAME_COLLISION, falls ein Geschwister mit NewName bereits existiert.

Häufige Malware-Nutzung

In Offensive-Operationen selten. Die plausible Nische ist *Allowlist-Umgehung*: Persistenz-Schemata, die den Namen eines `Run`-Werts (oder eines Schlüssels unter `Image File Execution Options`) rotieren, um naive Defender-Allowlists zu schlagen, die auf konkrete Schlüsselnamen filtern. Auch nutzbar, um einen sicherheitsrelevanten Schlüssel temporär umzubenennen, während eine andere Änderung vorbereitet wird, und ihn dann zurück umzubenennen — sauberer geht das aber mit NtSaveKey/NtRestoreKey. Ehrliches Signal: die meisten öffentlichen Berichte zu Registry-Rotation nutzen NtSetValueKey zur Änderung eines Wertnamens, nicht NtRenameKey auf dem Schlüssel selbst.

Erkennungs­möglichkeiten

Tatsächlich geringes Hintergrundrauschen — kaum legitime Software ruft NtRenameKey auf. ETW Microsoft-Windows-Kernel-Registry liefert ein RenameKey-Task-Event. Sysmon Event 12 (RegistryEvent CreateKey/DeleteKey) trennt Renames nicht sauber — es erscheint als DeleteKey auf den alten Pfad gefolgt von CreateKey auf den neuen Pfad mit demselben KCB. CmRegisterCallbackEx liefert RegNtPreRenameKey / RegNtPostRenameKey — der sauberste Hookpunkt. Ein einzelnes RenameKey unter HKLM\SYSTEM\CurrentControlSet\Services oder HKLM\Software\Microsoft\Windows\CurrentVersion\Run sollte stets untersucht werden.

Direkte Syscall-Beispiele

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) };

MITRE ATT&CK-Mappings

Last verified: 2026-05-20