CreateProcessAsUser创建空白/黑色窗口

时间:2014-11-21 20:32:14

标签: c++ c winapi

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

我发布了希望代码的相关部分。如果您想再看到更多内容,请与我们联系。

获取令牌的第一个LogonUser:

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);

这很好用 - 它会成功登录并创建流程,并且流程“有效”。问题是它创建的窗口是黑色的,就像在我的程序启动的记事本流程的屏幕截图中所示:

notepad screenshot

可能相关的背景:

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

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

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

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

1 个答案:

答案 0 :(得分:5)

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

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

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