I'm having the following setup: The DLL I'm writing is loaded dynamically at runtime and offers some API-like functionality to the host application. The host application is not running with admin rights (and therefor my DLL isn't either).
Some tasks my DLL needs to fulfill need admin rights though, specifically I have to save and copy files to the program files folder.
My current approach is to launch external applications via ShellExecute and the "runas" verb, which triggers the UAC prompt. This especially means that multiple subsequent actions triggered by the user will always result in an additional UAC prompt, which could be pretty annoying.
So the idea would be to launch a separate, elevated process once, which then runs in the background and receives the respective commands and executes them. This brings me to my question: Which methods of communication are even possible between an unelevated process and its elevated child process? Access to stdin seems to be forbidden due to obvious security reasons, but what about named pipes or shared memory? Do the same restrictions apply?
Related
Is there some way to launch a process in non-elevated way from an elevated one. My setup is launched elevated and when it finalizes, it will just launch the main application. Because the setup is elevated, the main process will be elevated as well which is not desirable. What is the best solution to this?
That's a problem, Vista/Win7 don't appear to have an API to obtain the unprivileged user token you need to call CreateProcessAsUser(). The only solutions I've found involve using the task scheduler to launch the program. That doesn't strike me as very practical.
An easy solution that jumps to mind is to use a small non-elevated helper process. It can in turn launch the elevated setup process and wait for a confirmation from that one to launch the non-elevated one. The handshake is simple enough to do this with a named mutex.
The only way to do this without hacks is to have two processes (Can be implemented in the same .exe)
Instance A starts Instance B with ShellExecute and the runas verb.
B does the installing, when its time to start your app on the "finish page", it uses some form of inter processes communication (RPC, shared memory+events etc) with A telling it to start a process on its behalf.
This seems like a nice way to do it, provided you don't care about situations where the Shell is not running (e.g. possibly some Terminal Services application-only setups, perhaps, though I'm not sure):
http://brandonlive.com/2008/04/27/getting-the-shell-to-run-an-application-for-you-part-2-how/
It gets an interface to Explorer.exe, which should be running in the user's normal context, and asks Explorer to execute a command in its behalf. This is done just using simple, documented COM interfaces and without having to mess around with process tokens or code/DLL injection.
I have an inyector application to map a remote DLL into another process. The process i am trying to insert into have its own manifest and require admin privileges. I am trying to use CreateProcess since i can create the process in a suspended state, do my mapping into remote memory and then resume it.
Now according to MS i can use ShellExecute with the runas verb but this will start running the process right away. Is there any method to request the user to run the process as admin and at the same time creating the process in a suspended state?.
If the target executable has a UAC manifest that specifies requiresAdminstrator then you don't need to do anything extra. Just use CreateProcess() normally and let the OS deal with the elevation for you. Elevation will be applied to the new process before CreateProcess() returns control back to you.
You only need to elevate manually if the target executable DOES NOT have a UAC manifest that forces elevation. In which case, you can use something like CreateProcessElevated() if you do not want to use ShellExecute/Ex().
I have an Avast antivirus and it has a process "AvastSvc.exe". If I try to end/kill that process in Windows Task Manager, then a windows with the following messages appears: "Unable to Terminate Process", "The operation could not be completed.", "Access is denied". Trying to end some system Windows processes (like winlogon.exe) may feature the same behaviour (although once I managed to kill winlogon.exe and got my machine hanged!).
I want my application (possibly, converted to a service) behave in the same way. How can I do this?
Disable Windows Task Manager so he cant kill my process is a similar question which has many interesting answers, but they don't seem to feature the technique which is used by the above antivirus and results in "Unable to Terminate Process" message.
http://forums.codeguru.com/showthread.php?t=503337 has a solution on how to prevent stopping a service (eg, via services.msc console), but I need preventing ending/killing its process in Task Manager.
I am writing the app in C++/winapi, no CLR/.Net, under Windows 7.
UPDATE on permissions:
Antivirus process AvastSvc.exe is owned by "system" account. However, I have other processes owned by "system" account, and they are killable and antivirus is not. Also, I compared executable permissions and owners of antivirus process and ones of killable processes, and I don't see any difference.
UPDATE on user control and purpose of the software:
The software functionality is somewhere between that of system and business software. The nature of the software requires it to run on a permanent basis. The application itself will have a "turn off" action, and we want to encourage users to use it and discourage them from killing the process (it's similar to what antiviruses do). I understand that it's not possible to completely prevent users from killing it, but I want to make it harder. This question is specifically about the way described above ("Unable to Terminate Process") which some services (like Avast) use to prevent killing their processes. It is sufficient for me to achieve just the same behavior. Also, users will be able to just uninstall the software if they don't like it/don't need it anymore.
This is not achieved through code (well, it might be for critical Windows system processes, but you are [probably] not writing components of the operating system), but rather through access permissions.
You can demonstrate this by elevating to Administrator and then attempting to kill Avast's process. It should succeed this time. Alternatively, you can take ownership of the executable (and possibly the folder in which it resides), then try to kill the process. Again, it should be successful.
Windows does not allow applications to exert more power over the computer than the user. If you own the machine and have the appropriate permissions, you can do anything you want, including terminating a running process. Thankfully, there is no way for you, as a developer, to block this.
The user is always in ultimate control. Attempting to create an alternative situation is a battle that virus and other malware developers fight—and lose—regularly. Since I'm not interested in helping anyone write malware, that's all I'm going to say about that.
And other than writing malware, I can't imagine what the motivation for this "feature" in an application would be in the first place. If you're simply trying to prevent regular users from killing a process that is critical to a business system, then you should just demote the privileges of the standard user accounts so that they will not be able to tamper with such things. As such, this is probably a job for Group Policy, rather than code.
I found that the function ProtectProcess() supplied in Prevent user process from being killed with "End Process" from Process Explorer results exactly in the effect I was looking for.
Hide your process by removing it from the eprocess structure
Issue persistent I/O requests that cannot be cancelled or completed by other processes
Create threads to debug your own process
Create separate process/es from memory that monitors the main process and re-starts it from memory once terminated by another process
I need a certain process to be constantly running in every user’s computer. If that .exe is killed, I must be able to restart it and send an alert.
I immediately thought of building a Windows Service as the ideal solution, but I am facing a problem:
The process started by that service needs to be able to interact with the user, e.g. be able to show him a GUI.
my application also sets a keyboard hook in order to monitor the user's typing rhythms, and when I start the .exe from a service, that information is not accessible.
From the service I am able to launch the process "as the user" (using the LogonUser and CreateProcessAsUser functions), but still can’t see the GUI.
Is this possible? If not, what can I use to achieve the desired functionality?
tia
By default the GUI .exe will be run in the service session, which is separate from the interactive session of the user. You need to look into techniques for building an interactive service.
I have a single thread that I'd like to run as an administrator in my application. The rest of the application I can happily run as the default user level (asInvoker). Is this possible? I notice there is an "ImpersonateLoggedOnUser" function. Can I somehow use this to log the administrator on and then get the thread to impersonate that person?
It seems as though this ought to be something pretty trivial to do ... but there doesn't appear to be any obvious way to do it. Can anyone help me out?
Edit: So if I have to fire off a seperate process is there any way I can CreateProcess a new process and have it launch from a specific entry point. I can, of course use command line processing to do it, but i'd really rather I could stop the user from entering the command line and starting an unclosable process!
No, elevation is per process, not thread.
If the rest of the application has to run non-elevated, you could run yourself elevated with some parameter (myapp.exe /uac "ipcparamhere") and use some sort of Inter-process communication to communicate back to the "main instance" of your app. (If the elevated process only performs a simple operation, you could probably check for success by using the exit code of the process)
This is not possible. You'll need to gain admin privileges by including a manifest in the app. Google "requireAdministrator" to find the manifest you'll need. Your user will probably quickly tire of doing this over and over again, your best bet is to spin-off the task that requires these privileges into a separate process. A service for example.
You can launch a separate exe and have a manifest on it saying it requires administrator. Then be sure to launch it with shell execute, which uses manifests, and you're all set. As a thoughtful touch, put a UAC shield on the button that kicks off that thread. (Send it a BCM_SETSHIELD message if you're doing this all by hand.)
You can decided whether you want a visible window or not on the separate process. Meanwhile the user can still drag and drop into the main app.