> Windows Syscalls
ntoskrnl.exeT1559T1106

NtConnectPort

Client-side connect to a legacy LPC server port, the pre-ALPC equivalent of NtAlpcConnectPort.

Prototype

NTSTATUS NtConnectPort(
  PHANDLE                       PortHandle,
  PUNICODE_STRING               PortName,
  PSECURITY_QUALITY_OF_SERVICE  SecurityQos,
  PPORT_VIEW                    ClientView,
  PREMOTE_PORT_VIEW             ServerView,
  PULONG                        MaxMessageLength,
  PVOID                         ConnectionInformation,
  PULONG                        ConnectionInformationLength
);

Arguments

NameTypeDirDescription
PortHandlePHANDLEoutReceives the handle to the connected client port if the server accepts.
PortNamePUNICODE_STRINGinFully qualified LPC port name in the object namespace, e.g. \RPC Control\myport.
SecurityQosPSECURITY_QUALITY_OF_SERVICEinImpersonation level and tracking mode the server may apply to the client (typically Identification).
ClientViewPPORT_VIEWin/outOptional shared section the client offers to the server; updated with the mapped server-side address.
ServerViewPREMOTE_PORT_VIEWoutReceives the server's shared section view (if the server attached one during accept).
MaxMessageLengthPULONGoutReceives the maximum LPC message length negotiated with the server (PORT_MAXIMUM_MESSAGE_LENGTH = 256).
ConnectionInformationPVOIDin/outOptional payload sent in the connect message; overwritten on return with the server's connect-accept data.
ConnectionInformationLengthPULONGin/outOn input, size of ConnectionInformation; on output, size of the server's reply.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 15070x99win10-1507
Win10 16070x9Awin10-1607
Win10 17030x9Cwin10-1703
Win10 17090x9Dwin10-1709
Win10 18030x9Ewin10-1803
Win10 18090x9Ewin10-1809
Win10 19030x9Ewin10-1903
Win10 19090x9Ewin10-1909
Win10 20040xA0win10-2004
Win10 20H20xA0win10-20h2
Win10 21H10xA0win10-21h1
Win10 21H20xA0win10-21h2
Win10 22H20xA0win10-22h2
Win11 21H20xA2win11-21h2
Win11 22H20xA2win11-22h2
Win11 23H20xA2win11-23h2
Win11 24H20xA4win11-24h2
Server 20160x9Awinserver-2016
Server 20190x9Ewinserver-2019
Server 20220xA2winserver-2022
Server 20250xA4winserver-2025

Kernel module

ntoskrnl.exeNtConnectPort

Related APIs

NtAcceptConnectPortNtSecureConnectPortNtAlpcConnectPortNtRequestPortNtRequestWaitReplyPortNtCreatePort

Syscall stub

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

NtConnectPort is the client-side counterpart of NtAcceptConnectPort and the legacy (pre-Vista) sibling of NtAlpcConnectPort. The 8-argument shape is documented by phnt and the Windows Internals book; the kernel implementation lives in `LpcpConnectPort` inside ntoskrnl.exe. Although ALPC superseded LPC functionally on Vista+, the LPC dispatch path was never removed — these SSNs are still wired and still resolve to working code on Windows 11 24H2. Note the SSN drifts across builds (unlike NtAcceptConnectPort), so direct-syscall stubs must resolve dynamically.

Common malware usage

Modern malware rarely picks LPC over ALPC or named pipes, but the surface remains a viable IPC primitive for components that want to avoid the better-instrumented ALPC paths. Historically (XP / 2003 era) some user-mode rootkit families used LPC for inter-module communication between a loader and an injected payload, since no Win32 wrapper existed and traffic stayed entirely in-kernel. Today the practical relevance is mostly *historical and educational*; treat any user-mode caller as suspicious because nearly nothing legitimately uses raw LPC on contemporary Windows.

Detection opportunities

There is no `Microsoft-Windows-Kernel-LPC` ETW provider analogous to the ALPC one; defenders rely on syscall-table hooks (kernel-mode EDR) or user-mode hooks on `ntdll!NtConnectPort`. The base-rate is so low on Windows 10/11 that *any* hit on NtConnectPort from a non-system process is worth alerting on. SystemInformer enumerates both LPC and ALPC ports per process — unexpected LPC port handles in a sandboxed app or in an unsigned binary are a high-confidence indicator. PORT_VIEW shared sections also create VAD entries that survive the connection.

Direct syscall examples

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtConnectPort (SSN 0xA4 on Win11 24H2 — drifts per build)
NtConnectPort PROC
    mov  r10, rcx          ; PortHandle
    mov  eax, 0A4h         ; SSN
    syscall
    ret
NtConnectPort ENDP

cConnect to a named LPC server

// Connect to a legacy LPC server port; minimal connect message, no shared view.
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI *pNtConnectPort)(
    PHANDLE, PUNICODE_STRING, PVOID /*PSECURITY_QOS*/,
    PVOID, PVOID, PULONG, PVOID, PULONG);

HANDLE LpcConnect(LPCWSTR name) {
    UNICODE_STRING us; RtlInitUnicodeString(&us, name);
    SECURITY_QUALITY_OF_SERVICE qos = {
        sizeof(qos), SecurityIdentification, SECURITY_DYNAMIC_TRACKING, FALSE
    };
    HANDLE h = NULL; ULONG maxLen = 0, cinfoLen = 0;
    pNtConnectPort fn = (pNtConnectPort)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtConnectPort");
    fn(&h, &us, &qos, NULL, NULL, &maxLen, NULL, &cinfoLen);
    return h;
}

rustResolve and call via GetProcAddress

// Cargo: windows-sys = "0.59"
use std::ffi::c_void;
use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleA, GetProcAddress};

type NtConnectPortFn = unsafe extern "system" fn(
    *mut *mut c_void, *const c_void, *const c_void,
    *mut c_void, *mut c_void, *mut u32, *mut c_void, *mut u32,
) -> i32;

unsafe fn resolve() -> Option<NtConnectPortFn> {
    let h = GetModuleHandleA(b"ntdll.dll\0".as_ptr());
    let p = GetProcAddress(h, b"NtConnectPort\0".as_ptr())?;
    Some(std::mem::transmute(p))
}

MITRE ATT&CK mappings

Last verified: 2026-05-20