> Windows Syscalls
ntoskrnl.exeT1562.002T1106

NtAccessCheckAndAuditAlarm

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

Prototype

NTSTATUS NtAccessCheckAndAuditAlarm(
  PUNICODE_STRING       SubsystemName,
  PVOID                 HandleId,
  PUNICODE_STRING       ObjectTypeName,
  PUNICODE_STRING       ObjectName,
  PSECURITY_DESCRIPTOR  SecurityDescriptor,
  ACCESS_MASK           DesiredAccess,
  PGENERIC_MAPPING      GenericMapping,
  BOOLEAN               ObjectCreation,
  PACCESS_MASK          GrantedAccess,
  PNTSTATUS             AccessStatus,
  PBOOLEAN              GenerateOnClose
);

Arguments

NameTypeDirDescription
SubsystemNamePUNICODE_STRINGinSubsystem identifier embedded in the resulting audit event.
HandleIdPVOIDinOpaque handle identifier the caller uses to correlate with subsequent close/delete audit events.
ObjectTypeNamePUNICODE_STRINGinObject type display name, e.g. L"File", L"RegistryKey", L"Section".
ObjectNamePUNICODE_STRINGinObject instance name (path, kernel-object name) recorded in the audit event.
SecurityDescriptorPSECURITY_DESCRIPTORinSelf-relative security descriptor with the DACL (access) and SACL (audit) to evaluate.
DesiredAccessACCESS_MASKinAccess bits the caller wants on the object (e.g. FILE_GENERIC_READ).
GenericMappingPGENERIC_MAPPINGinObject-type's generic-rights mapping (GENERIC_READ/WRITE/EXECUTE/ALL -> specific rights).
ObjectCreationBOOLEANinTRUE if the check is for creation (logged as create), FALSE for opening an existing object.
GrantedAccessPACCESS_MASKoutReceives the bitmask of access actually granted to the caller.
AccessStatusPNTSTATUSoutSTATUS_SUCCESS on grant, STATUS_ACCESS_DENIED otherwise. Function return value reports validity of the call only.
GenerateOnClosePBOOLEANoutTRUE if the caller must later invoke NtCloseObjectAuditAlarm to emit a matching 4658.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 15070x29win10-1507
Win10 16070x29win10-1607
Win10 17030x29win10-1703
Win10 17090x29win10-1709
Win10 18030x29win10-1803
Win10 18090x29win10-1809
Win10 19030x29win10-1903
Win10 19090x29win10-1909
Win10 20040x29win10-2004
Win10 20H20x29win10-20h2
Win10 21H10x29win10-21h1
Win10 21H20x29win10-21h2
Win10 22H20x29win10-22h2
Win11 21H20x29win11-21h2
Win11 22H20x29win11-22h2
Win11 23H20x29win11-23h2
Win11 24H20x29win11-24h2
Server 20160x29winserver-2016
Server 20190x29winserver-2019
Server 20220x29winserver-2022
Server 20250x29winserver-2025

Kernel module

ntoskrnl.exeNtAccessCheckAndAuditAlarm

Related APIs

AccessCheckAndAuditAlarmWNtAccessCheckNtAccessCheckByTypeNtAccessCheckByTypeAndAuditAlarmNtCloseObjectAuditAlarmNtDeleteObjectAuditAlarm

Syscall stub

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

The original, non-typed audit-alarm access check — pre-dates the ByType / ResultList variants by several Windows generations and remains the dispatcher used for simple flat-ACL objects (files, registry keys, kernel mutexes, sections). It produces Security event 4663 ("An attempt was made to access an object") when the SACL or the AUDIT_EVENT_TYPE forces emission. The function is the kernel back-end of the Win32 AccessCheckAndAuditAlarmW wrapper. The SSN `0x29` has been pinned since Windows 10 1507 — the entire `*AuditAlarm` family clusters in the low syscall range that predates the post-1909 reshuffles, which is one of the few stable reference points across the modern Windows lineage.

Common malware usage

Negligible. The whole point of this syscall is to leave a paper trail; malware writers avoid it for the same reason. The interesting attack pattern is not *calling* it — it is causing it to *not be called* when it should be. Adversaries that need to operate on SACL'd objects without leaving 4663 entries either (a) impair the audit subsystem entirely (T1562.002 via stopping EventLog, registry SACL stripping, or driver-installed SRM hooks), or (b) bypass the audited code path by going kernel-direct (read raw NTFS sectors via \\.\PhysicalDriveN to dodge object-manager-mediated file SACLs, e.g. as Lazarus's FudModule rootkit does for credential-store reads).

Detection opportunities

Event 4663 is the workhorse of object-access auditing on every Windows endpoint. On a baseline-tuned SIEM the volume sits in the hundreds-to-low-thousands per hour per workstation, dominated by Defender service-account access to the file system. Hunt patterns: 4663 on `\Device\HarddiskVolumeShadowCopy*` (shadow copy raw access, a Volsnap-bypass indicator); 4663 on lsass.exe handles with PROCESS_VM_READ; 4663 on registry keys under HKLM\SECURITY\Policy\Secrets. Conversely, a sudden drop in 4663 volume during business hours, especially on a domain controller, is a higher-fidelity alert than any single event.

Direct syscall examples

asmx64 direct stub

; Direct syscall stub for NtAccessCheckAndAuditAlarm (SSN 0x29, Win10 1507+)
NtAccessCheckAndAuditAlarm PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 29h          ; SSN
    syscall
    ret
NtAccessCheckAndAuditAlarm ENDP

cSACL-aware file open emitting 4663

// A user-mode service evaluates a file open against the file's SD and asks
// for the audit subsystem to record a 4663 if the SACL matches.
UNICODE_STRING sub  = RTL_CONSTANT_STRING(L"Security");
UNICODE_STRING tn   = RTL_CONSTANT_STRING(L"File");
UNICODE_STRING on_  = RTL_CONSTANT_STRING(L"\\??\\C:\\Windows\\System32\\config\\SAM");
ACCESS_MASK granted = 0;
NTSTATUS access_status = STATUS_ACCESS_DENIED;
BOOLEAN gen_on_close = FALSE;

NTSTATUS rc = NtAccessCheckAndAuditAlarm(
    &sub,
    (PVOID)0xCAFE1234,
    &tn, &on_,
    pSd,
    FILE_GENERIC_READ,
    &g_FileMapping,
    FALSE,
    &granted, &access_status,
    &gen_on_close);

// 4663 emitted with the file path and the granted access mask.
// If gen_on_close, remember to call NtCloseObjectAuditAlarm later.

rustWin32 AccessCheckAndAuditAlarmW wrapper

use windows_sys::Win32::Security::Authorization::AccessCheckAndAuditAlarmW;
use windows_sys::Win32::Security::*;

unsafe {
    let mut granted: u32 = 0;
    let mut access_status: i32 = 0;
    let mut gen_on_close: i32 = 0;

    let ok = AccessCheckAndAuditAlarmW(
        windows_sys::w!("Security"),
        handle_id as *mut _,
        windows_sys::w!("File"),
        windows_sys::w!("\\??\\C:\\Windows\\System32\\config\\SAM"),
        sd_ptr,
        desired_access,
        &mapping as *const _ as *mut _,
        0, // ObjectCreation == FALSE
        &mut granted, &mut access_status, &mut gen_on_close,
    );
    // ok != 0 -> call succeeded; access_status == 0 -> access granted; 4663 emitted.
}

MITRE ATT&CK mappings

Last verified: 2026-05-20