> Windows Syscalls
ntoskrnl.exeT1562.002T1106

NtAccessCheckByTypeAndAuditAlarm

Effectue un contrôle d'accès typé et inscrit une entrée d'alarme d'audit dans le journal Sécurité.

Prototype

NTSTATUS NtAccessCheckByTypeAndAuditAlarm(
  PUNICODE_STRING       SubsystemName,
  PVOID                 HandleId,
  PUNICODE_STRING       ObjectTypeName,
  PUNICODE_STRING       ObjectName,
  PSECURITY_DESCRIPTOR  SecurityDescriptor,
  PSID                  PrincipalSelfSid,
  ACCESS_MASK           DesiredAccess,
  AUDIT_EVENT_TYPE      AuditType,
  ULONG                 Flags,
  POBJECT_TYPE_LIST     ObjectTypeList,
  ULONG                 ObjectTypeListLength,
  PGENERIC_MAPPING      GenericMapping,
  BOOLEAN               ObjectCreation,
  PACCESS_MASK          GrantedAccess,
  PNTSTATUS             AccessStatus,
  PBOOLEAN              GenerateOnClose
);

Arguments

NameTypeDirDescription
SubsystemNamePUNICODE_STRINGinIdentifie le sous-système qui effectue le contrôle, ex. L"Security" ou L"WinLogon". Enregistré dans l'événement d'audit.
HandleIdPVOIDinIdentifiant opaque fourni par l'appelant pour le handle objet contrôlé ; apparaît dans l'enregistrement d'audit pour corrélation.
ObjectTypeNamePUNICODE_STRINGinNom de type lisible (ex. L"File", L"RegistryKey") journalisé dans l'événement d'audit.
ObjectNamePUNICODE_STRINGinNom d'instance d'objet à enregistrer dans l'événement d'audit, ex. le chemin du fichier.
SecurityDescriptorPSECURITY_DESCRIPTORinDescripteur de sécurité de l'objet cible ; la SACL pilote la génération d'audit.
PrincipalSelfSidPSIDinSID optionnel substitué au placeholder PRINCIPAL_SELF quand l'objet représente un principal (ex. un objet utilisateur AD).
DesiredAccessACCESS_MASKinDroits d'accès demandés par l'appelant, confrontés à la DACL.
AuditTypeAUDIT_EVENT_TYPEinAuditEventObjectAccess ou AuditEventDirectoryServiceAccess — sélectionne la catégorie d'audit.
FlagsULONGinRéservé / modificateurs de comportement (ex. AUDIT_ALLOW_NO_PRIVILEGE).
ObjectTypeListPOBJECT_TYPE_LISTinListe hiérarchique de types d'objets (ex. objet AD + property sets) sur lesquels porte le contrôle d'accès.
ObjectTypeListLengthULONGinNombre d'entrées dans ObjectTypeList.
GenericMappingPGENERIC_MAPPINGinMapping par type d'objet de GENERIC_READ/WRITE/EXECUTE/ALL vers les droits spécifiques.
ObjectCreationBOOLEANinTRUE si le contrôle concerne une création d'objet (journalisé en CreateObject), FALSE pour l'ouverture d'un objet existant.
GrantedAccessPACCESS_MASKoutReçoit le masque de bits des droits d'accès réellement accordés.
AccessStatusPNTSTATUSoutSTATUS_SUCCESS si l'accès est accordé, STATUS_ACCESS_DENIED sinon. La valeur de retour de la fonction indique la validité de l'appel, pas la décision d'accès.
GenerateOnClosePBOOLEANoutMis à TRUE quand le noyau veut aussi un événement d'audit à la fermeture du handle ; l'appelant doit le retenir et appeler NtCloseObjectAuditAlarm plus tard.

IDs de syscalls par version de Windows

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

Module noyau

ntoskrnl.exeNtAccessCheckByTypeAndAuditAlarm

APIs liées

AccessCheckByTypeAndAuditAlarmWAccessCheckByTypeResultListAndAuditAlarmWNtAccessCheckByTypeNtAccessCheckAndAuditAlarmNtCloseObjectAuditAlarmNtDeleteObjectAuditAlarm

Stub du syscall

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

Variante journalisée d'audit de NtAccessCheckByType. La variante sans alarme renvoie la décision d'accès et s'arrête ; celle-ci écrit en plus une entrée d'audit dans le journal Sécurité si la SACL de l'objet le demande (ou si AuditType + Flags le forcent). La fonction exige SeAuditPrivilege — seuls les appelants qui le détiennent (LSASS, le Security Reference Monitor, les sous-systèmes kernel-mode) peuvent l'utiliser utilement. Le SSN est stable à `0x59` depuis Windows 10 1507, ce qui est inhabituel mais cohérent avec le fait que tous les syscalls `*AuditAlarm` précèdent les renumérotations post-1909.

