windows CreateProcessWithLogonW() 问题 - 需要使用同一用户启动子进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/595176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CreateProcessWithLogonW() problems - Need to launch sub-processes with the same user
提问by Adam Cobb
I have a Windows executable that is launched from within a service by calling CreateProcessWithLogonW() with a set of specfied user details.
我有一个 Windows 可执行文件,它通过使用一组指定的用户详细信息调用 CreateProcessWithLogonW() 从服务中启动。
This works fine and the process starts as expected. However, when this process tries to launch other processes itself, currently just using CreateProcess() these start then die straight away - they are executables that require desktop access.
这工作正常,过程按预期开始。然而,当这个进程试图自己启动其他进程时,目前只使用 CreateProcess() 这些启动然后立即死亡 - 它们是需要桌面访问的可执行文件。
After reading up on Microsoft's article on CreateProcess() - http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx
阅读微软关于 CreateProcess() 的文章后 - http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx
I think can see why this is happening and it makes sense to an extent. CreateProcess() knows the calling process is impersonating a user so it uses it's parent process, which in this case is the Local System account. But of course anything run in the local system account doesn't have the access we need, so the launched process dies.
我认为可以理解为什么会发生这种情况,并且在一定程度上是有道理的。CreateProcess() 知道调用进程正在模拟用户,因此它使用它的父进程,在这种情况下是本地系统帐户。但是当然,在本地系统帐户中运行的任何东西都没有我们需要的访问权限,因此启动的进程就会终止。
Oddly when I was previously using LogonUser() and CreateProcessAsUser() to launch the initial executable within the service, it worked fine. But I had to change this to CreateProcessWithLogonW() due to problems with not having the correct privileges.
奇怪的是,当我之前使用 LogonUser() 和 CreateProcessAsUser() 在服务中启动初始可执行文件时,它运行良好。但是由于没有正确权限的问题,我不得不将其更改为 CreateProcessWithLogonW()。
Does anybody know of a solution to this? I've seen talk about this elsewhere on the web but not with any definite solution. It seems like I possibly need the token of the user i'm logging on with in CreateProcessWithLogonW() with so I can use it to launch the other processes later? But I have no way of getting hold of this token, can this be retreived for the current user in any way?
有人知道解决这个问题的方法吗?我在网上的其他地方看到过关于这个的讨论,但没有任何明确的解决方案。似乎我可能需要我在 CreateProcessWithLogonW() 中登录的用户的令牌,以便以后可以使用它来启动其他进程?但是我没有办法得到这个令牌,这可以以任何方式为当前用户检索吗?
Any help would be greatly appreciated, thanks :)
任何帮助将不胜感激,谢谢:)
采纳答案by vladr
Do you own the code launched using CreateProcessWithLogonW
(and which in turn calls CreateProcess
)? If you do not then you might need to perform IAT (or API) hookingon it (i.e. at run-time), as to substitute any calls to CreateProcess
with an appropriate procedure that also uses CreateProcessWithLogonW
or CreateProcessWithTokenW
. See APIHiHyman, Detours.
您是否拥有使用CreateProcessWithLogonW
(并且反过来调用CreateProcess
)启动的代码?如果您不这样做,那么您可能需要对其执行IAT(或 API)挂钩(即在运行时),以便将任何调用替换为CreateProcess
也使用CreateProcessWithLogonW
或的适当过程CreateProcessWithTokenW
。参见APIHiHyman、Detours。
After this is done, the child process may require access to HKCU
. If you are not already doing this, you should load the profile of each impersonated user, once per user, before calling CreateProcessWithLogonW
.
完成此操作后,子进程可能需要访问HKCU
. 如果您还没有这样做,您应该在调用 之前加载每个模拟用户的配置文件,每个用户一次CreateProcessWithLogonW
。
By default, CreateProcessWithLogonW does not load the specified user profile into the HKEY_USERS registry key. This means that access to information in the HKEY_CURRENT_USER registry key may not produce results that are consistent with a normal interactive logon. It is your responsibility to load the user registry hive into HKEY_USERS before calling CreateProcessWithLogonW, by using LOGON_WITH_PROFILE, or by calling the LoadUserProfile function.
默认情况下,CreateProcessWithLogonW 不会将指定的用户配置文件加载到 HKEY_USERS 注册表项中。这意味着访问 HKEY_CURRENT_USER 注册表项中的信息可能不会产生与正常交互式登录一致的结果。您有责任在调用 CreateProcessWithLogonW、使用 LOGON_WITH_PROFILE 或调用 LoadUserProfile 函数之前将用户注册表配置单元加载到 HKEY_USERS 中。
回答by SAMills
We solved the problem using some code that I found long-ago. The "copyright" section of one of the source modules contains the following:
我们使用我很久以前找到的一些代码解决了这个问题。源模块之一的“版权”部分包含以下内容:
/////////////////////////////////////////////////////////////
// CreateProcessAsUser.cpp
//
// Written by Valery Pryamikov (1999)
//
// Command line utility that executes a command under specified user identity
// by temporarily installing itself as a service.
//
// Based on Keith Brown's AsLocalSystem utility (http://www.develop.com/kbrown)
// Uses some code from Mike Nelson's dcomperm sample utility
// and from tlist sample (Microsoft Source Code Samples)
//
// Use:
// CreateProcessAsUser.exe [-i[nteractive]]|[-s[ystem]]|
// [-u"UserName" -d"DomainName" -p"Password"]|[-a"AppID"] command
// Command must begin with the process (path to the exe file) to launch
// -i process will be launched under credentials of the
// "Interactive User" (retrieved from winlogon\shell process)
// -a process will be launched under credentials of the user
// specified in "RunAs" parameter of AppID.
// -s process will be launched as local system
// -u -d -p process will be launched on the result token of the
// LogonUser(userName,domainName,password,LOGON32_LOGON_BATCH...)
//
// either (-s) or (-i) or (-a) or (-u -d -p) parameters must supplied
//
// Examples:
// CreateProcessAsUser -s cmd.exe
// CreateProcessAsUser -a"{731A63AF-2990-11D1-B12E-00C04FC2F56F}" winfile.exe
//
/////////////////////////////////////////////////////////////
Perhaps this information will yield hits within your Google searches - I attempted a few quick attempts but came up empty-handed. We decomposed the internals into a set of API that yielded the results we needed.
也许这些信息会在您的 Google 搜索中产生点击量 - 我尝试了几次快速尝试,但空手而归。我们将内部结构分解为一组 API,以产生我们需要的结果。
回答by Eric Petroelje
Isn't there an option for services to allow them to interact with the desktop? If setting that option for your service is a possibility, that would probably be the simplest solution.
服务没有选项可以让它们与桌面交互吗?如果可以为您的服务设置该选项,那可能是最简单的解决方案。
回答by Jared Oberhaus
I'm assuming that this process is a service; that isn't specified in the question, but seems logical given that it is running as Local System account.
我假设这个过程是一个服务;问题中未指定,但考虑到它作为本地系统帐户运行,这似乎是合乎逻辑的。
Where you're getting stuck isn't in CreateProcess
, It's in CreateService
. If you want your service to be able to interact with the desktop, you have to specify SERVICE_INTERACTIVE_PROCESS
as one of the flags to the argument dwServiceType
. This setting is inherited by child processes of the service.
你被卡住的地方不在CreateProcess
,而在CreateService
。如果您希望您的服务能够与桌面交互,您必须将其指定SERVICE_INTERACTIVE_PROCESS
为参数的标志之一dwServiceType
。此设置由服务的子进程继承。
You can also modify an existing service's setting by using the Services tool, select Properties for the service, click on the "Log On" tab, and select the check box "Allow service to interact with desktop".
您还可以使用服务工具修改现有服务的设置,选择服务的属性,单击“登录”选项卡,然后选中“允许服务与桌面交互”复选框。