【问题标题】:How RpcServerInqCallAttributes knows what ClientPID to retrieveRpcServerInqCallAttributes 如何知道要检索的 ClientPID
【发布时间】:2022-06-11 18:01:37
【问题描述】:

我正在阅读函数RpcServerInqCallAttributes (source)。

我看到一个程序(vmcompute.exe)这样调用这个函数(基于反转):

RPC_CALL_ATTRIBUTES CallAttributes;  

memset(&CallAttributes, 0, sizeof(CallAttributes));
CallAttributes.Version = 3;
CallAttributes.Flags = RPC_QUERY_CLIENT_PID;
Status = RpcServerInqCallAttributes(0, &ClientContextAttributes);

它检索 dockerd 的 PID,但它如何知道要检索的 PID?
它只是使用RPC_QUERY_CLIENT_PID 来查询PID,但基于什么?它没有指定进程的名称。

我阅读了this 的答案,但没有解释它如何知道要检索哪个进程 PID。

【问题讨论】:

  • “它如何知道要检索的 PID”是什么意思?进程id(即ClientPID结构体成员)是发起RPC调用的客户端进程的id,通常在RPC服务器例程中调用RpcServerInqCallAttributes。
  • 哦,我想我明白了。 RPC 会话的这一部分。在我的情况下,可能dockerd 调用vmcompute.exe(即RPC 服务器)中的一个函数,然后vmcompute 调用RpcServerInqCallAttributes 来识别调用进程(dockerd)。但是如果有多个客户端联系 RPC 服务器会发生什么,它怎么知道要检索哪个进程 ID?
  • 如果在 RPC 服务器例程线程中调用 RpcServerInqCallAttributes,则客户端是明确的,否则您必须将客户端绑定句柄作为第一个参数传递。
  • 好的,谢谢。我想我明白了。

标签: c++ winapi visual-c++ rpc


【解决方案1】:

RpcServerInqCallAttributes 及其较低级别的 I_RpcBindingInqLocalClientPID 都将 RPC_BINDING_HANDLE Binding 作为它们的第一个参数:

RPC_STATUS RpcServerInqCallAttributes(
  [in]      RPC_BINDING_HANDLE ClientBinding,
  [in, out] void               *RpcCallAttributes
);

RPC_STATUS I_RpcBindingInqLocalClientPID(
  [in, optional] RPC_BINDING_HANDLE Binding,
  [out]          unsigned long      *Pid
);

本地 RPC 请求通常通过 ALPC 发送,其中传递的每条消息都包含数据负载和 LPC/ALPC 协议标头,由PORT_MESSAGE structure 描述。此标头具有ClientId 字段,其中包含发件人 PID 和 TID。 收到 ALPC 请求后,服务器进程内的 RPC 运行时将这些值保存在 RPC_BINDING_HANDLE 对象中,可以从中检索它们。

将 NULL 句柄传递给 RpcServerInqCallAttributes/I_RpcBindingInqLocalClientPID 意味着使用当前线程的活动绑定,在这种情况下,这些 API 通过 ReservedForNtRpc 字段从当前线程的 TEB、IIRC 中获取 RPC_BINDING_HANDLE 指针。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多