I need to close some external programs.
Does my app require admin privileges to use Windows API GetWindowThreadProcessId, OpenProcess and TerminateProcess or user mode is enought?
I've checked in XP and 7 and works fine, but I know newer versions are more restrictive.
I'm using the following code:
bool CloseApp(const char *WindowName)
{
HWND hWnd;
hWnd=FindWindow(nullptr,WindowName);
if(!hWnd)return(true); // Not running
DWORD pid;
GetWindowThreadProcessId(hWnd,&pid);
if(!pid)return(false);
HANDLE prc;
prc=OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE,FALSE,pid);
if(!prc)return(false);
TerminateProcess(prc,0);
DWORD rst=WaitForSingleObject(prc,10000); // Wait until completion
CloseHandle(prc);
if(FindWindow(nullptr,WindowName))return(false); // Check if still running
return(true);
}
Thanks.
It really depends on your application and the external process you want to kill. Windows has a pretty complicated system of authorizations for process interactions (everything revolves around Access Tokens).
Process
Since Windows Vista, process now have an integrity level which can be :
Untrusted. No logon SID, no access to the filesystem. Basically a pariah.
Low. Can only access %LocalLow% and a restricted set of API. Usually used to sandbox dangerous parts of an application (parsers, evaluators, etc.)
Medium. Your run-of-the-mill application/user
High. Superior privileges. Need UAC confirmation.
As you can imagine, lower integrity level applications can not interfere with higher integrity level ones. Since this mechanism is rarely used by developers (apart from MS products and web browsers) I assume your program run as Medium.
From integrity levels analysis, your program can probably only terminate process created by the same user and without admin privileges.
Services
Services are long-term process that have they own set of access mechanism. Services usually require admin levels (or even SYSTEM) to be controlled and terminated. Some can even be modified only by Network admins (e.g. in a AD) or only by Windows itself (e.g. for PPL services)
Anyway, the best way to check it is to call OpenProcess with your arguements and, if the calls fails, retrieve the last error set (using GetLastError() and check check for the ERROR_ACCESS_DENIED (0x5) value.
Related
Is it possible to get a C++ application running in Windows to request administrator privileges from the operating system at run time?
I know it can be done at compile time, but can't seem to find anywhere whether it can be done at run time.
Thanks for your help!
EDIT: What if I want the current instance to have elevated privileges? For example, I might have data stored in memory which I want to keep.
If you want the application to always elevate, you can give it a manifest, either by building one in (not compiling technically) or by putting an external manifest in the same folder as the exe. If you want to decide, as a person, to run it elevated, you right click the exe or short cut and choose Run As Administrator. If you are launching it from code, then as #vcsjones comments, you use the runas verb when you launch that process. For example:
ShellExecute( NULL,
"runas",
"c:\\windows\\notepad.exe",
" c:\\temp\\report.txt",
NULL, // default dir
SW_SHOWNORMAL
);
You can elevate a process only during its creation. When a process already runs, there's no way to change its security token: it either runs elevated or not.
If your application needs to perform an administrative task, and it usually runs non-elevated, you have to create another .exe which will request elevation with its manifest. To start a process elevated, you have to use ShellExecute or ShellExecuteEx function. From your main process you will need a way to pass the commands to that new process that will run elevated.
For more information about UAC, read Designing UAC Applications for Windows Vista series.
Not quite, but you can do the opposite—you can drop privileges if you already have them. So, you can have your program start out running as an Administrator, using one of the methods listed by Kate Gregory. Then, drop your unneeded privileges; see Dropping privileges in C++ on Windows for how to do that.
Add a manifest file into your EXE as described here.
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Your process (and threads) have a token assinged to them. That token already have all your groups set up. Under UAC, the Administrator group is disabled. UAC will remove that disabled group so you end up with a full administrator token.
To acheive the same, you must have the TCB priviledge. In other words, to elevate a process at runtime, you will need help from a process running under the SYSTEM account, and Microsoft isn't providing one, nor an API to control the current UAC implementation. Otherwise, it would defeat the purpose.
For the sake of completness, there is a whitelist of process that can perform some elevated operations without prompting. In short, your executable needs :
To be signed by Microsoft
To perform predefined operations, like with IFileOperation
The best explanation I found is this hack. It has been fixed since then, but is sheds some light on the whole thing.
I have been dabbling with working nicely with UAC for a while and I found about a few things:
With UAC enabled, a program in the Startup folder, that requires to be run as admin (say by an embedded manifest), cannot be run according to this Stack Overflow thread.
Another method of running a program at startup is by creating a key containing the path to that application in: HKLM or HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run or HKLM or HKCU\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run in 64 bit machines.
Yet another method is using the task scheduler setting the Run with highest privileges option. This is the only method that bypasses the problem stated in point 1.
Coming from a Linux background, I had no clue about all these admin rights related problems. If someone can list out scenarios which absolutely need administrator privileges, it would be of great help!
I'm asking this because when I'm developing some application, I keep encountering several problems during implementation mostly because my application required admin rights when it shouldn't.
If I know, at design time, all possible scenarios that require admin rights, I could possibly design a common service for all my applications that takes care of all the administrator tasks (I think services are the Windows way of doing things like this).
There really isn't a list of scenarios or API function calls that require elevation. Your best option will probably be to focus on what API calls require elevation. The reason for this is that it may be required only if certain values are passed to the function. For instance CreateFile can create a file in your home directory without elevation but requires it for creating a file in C:\Windows. If the directory is provided through user input the only way you can know if elevation is required is to check the error code when the call fails. If elevation is required the function will set the error status to ERROR_ACCESS_DENIED and return a value indicating failure.
Ok, so we have a C++ app that runs fine in Windows XP.
It has the following code in the initialization
// Register all OLE server (factories) as running. This enables the
// OLE libraries to create objects from other applications.
COleObjectFactory::RegisterAll();
Now like i said, it works fine in Windows XP, but as far I understand the program tries to register its COM interface Which is fine in XP, but this may be a problem in Windows Vista and Windows 7 because of the UAC. Especially if its is run as a standard user (with no elevated privileges).
If i understand it correctly this is needed for the program to run properly, but it cant execute this code without elevated privileges. If it will run every time the app runs (this usually runs when CWinApp::init() is run)
Before you say just use admin privileges, the user will not have them, there is no way to change that
So, now my questions are:
1) am i correct in my assumptions?
2) if I am correct, what is the best way around this? Can i just remove this? Do i need to set up some other thing? (we changed some VB modules to use a XML file instead of stuff in the registry
PS: the modules compiles into DLLs
PPS: UAC MUST be on
Take note that:
The documentation for these functions makes no mention of any privilege requirements; and
nobody online seems to be having trouble with these functions in limited privilege environments; and
it's 2012, I think someone would have noticed if these functions didn't work under UAC by now.
So (with nothing to suggest otherwise) I'd say It Just Works.
Notwithstanding the above, I looked at the implementation of COleObjectFactory::RegisterAll() and COleObjectFactory::UpdateRegistryAll().
RegisterAll
Ultimately calling RegisterAll ends up in olefact.cpp:135 where CoRegisterClassObject is called. From MSDN:
Registers an EXE class object with OLE so other applications can connect to it.
I believe this registration will be limited to the current user's session and the lifetime of the application. The Remarks section touches on privileges (As of Windows Server 2003...) but doesn't provide anything concrete.
There's an object known as the Running Object Table (ROT) that can be retrieved via GetRunningObjectTable. The documentation has this snippet:
Each workstation has a local ROT that maintains a table of the objects that have been registered as running on that computer.
The COM Elevation Moniker has some more information about the ROT and privileges (it suggests processes of various privilege levels work fine with it). The links on the left-hand side might help, too.
Overall it seems there's nothing to suggest that CoRegisterClassObject requires administrator permissions.
UpdateRegistryAll
This function ends up in olefact.cpp:375 where it opens HKEY_CLASSES_ROOT. At this point the documentation gets a bit better:
Registry functions such as RegOpenKeyEx or RegQueryValueEx allow you to specify the HKEY_CLASSES_ROOT key. When you call these functions from a process running in the interactive user account, the system merges the default settings in HKEY_LOCAL_MACHINE\Software\Classes with the interactive user's settings at HKEY_CURRENT_USER\Software\Classes.
Further on:
If you write keys to a key under HKEY_CLASSES_ROOT, the system stores the information under HKEY_LOCAL_MACHINE\Software\Classes
The documentation doesn't define what happens when you try to write to HKEY_CLASSES_ROOT under limited privileges (i.e. a standard user can't write to HKLM), but I believe that you'll end up writing to HKCU instead.
And finally, note:
Windows Server 2003 and Windows XP/2000: Applications can register dependent COM objects to either the per-machine or per-user COM configuration store (HKEY_LOCAL_MACHINE\Software\Classes or HKEY_CURRENT_USER\Software\Classes).
So if it falls through to HKCU, you should be fine.
Caveat Implementor: Don't rely on implementation details.
I have some code that used to work, but recently stopped. It's in an Adobe Reader Plugin, and the latest Reader version has a "Protected Mode" which causes my problem.
My plugin can load some of my normal dlls, which load in-process:
MyNormalLib::IMyClassPtr foo;
HRESULT hr = foo.CreateInstance(__uuidof(MyNormalLib::MyClass));
But when I try to get a com pointer to my service (running on the same machine):
MyOtherLib::IMyServicePtr bar;
HRESULT hr = bar.CreateInstance(__uuidof(MyOtherLib::MyService));
I get E_ACCESSDENIED for my HRESULT.
This used to work fine, until Adobe Reader X came along. Without Protected Mode, Adobe runs normally and everything works. With Protected Mode, Adobe spawns another Reader process, with some restrictions on it. Looking at this with Process Explorer, I can see that the Security Tab for the parent Reader process has pretty much everything set to Mandatory; but the child Reader process has most groups set to "Deny, Mandatory", some "Mandatory, Restricted", some are just Mandatory. If this matters, I can provide more details.
All processes (my service and both Reader) are run as the same user -- me. I have admin rights, if that matters.
What can cause an AccessDenied error when trying to reach my own service? What security hoops do I have to jump through to get this to work?
The restricted process does not have admin rights. That's pretty much the point of the exercise - Reader X drops as many rights as it can from its token so that if it is pwned your computer is not.
(That's basically how UAC works too, you have to go to the Kernel to get permission to re-enable your Administrator group once you have disabled it).
Basically you need to look at the privs that Reader X has, and make sure your component can be used with those permissions. Process Monitor is your friend - just filter for DENIED and the problems will pop right out at you!
I was trying to get a Uuid via NtAllocateUuids or simply calling UuidCreateSequential,
but Windows wasn't able to get an Ethernet or token-ring hardware address for my laptop.
And so, when the system is booting, windows sets the UuidSeed to a random number instead of a given MAC.
--> uniqueness is guaranteed only until the system is next restarted.
I was trying to manual set the UuidSeed with NtSetUuidSeed but i was getting a STATUS_ACCESS_DENIED error.
"Windows NT/2000 Native API Reference" has following remarks:
--The token of the calling thread must have an AuthenticationId of SYSTEM_LUID
Is there any way to achieve this from a process, running as Administrator?
Something like ImpersonateLoggedOnUser() could work but afaik this is also only accessible as LocalSystem :/
Thx ;)
You can create a program and schedule to run it using the AT command. The scheduling service run as the local system account. On Vista things are different and I'm not sure if that is possible any more. You could write your own service of course.
ImpersonateLoggedOnUser worked fine with a token handle returned from:
HANDLE GetLSAToken() //duplicate a system token from the "System" process
or
BOOL CreatePureSystemToken(HANDLE &hToken) //create a new system token
http://www.codeproject.com/KB/system/RunUser.aspx
CoreCode.cpp