【问题标题】:Windows API: find process for a file mapping handleWindows API:查找文件映射句柄的进程
【发布时间】:2013-12-16 06:44:17
【问题描述】:

我创建了一个具有预定义协议的 SSH 代理(类似于 PuTTY 的 pageant.exe):身份验证请求通过包含文件映射名称的 WM_COPYDATA 发送到代理窗口:

// mapname is supplied via WM_COPYDATA
HANDLE filemap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapname);

是否可以找出哪个进程(最终是进程名称)创建了特定的文件映射?

我可以在“filemap”上使用 GetSecurityInfo 来获取安全属性(SID、GID、...),但如何获取进程本身?

重要提示:无法更改协议(例如,将有关发送者的信息添加到 WM_COPYDATA),因为这是所有 PuTTY 类应用程序使用的预定义协议!

【问题讨论】:

  • 可以以未记录的方式枚举用户空间中的所有 HANDLE。然后可以过滤“节”句柄(MemoryMapping)。但麻烦从这里开始。可能会留在用户空间并使用“OpenProcess”、“DuplicateHandle”和 GetFinalPathNameByHandle(在专用线程中,因为可以“挂起”)但内存映射不是文件......唯一的方法是动态加载一点内核驱动程序,但必须在 64b 操作系统上签名。

标签: winapi ipc file-mapping


【解决方案1】:

不要试图通过文件句柄来查找进程,您需要枚举进程以找到每个进程的打开句柄,这很复杂。 WM_COPYDATA 消息将发送者窗口的句柄发送给您,调用 GetWindowThreadProcessId 应该会给您答案。

请记住,WM_COPYDATA 是一种在 32 位和 64 位进程之间进行通信的方式,因此您的进程可能与调用者位于不同的空间中。

编辑-->
您在 WM_COPYDATA 中收到发送方 HWND,您只需使用该 HWND 即可获取进程 ID

switch (uiMsg)
{
case WM_COPYDATA:
    {
        DWORD theProcessID;
        GetWindowThreadProcessId((HWND) wParam, &theProcessID);
        COPYDATASTRUCT *pMyCDS = (PCOPYDATASTRUCT) lParam;
        /*...*/
    }
    /*...*/
}

【讨论】:

  • 如上所述:无法更改协议。我忘了提这个。 “它很复杂”是指它需要内核驱动程序(如上面的答案所述)?还是确实存在一种用户空间方式(枚举所有进程,枚举每个进程的所有句柄,检查句柄是否是我们通过 WM_COPYDATA 获得的句柄)?关于 32 位和 64 位:我不明白。进程总是在不同的地址空间中,这就是为什么使用 WM_COPYDATA。
  • 进行了编辑以显示 HWND 已经在 WM_COPYDATA 中而没有更改任何内容。
  • 您应该注意 WM_COPYDATA 的 wParam 可能为 NULL。没有“发射器”窗口,没有什么能阻止 SendMessage
猜你喜欢
  • 2014-01-18
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
相关资源
最近更新 更多