NtAcceptConnectPort
Server-seitige Annahme einer Legacy-LPC-Verbindungsanfrage mit optionalem Shared-View-Mapping.
Prototyp
NTSTATUS NtAcceptConnectPort( PHANDLE PortHandle, PVOID PortContext, PPORT_MESSAGE ConnectionRequest, BOOLEAN AcceptConnection, PPORT_VIEW ServerView, PREMOTE_PORT_VIEW ClientView );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| PortHandle | PHANDLE | out | Empfängt ein Handle auf den neu erzeugten Kommunikationsport, falls die Verbindung angenommen wird. |
| PortContext | PVOID | in | Opaker server-seitiger Kontextzeiger für diese Verbindung, der in späteren Messages zurückgereicht wird. |
| ConnectionRequest | PPORT_MESSAGE | in | Die zuvor via NtListenPort / NtReplyWaitReceivePort empfangene LPC_CONNECTION_REQUEST-Message. |
| AcceptConnection | BOOLEAN | in | TRUE zum Annehmen, FALSE zum Ablehnen (der Client erhält STATUS_PORT_CONNECTION_REFUSED). |
| ServerView | PPORT_VIEW | in/out | Optionale Shared-Section-View für den Client; wird mit der Client-seitigen Adresse befüllt. |
| ClientView | PREMOTE_PORT_VIEW | out | Empfängt die Client-seitige Shared-Section-View (sofern der Client eine im Connect angeboten hat). |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x2 | win10-1507 |
| Win10 1607 | 0x2 | win10-1607 |
| Win10 1703 | 0x2 | win10-1703 |
| Win10 1709 | 0x2 | win10-1709 |
| Win10 1803 | 0x2 | win10-1803 |
| Win10 1809 | 0x2 | win10-1809 |
| Win10 1903 | 0x2 | win10-1903 |
| Win10 1909 | 0x2 | win10-1909 |
| Win10 2004 | 0x2 | win10-2004 |
| Win10 20H2 | 0x2 | win10-20h2 |
| Win10 21H1 | 0x2 | win10-21h1 |
| Win10 21H2 | 0x2 | win10-21h2 |
| Win10 22H2 | 0x2 | win10-22h2 |
| Win11 21H2 | 0x2 | win11-21h2 |
| Win11 22H2 | 0x2 | win11-22h2 |
| Win11 23H2 | 0x2 | win11-23h2 |
| Win11 24H2 | 0x2 | win11-24h2 |
| Server 2016 | 0x2 | winserver-2016 |
| Server 2019 | 0x2 | winserver-2019 |
| Server 2022 | 0x2 | winserver-2022 |
| Server 2025 | 0x2 | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 02 00 00 00 mov eax, 0x2 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
NtAcceptConnectPort ist die Server-Hälfte des Legacy-**LPC**-Handshakes (Local Procedure Call) — der Pre-Vista-Vorläufer von ALPC. Er existiert weiterhin in ntoskrnl.exe aus Kompatibilitätsgründen und ist aus dem User-Mode aufrufbar, doch praktisch der gesamte moderne RPC-Verkehr läuft inzwischen über ALPC (`NtAlpc*`). Die SSN ist seit Einführung der Tabelle bei `0x2` eingefroren — ein Relikt aus LPC-Zeiten. Verwandte Aufrufe sind NtCreatePort (Server), NtListenPort, NtReplyWaitReceivePort, NtCompleteConnectPort und NtConnectPort (Client).
Häufige Malware-Nutzung
Direkter Missbrauch von LPC durch moderne Malware ist selten; die Fläche wurde weitgehend von ALPC und Named Pipes verdrängt. Historisch (XP / 2003-Ära) wurde LPC gelegentlich von User-Mode-Rootkits als Intra-Process- oder Intra-Host-C2-Kanal zwischen kooperierenden Komponenten genutzt, weil keine Win32-API existierte und der Verkehr für Netzwerk-Monitore unsichtbar war. Heute ist die Relevanz vor allem *historisch und didaktisch* — Kenntnis der Legacy-Schnittstelle hilft Red Teamern, sie in alten Codebasen zu erkennen, und Verteidigern, blinde Flecken auf Long-Tail-Windows-Installationen zu vermeiden, auf denen die LPC-Tabellen noch verdrahtet sind.
Erkennungsmöglichkeiten
Es gibt keinen dedizierten ETW-Provider für Legacy-LPC, wie ihn `Microsoft-Windows-Kernel-ALPC` für ALPC bietet; das verlässlichste Signal ist die *Abwesenheit* legitimer Caller — kaum eine In-Box-Komponente von Windows 10/11 verwendet rohes LPC. EDRs, die die Syscall-Tabelle im Kernel hooken, können jeden User-Mode-Prozess flaggen, der NtAcceptConnectPort außerhalb einer Handvoll Legacy-Komponenten aufruft (einige CSRSS- / SMSS-Pfade berühren ihn noch). Forensisch listet SystemInformers Port-Enumeration LPC-Ports neben ALPC-Ports — unerwartete benannte LPC-Ports in `\RPC Control\` oder `\BaseNamedObjects\` sind ermittlungswürdig.
Direkte Syscall-Beispiele
asmx64 direct stub
; Direct syscall stub for NtAcceptConnectPort (SSN 0x2, stable since Win10 1507)
NtAcceptConnectPort PROC
mov r10, rcx ; PortHandle
mov eax, 02h ; SSN
syscall
ret
NtAcceptConnectPort ENDPcLegacy LPC server accept skeleton
// Educational LPC server skeleton — modern code should use ALPC instead.
#include <windows.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI *pNtAcceptConnectPort)(
PHANDLE, PVOID, PVOID /*PPORT_MESSAGE*/, BOOLEAN, PVOID, PVOID);
NTSTATUS AcceptOrReject(PVOID connReq, BOOL allow) {
HANDLE hComm = NULL;
pNtAcceptConnectPort fn = (pNtAcceptConnectPort)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtAcceptConnectPort");
// PortContext = NULL, no shared views
return fn(&hComm, NULL, connReq, allow ? TRUE : FALSE, NULL, NULL);
}rustFFI declaration via ntapi
// Cargo: ntapi = "0.4"
use ntapi::ntlpcapi::NtAcceptConnectPort;
use winapi::shared::ntdef::{HANDLE, BOOLEAN, NTSTATUS};
unsafe fn accept(req: *mut u8) -> Result<HANDLE, NTSTATUS> {
let mut h: HANDLE = std::ptr::null_mut();
let s = NtAcceptConnectPort(
&mut h,
std::ptr::null_mut(),
req as *mut _,
1 as BOOLEAN,
std::ptr::null_mut(),
std::ptr::null_mut(),
);
if s == 0 { Ok(h) } else { Err(s) }
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20