In my research of "what is a process" every page keeps saying that it's exactly like a process but no GUI. So why does it need/have a PID? On top of that, I've seen 2 services with the same PID.
What's the real relationship between services and processes?
No two processes can have the same PID. Difference between service & process is that the service doesn't have user associated with it so it starts before any user login to the system where as process usually runs with a user login token.
Related
I wanted to know if there was any way of checking if a particular process was started by the user by him/her double clicking, typing the required commands in cmd, via the address bar in explorer, etc. or by another program using CreateProcess() or ShellExecute().
I tried checking the parent process id of the created process but failed to see any consistency among the parent pids of the user initiated processes. I wanted to know if there was any other way or a fool proof way using the ppids.
First you have to determine what the "process started by user" means to you. From Windows' point of view all the processes are started by another processes, whether it was somehow triggered by user or not.
I can only think of getting processes belonging to currently logged on user otherwise i doubt that you can distinguish processes created on a system.
I want to run an application under another user account's (non-elevated) credentials while that user is already logged-in. Specifically, I want my application's installer (which runs under any administrator account) to spawn processes into each logged-in user's desktop session. These processes communicate with a service and display windows on the desktop for the user to interact with.
Ordinarily, from a service running as LocalSystem, the approach is WTSQueryUserToken -> CreateProcessAsUser. However, WTSQueryUserToken won't run outside of the LocalSystem account (with SE_TCB_NAME privilege), which makes that approach fail here.
If the user weren't logged in already, I could just register the application to run under HKLM\...\Run, so that any logged-in user will get a copy of the application when they log in. But if the user's already logged-in, that doesn't work either (at least, not until they log out and log back in again).
I can see two possible answers:
You can't do this. Sorry.
You can get a token from somewhere else (maybe enumerate explorer.exe processes and pull the access token from each one?), call DuplicateTokenEx, then pass to CreateProcessAsUser. I tried this approach and consistently received "access denied" when trying to OpenProcessToken on a process running under another user session, even with the debug privilege enabled and the process opened with PROCESS_ALL_ACCESS.
What do you think?
If the answer is #1 ("you can't do this"), then what is the recommended best practice for spawning non-elevated processes to mediate between a service and the user? Is it best practice for the service to spawn these processes into each session via CreateProcessAsUser? Or is it best practice for the non-elevated processes to be run separately (e.g. via HKLM\...\Run or HKCU\...\Run)?
I have developed a C# Windows Forms application that runs in the background as a systray icon and does some stuff when it's clicked. It is supposed to launch when Windows starts and run continously, and a normal user without administrator rights shall not be allowed to shut it down.
What is the best way to do this? I initially intended to run it on the LocalSystem account through Task Scheduler, but then I learned (the hard way) about Session 0 isolation (i.e. the application will run but its UI elements do not show). When I run it with the logged in user, even if it runs elevated, the user can still shut it down through task manager (without requiring elevation).
Is there any way to give a process from LocalSystem access to the UI? I have a winlogon and a csrss process from LocalSystem running in session 1, so I guess it can be done, I just don't know how. Or is there maybe an easier way to disallow users to shut down a process of their own through the task manager? The only other option I can think of is to create an extra Windows Service that keeps polling if the app is running, and immediately launches it again if someone kills it - but that seems incredibly clumsy (also, I want it to stay dead when it crashed by itself, to avoid a single bug causing infinite loops of process creation).
Deponds on why they can't shut it down.
The natural way to go would to have created a service, started by a high priv account, and then had the desktop app just show what it was doing.
If there's something that they should see, but don't becasue they aren't running the service monitor app. (and acknowledge message back to the service), send them an email, send their boss an email, send yourself one and then go shout at them.....
Be a lot easier than trying to get the lid back on this tin of worms.
A nice way to make sure the desktop app is ruuning, would be simply to schedule it to run every X, but drop out immediately if it already is or the somethingwenthorriblywrong flkag is set.
Not worth writing a service to check if it's still there, as they could kill that as well, unless you want to make that a service they can't kill. :(
You are trying to be too draconian with this. Add some sort of auditing so you can see it dies or was shutdown, monitor that and deal with any adverse reports. It's a heck of a lot easier, and gives manage something to do...
You can run an administrative process in the user's logon session. One method would be to for a master process (a system service) to duplicate its own token, use SetTokenInformation to change the session associated with the token, and then call CreateProcessAsUser. The lpStartupInfo parameter can be used to associate the process with a particular window station and desktop. It may be necessary to explicitly change the permissions on the window station and desktop first.
HOWEVER, this is a bad idea from a security standpoint, because GUI applications are vulnerable to malicious messages sent from other processes on the same desktop ("shatter attacks").
It would be safer to run the process in the user's own context but apply an ACL to it. This can be done using the lpProcessAttributes parameter to CreateProcess or CreateProcessAsUser, or with the SetSecurityInfo function. I've never tried this, but it should in theory prevent the user from using task manager to close the process.
If you are creating the process from the user's context, then the user will be the owner, so a sufficiently knowledgeable person could change the permissions back in order to terminate the process. If you need to block this hole, using CreateProcessAsUser from a privileged master process (the token can be duplicated from one of the existing processes in the user's session) should (again, in theory) mean that the user is not the process owner.
Another potential issue: if you listen for messages indicating that the user is logging out (in order to exit) such a message could be faked. If you don't then you need to find some other way of exiting when the user logs out. You may need to experiment here, I'm not sure how the system will react.
Is it allowed to have some process's icon to be displayed in all user sessions including terminal/multiple local logons, without spawning another process per each session? I don't need to share any windows between session, just the status icon to be able to check service's status without taking additional actions..
It's not even possible. Shell_NotifyIcon communicates with a single instance of Explorer.EXE, the one running in the current user context.
Processes can only access the interactive window station and desktops in the same session as the process. So this means you need one process per session.
I know at least one program that do it - TightVNC server running as a service. You can lookup their sources to understandhow it's done.
I am building a Windows service that will watch for specific occurrences of events and disk activity. When such an event occurs my plan is to alert the user to the event via a client app, and provide remediation if necessary. I have (mostly) completed both the client and service components, which work great... unless the client app isn't running.
In short, I am looking for a way to start up the client app from the Windows service via CreateProcess to provide information to the user. However, it appears the service can't even see the file/folder of the client app to execute it. I suspect this is due to the credentials under which the service is running, or maybe due to service level restrictions, but wanted to reach out for some advise before I get into this any deeper.
So, the obvious question first... am I thinking about this clearly? Is the architecture plan sound, or should I look at another method? I would prefer not to re-do any of the work I have already completed, but obviously want to make sure the plan and process is solid.
Question #2, what are the limitations I face with this model? Is there a service account that will allow this level of access?
I am obviously struggling with this right now, so any thoughts or assistance will be greatly appreciated!
Thanks,
Kris
As others have mentioned already, you can't (easily) launch an application directly from the service, so I think the easiest way around the problem is to create a process that starts on login and runs with the credentials of the logged in user, eg an app that sits in the system tray, and it opens up a named pipe or a network port to the service. If the service needs to alert the user, it sends a message down that channel and then the client process can either show its own UI or launch an application. Interprocess communication using pipes or ports are the simplest way to deal with the restrictions on session 0 processes.
A Windows service does not have access to the user session in Vista and above, so it is blocked from starting an executable on that session. You can download a white paper from Microsoft that goes into detail: Impact of Session 0 Isolation on Services and Drivers in Windows.
Since Vista, services run in session 0 and the user's desktop is always in a different session. Thus you need to work hard to start a service on the user's desktop.
It can be done but it is pretty tricky. Details can be found here: http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx?wa=wsignin1.0