Martin Heller
Contributing Writer

Detecting Vista Integrity, for Real

analysis
Apr 20, 20072 mins

On April 6th and 9th I presented some sample C++ code I found on a Microsoft site for detecting whether IE is in protected mode and detecting the integrity of a Windows Vista process. In fact, as I found out when I went to implement it, that code doesn't even compile unless you have the Vista SDK installed. With a little work, I was able to extract the essential symbols from the version of WinNT.h in t

On April 6th and 9th I presented some sample C++ code I found on a Microsoft site for detecting whether IE is in protected mode and detecting the integrity of a Windows Vista process. In fact, as I found out when I went to implement it, that code doesn’t even compile unless you have the Vista SDK installed.

With a little work, I was able to extract the essential symbols from the version of WinNT.h in the Vista SDK, and make the code compile in a normal environment. I also added some code to detect whether Windows Vista is running, and bail if it is not. I’m not quite sure what would happen if you called GetTokenInformation with a flag of TokenIntegrityLevel on an operating system that doesn’t have that value defined, and I’d rather not find out.

//from Vista WinNT.h
typedef struct _TOKEN_MANDATORY_LABEL {
    SID_AND_ATTRIBUTES Label;
} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
#define SECURITY_MANDATORY_UNTRUSTED_RID            (0x00000000L)
#define SECURITY_MANDATORY_LOW_RID                  (0x00001000L)
#define SECURITY_MANDATORY_MEDIUM_RID               (0x00002000L)
#define SECURITY_MANDATORY_HIGH_RID                 (0x00003000L)
#define SECURITY_MANDATORY_SYSTEM_RID               (0x00004000L)
#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID    (0x00005000L)
#define TokenIntegrityLevel (TOKEN_INFORMATION_CLASS)25

// 0 if it fails, 1 if low, 2 if medium, 3 if high
STDMETHODIMP CIE::get_Integrity(BYTE* pVal)
{
    *pVal=0;

    //return if not Windows Vista or later
    OSVERSIONINFO osvi = {0};
    osvi.dwOSVersionInfoSize=sizeof(osvi);
    GetVersionEx (&osvi);
    if(osvi.dwMajorVersion<6)
        return S_OK;

    HANDLE hToken;
    HANDLE hProcess;

    DWORD dwLengthNeeded;
    DWORD dwError = ERROR_SUCCESS;

    PTOKEN_MANDATORY_LABEL pTIL = NULL; //nb: Vista SDK definition
    DWORD dwIntegrityLevel;

    hProcess = GetCurrentProcess();
    if (OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &hToken)) //nb: Win NT+ only, not Win9x
    {
        // Get the Integrity level.
        if (!GetTokenInformation(hToken, TokenIntegrityLevel,  //nb: Win NT+ only, not Win9x
            NULL, 0, &dwLengthNeeded))
        {
            dwError = GetLastError();
            if (dwError == ERROR_INSUFFICIENT_BUFFER)
            {
                pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, 
                    dwLengthNeeded);
                if (pTIL != NULL)
                {
                    if (GetTokenInformation(hToken, TokenIntegrityLevel, 
                        pTIL, dwLengthNeeded, &dwLengthNeeded))
                    {
                        dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, //nb: Win NT+ only, not Win9x
                            (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid)-1));

                        if (dwIntegrityLevel < SECURITY_MANDATORY_MEDIUM_RID) //nb: Vista SDK definition
                        {
                            // Low Integrity
                            *pVal=1;
                        }
                        else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && 
                            dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
                        {
                            // Medium Integrity
                            *pVal=2;
                        }
                        else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
                        {
                            // High Integrity
                            *pVal=3;
                        }
                    }
                    LocalFree(pTIL);
                }
            }
        }
        CloseHandle(hToken);
    }
    return S_OK;
}

Martin Heller

Martin Heller is a contributing writer at InfoWorld. Formerly a web and Windows programming consultant, he developed databases, software, and websites from his office in Andover, Massachusetts, from 1986 to 2010. From 2010 to August of 2012, Martin was vice president of technology and education at Alpha Software. From March 2013 to January 2014, he was chairman of Tubifi, maker of a cloud-based video editor, having previously served as CEO.

Martin is the author or co-author of nearly a dozen PC software packages and half a dozen Web applications. He is also the author of several books on Windows programming. As a consultant, Martin has worked with companies of all sizes to design, develop, improve, and/or debug Windows, web, and database applications, and has performed strategic business consulting for high-tech corporations ranging from tiny to Fortune 100 and from local to multinational.

Martin’s specialties include programming languages C++, Python, C#, JavaScript, and SQL, and databases PostgreSQL, MySQL, Microsoft SQL Server, Oracle Database, Google Cloud Spanner, CockroachDB, MongoDB, Cassandra, and Couchbase. He writes about software development, data management, analytics, AI, and machine learning, contributing technology analyses, explainers, how-to articles, and hands-on reviews of software development tools, data platforms, AI models, machine learning libraries, and much more.

More from this author