Windows : How to protect process from getting killed in C/C++ - c++

Is there any "GODLY" method through which i can protect my process from getting killed from:
1>Task manager 2>Command prompt -- forcefully kill
Things i tried : 1. Hooking Open Process and Terminate Process
Result i got: well not much , i could only protect it from task manager but it gets killed through command prompt task kill command

It is not too difficult to modify a process so it cannot be terminated by any other user than an administrator.
Look into:
GetKernelObjectSecurity
SetKernelObjectSecurity
In short: Obtain the security descriptor of the process to be protected, modify its DACL and write it back. Users that you deny access this way get an "Access denied" when trying to kill the process.

Related

MFC app - Block shutdown initiated by an MSI Installer

Goal
Block or pause a reboot until my app's files have finished saving. Specifically a reboot initiated from another apps MSI installer.
Summary
The app I'm working on captures and records information during an app install on windows. Occasionally, the other app finishes installing and requires a reboot. When that happens, I need time to finish saving my files before the reboot continues.
What's Working
ShutdownBlockReasonCreate()
ShutdownBlockReasonDestory()
These work as expected; but only if I manually trigger a reboot with Start -> reboot. Windows displays the Shutdown Block message to the user with the 'force shutdown' UI (full screen blue screen)
A program is preventing shutdown.
"shutdown block reason message"
shutdown anyway?
Program Flow
my app : begin watching install process from another app
shutdown block reason create (message)
other app finishes install
You must restart your system for the configuration changes to take effect.
Click 'Yes' to restart now or 'No' if you plan to restart later.
User clicks 'Yes'
WM_QUERYENDSESSION
return false // Do not continue reboot
WM_ENDSESSION
bEnding = True
return false // App is not ready to close
ShutdownBlockReasonDestroy( ) // continue shutdown
Expected Behavior
Same behavior as when I manually start a reboot. When I return false from OnQueryEndSession() the reboot should stop, or at least pause until I have destroyed the shutdown block reason. If there is a current ShutdownBlockReason, Windows should display the shutdown block reason to the user. Windows gives the user the chance to shutdown now, wait for the process to finish, or wait and go back to save their work.
Current Behavior
The Windows Force Shutdown UI is never displayed to the user.
The BlockShutdownReason is never displayed to the user.
The app is not given time to complete the file save.
Windows asks if the shutdown can continue (WM_QUERYENDSESSION) but always follows that up with WM_ENDSESSION, bEnding = True. Windows gives minimal time to complete the file save (3 seconds) and does not give my app a chance to inform the user that a file save is in progress.
The user is not informed that a file save is in progress.
What I've Tried
Create and destroy ShutdownBlockReason
CreateProcess("C:\...\shutdown.exe /a")
AbortSystemShutdown
if I call this before the shutdown has started:
'Error: No shutdown is in progress'
if I call this after the shutdown has begun:
'Error: A shutdown is in progress'
que frustrated confused developer
Set registry key:values to not automatically shut down apps
AutoEndTasks : False
HungAppTimeout : 120_000
WaitToKillAppTimeout : 120_000
Validation
I have ensured the application has valid shutdown permissions
I have set the permissions with the app token
I have double checked that the permissions were set correctly
I have used ShutdownBlockReasonQuery() to validate that the shutdown block reason exists before during and after OnQueryEndSession and OnEndSession.
I have validated that the window is a valid top level window.
References
Windows Official Documentation
ShutdownBlockReasonCreate
ShutdownBlockReasonDestroy
Application Shutdown Changes in Windows Vista
Shutting Down
Example :: How to shut down the system
Force Reboot
Disable Automatic Application Shutdown
Enables the files in use dialog (prior to install)
Does not effect the Force Shutdown (blue screen) UI (at the end of the install)
Restart Dialog Function
ExitWindowsEx
Windows Installer : System Reboots
Blogs and Forums
Now that windows makes it harder for your problem to block shutdown, how do you block shutdown?
Stack Overflow :: Example of ShutdownBlockReasonCreate
Stack Overflow :: ShutdownBlockReasonCreate causes shutdown to be canceled after one minute
Turn off automatic termination of applications
Allows non-window applications to be considered valid when responding to "WM_QUERYENDSESSION"
My application has a top level window and should already be considered valid, as evidenced when the user clicks Start -> Reboot
SO : Is there a way to delay a forced reboot
Only applies to Windows Update reboots
Suppress a MSI Reboot
Suppress reboot from the originating installer, not a 3rd party application.
Four ways to stop a shutdown or reboot
These apply to normal reboots, not a reboot from Windows Installer, which overrides all options.
None of these solutions have provided a way to block a shutdown from the end of an install, when it asks if you want to shutdown.
They all work as expected when the user clicks Start -> shutdown, but otherwise all attempts I have made to block or delay the shutdown have failed with no message to the user, and no effect on the shutdown / reboot.

