Click here to Skip to main content
15,860,943 members
Articles / Security

Elevating During Runtime

Rate me:
Please Sign up or sign in to vote.
4.93/5 (65 votes)
15 Feb 2013CPOL3 min read 144.2K   5.6K   107   53
How can an application elevate itself to gain "Admin" rights during runtime
This article explains how to elevate an application during runtime. If your application would not require Admin rights except for certain occasions, you might prefer building your application with no specific requirement to be run in Admin mode, but when it needs to make a Registry change, only then, it will elevate itself to Admin mode. This article explains how that is done.

Background

Some actions and tasks require elevation to Admin rights. The User Access Control mechanism (UAC) provides the protection required to prevent performing critical changes by users other than the ones with Admin privileges. For example, if your application needs to make a change in the Registry, it will require Admin users to run it.

What happens if your application would not require Admin rights except for certain occasions, i.e., during first run only. In such case, you might prefer building your application with no specific requirement to be run in Admin mode, but when it needs to make a Registry change, only then, it will elevate itself to Admin mode.

Here is how that is done.

What is UAC

User Account Control (UAC) is a mechanism developed by Microsoft as part of the newer Windows versions (starting of Vista). It provides higher security level by limiting applications from performing sensitive and dangerous tasks without gaining administrative rights.

Is It Really Possible to Elevate During Runtime?

Well, not exactly. The entire idea behind UAC is to prevent users with limited access rights to perform tasks that require higher access rights, so when an application is executed in "user" mode, it can't change itself, as if it was initially ran in "Admin" mode. The trick is to be able to elevate itself during runtime, when required, by restarting it, elevated to "admin" this time.

Am I Running in Admin Mode?

This is the first question you should ask when you need to do something that requires administrative privileges. If your application was already started in "admin" rights, there is no need to elevate. Only when a certain task you are about to perform, requires "admin" rights, and your application was started in "user" mode, you need to elevate. So to begin with, how can you determine if your application is run elevated already.

First, you allocate and initialize a SID of the Admin group. According to MSDN, A security identifier (SID) is a unique value of variable length that is used to identify a security principal or security group in Windows operating systems. Well-known SIDs are a group of SIDs that identify generic users or generic groups. Their values remain constant across all operating systems.

Before we proceed, let's get familiar with another function, CheckTokenMembership.

The CheckTokenMembership function determines whether a specified security identifier (SID) is enabled in an access token. In order to determine group membership for tokens of applications, CheckTokenMembershipEx is used instead.

For our purpose, we can call CheckTokenMembership and by doing so, enquire whether the SID is enabled in the primary access token of the process.

To sum the first part, here is how we check if our application is running with administrative privileges:

C++
//
BOOL IsAppRunningAsAdminMode()
{
    BOOL fIsRunAsAdmin = FALSE;
    DWORD dwError = ERROR_SUCCESS;
    PSID pAdministratorsGroup = NULL;

    // Allocate and initialize a SID of the administrators group.
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    if (!AllocateAndInitializeSid(
        &NtAuthority, 
        2, 
        SECURITY_BUILTIN_DOMAIN_RID, 
        DOMAIN_ALIAS_RID_ADMINS, 
        0, 0, 0, 0, 0, 0, 
        &pAdministratorsGroup))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // Determine whether the SID of administrators group is enabled in 
    // the primary access token of the process.
    if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

Cleanup:
    // Centralized cleanup for all allocated resources.
    if (pAdministratorsGroup)
    {
        FreeSid(pAdministratorsGroup);
        pAdministratorsGroup = NULL;
    }

    // Throw the error if something failed in the function.
    if (ERROR_SUCCESS != dwError)
    {
        throw dwError;
    }

    return fIsRunAsAdmin;
}
// 

If IsAppRunningAsAdminMode returns TRUE, then there is nothing left to be done, and everything is OK to continue with any task.

If it returns FALSE, then we need to elevate.

How to Elevate

320748/Elevator.jpg

The way we elevate during runtime is obtaining the application name and path and executing it elevated to "Admin", while the currently running instance, of course, must terminate.

We also need to address the scenario in which the end user refuses to confirm this elevation, which is addressed, as you can see in the following code:

C++
wchar_t szPath[MAX_PATH];
if (GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)))
{
    // Launch itself as admin
    SHELLEXECUTEINFO sei = { sizeof(sei) };
    sei.lpVerb = L"runas";
    sei.lpFile = szPath;
    sei.hwnd = NULL;
    sei.nShow = SW_NORMAL;
    if (!ShellExecuteEx(&sei))
    {
        DWORD dwError = GetLastError();
        if (dwError == ERROR_CANCELLED)
        {
            // The user refused to allow privileges elevation.
            std::cout << "User did not allow elevation" << std::endl;
        }
    }
    else
    {
        _exit(1);  // Quit itself
    }
}  

