NtAcceptConnectPort
Acceptation côté serveur d'une demande de connexion LPC historique, avec mappage facultatif d'une vue partagée.
Prototype
NTSTATUS NtAcceptConnectPort( PHANDLE PortHandle, PVOID PortContext, PPORT_MESSAGE ConnectionRequest, BOOLEAN AcceptConnection, PPORT_VIEW ServerView, PREMOTE_PORT_VIEW ClientView );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| PortHandle | PHANDLE | out | Reçoit un handle vers le port de communication nouvellement créé si la connexion est acceptée. |
| PortContext | PVOID | in | Pointeur de contexte opaque côté serveur associé à cette connexion, restitué dans les messages suivants. |
| ConnectionRequest | PPORT_MESSAGE | in | Le message LPC_CONNECTION_REQUEST reçu précédemment via NtListenPort / NtReplyWaitReceivePort. |
| AcceptConnection | BOOLEAN | in | TRUE pour accepter la connexion, FALSE pour la refuser (le client reçoit STATUS_PORT_CONNECTION_REFUSED). |
| ServerView | PPORT_VIEW | in/out | Vue de section partagée optionnelle exposée au client ; mise à jour avec l'adresse côté client. |
| ClientView | PREMOTE_PORT_VIEW | out | Reçoit la vue de section partagée du client (si le client en a proposé une dans le connect). |
IDs de syscalls par version de Windows
| Version de Windows | ID de syscall | 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 |
Module noyau
APIs liées
Stub du syscall
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
Notes non documentées
NtAcceptConnectPort est la moitié serveur du handshake **LPC** (Local Procedure Call) historique — l'ancêtre pré-Vista d'ALPC. Il subsiste dans ntoskrnl.exe pour rétrocompatibilité et reste joignable depuis le user mode, mais l'essentiel du RPC moderne passe désormais par ALPC (`NtAlpc*`). Le SSN est gelé à `0x2` depuis l'introduction de la table, vestige de l'âge de LPC. Les appels associés sont NtCreatePort (serveur), NtListenPort, NtReplyWaitReceivePort, NtCompleteConnectPort, et NtConnectPort (client).
Usage courant par les malwares
L'abus direct de LPC par les malwares modernes est rare ; la surface a largement été supplantée par ALPC et les named pipes. Historiquement (ère XP / 2003), LPC servait parfois de canal C2 intra-process ou intra-host entre composants coopérants de rootkits user-mode, car aucune API Win32 n'existait et le trafic était invisible aux moniteurs réseau. Aujourd'hui la pertinence est surtout *historique et éducative* — connaître l'interface héritée aide les red teamers à la repérer dans de vieilles bases de code et aide les défenseurs à éviter les angles morts sur les installations Windows à longue traîne où les tables LPC sont toujours câblées.
Opportunités de détection
Aucun provider ETW dédié au LPC historique n'existe à l'image de `Microsoft-Windows-Kernel-ALPC` pour ALPC ; le signal le plus fiable est l'*absence* d'appelants légitimes — quasiment aucun composant in-box de Windows 10/11 n'utilise du LPC brut. Les EDR qui hookent la table syscall en kernel peuvent flaguer tout processus user-mode appelant NtAcceptConnectPort hors d'une poignée de composants legacy (quelques chemins CSRSS / SMSS y touchent encore). Forensiquement, l'énumération de ports par SystemInformer affiche les ports LPC à côté des ports ALPC — un port LPC nommé inattendu dans `\RPC Control\` ou `\BaseNamedObjects\` mérite enquête.
Exemples de syscalls directs
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) }
}Mappings MITRE ATT&CK
Last verified: 2026-05-20