Assigning JobObject to process with non-zero session id launched from a SYSTEM service

I have a Windows SYSTEM service which needs to launch a new process in the context of the logged-in user. Along with this, I need to create a Job for the new process with certain limits.
I am extracting the process token of explorer.exe and duplicating it to create a primary token. I use this token in CreateProcessAsUser to create the new process running in the context of the user with a session id which is non-zero. When I assign the Job to this process, AssignProcessToJobObject function fails with Access denied error. Specifically, I am not able to set JOBOBJECT_BASIC_UI_RESTRICTIONS limits (JOBOBJECT_EXTENDED_LIMIT_INFORMATION works though).
The process is created as suspended and after assigning the job, I am resuming the thread.
When I use the token of the current process (i.e. SYSTEM service with session id 0) instead of explorer.exe, everything works fine.
I am testing this on Windows 10

How to get the logged on user from a process running as root?

I have a program running as root and call another program to run(A).
I want A to run when the user logs on. I've used command: su - 'username' -c A,
or in the A main function, I've called: setuid(current_uid_logged).
But I don't know the way to get the user-name of the logged on user, or the uid in the root process.
Ways that I've tried: getenv("USERNAME") or getlogin() always return root account.
I've confused with getlogin(), my program is running when kernel start and wait for user login (I have a thread to wait a Finder process (Mac OSX) running to detect user logged on), wait 10 seconds and call getlogin() but sometime, it returned root but can return user login. I think Finder process is running when user logged on.
But when I call my app to run with sudo command, getlogin() always returns current user logged on.
How do I do this?
getlogin(3) returns the name of the user who owns the process's controlling terminal. This has nothing to do with the username of whoever might log in to the GUI of the operating system. Instead, getlogin(3) and getuid(2) will only ever return the name / uid of the user account that started the program -- they have more to do with the process history than with any user sitting in front of the computer.
There are similar stories with the environment variables USER and LOGNAME -- if either one was set in a process, it was by a process higher in the process's call tree. It too cannot be influenced by whichever user eventually sits in front of the computer.
I'm sure there is some mechanism to discover the currently-logged-on user on an OS X machine, but it won't be a traditional Unix API that provides it to you.
how about uid_t getuid()?
more details at http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/getuid.2.html

Impersonating and CreateProcess

The document states CreateProcess create a process running under the calling process’s security context, not the current impersonating token’s security context. Does this mean the permission for the new process will be the same regardless impersonating or not?
I have the following code that fails with ACCESS_DENIED error:
Process A runs under administrator;
Process A impersonates a normal user “test”;
Process A starts a new process B by calling CreateProcess;
Process B calls OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, ..);
Step 4 fails with ACCESS_DENIED error (5). I checked process B is running under Administrator as process A. Why would it fail when it’s running under the same user context as process A?
As a commenter said, you want CreateProcessAsUser. You might find the following sample code on MSDN helpful, I used it with success a few years ago: http://support.microsoft.com/kb/165194

OpenProcess / SetProcessAffinityMask on process started by my service

In my manager.exe, I'm trying to change the CPU usage of my worker.exe, which is started by my service.exe. Service.exe is running under the System Account, while manager.exe is running under the logged in user's account.
When I call OpenProcess in manager.exe with worker.exe's PID, I get NULL for procHandle:
HANDLE procHandle = OpenProcess(PROCESS_SET_INFORMATION, 0, pid);
Using GetLastError() I see that I got an Access Denied error.
Any ways around this? Can I somehow modify worker.exe to grant other processes full control over itself?
You shouldn't have to call OpenProcess.
The service should already have a full-permission handle to the worker from when it called CreateProcessAsUser or CreateProcessWithLogonW. Use DuplicateHandle to make a version of that handle suitable for use by the manager process, and then have the service send that handle to the manager. The service already has a handle to the manager, right? It will need that for DuplicateHandle.
Or have the manager ask the service to change the worker process.