zoukankan      html  css  js  c++  java
  • 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
    
       +0x000 ConnectionPort : Ptr32 _LPCP_PORT_OBJECT
    
       +0x004 ConnectedPort : Ptr32 _LPCP_PORT_OBJECT
    
       +0x008 MsgQueue : _LPCP_PORT_QUEUE
    
       +0x018 Creator : _CLIENT_ID
    
       +0x020 ClientSectionBase : Ptr32 Void
    
       +0x024 ServerSectionBase : Ptr32 Void
    
       +0x028 PortContext : Ptr32 Void
    
       +0x02c ClientThread : Ptr32 _ETHREAD
    
       +0x030 SecurityQos : _SECURITY_QUALITY_OF_SERVICE
    
       +0x03c StaticSecurity : _SECURITY_CLIENT_CONTEXT
    
       +0x078 LpcReplyChainHead : _LIST_ENTRY
    
       +0x080 LpcDataInfoChainHead : _LIST_ENTRY
    
       +0x088 ServerProcess : Ptr32 _EPROCESS
    
       +0x088 MappingProcess : Ptr32 _EPROCESS
    
       +0x08c MaxMessageLength : Uint2B
    
       +0x08e MaxConnectionInfoLength : Uint2B
    
       +0x090 Flags : Uint4B
    
       +0x094 WaitEvent : _KEVENT

    Field

    Description

    ConnectedPort

    Points to the Server Communication Port

    ConnectionPort

    Points to the Server Connection Port

    MsgQueue.Semaphore

    Used to signal the server thread about the presence of a message in MsgQueue.ReceiveHead

    MsgQueue.ReceiveHead

    Head of a doubly linked list containing all the messages that are waiting to be dequeued by the server.

    MsgQueue.NonPagedPortQueue

    Points to the LPCP_NONPAGED_PORT_QUEUE structure for the client communication port for tracking lost replies.

    LpcReplyChainHead

    Head of a doubly linked list containing all the threads that are waiting for replies to messages sent to this port.

    LPC Message Data Structure

    LPC消息是将信息从LPC客户机传送到LPC服务器的数据结构,可以是各种类型的,如连接、请求、关闭等。
    LPCP_MESSAGE是LPC用来表示消息的内部数据结构。LPCP_MESSAGE结构是从带有标记“LpcM”的系统范围的lookaside列表中分配的。

    kd> dt nt!_LPCP_MESSAGE
    
       +0x000 Entry : _LIST_ENTRY
    
       +0x000 FreeEntry : _SINGLE_LIST_ENTRY
    
       +0x004 Reserved0 : Uint4B
    
       +0x008 SenderPort : Ptr32 Void
    
       +0x00c RepliedToThread : Ptr32 _ETHREAD
    
       +0x010 PortContext : Ptr32 Void
    
       +0x018 Request : _PORT_MESSAGE

    Field

    Description

    Request.MessageId

    Generated from the value of a global epoch LpcpNextMessageId. Used to uniquely identify a message.

    SenderPort

    Points to the LPCP_PORT_OBJECT of the client communication port

    Entry

    Is the list entry that is used to queue the message to the Server Communication/Connection Port’s MsgQueue.ReceiveHead

    Request

    Is a copy of the message buffer that was provided as the Request parameter to the call to NtRequestWaitReplyPort() or a copy the message buffer that was provided as the Reply parameter to NtReplyWaitRecivePortEx().

    LPC related fields in Thread Data Structure

    kd> dt nt!_ETHREAD -y Lpc
    
       +0x1c8 LpcReplyChain : _LIST_ENTRY
    
       +0x1f4 LpcReplySemaphore : _KSEMAPHORE
    
       +0x208 LpcReplyMessage : Ptr32 Void
    
       +0x208 LpcWaitingOnPort : Ptr32 Void
    
       +0x228 LpcReceivedMessageId : Uint4B
    
       +0x23c LpcReplyMessageId : Uint4B
    
       +0x250 LpcReceivedMsgIdValid : Pos 0, 1 Bit
    
       +0x250 LpcExitThreadCalled : Pos 1, 1 Bit

    下表描述了用于LPC客户端和服务器进程之间通信的ETHREAD数据结构的字段。

    Field

    Description

    LpcReplyMessageId

    Contains the ID of the message sent to the server while the client thread is waiting on the response.

    LpcWaitingOnPort

    Used by the LPC Client Thread to stores the LPC client communication port on which it is waiting for a reply.

    LpcReplySemaphore

    Used to block the LPC Client Thread while the server is processing the LPC message.

    LpcExitThreadCalled

    Used by the Lpc APIs to determine if the thread is currently in the process of exiting and if so returns STATUS_THREAD_IS_TERMINATING from the API call.

    LpcReplyChain

    Used to queue the thread to the list of threads waiting for replies from the server communication/connection port. The list head of this list is in LPCP_PORT_OBJECT->LpcReplyChainHead.

    Important global LPC connection ports

    Table 5

    Field

    Description

    LsaAuthenticationPort

     Used for the following tasks:

    1. Security package management like Kerberos, NTLM etc…
    2. Credential management
    3. User Account management
    4. EFS (Encrypted File System) key encryption, decryption

    SmssWinStationApiPort

     This port is used by the CSRSS to manage Window Stations i.e. multiple sessions.

    ErrorLogPort

     This port is used by IO manager and other components to send error log entries to the EventLog service.

    Important LPC port fields in the Process

    (nt!_EPROCESS)

    Table 6

    Field

    Description

    SecurityPort

    LSA uses this port for EFS (encrypted file system) and authentication.

    ExceptionPort

     When a thread does not catch an exception an LPC_EXCEPTIONmessage is sent to this port. A subsystem might register an LPC port in this field to receive second chance exception information of process running in the subsystem. Default action of CSRSS is to terminate the process.

    DebugPort

     The kernel dispatches user mode exceptions to the process debugger on this port. Debug outputs using OutputDebugString( ) are passed to this port as DBG_PRINTEXCEPTION_C.

    Important LPC port fields in the Thread

    (nt!_ETHREAD)

    Table 7

    Field

    Description

    TerminationPort

    This is not a single port rather a chain of ports registered with the Process Manager. The process manager notifies all ports when the thread terminates.

    LpcWaitingOnPort

    This field has the address of the client communication port when the client thread waits for a reply to a LPC message from a server thread.

    请继续关注……在下一篇文章中,我们将卷起袖子,深入研究LPC的调试扩展,以及您可能发现这些调用被卡住的一些常见状态。

  • 相关阅读:
    《Hadoop实战》第一章
    找工作必备技能
    范数的深刻解读(转自知乎)
    贝叶斯定理(贝叶斯分类)
    什么是机器学习?
    线性可分 与线性不可分
    正则化和归一化
    过拟合问题是什么?
    CVPR 2016 paper reading (6)
    CVPR 2016 paper reading (3)
  • 原文地址:https://www.cnblogs.com/yilang/p/13580976.html
Copyright © 2011-2022 走看看