2014-11-21 57 views
5

我使用CreateProcessAsUser在用户指定的凭据下创建一个进程。CreateProcessAsUser创建空白/黑色窗口

我发布了希望代码的相关部分。让我知道你是否想看更多。

首先LogonUser的获得令牌:

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

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

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

这工作正常 - 它登录并成功创建过程,并且过程“工作”。问题是,它创建的窗户是黑色的,因为在这个截图记事本进行的与我的计划启动:

notepad screenshot

可能相关的方面:

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

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

我也不能使用CreateProcessWithLogonW函数,因为它从SYSTEM帐户运行时必须工作 - 该函数以及随Windows附带的“runas”程序在SYSTEM下无效。有趣的是,我不能使用我当前的方法来打开进程,除非我在SYSTEM帐户下运行它,因为“所需的特权不是由客户端持有的”,所以我无法比较这些窗口在我的帐户下启动我的程序vs SYSTEM帐户时创建...

+0

您是否传递| envblock |?这看起来很像我成功使用的代码。不同之处在于(可能):我总是传递一个使用CreateEnvironmentBlock()创建的环境块,而我的情况下的用户令牌来自WTSQueryUserToken()。 – NuSkooler 2014-11-21 23:14:50

+0

@NuSkooler如果对CreateEnvironmentBlock()的调用成功,那么我会传递该环境块。如果程序没有通知我,调用就会成功,我使用Process Explorer检查了进程环境,并且加载了用户的环境。 – eurotrash 2014-11-22 07:50:27

+1

@NuSkooler:WTSQueryUserToken会为您提供一个令牌,其中包含目标会话的登录SID,因此您的子进程已拥有对窗口站和桌面的所有必要权限。这就是为什么它为你工作,但不是为了OP。 – 2014-11-22 22:22:01

回答

4

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

LogonUser的调用会生成新会话(和关联的登录SID),而不是重新使用现有的,所以你的过程无法访问桌面,只有最低限度的访问窗口站。 (其实我对这个过程如何管理运行有点困惑;当我试图重现你的结果时,程序立即退出,退出代码为0xC0000142,如预期的那样)。

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

+0

添加权限到窗口站和桌面修复它,非常感谢。 Re:使用代码0xC0000142立即退出进程,实际上我也经历过这种情况,如果用户的凭据传递给我的程序不是管理员组的成员。如果它是成员,则该过程将成功启动。在进行更改以成功显示GUI后,我仍然遇到此行为。仍然排除故障...... – eurotrash 2014-11-22 13:22:11

+0

我猜测链接答案中的代码只是针对管理用户进行过测试,您可能只需调整一个或两个权限掩码即可。我编辑了我的答案,以包含我建议先尝试的更改。请让我知道这是否有效,如果是这样,我会相应地编辑其他答案。 – 2014-11-22 22:19:48

+0

我可以确认添加了'READ_CONTROL'和'WINSTA_ALL_ACCESS'这个窗口站的访问权限已经解决了它:在非管理员帐户下创建的进程成功启动。非常感谢! – eurotrash 2014-11-23 12:58:16