NtAccessCheckByTypeResultList
Effectue un contrôle d'accès typé renvoyant une liste de résultats par type d'objet, sans écrire d'événements d'audit.
Prototype
NTSTATUS NtAccessCheckByTypeResultList( PSECURITY_DESCRIPTOR SecurityDescriptor, PSID PrincipalSelfSid, HANDLE ClientToken, ACCESS_MASK DesiredAccess, POBJECT_TYPE_LIST ObjectTypeList, ULONG ObjectTypeListLength, PGENERIC_MAPPING GenericMapping, PPRIVILEGE_SET PrivilegeSet, PULONG PrivilegeSetLength, PACCESS_MASK GrantedAccessList, PNTSTATUS AccessStatusList );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| SecurityDescriptor | PSECURITY_DESCRIPTOR | in | Descripteur de sécurité de l'objet composite dont on contrôle les property sets. |
| PrincipalSelfSid | PSID | in | SID optionnel substitué à PRINCIPAL_SELF dans les ACE (utilisé sur les objets principaux Active Directory). |
| ClientToken | HANDLE | in | Jeton d'impersonation du client dont on évalue l'accès. |
| DesiredAccess | ACCESS_MASK | in | Droits d'accès à évaluer contre chaque entrée de ObjectTypeList. |
| ObjectTypeList | POBJECT_TYPE_LIST | in | Liste aplatie en arbre de types d'objets (objet + property sets + propriétés) — le contrôle s'exécute une fois par entrée. |
| ObjectTypeListLength | ULONG | in | Nombre d'entrées dans ObjectTypeList. Dimensionne aussi GrantedAccessList et AccessStatusList. |
| GenericMapping | PGENERIC_MAPPING | in | Mapping par type d'objet de GENERIC_* vers les droits spécifiques. |
| PrivilegeSet | PPRIVILEGE_SET | in/out | Reçoit les privilèges utilisés par le contrôle (ex. SE_SECURITY_NAME pour l'accès SACL). |
| PrivilegeSetLength | PULONG | in/out | En entrée, taille du buffer PrivilegeSet ; en sortie, octets requis / utilisés. |
| GrantedAccessList | PACCESS_MASK | out | Tableau de ObjectTypeListLength masques d'accès, un par entrée de la liste, indiquant les droits accordés à chaque niveau. |
| AccessStatusList | PNTSTATUS | out | Tableau de ObjectTypeListLength valeurs NTSTATUS — STATUS_SUCCESS ou STATUS_ACCESS_DENIED par entrée. |
IDs de syscalls par version de Windows
| Version de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x64 | win10-1507 |
| Win10 1607 | 0x64 | win10-1607 |
| Win10 1703 | 0x64 | win10-1703 |
| Win10 1709 | 0x64 | win10-1709 |
| Win10 1803 | 0x64 | win10-1803 |
| Win10 1809 | 0x64 | win10-1809 |
| Win10 1903 | 0x64 | win10-1903 |
| Win10 1909 | 0x64 | win10-1909 |
| Win10 2004 | 0x64 | win10-2004 |
| Win10 20H2 | 0x64 | win10-20h2 |
| Win10 21H1 | 0x64 | win10-21h1 |
| Win10 21H2 | 0x64 | win10-21h2 |
| Win10 22H2 | 0x64 | win10-22h2 |
| Win11 21H2 | 0x64 | win11-21h2 |
| Win11 22H2 | 0x64 | win11-22h2 |
| Win11 23H2 | 0x64 | win11-23h2 |
| Win11 24H2 | 0x64 | win11-24h2 |
| Server 2016 | 0x64 | winserver-2016 |
| Server 2019 | 0x64 | winserver-2019 |
| Server 2022 | 0x64 | winserver-2022 |
| Server 2025 | 0x64 | winserver-2025 |
Module noyau
APIs liées
Stub du syscall
4C 8B D1 mov r10, rcx B8 64 00 00 00 mov eax, 0x64 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
Comme NtAccessCheckByType mais renvoie un *vecteur* de décisions d'accès — une entrée par élément ObjectTypeList — au lieu d'un verdict composite unique. Le cas d'usage canonique est Active Directory : une seule tentative de lecture d'un objet utilisateur peut requérir simultanément l'évaluation de l'objet lui-même et de plusieurs ACE de property sets (ex. Personal-Information, Public-Information, Account-Restrictions). La liste de résultats permet à l'appelant de signaler exactement quel property set a été refusé. Le SSN `0x64` est stable sur toutes les builds Windows supportées depuis 1507. Aucun effet de bord d'émission d'audit — combiner avec NtAccessCheckByTypeResultListAndAuditAlarm quand la SACL exige la journalisation.
Usage courant par les malwares
Pratiquement nulle. La fonction est consommée par LSASS, NTDS et les composants SAM/AD-aware ; les malwares grand public n'ont aucune raison d'effectuer des contrôles ACL structurés à la AD. L'angle malware est inverse : les attaquants interrogent les ACL AD (BloodHound, PowerView) pour *éviter* des opérations qui déclencheraient des contrôles audit-alarm ailleurs.
Opportunités de détection
Sur un contrôleur de domaine, le débit d'appels est dominé par ntdsa.dll dans lsass.exe. Tout appelant anormal (autre que {lsass.exe, services.exe, un service AD signé MS}) mérite signalement via ETW Microsoft-Windows-Kernel-Audit-API-Calls. Sur poste de travail, l'appel est rare hors des chemins de validation d'identifiants LSASS ; des images peu communes l'appelant méritent investigation.
Exemples de syscalls directs
asmx64 direct stub
; Direct syscall stub for NtAccessCheckByTypeResultList (SSN 0x64, Win10 1507+)
NtAccessCheckByTypeResultList PROC
mov r10, rcx ; syscall convention
mov eax, 64h ; SSN
syscall
ret
NtAccessCheckByTypeResultList ENDPcPer-property-set decision (AD-style)
// Evaluate read access against an AD user object plus two property sets.
OBJECT_TYPE_LIST otl[3] = {
{ ACCESS_OBJECT_GUID, 0, &GUID_USER_OBJECT }, // level 0
{ ACCESS_PROPERTY_SET_GUID, 0, &GUID_PERSONAL_INFO }, // level 1
{ ACCESS_PROPERTY_SET_GUID, 0, &GUID_PUBLIC_INFO }, // level 1
};
ACCESS_MASK granted[3] = {0};
NTSTATUS statuses[3] = {0};
PRIVILEGE_SET privs;
ULONG privs_len = sizeof privs;
NTSTATUS rc = NtAccessCheckByTypeResultList(
pSd, NULL, hClientToken,
READ_CONTROL | ADS_RIGHT_DS_READ_PROP,
otl, ARRAYSIZE(otl),
&g_DsGenericMapping,
&privs, &privs_len,
granted, statuses);
// Inspect statuses[0..2] to report which property set was denied.Mappings MITRE ATT&CK
Last verified: 2026-05-20