January 6th, 2021

How can I tell whether my process is running as SYSTEM?

A customer wanted to know how to check whether the current process is running as the SYSTEM account. They proposed this algorithm:

// Code in italics is wrong
bool IsCurrentProcessRunningAsSystem()
{
 DWORD session_id;
 return ProcessIdToSessionId(GetCurrentProcessId(), &session_id) &&
        session_id == 0;
}

This algorithm is flawed both for the possibility of false positives as well as false negatives.

You can see this for yourself by opening Task Manager:

Name User name Session ID
LogonUI.exe SYSTEM 3
winlogon.exe SYSTEM 3
fontdrvhost.exe UMFD-0 0

We have some processes running as SYSTEM which aren’t in session zero. And we have a process in session zero that is not running as SYSTEM.

If you want to know whether you are running as SYSTEM, check your token to see whether it represents the SYSTEM user.

I’m going to use wil as my RAII library.

#include <wil/token_helpers.h>

bool DoesTokenRepresentSid(HANDLE token, WELL_KNOWN_SID_TYPE type)
{
 // maps to GetTokenInformation(token, TokenUser, ...);
 auto user = wil::get_token_information<TOKEN_USER>(token);
 return !!IsWellKnownSid(user->User.Sid, type);
}

bool IsCurrentProcessRunningAsSystem()
{
 return DoesTokenRepresentSid(GetCurrentProcessToken(),
                              WinLocalSystemSid);
}

bool IsCurrentThreadRunningAsSystem()
{
 return DoesTokenRepresentSid(GetCurrentThreadEffectiveToken(),
                              WinLocalSystemSid);
}
Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

6 comments

Discussion is closed. Login to edit/delete existing comments.

Newest
Newest
Popular
Oldest
  • Neil Rashbrook

    That begs the question, why does the customer think that he needs to tell whether the current process is running as the SYSTEM account…

    • Raymond ChenMicrosoft employee Author

      Because their code doesn’t work when running as SYSTEM.

  • Piotr Siódmak

    why the “not not” in

    !!IsWellKnownSid(user->User.Sid, type)

    ?

    • Marek Knápek

      I guess to convert from BOOL to bool (or from BOOLEAN or from DWORD or from int).

      • Kasper Brandt

        IsWellKnownSid is documented as returning either TRUE or FALSE, so seems pretty pointless to me.

      • skSdnW

        The WinAPI BOOL is 4 bytes, the C++ bool is 1 byte (and strictly 0 or 1 these days, the WinAPI is often just 0 or != 0). Without !! (or != 0) the compiler is going to give you a warning.

Feedback