> Windows Syscalls
ntoskrnl.exeT1559T1106

NtConnectPort

Client-seitige Verbindung zu einem Legacy-LPC-Server-Port, das Pre-ALPC-Pendant zu NtAlpcConnectPort.

Prototyp

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

Argumente

NameTypeDirDescription
PortHandlePHANDLEoutEmpfängt das Handle auf den verbundenen Client-Port, wenn der Server annimmt.
PortNamePUNICODE_STRINGinVoll qualifizierter LPC-Port-Name im Object-Namespace, z. B. \RPC Control\myport.
SecurityQosPSECURITY_QUALITY_OF_SERVICEinImpersonation-Level und Tracking-Modus, den der Server dem Client zuweisen darf (üblicherweise Identification).
ClientViewPPORT_VIEWin/outOptionale Shared-Section, die der Client dem Server anbietet; wird mit der Server-seitigen Adresse befüllt.
ServerViewPREMOTE_PORT_VIEWoutEmpfängt die Shared-Section-View des Servers (sofern dieser im Accept eine angehängt hat).
MaxMessageLengthPULONGoutEmpfängt die mit dem Server ausgehandelte maximale LPC-Message-Länge (PORT_MAXIMUM_MESSAGE_LENGTH = 256).
ConnectionInformationPVOIDin/outOptionale Payload im Connect; bei Rückkehr mit den Connect-Accept-Daten des Servers überschrieben.
ConnectionInformationLengthPULONGin/outEingangs Größe von ConnectionInformation; ausgangs Größe der Server-Antwort.

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

ntoskrnl.exeNtConnectPort

Verwandte 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

Undokumentierte Hinweise

NtConnectPort ist das Client-Gegenstück zu NtAcceptConnectPort und der Pre-Vista-Vorläufer von NtAlpcConnectPort. Die 8-Argument-Signatur ist von phnt und dem Windows-Internals-Buch dokumentiert; die Kernel-Implementierung liegt in `LpcpConnectPort` in ntoskrnl.exe. Obwohl ALPC LPC ab Vista funktional ablöste, wurde der LPC-Dispatch-Pfad nie entfernt — diese SSNs sind weiterhin verdrahtet und liefern auf Windows 11 24H2 funktionierenden Code. Die SSN driftet zwischen Builds (anders als bei NtAcceptConnectPort), Direkt-Syscall-Stubs müssen sie also dynamisch auflösen.

Häufige Malware-Nutzung

Moderne Malware wählt selten LPC anstelle von ALPC oder Named Pipes, doch die Fläche bleibt eine brauchbare IPC-Primitive für Komponenten, die die besser instrumentierten ALPC-Pfade meiden wollen. Historisch (XP- / 2003-Ära) nutzten manche User-Mode-Rootkits LPC zur Inter-Modul-Kommunikation zwischen Loader und injiziertem Payload, da kein Win32-Wrapper existierte und der Verkehr vollständig im Kernel blieb. Heute ist die praktische Relevanz vor allem *historisch und didaktisch*; jeder User-Mode-Caller ist verdächtig, da auf zeitgenössischem Windows kaum etwas legitim rohes LPC einsetzt.

Erkennungs­möglichkeiten

Es gibt keinen ETW-Provider `Microsoft-Windows-Kernel-LPC` analog zu ALPC; Verteidiger verlassen sich auf Syscall-Tabellen-Hooks (Kernel-EDR) oder User-Mode-Hooks auf `ntdll!NtConnectPort`. Die Baseline ist auf Windows 10/11 so niedrig, dass *jeder* Treffer auf NtConnectPort aus einem Nicht-System-Prozess alarmwürdig ist. SystemInformer listet LPC- und ALPC-Ports pro Prozess — ein unerwartetes LPC-Handle in einer Sandbox-App oder einem unsignierten Binary ist ein hochkonfidentes Indiz. PORT_VIEW Shared-Sections erzeugen zudem VAD-Einträge, die die Verbindung überdauern.

Direkte Syscall-Beispiele

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