> Windows Syscalls
ntoskrnl.exeT1559T1071T1106

NtCreateMailslotFile

Creates the server side of a mailslot — a legacy, one-way, datagram-style IPC primitive accessed via \Device\Mailslot.

Prototype

NTSTATUS NtCreateMailslotFile(
  PHANDLE            FileHandle,
  ACCESS_MASK        DesiredAccess,
  POBJECT_ATTRIBUTES ObjectAttributes,
  PIO_STATUS_BLOCK   IoStatusBlock,
  ULONG              CreateOptions,
  ULONG              MailslotQuota,
  ULONG              MaximumMessageSize,
  PLARGE_INTEGER     ReadTimeout
);

Arguments

NameTypeDirDescription
FileHandlePHANDLEoutReceives the handle to the newly created mailslot server endpoint.
DesiredAccessACCESS_MASKinAccess rights requested — typically GENERIC_READ | SYNCHRONIZE for a server.
ObjectAttributesPOBJECT_ATTRIBUTESinNames the mailslot, typically \??\mailslot\<name> (corresponds to \\.\mailslot\<name>).
IoStatusBlockPIO_STATUS_BLOCKoutReceives FILE_CREATED on success and the I/O completion status.
CreateOptionsULONGinReserved create-time flags — almost always 0 for mailslots.
MailslotQuotaULONGinMaximum bytes that can be queued in the slot at once. 0 = system default.
MaximumMessageSizeULONGinLargest message a single write may carry. 0 means any size up to MailslotQuota.
ReadTimeoutPLARGE_INTEGERinDefault timeout for blocking reads. NULL = wait forever, 0 = return immediately.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 15070xA6win10-1507
Win10 16070xA8win10-1607
Win10 17030xABwin10-1703
Win10 17090xACwin10-1709
Win10 18030xADwin10-1803
Win10 18090xADwin10-1809
Win10 19030xAEwin10-1903
Win10 19090xAEwin10-1909
Win10 20040xB2win10-2004
Win10 20H20xB2win10-20h2
Win10 21H10xB2win10-21h1
Win10 21H20xB3win10-21h2
Win10 22H20xB3win10-22h2
Win11 21H20xB6win11-21h2
Win11 22H20xB7win11-22h2
Win11 23H20xB7win11-23h2
Win11 24H20xB9win11-24h2
Server 20160xA8winserver-2016
Server 20190xADwinserver-2019
Server 20220xB5winserver-2022
Server 20250xB9winserver-2025

Kernel module

ntoskrnl.exeNtCreateMailslotFile

Related APIs

CreateMailslotWGetMailslotInfoSetMailslotInfoNtCreateNamedPipeFileNtCreateFile

Syscall stub

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

Mailslots are a connectionless, one-way IPC — the *server* creates the slot via NtCreateMailslotFile and reads incoming datagrams; *clients* simply open `\\<host>\mailslot\<name>` with NtOpenFile/NtCreateFile and write to it. They predate named pipes and are implemented by mailslot.sys / mrxsmb.sys (cross-host delivery rides SMB). Messages can be broadcast to a domain-wide name (`\\*\mailslot\foo`), though that path is heavily restricted on modern domains. Maximum cross-network message size is 424 bytes; local-only mailslots can be much larger.

Common malware usage

Mailslots are an *OPSEC-favourable* IPC because almost no modern security stack inspects them. Cobalt Strike historically offered a mailslot SMB transport for beacon-to-beacon delivery — it's lower fidelity than named pipes but largely invisible to EDRs that hook NtCreateNamedPipeFile / FltMgr name-callbacks for pipes. Niche real-world use today: covert local IPC between cooperating implants in the same lateral-movement chain, where named pipes would draw immediate Sysmon Event 17/18 attention. Genuine modern named-malware-family use is rare; the asymmetric detection gap is the main draw.

Detection opportunities

Detection is genuinely sparse. Sysmon has no MailslotEvent (Events 17 / 18 cover named pipes only). ETW Microsoft-Windows-Kernel-File emits Create events with a `\Device\Mailslot\` path — write rules against that prefix in EDR file-create hooks. CmRegisterCallbackEx doesn't apply (no registry involvement); the right hookpoint is FltRegisterFilter against mailslot.sys's file system minifilter chain. Hunt query: any process creating an object under `\Device\Mailslot\` outside of `lsass.exe` (NETLOGON), `services.exe`, or `winlogon.exe` is worth investigating.

Direct syscall examples

cMinimal mailslot server

// Creates \\.\mailslot\implant_chan as a passive receiver.
UNICODE_STRING name;
RtlInitUnicodeString(&name, L"\\??\\mailslot\\implant_chan");

OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);

IO_STATUS_BLOCK iosb;
HANDLE hSlot = NULL;

NTSTATUS st = NtCreateMailslotFile(
    &hSlot,
    GENERIC_READ | SYNCHRONIZE,
    &oa,
    &iosb,
    0,        // CreateOptions
    0,        // MailslotQuota — system default
    1024,     // MaximumMessageSize
    NULL      // ReadTimeout — wait forever
);

asmx64 direct stub (Win11 24H2 SSN 0xB9)

NtCreateMailslotFile PROC
    mov  r10, rcx
    mov  eax, 0B9h
    syscall
    ret
NtCreateMailslotFile ENDP

rustwindows-sys receiver

// Cargo: windows-sys = "0.59" (Win32_Storage_FileSystem, Win32_Foundation)
use windows_sys::Win32::Storage::FileSystem::*;
let h = unsafe {
    CreateMailslotW(
        w!("\\\\.\\mailslot\\implant_chan"),
        1024,                       // nMaxMessageSize
        MAILSLOT_WAIT_FOREVER,      // lReadTimeout
        null_mut(),                 // lpSecurityAttributes
    )
};
// CreateMailslotW funnels into NtCreateMailslotFile.

MITRE ATT&CK mappings

Last verified: 2026-05-20