views:

222

answers:

2

I've written a program with a manifest that includes requireAdministrator. On Windows 7 systems with UAC enabled, Windows pops up a dialog asking for permissions, as it should. Works great.

If a user starts my program by right-clicking it and choosing "Run as administrator", then Windows 7 also pops up a dialog asking for permissions. However, there are some slight differences in how my program operates in some of the more esoteric parts of my program.

So what are the differences between "Run as administrator" and a manifest with requireAdministrator? Any links to documentation that describe differences would be appreciated.

Edit: This is with UAC enabled.

Edit: As promised below is the full explanation of the difference I'm seeing.

I'm using the EasyHook library to inject a DLL into another process. When my application is run with "Run as administrator", the injected process crashes and EasyHook returns the error "Unknown error in injected assembler code". None of the code in my DLL gets a chance to execute; the crash occurs before then. (Moreover, the crash occurs even if I strip the DLL down to nothing)

If I run my program normally (i.e., elevated via requireAdministrator), everything works fine.

My application is composed of a few different executables. The process that the user launches is not the same process that performs the injection.

+2  A: 

With the information given there would be no differences in the permissions between the two processes.

If you request an execution level of "requireAdministrator" via the applications manifest your application will either be launched with the full access token of an administrator or not at all if the user denies consent (see Create and Embed an Application Manifest (UAC) for further information).

The same will happen when a user chooses Run as Administrator.

The only difference is the way that the process is started. When you start an executable from the shell, e.g. by double-clicking in Explorer or by selecting Run as Administrator from the context menu, the shell will call ShellExecute to actually start process execution. The whole process of elevation is hidden inside this function. Kenny Kerr describes this process in more details in Windows Vista for Developers – Part 4 – User Account Control:

ShellExecute first calls CreateProcess to attempt to create the new process. CreateProcess does all the work of checking application compatibility settings, application manifests, runtime loaders, etc. If it determines that the application requires elevation but the calling process is not elevated then CreateProcess fails with ERROR_ELEVATION_REQUIRED. ShellExecute then calls the Application Information service to handle the elevation prompt and creation of the elevated process since the calling process obviously doesn’t have the necessary permissions to perform such a task. The Application Information service ultimately calls CreateProcessAsUser with an unrestricted administrator token.

If on the other hand you want to create an elevated process regardless of what application information is available then you can specify the little-known “runas” verb with ShellExecute. This has the effect of requesting elevation regardless of what an application’s manifest and compatibility information might prescribe. The runas verb is not actually new to Windows Vista. It was available on Windows XP and Windows 2003 and was often used to create a restricted token directly from the shell. This behavior has however changed. Here is a simple example:

::ShellExecute(0, // owner window
           L"runas",
           L"C:\\Windows\\Notepad.exe",
           0, // params
           0, // directory
           SW_SHOWNORMAL);

So essentially starting an executable using the Run as Administrator option means that ShellExecute bypasses the checks for compatibility settings, application manifests etc and directly requests elevation.

Kenny Kerr's article also has sample code to query the current process' token for its permission using the OpenProcessToken function. Possibly you can use the example to identify that there are no differences in the way your process is elevated.

I'm definitely curious to know which differences you are observing as I strongly doubt they are related to elevation.

As a last thing: Can you double check that you really request a level of requireAdministrator and not by mistake only a level of highestAvailable?

0xA3
@0xA3: I double checked and it's set to requireAdministrator.
Daniel Stutzbach
Could there be subtle differences in the behavior between CreateProcessAsUser and the runas verb? (whether related to elevation or unrelated things such as environmental variables)
Daniel Stutzbach
@Daniel Stutzbach: Sorry to repeat myself, but when you like to get help then please don't hide all the relevant information you have. We're not here to play games, aren't we? With the information you provided my above answer is as much as I can help you I'm afraid.
0xA3
+1  A: 

One possible difference might be the rarely used/understood/deliberately-chosen uiAccess attribute. Can you create two manifests, one with uiAccess=false and one with uiAccess=true, then tell us whether one of them gives the same behaviour as you see with right-click-run-as-admin?

Kate Gregory
If that would be the case then @Daniel Stutzbach should really be ashamed of not telling us what his application is doing or not doing correctly. However, from my understanding this setting should not have any effect here. Setting `uiAccess` to true allows the application to talk to higher privilege windows on the desktop, but as it is already running with highest privileges there should be no windows with even higher privileges.
0xA3
@Kate: Right now I'm using uiAccess=false. I'll try uiAccess=true and report back.
Daniel Stutzbach
@Kate: with uiAccess=true, requireAdministrator has the same behavior as before. However, "Run as Administrator" changed behavior to match requireAdministrator. * confused *
Daniel Stutzbach
@Daniel so maybe it's time to be clear about what you saw as differences? You may have just been running two versions of the app.
Kate Gregory
@Daniel Stutzbach: Could you solve the problem meanwhile? Or will you give an update?
0xA3