您只能在与您的进程相同的终端服务会话(也称为远程桌面会话)上枚举窗口。但是,如果有适当的权限,您可以在另一个终端服务会话中启动子进程来代表您完成工作,但您需要了解潜在的安全问题,具体取决于您如何执行此操作。
假设您已经获得了目标进程的句柄,最简单的方法是使用OpenProcessToken
在目标会话中获取令牌、DuplicateTokenEx
复制它并CreateProcessAsUser
启动子进程。由于您只需要一个是/否的答案,因此您可以使用进程退出代码而不需要 IPC 机制。
安全隐患:由于您的子进程在用户的上下文中运行,因此知识渊博的用户可能会阻止它正常运行。此外,如果您确实使用 IPC 机制,则必须将来自子进程的输入视为不受信任(检查缓冲区溢出等)。
另一种方法是在您自己的上下文中但在目标会话中启动子流程。IIRC,您可以通过复制自己的令牌并SetTokenInformation
在副本上使用来更改TokenSessionId
,然后再使用CreateProcessAsUser
.
安全隐患:子进程,以及通过它的服务进程和服务帐户,可能会受到破坏攻击(恶意窗口消息)和其他风险,尽管完整性级别机制可能会在一定程度上缓解这种情况。据我了解,创建单独的窗口站和桌面(使用适当的 ACL)可以消除这些风险,但我不确定对您要运行的代码的影响。另一种缓解措施是CreateRestrictedToken
在启动子进程之前从令牌中删除所有组和权限。
除非绝对必要用户不能破坏您检测对话框窗口存在的能力,否则我强烈推荐第一种方法。