> Windows Syscalls
ntoskrnl.exeT1562.002T1106

NtAccessCheckByTypeAndAuditAlarm

Performs a typed access check and writes an audit-alarm entry to the Security event log.

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_STRINGinIdentifies the subsystem performing the check, e.g. L"Security" or L"WinLogon". Recorded in the audit event.
HandleIdPVOIDinCaller-supplied opaque identifier for the object handle being checked; appears in the audit record for correlation.
ObjectTypeNamePUNICODE_STRINGinHuman-readable type name (e.g. L"File", L"RegistryKey") logged in the audit event.
ObjectNamePUNICODE_STRINGinObject instance name to record in the audit event, e.g. the file path.
SecurityDescriptorPSECURITY_DESCRIPTORinSecurity descriptor of the target object; SACL drives audit generation.
PrincipalSelfSidPSIDinOptional SID substituted for the PRINCIPAL_SELF placeholder when the object represents a principal (e.g. a user object in AD).
DesiredAccessACCESS_MASKinAccess rights requested by the caller, mapped against the DACL.
AuditTypeAUDIT_EVENT_TYPEinAuditEventObjectAccess or AuditEventDirectoryServiceAccess — selects the audit category.
FlagsULONGinReserved / behavior modifiers (e.g. AUDIT_ALLOW_NO_PRIVILEGE).
ObjectTypeListPOBJECT_TYPE_LISTinHierarchical list of object types (e.g. for AD object + property sets) the access check is scoped over.
ObjectTypeListLengthULONGinNumber of entries in ObjectTypeList.
GenericMappingPGENERIC_MAPPINGinPer-object-type mapping of GENERIC_READ/WRITE/EXECUTE/ALL to specific rights.
ObjectCreationBOOLEANinTRUE if the check is for object creation (logged as CreateObject), FALSE for an open of an existing object.
GrantedAccessPACCESS_MASKoutReceives the bitmask of access rights actually granted.
AccessStatusPNTSTATUSoutSTATUS_SUCCESS if access was granted, STATUS_ACCESS_DENIED otherwise. The function's own return value reports validity of the call, not the access decision.
GenerateOnClosePBOOLEANoutSet to TRUE when the kernel wants an audit event also emitted when the handle is closed; the caller must remember it and call NtCloseObjectAuditAlarm later.

Syscall IDs by Windows version

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

Kernel module

ntoskrnl.exeNtAccessCheckByTypeAndAuditAlarm

Related APIs

AccessCheckByTypeAndAuditAlarmWAccessCheckByTypeResultListAndAuditAlarmWNtAccessCheckByTypeNtAccessCheckAndAuditAlarmNtCloseObjectAuditAlarmNtDeleteObjectAuditAlarm

Syscall stub

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

Undocumented notes

Audit-logged sibling of NtAccessCheckByType. The non-alarm variant returns the access decision and stops; this variant additionally writes an audit entry to the Security event log if the object's SACL requests it (or if the AuditType + Flags force it). The function holds the SeAuditPrivilege requirement — only callers with that privilege (LSASS, the Security Reference Monitor, kernel-mode subsystems) can usefully invoke it. The SSN has been stable at `0x59` since Windows 10 1507, which is unusual but consistent with the broader pattern that all `*AuditAlarm` syscalls predate the post-1909 reshuffles.

Common malware usage

Negligible. By design, every successful call produces a Security event log entry — which is the opposite of what most malware wants. The handful of in-the-wild references are LSASS pretending to be itself (i.e. legitimate behavior from `lsass.exe` during AD object access decisions). No commodity family is known to misuse it. The interesting defensive angle is the *absence* of expected audit-alarm calls when a SACL-monitored object is touched, which can indicate that an attacker has tampered with the SACL or with the SRM-side dispatch path.

Detection opportunities

These calls *are* the Security event log for object access. Event IDs 4656 (handle requested), 4658 (handle closed), 4660 (object deleted), 4663 (access attempt), 4690 (handle duplicated) all trace back to the NtAccessCheck*AuditAlarm family + NtCloseObjectAuditAlarm + NtDeleteObjectAuditAlarm. Defenders should ensure SACLs on high-value objects (LSASS process, Active Directory naming contexts, DPAPI master-key store) are configured to trigger AuditAlarm-flavored checks, and should treat absence of expected events as a tampering signal. ETW provider Microsoft-Windows-Security-Auditing carries the same data with more detail than the legacy Eventlog channel.

Direct syscall examples

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.
}

MITRE ATT&CK mappings

Last verified: 2026-05-20