wraithdu Posted October 29, 2009 Posted October 29, 2009 (edited) First, thanks to arcker for his Services UDF for making this possible. It works like this:When launched, the app will install itself as a service, launch the service, then exit. The service runs in the SYSTEM account. To interact with the desktop of the currently logged on user it will get the security information from the winlogon.exe token and the user's environment from the explorer.exe token. The service will relaunch the app with these security settings and environment, then stop. On relaunch, the process will wait for the service to end then uninstall it. The process will now be running in the SYSTEM account in the currently logged on user's session with the user's environment. If you look into the _Svc_Main() function there's a note about how to relaunch the process in Session 0 (same as the service) if you need to do this. In this case it will be running solely in the SYSTEM account in Session 0 with it's own environment.I've included two more functions for when you need to access certain other user specific items, such as using the @UserName macro, or accessing the HKCU branch of the registry (these things are not taken from the environment, but from the security context of the process). You should test any macros you intend to use to make sure the correct information is returned before running your process for real. _ImpersonateUserStart() and _ImpersonateUserEnd() will enable and disable this impersonation. Keep in mind this alters your security access as well, you will have the same security level as the logged on user during this time.NOTE: For retrieval of the user environment and user impersonation it is required that explorer.exe is running. If you're using a 3rd party shell replacement, you can edit the UDF to change the requirements to another process, but I can't guarantee it will work.I've included a stripped down version of arcker's UDF, since not all of it is needed. If I could get some test results from users running XP and Vista/7 with UAC, that would be great too.Sources:Link 1Link 2ANY SCRIPT USING THESE FUNCTIONS MUST BE COMPILED TO WORK. IT WILL NOT WORK FROM SCITE.ADMIN RIGHTS REQUIRED AS WELL.UPDATE 1 (2009/10/29)- added a function to launch a process as the user of a currently running process in the specified session (ie, to de-elevate a process back to your user account).UPDATE 2 (2009/10/29)- fixed a wrong function export which caused problems on XP (thanks trancexxx)UPDATE 3 (2009/10/30)- I think I have a stable version now, tested on Win7, XP SP3 VM, and a physical XP SP3 box. As a bonus the service control handler now works in Win7 as well, so we can have a fully functioning service._Services_Mini.au3SystemElevate.au3 Edited October 30, 2009 by wraithdu this-is-me and zalomalo 2
arcker Posted October 29, 2009 Posted October 29, 2009 Excellent that's how remote installation works (psexec is a good example, or other deployment software ) -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 I'm still curious how psexec works (if it's not by this same procedure). I wish Sysinternals would release source for their apps. So much to learn... Duck 1
trancexx Posted October 29, 2009 Posted October 29, 2009 Excellentthat's how remote installation works (psexec is a good example, or other deployment software )What do you mean 'Excellent'? It works for you?@wraithdu, CreateProcessAsUser function is exported by advapi32.dll.I got it working, but some funny crashes while. XP SP3. ♡♡♡ . eMyvnE
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 (edited) I don't have XP readily available to test, so if there are problems I'll try to look into it. Anything more specific to offer? Post the contents of the log maybe? Edited October 29, 2009 by wraithdu
trancexx Posted October 29, 2009 Posted October 29, 2009 I don't have XP readily available to test, so if there are problems I'll try to look into it. Anything more specific to offer? Post the contents of the log maybe? Logs are gone. This: $ret = DllCall("kernel32.dll", "int", "CreateProcessAsUserW", "ptr", $hDupToken, "ptr", 0, "wstr", $sAppPath, "ptr", 0, "ptr", 0, "int", 0, _ "dword", $dwCreationFlags, "ptr", $pEnvBlock, "ptr", 0, "ptr", DllStructGetPtr($SI), "ptr", DllStructGetPtr($PI)) If Not @error And $ret[0] Then ... It's not "kernel32.dll". ♡♡♡ . eMyvnE
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 Good catch. Strangely CreateProcessAsUser is also exported by kernel32 on Win7. Guess that's why I didn't notice.
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 (edited) Fixed and updated. Also tested in an XP SP3 VM and it works fine after the fix. Edited October 29, 2009 by wraithdu
monoceres Posted October 29, 2009 Posted October 29, 2009 (edited) Good catch. Strangely CreateProcessAsUser is also exported by kernel32 on Win7. Guess that's why I didn't notice.Microsoft have moved lots of the api's that was currently inside different modules into kernel32.dll. This is probably because the speed / efficiency increase is now more important than the memory footprint. The exports in advapi32 and similar are just probably just redirects and are probably there because microsoft doesn't want applications to break on win7 (very strange indeed ). Edited October 29, 2009 by monoceres Broken link? PM me and I'll send you the file!
trancexx Posted October 29, 2009 Posted October 29, 2009 (edited) Btw, I found what was/is causing the crash.It's ProcessWaitClose($CmdLine[2]) you use. It should be:Case "-run" ; as elevated app ; wait for service to end and uninstall service (PID passed as $CmdLine[2]) ProcessClose($CmdLine[2]) ; <- This! MsgBox(0, "Hey", "Closed") _RemoveService() ...edit: Or something like that Edited October 29, 2009 by trancexx ♡♡♡ . eMyvnE
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 (edited) No, it's supposed to be ProcessWaitClose() as the Service will stop itself properly, and the process must wait for it to close before removing it. That said, I tested on another XP system and did get a crash, but it's a crash in the service, not the newly spawned process. Once you close the crashed app the new process will continue. I still don't know why the service is crashing though. Edited October 29, 2009 by wraithdu
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 It's crashing right here _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0) WTF?
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 (edited) Turns out the problem is stopping the service cleanly in Win7. I can issue a _Service_Stop() command even from in the service in XP and it ends. In 7 that control message is never received so the thing doesn't exit cleanly (leaves a crash log in Event Viewer). Unless arcker or someone can figure that out, I might just switch to using ProcessClose() to kill the service before removing it. It's ugly and bad, but I don't have another workaround at the moment. EDIT: I'm confused again. Now it seems to work OK the way I had it in Vista. Maybe I just need to use _Service_Stop() in XP instead. Edited October 29, 2009 by wraithdu
trancexx Posted October 29, 2009 Posted October 29, 2009 Turns out the problem is stopping the service cleanly in Win7. I can issue a _Service_Stop() command even from in the service in XP and it ends. In 7 that control message is never received so the thing doesn't exit cleanly (leaves a crash log in Event Viewer).Unless arcker or someone can figure that out, I might just switch to using ProcessClose() to kill the service before removing it. It's ugly and bad, but I don't have another workaround at the moment.EDIT:I'm confused again. Now it seems to work OK the way I had it in Vista. Maybe I just need to use _Service_Stop() in XP instead.I think there is a problem with logic.Why don't you exit after successful CreateProcessAsUserW. Don't return if ok, just exit. That makes sense to you? ♡♡♡ . eMyvnE
wraithdu Posted October 29, 2009 Author Posted October 29, 2009 Doesn't matter. I tried, but it was still crashing / hanging. But I've had a breakthrough! I switched to use RegisterServiceCtrlHandlerExW() and a HandlerEx() callback and....it works in Win7! So I'm testing a proper course of events here where the new process stops the service, waits for it to close, then removes it. So far it is working in Win7 and I'm about to do testing in XP. It also seems that calling the _DebugLog() function at certain times causes a hang, especially if it's called from the child before the server has ended, so we must be careful about that.
wraithdu Posted October 30, 2009 Author Posted October 30, 2009 I think I have it stable now. I'm going to test again tomorrow on my XP computer at work and make sure it works there too, then I'll post the update.
wraithdu Posted October 30, 2009 Author Posted October 30, 2009 Updated above. It seems to be stable on all my test machines/VMs now. As a bonus I've got the service control handler working in Win7
wraithdu Posted October 30, 2009 Author Posted October 30, 2009 I noticed an uneven number a downloads above...be sure to download both scripts, as they both have been updated.
trancexx Posted October 30, 2009 Posted October 30, 2009 (edited) I noticed an uneven number a downloads above...be sure to download both scripts, as they both have been updated. You mean: Mod($iNumberofDownloads, 2) = True or not? edit: Not crashing and working ok on XP SP3. Nice job. 5 from me. Edited October 30, 2009 by trancexx ♡♡♡ . eMyvnE
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now