2

We have a service that runs as LocalSystem. We use CreateProcessAsUser and LoadUserProfile to start a working app as a specific user. Works just great. But if we try to use CreateProcessWithTokenW to avoid explicitly loading and managing user profile, it fails, and the following is recorded in event log:

Faulting application name: SomeApp.exe, version: 1.0.0.0, time stamp: 0x578a7819
Faulting module name: KERNELBASE.dll, version: 10.0.10586.494, time stamp: 0x5775e4c5
Exception code: 0xc06d007e
Fault offset: 0x0000000000071f28
Faulting process id: 0x24e4
Faulting application start time: 0x01d1df8d223316a6
Faulting application path: C:\SomePath\SomeApp.exe
Faulting module path: C:\Windows\system32\KERNELBASE.dll
Report Id: a2310c0d-7ddf-4241-92c9-de03e8de71e8
Faulting package full name: 
Faulting package-relative application ID:

Is there a trick to get CreateProcessWithTokenW to work?

Ken White
  • 123,280
  • 14
  • 225
  • 444
Alex I
  • 2,078
  • 3
  • 18
  • 24
  • and what you want ? based on your info impossible give answer. you need paste some code or use debugger for view where error – RbMm Jul 18 '16 at 00:11
  • I want CreateProcessWithTokenW to succeed where CreateProcessAsUser does. – Alex I Jul 18 '16 at 01:48
  • 1
    It's impossible to tell you why your code does not work when we cannot see your code. See [ask] and then [edit] your question to include a [mcve]. – Ken White Jul 18 '16 at 02:20
  • Most probable cause: according to the documentation, CreateProcessAsUser will (by default) create a new window station and desktop with appropriate permissions based on the user token. The documentation for CreateProcessWithTokenW does not mention this, so presumably you need to do it yourself. (Assuming this is the problem, it would probably be easier to stick with CreateProcessAsUser.) – Harry Johnston Jul 18 '16 at 03:10
  • @Harry Jonston, that may explain it. – Alex I Jul 18 '16 at 06:30
  • i dont think that here problem in window station - i test this (call CreateProcessWithTokenW without any code for window station and desktop) and this work well. however CreateProcessWithTokenW is very "heavy" function (compare to CreateProcessAsUser) - it use rpc call to svchost seclogon service(seclogon.SlrCreateProcessWithLogon) which internal call .. CreateProcessAsUser . without more info - hard say in what problem. this is new created process start and crashed ? in this case need debug it – RbMm Jul 18 '16 at 10:39
  • @RbMm, did you test CreateProcessWithTokenW running as LocalSystem? – Alex I Jul 18 '16 at 16:00
  • @AlexI - exactly CreateProcessWithTokenW - no, only CreateProcessAsUser. now check this for shure – RbMm Jul 18 '16 at 16:05
  • @AlexI - just test (exec notepad from service) by CreateProcessAsUser and CreateProcessWithTokenW - both functions really exec process and return true. but CreateProcessWithTokenW create interactive(visible) notepad on "\Sessions\1\Windows\WindowStations\WinSta0" when CreateProcessAsUser create invisible notepad at "\Windows\WindowStations\WinSta0" - now try invistigate more deep – RbMm Jul 18 '16 at 16:28
  • @AlexI, - i research this - all task in TokenSessionId - usually before call CreateProcessAsUser we set TokenSessionId from interactive session to token. and this is woked. but CreateProcessWithTokenW by self set creator process sessionId in token - as result your new process created in session 0 – RbMm Jul 18 '16 at 16:59
  • @AlexI and in previous comment i confuse functions names - CreateProcessAsUser create visible notepad and CreateProcessWithTokenW create invisible notepad – RbMm Jul 18 '16 at 17:01
  • CreateProcessWithTokenW: "If the lpDesktop member is NULL or an empty string, the new process inherits the desktop and window station of its parent process. The function adds permission for the specified user account to the inherited window station and desktop. Otherwise, if this member specifies a desktop, it is the responsibility of the application to add permission for the specified user account to the specified window station and desktop, even for WinSta0\Default." So CreateProcessWithTokenW *should* work, *provided* you haven't specified a window station and desktop. Have you? – Harry Johnston Jul 18 '16 at 21:42
  • ... oh, and things might also get messed up if you're impersonating at the time of the call. – Harry Johnston Jul 18 '16 at 21:50
  • What happens if you launch notepad (as per RbMm's suggestion) rather than your application? – Harry Johnston Jul 18 '16 at 21:55

1 Answers1

8

when CreateProcessWithTokenW called - system make RPC call to ncalrpc:[SECLOGON] and actually main task done in context of some svchost. SeclCreateProcessWithLogonW from seclogon.dll called. here trase of this function call: enter image description here

internally CreateProcessAsUserW called, but before this - you can view call - SetTokenInformation(..TokenSessionId..) - so another sessionid assigned to token (read comment about this in MSDN - The process is run in the session specified in the token. By default, this is the same session that called LogonUser. To change the session, use the SetTokenInformation function.) which is this SessionId ? this is your service - look for call ProcessIdToSessionIdStub. but we really need have interactive SessionId in token, not from service. so my conclusion - CreateProcessWithTokenW not suitable for exec interactive process from service

---------- EDIT ----------------------

CreateProcessWithTokenW - very thick shell around CreateProcessAsUserW. CreateProcessAsUserW required SE_ASSIGNPRIMARYTOKEN_PRIVILEGE, but CreateProcessWithTokenW - not. by this reason CreateProcessWithTokenW used remote call to seclogon service (which have SE_ASSIGNPRIMARYTOKEN_PRIVILEGE) for call CreateProcessAsUserW internally. but if we have SE_ASSIGNPRIMARYTOKEN_PRIVILEGE - better direct call CreateProcessAsUserW by self. main restrictions of CreateProcessWithTokenW that he set SessionId in token, based of caller process SessionId and we can not change this. however CreateProcessAsUserW not modify SessionId in token - so we can by self set interactive SessionId in token or do nothing, if this token already from interactive session. if we call CreateProcessWithTokenW from service - started app will be run on nointeractive window station (belong to session 0)

RbMm
  • 31,280
  • 3
  • 35
  • 56
  • You trace has no mention of CreateProcessWithTokenW. Instead it is about CreateProcessWithLogonW. – Alex I Jul 18 '16 at 20:42
  • @AlexI no, both CreateProcessWithTokenW and CreateProcessWithLogonW call CreateProcessWithLogonCommonW - i not mistake – RbMm Jul 18 '16 at 20:44
  • @AlexI - look - http://i.imgur.com/V51b0vx.png BOOL WINAPI CreateProcessWithLogonCommonW( __in HANDLE hToken, __in LPCWSTR lpUsername, __in_opt LPCWSTR lpDomain, __in LPCWSTR lpPassword, __in DWORD dwLogonFlags, __in_opt LPCWSTR lpApplicationName, __inout_opt LPWSTR lpCommandLine, __in DWORD dwCreationFlags, __in_opt LPVOID lpEnvironment, __in_opt LPCWSTR lpCurrentDirectory, __in LPSTARTUPINFOW lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInfo ); – RbMm Jul 18 '16 at 20:47
  • I don't think the OP is trying to make the new process visible to the interactive user. Also, the documentation for `CreateProcessWithTokenW` is very clear that the new process winds up in the session specified by the token provided, are you *certain* that this isn't true? Have you actually seen it put a process into the wrong session? – Harry Johnston Jul 18 '16 at 21:32
  • @HarryJohnston 1) if we not need visible process - CreateProcessWithTokenW will be worked in general well - process started and runned (tested on notepad). but however - better use direct CreateProcessAsUserW 2) "are you certain that this isn't true?" - yes !! this is true for CreateProcessAsUserW but not for CreateProcessWithTokenW - dont know this is documentation or windows bug – RbMm Jul 18 '16 at 21:43
  • @HarryJohnston 3) i investigated this by self today (win 8.1 x64) - exec notepad.exe from service with CreateProcessWithTokenW and CreateProcessAsUserW - 2 notepad running - 1 visible in session 1 and one invisible in session 0. but i pass same token for both calls 4.) what is happens in seclogon - i describe - SlrCreateProcessWithLogonW overwrite SessionId in token! – RbMm Jul 18 '16 at 21:44
  • @HarryJohnston Have you actually seen it put a process into the wrong session? - yes – RbMm Jul 18 '16 at 21:44
  • however - no any crash in my test. all worked. so why crash was for topic starter - how i wrote at very begin - need more info. may be app crashed because not design running in invisible mode ? – RbMm Jul 18 '16 at 21:45
  • A search on the exception code didn't turn up much concrete information, but it suggested that it usually arises when a process doesn't have the right permissions to the window station and/or desktop. I found the part of the documentation that explains why CreateProcessWithTokenW works, seems it changes the window station and desktop permissions. I think we need a MCVE from the OP at this point. – Harry Johnston Jul 18 '16 at 21:49
  • but notepad launched by CreateProcessWithTokenW work well on invisible windows station. no any problems with permissions – RbMm Jul 18 '16 at 21:51
  • I believe it works because CreateProcessWithTokenW changes the permissions. Without knowing exactly how the OP is calling it, it's probably futile to try to guess why it isn't working for him. And yes, it might also be something unusual that the child process is doing. – Harry Johnston Jul 18 '16 at 21:54
  • @HarryJohnston maybe. but wrote general explanation about CreateProcessWithTokenW and CreateProcessAsUserW. and i claim that exist bug in documentation or realization of CreateProcessWithTokenW: "The process is run in the session specified in the token. By default, this is the same session that called LogonUser. To change the session, use the SetTokenInformation function." this is true only for CreateProcessAsUserW, CreateProcessWithTokenW overwrite this – RbMm Jul 18 '16 at 21:58
  • That comes down to the question of whether the OP is attempting to launch the process in a different session or not. We'll have to wait for clarification. – Harry Johnston Jul 18 '16 at 22:01
  • @HarryJohnston i exec 2 notepad from service with SAME token and all parameters - and look for result - http://i.imgur.com/CT05qbJ.png – RbMm Jul 18 '16 at 22:07
  • one notepad (2c4) (launched by AsUser) - in interactive session 1 (this and was in token) and one notepad (850) (launched WithToken) in session 0 – RbMm Jul 18 '16 at 22:09
  • That's very interesting, and I'll want to experiment with it myself at some point, but I'm not sure whether it is relevant to the question. If the token the OP is using is in session 0, it won't make any difference. – Harry Johnston Jul 18 '16 at 22:12
  • @HarryJohnston yes, if need run in same session - no problem. but i test exec notepad in interactive session(1) from service in session(0). also now i change call order (in first test i call CreateProcessAsUser and than CreateProcessWithTokenW) - now visa versa - as result both nopepad in o session - this is because CreateProcessWithTokenW affect SessionId in token (replace 1 to 0) – RbMm Jul 18 '16 at 22:16
  • @HarryJohnston if direct call ZwSetInformationToken(hProcess, TokenSessionId, &SessionId, sizeof(SessionId)); before CreateProcessAsUser (this is after CreateProcessWithTokenW call) - again got interactive notepad in session 1. so definitely windows bug – RbMm Jul 18 '16 at 22:20
  • For my reference, what version of Windows are you running on? – Harry Johnston Jul 18 '16 at 22:23
  • win 8.1 x64 but i can check this now on another versions – RbMm Jul 18 '16 at 22:24
  • It'll probably be the same for all current versions, but it *would* be an interesting experiment. Would you be willing to email me the source code to your test application? (My email address is in my profile.) – Harry Johnston Jul 18 '16 at 22:34
  • @HarryJohnston - you was right. i now check on win 10 x64 - and notepad created by *WithToken - crashed (failing init) - 0db0:0230 @ 00710531 - LdrpInitializeNode - ERROR: Init routine 00007FFCA13CA8D0 for DLL "C:\Windows\system32\USER32.dll" failed during DLL_PROCESS_ATTACH – RbMm Jul 18 '16 at 22:40
  • @RbMm What tool did you use to get the API Trace screenshot? – user1438233 Nov 06 '22 at 13:20
  • @user1438233 - my own tool – RbMm Nov 06 '22 at 13:22
  • @RbMm Looks like an awesome tool, can you share it? – user1438233 Nov 07 '22 at 07:52
  • @user1438233 - this is part of my debugger. look at [*about*](https://stackoverflow.com/users/6401656/rbmm?tab=profile). are you have concrete problem, where i can help ? – RbMm Nov 07 '22 at 09:36