> Windows Syscalls
ntoskrnl.exeT1562.002T1106

NtAccessCheckByTypeAndAuditAlarm

Führt eine typisierte Zugriffsprüfung aus und schreibt einen Audit-Alarm-Eintrag ins Security-Eventlog.

Prototyp

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
);

Argumente

NameTypeDirDescription
SubsystemNamePUNICODE_STRINGinIdentifiziert das prüfende Subsystem, z. B. L"Security" oder L"WinLogon". Wird im Audit-Event protokolliert.
HandleIdPVOIDinAufruferseitiger opaker Identifikator für das geprüfte Objekt-Handle; erscheint im Audit-Eintrag zur Korrelation.
ObjectTypeNamePUNICODE_STRINGinLesbarer Typname (z. B. L"File", L"RegistryKey"), der im Audit-Event protokolliert wird.
ObjectNamePUNICODE_STRINGinObjektinstanzname für die Audit-Event-Aufzeichnung, z. B. der Dateipfad.
SecurityDescriptorPSECURITY_DESCRIPTORinSicherheitsdeskriptor des Zielobjekts; SACL steuert die Audit-Erzeugung.
PrincipalSelfSidPSIDinOptionale SID, die für den Platzhalter PRINCIPAL_SELF eingesetzt wird, wenn das Objekt einen Principal repräsentiert (z. B. ein AD-Benutzerobjekt).
DesiredAccessACCESS_MASKinVom Aufrufer angeforderte Zugriffsrechte, abgeglichen gegen die DACL.
AuditTypeAUDIT_EVENT_TYPEinAuditEventObjectAccess oder AuditEventDirectoryServiceAccess — wählt die Audit-Kategorie.
FlagsULONGinReserviert / Verhaltens-Modifikatoren (z. B. AUDIT_ALLOW_NO_PRIVILEGE).
ObjectTypeListPOBJECT_TYPE_LISTinHierarchische Liste von Objekttypen (z. B. AD-Objekt + Property Sets), über die die Zugriffsprüfung läuft.
ObjectTypeListLengthULONGinAnzahl der Einträge in ObjectTypeList.
GenericMappingPGENERIC_MAPPINGinPro-Objekttyp-Mapping von GENERIC_READ/WRITE/EXECUTE/ALL auf spezifische Rechte.
ObjectCreationBOOLEANinTRUE bei Objekterzeugung (als CreateObject protokolliert), FALSE beim Öffnen eines bestehenden Objekts.
GrantedAccessPACCESS_MASKoutErhält die Bitmaske der tatsächlich gewährten Zugriffsrechte.
AccessStatusPNTSTATUSoutSTATUS_SUCCESS bei gewährtem Zugriff, sonst STATUS_ACCESS_DENIED. Der Rückgabewert der Funktion meldet die Gültigkeit des Aufrufs, nicht die Zugriffsentscheidung.
GenerateOnClosePBOOLEANoutWird auf TRUE gesetzt, wenn der Kernel auch beim Schließen des Handles ein Audit-Event möchte; der Aufrufer muss dies merken und später NtCloseObjectAuditAlarm aufrufen.

Syscall-IDs pro 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-Modul

ntoskrnl.exeNtAccessCheckByTypeAndAuditAlarm

Verwandte 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

Undokumentierte Hinweise

Audit-protokollierender Geschwister-Syscall von NtAccessCheckByType. Die Nicht-Alarm-Variante liefert die Zugriffsentscheidung und endet; diese Variante schreibt zusätzlich einen Audit-Eintrag ins Security-Eventlog, wenn die SACL des Objekts es verlangt (oder wenn AuditType + Flags es erzwingen). Die Funktion erfordert SeAuditPrivilege — nur Aufrufer mit diesem Privileg (LSASS, der Security Reference Monitor, Kernel-Mode-Subsysteme) können sie sinnvoll nutzen. Die SSN ist seit Windows 10 1507 stabil bei `0x59` — ungewöhnlich, aber konsistent damit, dass alle `*AuditAlarm`-Syscalls die Post-1909-Umnummerierungen vordatieren.

Häufige Malware-Nutzung

Vernachlässigbar. Per Design erzeugt jeder erfolgreiche Aufruf einen Security-Eventlog-Eintrag — das Gegenteil dessen, was die meisten Malwares wollen. Die wenigen In-the-Wild-Vorkommen sind LSASS, das sich legitim verhält (`lsass.exe` bei AD-Objekt-Zugriffsentscheidungen). Keine Commodity-Familie nutzt es bekanntermaßen missbräuchlich. Interessant aus Verteidigersicht ist die *Abwesenheit* erwarteter Audit-Alarm-Aufrufe beim Zugriff auf ein SACL-überwachtes Objekt — möglicherweise ein Tampering-Signal an der SACL oder am SRM-Dispatch-Pfad.

Erkennungs­möglichkeiten

Diese Aufrufe *sind* das Security-Eventlog für Objektzugriff. Event IDs 4656 (Handle angefordert), 4658 (Handle geschlossen), 4660 (Objekt gelöscht), 4663 (Zugriffsversuch), 4690 (Handle dupliziert) gehen alle auf die Familie NtAccessCheck*AuditAlarm + NtCloseObjectAuditAlarm + NtDeleteObjectAuditAlarm zurück. Verteidiger sollten sicherstellen, dass SACLs auf hochwertigen Objekten (LSASS-Prozess, AD-Naming-Contexts, DPAPI-Masterkey-Store) so konfiguriert sind, dass sie Audit-Alarm-Prüfungen auslösen, und die Abwesenheit erwarteter Events als Tampering-Signal werten. Der ETW-Provider Microsoft-Windows-Security-Auditing trägt dieselben Daten mit mehr Detail als der Legacy-Eventlog-Kanal.

Direkte Syscall-Beispiele

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