I am developing a program for Windows which consists of two components:
A kernel driver (signed with an EV certificate)
A user-level GUI component, the .exe file (written in Delphi).
The .exe requires to be run elevated, in order to start the driver and perform other elevated tasks.
How can such a program be automatically run on Windows startup without displaying UAC prompt?
I saw that many similar applications, such as Anti-Malware programs, are able to startup elevated, without UAC prompt.
I am considering the following options, and would be grateful if you can point to the right direction:
1. Set driver startup as automatic, launch .exe from kernel service
However, my research indicates that there is no documented way to start a user-level process from the kernel.
2. Create a separate user-level service which will start the .exe
I read that user-level services are exempt from UAC.
A possible approach would be to create an automatic startup user-level service, which just runs the .exe process (using CreateProcessAsUser()) and then terminates itself.
3. Convert the .exe program from a Delphi GUI application to a user-level service
Similar to option 2, but instead of creating a separate .exe for the service, we are converting the current GUI application to work also as a service.
I found some documentation about this on this StackOverflow thread.
However, this approach seems more complicated then creating a separate dedicated service.
4. Does an EV certificate provide some advantage to allow this task?
5. Is there any better way other then the above mentioned ones?
As it was pointed out by Sertac Akyuz in his comment you should use windows Task Schedluer for this.
With Task Scheduler you can create a task that will run at user logon and run your EXE with highest privileges available.
And when I say highest privilege available I mean the highest privilege of current user when you specify a group of users in When running the task, use the following user account field provided that current user is a member of that group. So if current user does not have sufficient right to execute programs with elevated privileges the task will execute your application with standard privileges.
But as field name suggest you can also specify that this task will always run your application using a specific user account meaning that it will use that account privilege levels instead of of the current user account.
Any way using task scheduler to execute GUI application that comes with some drivers is quite popular. For instance ASUS uses such approach to launch their AI Suite program that allows monitoring and tweaking various settings of their motherboards. Here is how such task is configured on my computer.
PS: I have purposely chose to show you task properties for ASUS AI Suite as it is actually made with Delphi
Related
Recently, I once again came across the problem of having to run my Windows app on startup and wondered which of the options is the most usual one and causing least trouble long term.
Registry
Add string value of the path to your exe to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run or \HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run for x86 applications running on a x64 Windows.
Feels the most natural
Fairly easy, especially when using frameworks simplifying registry entry creation
When uninstalling an application, you could end up with a dead registry entry
User won't be able to edit this entry
Autostart
Create a .lnk inside the user or system wide autostart folder (shell:startup).
Able to do it programmatically
Very easy to create, add arguments and modify
User is able to edit entries in his usual environment
Task scheduler
Create a 'When the computer starts' or 'When I log on' run entry in the Task Scheduler.
Able to do it programmatically
There is a GUI, but I would assume the average user won't find it
So what are further considerations when selecting an option?
Registry is always being used by production software, since that's the most controlled way and Windows suggests it.
Pros:
No need to enter the users personal space (powershell:startup)
Option to autostart the software only once (windows cleans up the registry)
Decide if the software should autostart for the whole local machine or the current user
Can be executed even when the machine is started in safe mode by using RunOnce with an exclamation point (!)
Here you can read more information about using Run and RunOnce Registry Keys.
shell:startup(not recommended) is the personal startup folder of the user, where shortcuts are being stored, that have been created & copied over by the user. The user will also experience an error prompt, if the application has been deleted, but the shortcut still remains. [BAD USER EXPERIENCE]
Task Sheduler is great for scripting, conditional event triggering and mostly used by Administrators. This option would be overkill, since Registry is much simpler and doesn't leave a Task Event, that the user has to disable on his own.
There is a GUI, but I would assume the average user won't find it
Task Manager [Startup tab] will display applications that will be automatically executed by Windows (registry & startup), which allows the user to enable/disable the software from doing that, so that's not an issue.
TLDR: Registry is by far the most used and best option to automatically run software.
The registry and start-menu are pretty similar. The registry gives you zero control over the execution, the only setting is the command line arguments. The start-menu uses shortcuts so that gives you the ability to control the working directory and initial window state.
The task scheduler is not the traditional way to launch startup applications. It feels like overkill and that you are trying to be obscure on purpose.
I'm trying to figure out how to install software when the PC reboots Note that this is on machine startup, not user login. Anyone have any suggestions? Google searches just return how to set programs to start on user login. That's not what I need.
You have a few puzzle pieces to unravel here:
Choosing a mechanism for running on startup prior to user login. For this, the fact that your task is installation of further software doesn't matter. A "service" is the usual way to do this, although for example antivirus software tends to use device drivers.
Automating scheduling your code to run at startup. If you chose a service in the above step, this means using the Service Control Manager API.
Actually doing the work, without having an active user login session. Services run in an environment where there is no UI available, the user registry is associated with a service account and not any real user, etc. Other than that, code runs normally (you can load DLLs, access files and directories, etc). Permissions needed by your installer may also become a problem and cause you to modify the service installation options in step 2.
I'm developing a Windows application that must execute other GUI programs with privileges (executed as administrator).
Scope
My application is a "daemon", a long-running process that it will be launched with no user action;
My application must be executed as administrator (privileges elevation);
Processes executed by my application must be executed as administrator and must display on the screen.
Approach
Firstly, I developed my application as Windows service. I thought that it was the best way to run programs with privileges but services can't run programs that use the GUI session.
This restriction has been introduced by Microsoft with Windows Vista. An article from Microsoft - Impact of Session 0 Isolation on Services and Drivers in Windows - explains these changes. I tried to change the user who runs my service but this isolation appears to apply for all services.
Purpose
So my question is "What's the best way to run a program that it will launch another program with elevation of privileges (executed as administrator) with no action from user ?"
Currently, the only once idea to solve my problem is to register my application into Task Scheduler but I think that it probably exists a best way.
Windows Services have not been designed to interact in current session (user session). Services are running into Session 0 since the deployment of Windows Vista.
Explanations about this changes can be found in "Impact of Session 0 Isolation on Services and Drivers in Windows".
I have found another Microsoft post "Launching an interactive process from Windows Service in Windows Vista and later" but we can read at the beginning:
The first thing you should do about it is that, don't do it. There are many limitations, bad implications and restrictions involved into it.
Windows Services are definitely a wrong solution for this use case. The unique solution that I can found is the Task Scheduler.
Let's say app.exe has been built with requireAdministrator manifest as detailed here (this is really needed for a reason that would be out of topic here). When launching the app, when Windows UAC is enabled, there is a normal prompt:
Now this application needs to run on Windows startup: in an Options dialog, there is a "Launch at Windows startup" checkbox that can be checked or not. When checked, it adds a key in the registry in
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
to enable this "launch on Windows startup feature".
Problem: At Windows startup, when app.exe is (automatically) launched in background, there is this UAC dialog box (see screenshot before), which is annoying for the user.
Question: How to make that app.exe can be launched 1. with requireAdminstrator 2. silently at Windows startup ?
What is the clean way to do this? Lots of software do this (indexing software that both run on background since Windows startup, and don't show such a dialog box).
Note: I would like to avoid TaskScheduler method if possible: https://www.sevenforums.com/tutorials/11949-elevated-program-shortcut-without-uac-prompt-create.html
The indexing software "Everything" does show such a dlalog.
The others you are thinking of run only services with admin rights, not UI.
Running a service requires the software to be architected with that intent, ordinary user applications can be started with the service rules with the help of the "at" service, which you already know how to do (Task Scheduler).
You can substitute some other service for Task Scheduler, at the risk of annoying the user through needless duplication, waste of resources, and likely new security flaws.
Set aside your preference, and use Task Scheduler.
Or remove the background parts of your app and write a service to do those instead.
And be very careful when giving your code administrator rights. Any bug can result in subverting the entire security infrastructure. With great power comes great responsibility.
This is a Windows 2003 (or later) machine that gets switched on every morning, but no one logs on until some hours later.
I want to use the time in between to run a backup script c:\script\backup.cmd
How can I start this unattended after the machine has come up?
I tried 2 registry keys, but this resulted in the script being run after a user logs on (which is too late):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices
In the end I used Windows TaskScheduler, who has such an option, but I was wondering if there is another possibility?
Short answer: GPEDIT.MSC (Start, Run, GPEdit.msc)
Windows 2000 and above [1] offer a computer Startup Scripts collection in the policy editor:
Computer Settings -> Windows Settings -> Scripts (Startup/Shutdown)
There's an equivalent logon script area (i.e. after computer startup, when a user logs on) in the User configuration bit.
Longer:
GPEDIT.MSC is the Group Policy editing console, and runs against the local computer's Local Group Policy store when it's used directly, so it's useful for setting local-only parameters. When using Active Directory, a similar interface is used to edit AD Forest-hosted group policy objects (GPOs), so the same settings are available across a bunch of machines.
The computer startup scripts run in the computer context, i.e. as LocalSystem, as you noted, so they often can't access network drives which require a certain user or group membership to work. When domain-member computers access network resources, they generally (with exceptions) authenticate using their MACHINENAME$ account - which lets you set Share/NTFS permissions to allow a computer to access those resources.
A startup script is a quick and easy way of getting a process running when the machine boots.
The computer startup process will be affected by the time it takes to run the program, though, so you might want to ensure you call it with the START command from a batch file, or specifying not to wait for the executable to complete in whatever script language you use. (the key point there is: run the script asynchronously unless it's critical, or doesn't need to be run asynchronously cos it will always take no time at all. Long boots = unhappy users).
Using a Win32 Service is an alternative option - you can use the SRVANY utility from the Resource Kit to "service-ify" pretty much any executable. VS.Net 2002 and later also let you build a managed service directly.
And Task Scheduler gets much more capable as of Vista/2008, able to run scripts at startup, on idle, and/or when Event Logs are generated or certain other conditions are met: it's pretty cool! Scheduled Tasks has the possible advantage of being able to specify the user account under which the task runs, if that's important to you.
Caveat Scriptor:
http://support.microsoft.com/kb/256320
Run Startup Scripts Asynchronously:
http://msdn.microsoft.com/en-us/library/ms811602.aspx
Vista Task Scheduler (what's new):
http://technet.microsoft.com/en-us/appcompat/aa906020.aspx
[1] Windows XP, 2003, Vista/2008, Windows 7/2008R2, Windows 8/2012, Windows 8.1/2012R2, Windows 10/Windows Server 2016. Everything. But NT4 didn't!
You have already outlined a good solution:
Setup a scheduled task to run at Start Up and allow the job to run when the user isn't logged on.
You can run a script at system startup using group policy gpedit.msc
The way you aleady do this seems fine to me; however if you want an alternative approach then services get started when the machine boots so you could write a service that detects if it's a new day (to allow for reboots) and if it is then run your backup.
If I was doing this as a service I'd use TCL because I know it and like it and it has an extension twapi that allows you to run a script as a service. Other scripting languages may well have similar facilities.
There is, if you're using Active Directory. If you can isolate the computer to its own OU or use WMI filtering, you could assign a GPO which has a startup script for the computer. This would ensure that even if someone went in via safe mode and disabled the Task Scheduler, upon startup and connection to the domain, the script would run.