【问题标题】:CreateProcessAsUser creates blank/black windowCreateProcessAsUser 创建空白/黑色窗口
【发布时间】:2015-01-20 02:23:02
【问题描述】:

我正在使用 CreateProcessAsUser 在用户指定的凭据下创建一个进程。

我希望发布代码的相关部分。如果您想看更多内容,请告诉我。

获取令牌的第一个登录用户:

result = LogonUser(
        username,
        wcschr(username, '@') ? NULL : (domain ? domain : L"."),
        password,
        LOGON32_LOGON_INTERACTIVE,
        LOGON32_PROVIDER_DEFAULT,
        &hrunastoken);

然后我加载配置文件,将 STARTUPINFO 结构的 lpDesktop 值设置为 NULL(这使它使用调用进程的桌面),然后调用 CreateProcessAsUser:

result = CreateProcessAsUser(
        hrunastoken,
        NULL,
        apptorun,
        NULL,
        NULL,
        FALSE,
        CREATE_UNICODE_ENVIRONMENT,
        envblock ? envblock : NULL,
        NULL,
        &si,
        &pi);

这工作正常 - 它成功登录并创建进程,并且进程“工作”。问题是它创建的窗口是黑色的,正如我的程序启动的记事本进程的截图所示:

可能相关的上下文:

我的帐户是具有完全管理员权限的 Windows 7 计算机上的本地帐户,并且我使用该帐户登录。我使用 psexec(Sysinternals 实用程序)打开在本地系统帐户下以交互方式运行的命令提示符。我正在从该命令提示符启动我的程序。我传递给它的凭据来自我的帐户。

我没有对windowstations/desktops 做任何事情;我假设我创建的进程应该拥有这些权限,因为该进程是在我的会话中创建的,并且使用我已经登录的相同帐户 - 尽管首先通过 SYSTEM 帐户。使用Process Explorer,我看不到通过我的程序打开的进程与正常打开的进程对windowstation/desktop的值和句柄的权限有任何区别。也许这完全无关紧要。

我也不能使用 CreateProcessWithLogonW 函数,因为它必须在从 SYSTEM 帐户运行时才能工作 - 该函数以及 Windows 附带的“runas”程序在 SYSTEM 下不起作用。

有趣的是,除非我在 SYSTEM 帐户下运行它,否则我无法使用我当前的方法打开进程,因为“客户端没有所需的权限”,所以我无法比较创建的窗口在我的帐户与 SYSTEM 帐户下启动我的程序时...

【问题讨论】:

  • 你在通过|envblock|吗?这看起来很像我成功使用的代码。差异是(可能):我总是传递一个使用 CreateEnvironmentBlock() 创建的环境块,而我的用户令牌来自 WTSQueryUserToken()。
  • @NuSkooler 如果对 CreateEnvironmentBlock() 的调用成功,那么我通过环境块。调用成功,如果没有,程序会通知我,我用 Process Explorer 检查了进程环境,并加载了用户的环境。
  • @NuSkooler:WTSQueryUserToken 将为您提供一个令牌,其中包括目标会话的登录 SID,因此您的子进程将已经拥有对窗口站和桌面的所有必要权限。这就是为什么它对你有用,但对 OP 无效。

标签: c++ c winapi


【解决方案1】:

窗口站和桌面的默认 DACL 授予对登录 SID(当前 logon session 唯一)而不是用户 SID 的完全访问权限。 (用户的 SID 也出现在窗口站的 DACL 中,但只有有限的权限。它不会出现在桌面 DACL 中。)

LogonUser 的调用会生成一个新会话(和关联的登录 SID),而不是重复使用现有的会话,因此您的进程无法访问桌面,并且只能访问窗口站的权限很小。 (实际上,我对进程是如何运行的有点困惑;当我试图重现你的结果时,进程立即退出,退出代码为 0xC0000142,正如预期的那样。)

this answer 中的第二段代码显示了如何更改窗口站和桌面上的 DACL 以允许进程正常运行。 (不过,这可能不是最佳解决方案,具体取决于您的具体目标。)

【讨论】:

  • 添加窗口站和桌面权限修复了,非常感谢。回复:进程立即退出,代码为 0xC0000142,如果我将凭据传递给我的程序的用户不是管理员组的成员,我实际上也遇到了这种情况。如果它是成员,则该过程成功启动。在进行更改以成功显示 GUI 后,我仍然遇到这种行为。仍在排除故障...
  • 我猜链接答案中的代码仅针对管理用户进行了测试,您可能只需要调整一个或两个权限掩码。我已经编辑了我的答案,以包括我建议首先尝试的更改。请让我知道这是否有效,如果有效,我将相应地编辑另一个答案。
  • 我可以确认将READ_CONTROLWINSTA_ALL_ACCESS添加到window station的访问权限已经解决:在非管理员帐户下创建的进程启动成功。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
相关资源
最近更新 更多