soolidsnake soolidsnake - 3 months ago 12
C Question

How can I check that an executable is being run as an administrator?

I am writing an application with c++/c. How can I detect if the process was launched as an administrator (right click run as admin)?

Answer

Assuming the problem statement is "how to determine if my process has been elevated under UAC",

  1. Check UAC is enabled
  2. Check if IsUserAnAdmin() returns true
  3. Check the process token's elevation type is TokenElevationTypeFull

If all three tests are true, your process has been elevated under UAC. Note that it's possible the GetProcessElevationType check on its own would be enough, but in our own code we do the others in case there are other types of split token in the future.

Details:

  1. Check UAC is enabled

There may be other ways to do this, but the easiest is to look in the registry. If the value EnableLUA exists under the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System then UAC is enabled.

  1. Check if IsUserAnAdmin() returns true

This is easy - simply call the IsUserAnAdmin() function. Note that the this function is deprecated; you can also use the CheckTokenMembership() function.

  1. Check the process token's elevation type is TokenElevationTypeFull

You can obtain the token's elevation type using the following function:

// TokenElevationTypeDefault -- User is not using a split token. (e.g. UAC disabled or local admin "Administrator" account which UAC may not apply to.)
// TokenElevationTypeFull    -- User has a split token, and the process is running elevated.
// TokenElevationTypeLimited -- User has a split token, but the process is not running elevated.
bool GetProcessElevationType(TOKEN_ELEVATION_TYPE *pOutElevationType)
{
    *pOutElevationType = TokenElevationTypeDefault;
    bool fResult = false;

    HANDLE hProcToken = NULL; 

    if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hProcToken))
    {
        DWORD dwSize = 0;
        TOKEN_ELEVATION_TYPE elevationType = TokenElevationTypeDefault;

        if (::GetTokenInformation(hProcToken, TokenElevationType, &elevationType, sizeof(elevationType), &dwSize)
        &&  dwSize == sizeof(elevationType))
        {
            *pOutElevationType = elevationType;
            fResult = true;
        }

        ::CloseHandle(hProcToken);
    }

    return fResult;
}
Comments