Check if process is elevated?

x13

Nov 9, 2016
72
1
Netherlands
Hi.

Sorry if this question has already been asked.

Suppose a program starts as admin. How can that be queried with TCC?
The %_ELEVATED system variable only applies to TCMD/TCC itself.

A function like %@ELEVATED[pid] = 0 | 1 (1= admin, 0=not) would be very handy.

Unless there's another cunning way I'm not seeing?

Thanks.
x¹³
 
  • Like
Reactions: Alpengreis
May 20, 2008
10,634
82
Syracuse, NY, USA
If the CURRENT process IS NOT ELEVATED, this will work because , unelevated, WMI can't get the command line of an elevated process.

Code:
v:\> function elevated `%@if[*%@instr[0,1,%@wmi[.,"Select CommandLine from Win32_Process where ProcessId=%1"]]* == **,1,0]`

v:\> echo %@elevated[%_pid]
0

v:\> start /elevated

v:\> echo %@elevated[%_startpid]
1
And it will fail if the current process is elevated.
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
4,223
78
Albuquerque, NM
prospero.unm.edu
Here's what I use:

Code:
int ProcessElevated( DWORD Pid )
{
    HANDLE ProcessHandle        = NULL;
    HANDLE ProcessToken         = NULL;
    TOKEN_ELEVATION Elevated    = { 0 };
    DWORD ReturnSize            = 0;

    int rv                      = -1;


    ProcessHandle = OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, Pid );
    if ( ProcessHandle ) {

        if ( OpenProcessToken( ProcessHandle, TOKEN_QUERY, &ProcessToken ) ) {

            if ( GetTokenInformation( ProcessToken, TokenElevation, &Elevated, sizeof( TOKEN_ELEVATION ), &ReturnSize ) )
                rv = Elevated.TokenIsElevated ? 1 : 0;

            CloseHandle( ProcessToken );
        }

        CloseHandle( ProcessHandle );
    }

    return rv;
}
Returns 1 for elevated, 0 for not elevated, and -1 on any error (invalid PID?)

I suspect the internal _ELEVATED variable uses something similar.
 
  • Like
Reactions: Joe Caverly
May 20, 2008
10,634
82
Syracuse, NY, USA
Yes. That's why I'm using PROCESS_QUERY_LIMITED_INFORMATION instead of the more obvious PROCESS_QUERY_INFORMATION.
I'm a little surprised since the documentation for the latter specifically mentions OpenProcessToken while the documentation for the former doesn't.

PROCESS_QUERY_INFORMATION (0x0400)Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken).
PROCESS_QUERY_LIMITED_INFORMATION (0x1000)Required to retrieve certain information about a process (see GetExitCodeProcess, GetPriorityClass, IsProcessInJob, QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION.Windows Server 2003 and Windows XP: This access right is not supported.
 

x13

Nov 9, 2016
72
1
Netherlands
@vefatica :

I tried your function, but I get an error :

function elevated `%@if[*%@instr[0,1,%@wmi[.,"Select CommandLine from Win32_Process where ProcessId=%1"]]* == **,1,0]`

echo %@elevated[%_pid]
TCC: (Sys) The parameter is incorrect.
"%@if[*"* == **,1,0]"
 
May 20, 2008
10,634
82
Syracuse, NY, USA
@vefatica :

I tried your function, but I get an error :

function elevated `%@if[*%@instr[0,1,%@wmi[.,"Select CommandLine from Win32_Process where ProcessId=%1"]]* == **,1,0]`

echo %@elevated[%_pid]
TCC: (Sys) The parameter is incorrect.
"%@if[*"* == **,1,0]"
I didn't consider that the command line might start with a quote. Actually, MaximumWorkingSetSize works also and it will either be empty or contain just numbers. So this should work as long as the current TCC in not elevated. Note that it will give "1" if the PID doesn't exist.

Code:
function elevated `%@if[*%@wmi[.,"Select MaximumWorkingSetSize from Win32_Process where ProcessId=%1"]* == **,1,0]`