LPC (Local procedure calls) (一)数据结构
什么是LPC
LPC(Local-Process-communicationandnotlocalprocedure-Calls)是一种在NT内核中实现的基于消息的高速通信机制。LPC可用于两个用户模式进程之间、用户模式进程与内核模式驱动程序之间或两个内核模式驱动程序之间的通信。一个例子是通过LPC通信的两个用户模式进程。像CSRSS.exe与SMSS.exe通信,在创建登录会话或任何与LSASS.exe。出于安全原因,通过lsa认证端口。用户模式进程与内核模式驱动程序通信的另一个例子是 KSecDD.sys司与LSASS.exe通信用于在读/写加密文件期间对EFS密钥进行加密和解密。
LPC使用两种不同的机制在客户端和服务器进程之间传递数据。它使用LPC消息缓冲区(对于小于304字节的数据),或者使用映射到客户机和服务器地址空间的共享内存部分(对于大于304字节的数据)。
除了用作在同一系统上运行的进程之间选择远程过程调用的协议外,LPC还用于整个系统,例如用于Win32应用程序与CSRSS.exe文件,安全参考监视器与LSASS的通信,WinLogon与LSASS的通信等。
LPC强制客户机进程和服务器进程之间的同步通信模型。Vista反对使用一种称为异步本地进程间通信(ALPC)的新机制来使用LPC。与LPC相比,ALPC有一个固有的优势,即从客户端到服务器的所有调用都是异步的,即客户端不需要阻塞/等待服务器响应消息。在Vista中,对lpcapis的旧应用程序调用会自动重定向到更新的alpcapi。
LPC APIs
LPC api是本机api,即它们在用户模式下通过NTDLL.dll在内核模式下NTOSKRNL.exe文件. lpcapis没有在Win32级别公开,因此Win32应用程序不能直接使用LPC工具。然而,在使用RPC时,Win32应用程序可以通过协议序列“ncalrpc”将LPC指定为其底层传输,从而间接地使用LPC。所有lpcapis都以单词“Port”结尾,这意味着LPC通信端点。
API |
Description |
NtCreatePort |
Used by server to create a connection port |
NtConnectPort |
Used by client to connect to a connection port |
NtListenPort |
Used by server to listen for connection requests on the connection port. |
NtAcceptConnectPort |
Used by server to accept connection requests on the connection port |
NtCompleteConnectPort |
Used by server to complete the acceptance of a connection request |
NtRequestPort |
Used to send a datagram message that does not have a reply |
NtRequestWaitReplyPort |
Used to send a message and wait for a reply |
NtReplyPort |
Used to send a reply to a particular message |
NtReplyWaitReplyPort |
Used to send a reply to a particular message and wait for a reply to a previous message |
NtReplyWaitReceivePort |
Used by server to send a reply to the client and wait to receive a message from the client |
NtImpersonateClientOfPort |
Used by server thread to temporarily borrow the security context of a client thread |
下图说明了LPC服务器进程侦听来自潜在客户端的连接请求所采取的步骤,以及客户端连接到侦听服务器所采取的步骤。
LPC客户机-服务器连接建立顺序
注意:许多服务器进程使用NtReplyWaitReceivePort()API而不是NtListenPort()。NtListenPort()除去连接请求之外的所有LPC消息。因此NtListenPort()只能用于第一个连接。对于以后的连接请求,使用NtReplyWaitReceivePort()。
下图说明了LPC客户机向已建立连接的LPC服务器发送请求所采取的步骤,以及服务器响应消息所采取的步骤。
客户端-服务器数据传输序列
LPC Data Structures
LPC Port Data Structure
LPC Port被称为端口。LPC实现使用相同的端口结构来表示各种类型的端口。LPC使用的端口是服务器连接端口,这些端口是由服务器进程创建的用于接受来自客户端的传入连接的命名端口。客户机通信端口由客户机进程创建以连接到服务器进程和服务器进程创建的服务器通信端口。
LPC端口类型及其关系
LPCP_PORT_OBJECT是LPC用来表示LPC端口的内部数据结构。LPCP_PORT_对象是从带有标记“PORT”的分页池中分配的。
kd> dt nt!_LPCP_PORT_OBJECT+0x000ConnectionPort : Ptr32 _LPCP_PORT_OBJECT+0x004ConnectedPort : Ptr32 _LPCP_PORT_OBJECT+0x008MsgQueue : _LPCP_PORT_QUEUE+0x018Creator : _CLIENT_ID+0x020ClientSectionBase : Ptr32 Void+0x024ServerSectionBase : Ptr32 Void+0x028PortContext : Ptr32 Void+0x02cClientThread : Ptr32 _ETHREAD+0x030SecurityQos : _SECURITY_QUALITY_OF_SERVICE+0x03cStaticSecurity : _SECURITY_CLIENT_CONTEXT+0x078LpcReplyChainHead : _LIST_ENTRY+0x080LpcDataInfoChainHead : _LIST_ENTRY+0x088ServerProcess : Ptr32 _EPROCESS+0x088MappingProcess : Ptr32 _EPROCESS+0x08cMaxMessageLength : Uint2B+0x08eMaxConnectionInfoLength : Uint2B+0x090Flags : Uint4B+0x094 WaitEvent : _KEVENT
- 上一篇: 仅通过转储来排除内存泄漏
- 下一篇: 使用Java中的InputStream读取文件数据