Running My POC

I have written a little POC to demonstrate this idea.

320748/HowToElevate-1.jpg

After pressing "Y", the application will try to elevate itself, only if it is not run in Admin privileges already.

History

  • 27th January, 2012: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Secured Globe, Inc.
United States United States
Michael Haephrati is a music composer, an inventor and an expert specializes in software development and information security, who has built a unique perspective which combines technology and the end user experience. He is the author of a the book Learning C++ , which teaches C++ 20, and was published in August 2022.

He is the CEO of Secured Globe, Inc., and also active at Stack Overflow.

Read our Corporate blog or read my Personal blog.





Comments and Discussions

 
GeneralMy vote of 5 Pin
alonamir13-Oct-12 11:46
alonamir13-Oct-12 11:46 
GeneralMy vote of 5 Pin
Barb Henry 213-Oct-12 11:26
Barb Henry 213-Oct-12 11:26 
GeneralMy vote of 5 Pin
George Rogers II13-Oct-12 6:42
George Rogers II13-Oct-12 6:42 
GeneralMy vote of 5 Pin
Emma20123217-Sep-12 6:47
Emma20123217-Sep-12 6:47 
AnswerRe: My vote of 5 Pin
Michael Haephrati21-Sep-17 10:26
professionalMichael Haephrati21-Sep-17 10:26 
GeneralMy vote of 5 Pin
Hillary Higg17-Sep-12 3:32
Hillary Higg17-Sep-12 3:32 
AnswerRe: My vote of 5 Pin
Michael Haephrati21-Sep-17 8:57
professionalMichael Haephrati21-Sep-17 8:57 
QuestionNot working correctly Pin
duongkha17-Aug-12 22:52
duongkha17-Aug-12 22:52 
Hi,
I have tried your code to check admin user. My account on win 7 is in administrator group, however, i run your code, it returns that my account is not administrator. Then it elevated.
Am I doing something wrong? I just run your source code.
Thanks.
AnswerRe: Not working correctly Pin
Michael Haephrati17-Aug-12 23:09
professionalMichael Haephrati17-Aug-12 23:09 
AnswerRe: Not working correctly Pin
Dexterus18-Feb-13 1:57
Dexterus18-Feb-13 1:57 
GeneralRe: Not working correctly Pin
Michael Haephrati18-Feb-13 4:04
professionalMichael Haephrati18-Feb-13 4:04 
GeneralRe: Not working correctly Pin
Dexterus18-Feb-13 5:31
Dexterus18-Feb-13 5:31 
GeneralRe: Not working correctly Pin
Michael Haephrati18-Feb-13 6:10
professionalMichael Haephrati18-Feb-13 6:10 
AnswerRe: Not working correctly Pin
Michael Haephrati18-Feb-13 10:07
professionalMichael Haephrati18-Feb-13 10:07 
GeneralMy vote of 1 Pin
mier1-Feb-12 5:54
mier1-Feb-12 5:54 
AnswerRe: My vote of 1 Pin
Michael Haephrati21-Sep-17 10:27
professionalMichael Haephrati21-Sep-17 10:27 
GeneralMy vote of 5 Pin
Jeff Kibling31-Jan-12 3:27
Jeff Kibling31-Jan-12 3:27 
GeneralMy vote of 3 Pin
Assaf Levy30-Jan-12 21:40
Assaf Levy30-Jan-12 21:40 
QuestionNo elevation - but process creation Pin
Ajay Vijayvargiya29-Jan-12 16:18
Ajay Vijayvargiya29-Jan-12 16:18 
AnswerRe: No elevation - but process creation Pin
Michael Haephrati29-Jan-12 21:55
professionalMichael Haephrati29-Jan-12 21:55 
GeneralRe: No elevation - but process creation Pin
zart_zurt30-Jan-12 3:36
zart_zurt30-Jan-12 3:36 
GeneralRe: No elevation - but process creation Pin
Michael Haephrati30-Jan-12 5:04
professionalMichael Haephrati30-Jan-12 5:04 
GeneralRe: No elevation - but process creation Pin
Ajay Vijayvargiya30-Jan-12 16:01
Ajay Vijayvargiya30-Jan-12 16:01 
GeneralRe: No elevation - but process creation Pin
Ajay Vijayvargiya30-Jan-12 15:58
Ajay Vijayvargiya30-Jan-12 15:58 
AnswerRe: No elevation - but process creation Pin
Michael Haephrati20-Feb-13 7:33
professionalMichael Haephrati20-Feb-13 7:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.