> Windows Syscalls
ntoskrnl.exeT1559T1106

NtConnectPort

Connexion client à un port serveur LPC historique, équivalent pré-ALPC de 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
PortHandlePHANDLEoutReçoit le handle vers le port client connecté si le serveur accepte.
PortNamePUNICODE_STRINGinNom complet du port LPC dans le namespace objet, ex. \RPC Control\myport.
SecurityQosPSECURITY_QUALITY_OF_SERVICEinNiveau d'usurpation et mode de suivi que le serveur peut appliquer au client (typiquement Identification).
ClientViewPPORT_VIEWin/outSection partagée optionnelle offerte par le client au serveur ; mise à jour avec l'adresse côté serveur.
ServerViewPREMOTE_PORT_VIEWoutReçoit la vue de section partagée du serveur (si le serveur en a attaché une lors de l'accept).
MaxMessageLengthPULONGoutReçoit la longueur maximale de message LPC négociée avec le serveur (PORT_MAXIMUM_MESSAGE_LENGTH = 256).
ConnectionInformationPVOIDin/outPayload optionnel envoyé dans le connect ; écrasé au retour par les données d'acceptation du serveur.
ConnectionInformationLengthPULONGin/outEn entrée, taille de ConnectionInformation ; en sortie, taille de la réponse serveur.

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
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

Module noyau

ntoskrnl.exeNtConnectPort

APIs liées

NtAcceptConnectPortNtSecureConnectPortNtAlpcConnectPortNtRequestPortNtRequestWaitReplyPortNtCreatePort

Stub du syscall

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

Notes non documentées

NtConnectPort est le pendant client de NtAcceptConnectPort et l'ancêtre pré-Vista de NtAlpcConnectPort. La signature à 8 arguments est documentée par phnt et le livre Windows Internals ; l'implémentation kernel vit dans `LpcpConnectPort` de ntoskrnl.exe. Bien que ALPC ait fonctionnellement supplanté LPC à partir de Vista, le chemin de dispatch LPC n'a jamais été retiré — ces SSN sont toujours câblés et résolvent toujours du code fonctionnel sur Windows 11 24H2. Le SSN dérive entre builds (contrairement à NtAcceptConnectPort), donc les stubs en syscall direct doivent résoudre dynamiquement.

Usage courant par les malwares

Les malwares modernes choisissent rarement LPC plutôt qu'ALPC ou les named pipes, mais la surface reste une primitive IPC viable pour les composants voulant éviter les chemins ALPC mieux instrumentés. Historiquement (ère XP / 2003), certaines familles de rootkits user-mode utilisaient LPC pour la communication inter-module entre un loader et un payload injecté, puisqu'aucun wrapper Win32 n'existait et que le trafic restait entièrement en kernel. Aujourd'hui la pertinence pratique est surtout *historique et éducative* ; tout appelant user-mode est suspect car quasiment rien n'utilise légitimement du LPC brut sur Windows contemporain.

Opportunités de détection

Aucun provider ETW `Microsoft-Windows-Kernel-LPC` analogue à celui d'ALPC ; les défenseurs s'appuient sur les hooks de table syscall (EDR kernel) ou les hooks user-mode sur `ntdll!NtConnectPort`. La base rate est si faible sur Windows 10/11 que *tout* hit sur NtConnectPort depuis un processus non système mérite une alerte. SystemInformer énumère ports LPC et ALPC par processus — un handle LPC inattendu dans une appli sandboxée ou un binaire non signé est un indicateur à forte confiance. Les sections partagées PORT_VIEW créent aussi des entrées VAD qui survivent à la connexion.

Exemples de syscalls directs

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

Mappings MITRE ATT&CK

Last verified: 2026-05-20