Usage courant par les malwares

Négligeable. Par conception, chaque appel réussi produit une entrée dans le journal Sécurité — l'inverse de ce que veut la plupart des malwares. Les rares occurrences en environnement réel sont LSASS faisant son travail (comportement légitime de `lsass.exe` lors des décisions d'accès aux objets AD). Aucune famille grand public n'est connue pour en abuser. L'angle défensif intéressant est l'*absence* d'appels d'audit-alarm attendus lorsqu'un objet sous SACL est touché, signe possible que l'attaquant a altéré la SACL ou le chemin de dispatch côté SRM.

Opportunités de détection

Ces appels *sont* le journal Sécurité pour l'accès aux objets. Les Event IDs 4656 (handle demandé), 4658 (handle fermé), 4660 (objet supprimé), 4663 (tentative d'accès), 4690 (handle dupliqué) remontent tous à la famille NtAccessCheck*AuditAlarm + NtCloseObjectAuditAlarm + NtDeleteObjectAuditAlarm. Les défenseurs doivent s'assurer que les SACL sur les objets de grande valeur (processus LSASS, contextes de nommage AD, magasin des clés maîtres DPAPI) sont configurées pour déclencher des contrôles audit-alarm, et traiter l'absence d'événements attendus comme un signal de tampering. Le provider ETW Microsoft-Windows-Security-Auditing porte les mêmes données avec plus de détail que le canal Eventlog hérité.

Exemples de syscalls directs

asmx64 direct stub

; Direct syscall stub for NtAccessCheckByTypeAndAuditAlarm (SSN 0x59, Win10 1507+)
; 16 args -> 4 in regs + 12 on stack per x64 calling convention.
NtAccessCheckByTypeAndAuditAlarm PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 59h          ; SSN
    syscall
    ret
NtAccessCheckByTypeAndAuditAlarm ENDP

cLSASS-style audited check (illustrative)

// Sketch of how a SACL-monitored AD object access is dispatched inside LSASS.
// In production this is reached through AccessCheckByTypeAndAuditAlarmW;
// shown here against the Nt-level for clarity.

UNICODE_STRING subsystem = RTL_CONSTANT_STRING(L"Security");
UNICODE_STRING objectType = RTL_CONSTANT_STRING(L"DS-Object");
UNICODE_STRING objectName = RTL_CONSTANT_STRING(L"CN=Administrator,CN=Users,DC=contoso,DC=com");
ACCESS_MASK granted = 0;
NTSTATUS access_status = STATUS_ACCESS_DENIED;
BOOLEAN gen_on_close = FALSE;

NTSTATUS s = NtAccessCheckByTypeAndAuditAlarm(
    &subsystem,
    (PVOID)hHandleId,
    &objectType,
    &objectName,
    pSd,
    NULL,
    READ_CONTROL | ADS_RIGHT_DS_READ_PROP,
    AuditEventDirectoryServiceAccess,
    0,
    pObjectTypeList, objectTypeListCount,
    &g_DsGenericMapping,
    FALSE,
    &granted,
    &access_status,
    &gen_on_close);

// On STATUS_SUCCESS, the SRM emitted Event 4662 ("An operation was performed on an
// object") into the Security log. If gen_on_close==TRUE remember to call
// NtCloseObjectAuditAlarm when releasing the handle.

rustwindows-sys typed-access audit (advapi32 wrapper)

// The public Win32 wrapper is AccessCheckByTypeAndAuditAlarmW.
// windows-sys exposes it under Win32::Security::Authorization.
use windows_sys::Win32::Security::Authorization::AccessCheckByTypeAndAuditAlarmW;
use windows_sys::Win32::Security::*;
use windows_sys::core::PCWSTR;

unsafe {
    let mut granted: u32 = 0;
    let mut access_status: i32 = 0;
    let mut gen_on_close: i32 = 0;
    let rc = AccessCheckByTypeAndAuditAlarmW(
        windows_sys::w!("Security"),
        handle_id as *mut _,
        windows_sys::w!("DS-Object"),
        windows_sys::w!("CN=Administrator,..."),
        sd_ptr,
        std::ptr::null_mut(),
        desired_access,
        object_type_list.as_ptr(),
        object_type_list.len() as u32,
        0, // ObjectCreation == FALSE
        &mut granted,
        &mut access_status,
        &mut gen_on_close,
    );
    // rc != 0 means the *call* succeeded; access_status == 0 means it was granted.
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20