> Windows Syscalls
ntoskrnl.exeT1559T1106

NtCreatePort

Creates a named server-side LPC port object — the legacy pre-ALPC IPC listener primitive.

Prototype

NTSTATUS NtCreatePort(
  PHANDLE             PortHandle,
  POBJECT_ATTRIBUTES  ObjectAttributes,
  ULONG               MaxConnectionInfoLength,
  ULONG               MaxMessageLength,
  ULONG               MaxPoolUsage
);

Arguments

NameTypeDirDescription
PortHandlePHANDLEoutReceives the handle to the newly created server port object.
ObjectAttributesPOBJECT_ATTRIBUTESinObject attributes; typically supplies an NT path like \RPC Control\<Name> as the port name.
MaxConnectionInfoLengthULONGinMaximum size in bytes of connection-info payload exchanged at NtAcceptConnectPort time.
MaxMessageLengthULONGinMaximum size of an inline LPC message; capped at PORT_MAXIMUM_MESSAGE_LENGTH (256 bytes).
MaxPoolUsageULONGinUpper bound on paged-pool usage for queued messages on this port.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 15070xABwin10-1507
Win10 16070xADwin10-1607
Win10 17030xB0win10-1703
Win10 17090xB1win10-1709
Win10 18030xB2win10-1803
Win10 18090xB2win10-1809
Win10 19030xB3win10-1903
Win10 19090xB3win10-1909
Win10 20040xB7win10-2004
Win10 20H20xB7win10-20h2
Win10 21H10xB7win10-21h1
Win10 21H20xB8win10-21h2
Win10 22H20xB8win10-22h2
Win11 21H20xBBwin11-21h2
Win11 22H20xBCwin11-22h2
Win11 23H20xBCwin11-23h2
Win11 24H20xBEwin11-24h2
Server 20160xADwinserver-2016
Server 20190xB2winserver-2019
Server 20220xBAwinserver-2022
Server 20250xBEwinserver-2025

Kernel module

ntoskrnl.exeNtCreatePort

Related APIs

NtAcceptConnectPortNtCompleteConnectPortNtReplyWaitReceivePortNtConnectPortNtAlpcCreatePort

Syscall stub

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

NtCreatePort is the *server* side of the legacy **LPC** IPC mechanism (pre-Vista). It registers a named port object — typically under `\RPC Control\` — that clients reach via NtConnectPort. After accepting a connection with NtAcceptConnectPort and completing the handshake with NtCompleteConnectPort, the server enters its receive loop using NtReplyWaitReceivePort. Since Vista, the kernel exposes the richer **ALPC** API (NtAlpcCreatePort etc.) and Microsoft has migrated almost all in-box RPC traffic to ALPC. LPC remains in the Service Descriptor Table for backwards compatibility but is rarely used by anything shipping today.

Common malware usage

Modern offensive use of NtCreatePort is *uncommon*. The relevant historical pattern is a kernel- or user-mode implant that registers an LPC port name mimicking a legitimate kernel component (e.g. something resembling `\SeLsaCommandPort`) and uses it as a covert intra-host C2 channel that never touches Winsock or named-pipe APIs. Today an attacker who wants in-host IPC will almost always reach for ALPC, named pipes, mailslots or shared sections instead. Treat any non-Microsoft-signed process invoking NtCreatePort as anomalous.

Detection opportunities

There is no dedicated ETW provider for legacy LPC equivalent to `Microsoft-Windows-Kernel-ALPC`. Detection therefore relies on kernel callbacks (object-manager ObCreateObject hooks via ObRegisterCallbacks for type `Port`) or driver-level syscall hooking. SystemInformer and WinObj enumerate live port objects under `\RPC Control` and `\Sessions\<n>\Windows`. Any new port name that doesn't match a known Microsoft component (csrss, lsass, smss, RPC subsystem) is worth investigating.

Direct syscall examples

asmx64 direct stub

; Direct syscall stub for NtCreatePort (SSN 0xBE on Win11 24H2)
NtCreatePort PROC
    mov  r10, rcx          ; PortHandle
    mov  eax, 0BEh         ; SSN — verify per-build before deploying
    syscall
    ret
NtCreatePort ENDP

cRegister a named LPC server port

// Create an LPC server port under \RPC Control.
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI *pNtCreatePort)(
    PHANDLE, POBJECT_ATTRIBUTES, ULONG, ULONG, ULONG);

NTSTATUS CreateLpcPort(HANDLE *outHandle, PCWSTR ntName) {
    UNICODE_STRING name;
    OBJECT_ATTRIBUTES oa;
    RtlInitUnicodeString(&name, ntName);
    InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);

    pNtCreatePort fn = (pNtCreatePort)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtCreatePort");
    return fn(outHandle, &oa, 0x100, 0x100, 0x2000);
}

MITRE ATT&CK mappings

Last verified: 2026-05-20