进程是否以管理员身份运行

问题描述:

嘿朋友



是否有可能以某种方式确定是否有任何应用程序以管理员身份运行



在我的桌面上使用Win32 API或其他一些API?



类似



EnumProcess(enumFunc);并为每个过程检查我是否



enumFunc()

{

if(我正在运行)管理员)

{

TRACE(发现它'\\ n);

}



}

问候

Hey Friends

Is it possible somehow to determine whether any application is running as Administrator

on my Desktop using Win32 API or some other API ?

Something like

EnumProcess (enumFunc); and for each process check whether i do

enumFunc()
{
if(I am Running as Administrator)
{
TRACE("Found It\n");
}

}
Regards

你想要什么,看起来像这样:

What you want, looks something like this:
HRESULT CheckIfIsUserAdmin(BOOL *pIsAdmin)
{
    int b;
    HANDLE hProcess = NULL;
    HANDLE hProcessToken = NULL;
    HANDLE hLinkedToken = NULL;
    BOOL fIsAdmin = FALSE;
    DWORD dwLength = 0;
    OSVERSIONINFO osver = {sizeof(OSVERSIONINFO)};
    HRESULT hr = S_OK;
 
    *pIsAdmin = FALSE;
 
    hProcess = GetCurrentProcess();
    if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    char AdminSID[SECURITY_MAX_SID_SIZE];
    dwLength = sizeof(AdminSID);
    if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &AdminSID, &dwLength)) 
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    } 

    if (!CheckTokenMembership( NULL, &AdminSID, &fIsAdmin)) 
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    if (fIsAdmin) 
    {
        *pIsAdmin = TRUE;
        goto Exit;
    }
 
    if (!GetVersionEx(&osver))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    if (osver.dwMajorVersion < 6) 
    {
        goto Exit;        
    }
 
    // Code to handle admin SID filtering in Vista and above
    if (!GetTokenInformation(hProcessToken, TokenLinkedToken,
                                (VOID*) &hLinkedToken, sizeof(HANDLE), &dwLength) )
    {
        b = GetLastError();
        if( b == ERROR_NO_SUCH_LOGON_SESSION ||  b == ERROR_PRIVILEGE_NOT_HELD)
        {
            goto Exit;
        }
 
        hr = HRESULT_FROM_WIN32(b);
        goto Exit;
    } 

    if (!CheckTokenMembership(hLinkedToken, &AdminSID, &fIsAdmin))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Exit;
    }
 
    if (fIsAdmin)
    {
        *pIsAdmin = TRUE;
    }
 
Exit:
    if (hProcess) 
    {
        CloseHandle(hProcess);
    }
 
    if (hProcessToken)
    {
        CloseHandle(hProcessToken);
    }
 
    if (hLinkedToken)
    {
        CloseHandle(hLinkedToken);
    }
 
    return hr;
}



如果当前令牌不包含管理员SID,那并不总是意味着当前用户不是管理员,因为对于Vista及以上default用于过滤管理员组成员的令牌上的admininistrator SID。



因此,我们需要调用GetTokenInformation来检索链接的令牌,然后再次在喜欢的令牌上调用CheckTokenMembership以检查未经过滤的管理员SID。



最好的问候

Espen Harlinn


If the current token does not contain the administrator SID, that does not always mean that the current user is not an admininistrator since for Vista and above the default is to filter the admininistrator SID on the tokens for members of the administrator group.

So, we need to call GetTokenInformation to retrieve the linked token, and then call CheckTokenMembership once more on the liked token to check for the unfiltered admininistrator SID.

Best regards
Espen Harlinn


您的应用程序是否以管理员身份运行? [ ^ ]


这是我的我也是的答案,基于在KB#Q118626上:



Here is my "me too" answer, based on KB #Q118626:

//-------------------------------------------------------------------------
// This function checks the token of the calling thread to see if the caller
// belongs to the Administrators group.
//
// Return Value:
//   TRUE if the caller is an administrator on the local machine.
//   Otherwise, FALSE.
// --------------------------------------------------------------------------
// Based on code from KB #Q118626, at http://support.microsoft.com/kb/118626
BOOL IsCurrentUserLocalAdministrator()
{
    BOOL   fReturn         = FALSE;
    DWORD  dwStatus        = 0;
    DWORD  dwAccessMask    = 0;
    DWORD  dwAccessDesired = 0;
    DWORD  dwACLSize       = 0;
    DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
    PACL   pACL            = NULL;
    PSID   psidAdmin       = NULL;

    HANDLE hToken              = NULL;
    HANDLE hImpersonationToken = NULL;

    PRIVILEGE_SET   ps = {0};
    GENERIC_MAPPING GenericMapping = {0};

    PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

    // Determine if the current thread is running as a user that is a member 
    // of the local admins group.  To do this, create a security descriptor 
    // that has a DACL which has an ACE that allows only local administrators 
    // access.  Then, call AccessCheck with the current thread''s token and
    // the security descriptor.  It will say whether the user could access an
    // object if it had that security descriptor.  Note: you do not need to
    // actually create the object.  Just checking access against the
    // security descriptor alone will be sufficient.

    const DWORD ACCESS_READ  = 1;
    const DWORD ACCESS_WRITE = 2;

    __try
    {
        // AccessCheck() requires an impersonation token.  We first get a 
        // primary token and then create a duplicate impersonation token.
        // The impersonation token is not actually assigned to the thread, but
        // is used in the call to AccessCheck.  Thus, this function itself never
        // impersonates, but does use the identity of the thread.  If the thread
        // was impersonating already, this function uses that impersonation 
        // context.
        if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))
        {
            if (GetLastError() != ERROR_NO_TOKEN)
                __leave;

            if (!OpenProcessToken(GetCurrentProcess(), 
                TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
                __leave;
        }

        if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken))
            __leave;

        // Create the binary representation of the well-known SID that
        // represents the local administrators group.  Then create the 
        // security descriptor and DACL with an ACE that allows only local
        // admins access.  After that, perform the access check.  This will
        // determine whether the current user is a local admin.
        if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
            SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
            0, 0, 0, 0, 0, 0, &psidAdmin))
            __leave;

        psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
        if (psdAdmin == NULL)
            __leave;

        if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
            __leave;

        // Compute size needed for the ACL.
        dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psidAdmin) - sizeof(DWORD);

        pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
        if (pACL == NULL)
            __leave;

        if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
            __leave;

        dwAccessMask= ACCESS_READ | ACCESS_WRITE;

        if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))
            __leave;

        if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
            __leave;

        // AccessCheck validates a security descriptor somewhat; set the group
        // and owner so that enough of the security descriptor is filled out to
        // make AccessCheck happy.

        SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
        SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

        if (!IsValidSecurityDescriptor(psdAdmin))
            __leave;

        dwAccessDesired = ACCESS_READ;

        // Initialize GenericMapping structure even though you
        // do not use generic rights.
        GenericMapping.GenericRead    = ACCESS_READ;
        GenericMapping.GenericWrite   = ACCESS_WRITE;
        GenericMapping.GenericExecute = 0;
        GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;

        if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
            &GenericMapping, &ps, &dwStructureSize, &dwStatus,
            &fReturn))
        {
            fReturn = FALSE;
            __leave;
        }
    }
    __finally
    {
        // Clean up.
        if (pACL)
            LocalFree(pACL);
        if (psdAdmin)
            LocalFree(psdAdmin);
        if (psidAdmin)
            FreeSid(psidAdmin);
        if (hImpersonationToken)
            CloseHandle (hImpersonationToken);
        if (hToken)
            CloseHandle (hToken);
    }

    return fReturn;
}