提问人:InversionDK 提问时间:11/2/2023 更新时间:11/2/2023 访问量:37
使用命名管道获取 ProcessID 的安全方法
Safe way to get ProcessID using Named Pipes
问:
我有一个由 GUI 和服务组成的应用程序。它们在同一台计算机上运行,并通过 WCF 通过命名管道进行通信。
从服务中,我尝试获取通过命名管道调用服务的进程的进程 ID。但是,在使用 WCF 时,我很难做到这一点。
我创建了一个测试应用程序,它允许我使用没有 WCF 的命名管道(直接通过 System.IO.Pipes)来执行此操作 - 但我能弄清楚如何做到这一点的唯一方法需要我使用 SafePipeHandle.DangerousGetHandle()。
我想知道是否有人可以给我一些指导
- 是否可以使用 WCF 或不使用 DangerousGetHandle() 来获取 PID?
- 使用 SafePipeHandle.DangerousGetHandle() 方法可以吗?(听起来不安全)
我真的不想将 PID 作为元数据或来自 GUI 的消息的一部分发送,因为这很容易被欺骗。
我的示例服务器代码:
static void Main(string[] args)
{
using (var server = new NamedPipeServerStream("TestPipe", PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous))
{
Console.WriteLine("Server waiting for connection...");
server.WaitForConnection();
using (StreamReader reader = new StreamReader(server))
{
string message;
while ((message = reader.ReadLine()) != null)
{
uint clientProcessId;
if (NativeMethods.GetNamedPipeClientProcessId(server.SafePipeHandle.DangerousGetHandle(), out clientProcessId))
{
Console.WriteLine($"Received: {message} from PID {clientProcessId}");
}
else
{
Console.WriteLine("Failed to get client process ID.");
}
}
}
server.Disconnect();
}
Console.WriteLine("Server disconnected...");
}
NativeMethods 只是一个包装器:
public static class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetNamedPipeClientProcessId(IntPtr Pipe, out uint ClientProcessId);
}
任何指点将不胜感激。我已经完全没有想法了:)
答:
0赞
Tenatus
11/2/2023
#1
我假设当服务器仍连接到管道时,管道的句柄将保持有效,因此这是对一般不安全方法的安全使用。
警告的风险是针对标记为无效/重用的句柄,但我认为您的代码根本不可能出现这种情况: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.safehandle.dangerousgethandle
评论
0赞
InversionDK
11/3/2023
我有点担心文档中的这个表述:“例如,不受信任的调用方可以查询刚刚返回的句柄上的数据,并接收完全不相关资源的信息。如果我在请求传入时验证客户端的 ProcessID(例如,通过验证进程签名或类似方法)作为服务器上的第一件事,这会让我免受这种情况的影响吗?
0赞
Tenatus
11/3/2023
我认为管道的句柄在服务器之前不会失效。Disconnect() 行。该代码从管道中获取 SafeHandle 并立即使用底层句柄,因此我认为 Windows 不可能在此过程中重用它。存放该手柄并在以后使用它会很危险。
评论