判断自己是否有管理员权限和自己是否为服务

前言

在逆向一个专杀, MFC Dialog的程序.
在CxxWinApp::InitInstance中看到, 在增加权限之前, 先判断自己是否有管理员权限.
这代码MS都给了, 不用去逆向了, 找了一段MS的例子.
MS的例子中, 给了如何判断当前程序有管理员权限, 如何判断本程序是服务.
经过比对, 逆向出来的判断管理员身份的函数,更有实用性. 可以用在其他工程里面.
MS的例子还要改改, 将报错代码拿掉, 换成错误码.

记录

逆向出来的函数

BOOL isAdministrator()
{
    BOOL bRc = FALSE;
    BOOL bTmp = FALSE;
    SID_IDENTIFIER_AUTHORITY pIdentifierAuthority = { SECURITY_NT_AUTHORITY };
    PSID pSid = NULL;
    HANDLE TokenHandle = NULL;
    DWORD ReturnLength;
    UCHAR TokenInformation[1024];
    PTOKEN_GROUPS Groups = (PTOKEN_GROUPS)TokenInformation;
    DWORD dwIndex = 0;
    bRc = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY/*8u*/, &TokenHandle);

    if (bRc) {
        bTmp = GetTokenInformation(TokenHandle, TokenGroups, &TokenInformation, sizeof(TokenInformation), &ReturnLength);
        CloseHandle(TokenHandle);

        if (bTmp) {
            bRc = AllocateAndInitializeSid(
                      &pIdentifierAuthority,
                      2u,
                      SECURITY_BUILTIN_DOMAIN_RID/*0x20u*/,
                      DOMAIN_ALIAS_RID_ADMINS/*0x220u*/,
                      0,
                      0,
                      0,
                      0,
                      0,
                      0,
                      &pSid);

            if (bRc) {
                bTmp = FALSE;

                if (TokenInformation > 0) {
                    for (dwIndex = 0; dwIndex < Groups->GroupCount; dwIndex++) {
                        if (EqualSid(pSid, Groups->Groups[dwIndex].Sid)) {
                            bTmp = TRUE;
                            break;
                        }
                    }
                }

                FreeSid(pSid);
                bRc = bTmp;
            }
        } else {
            bRc = FALSE;
        }
    }

    return bRc;
}

MS的例子

/*-------------------------------------------------------------------------
 *
 * security.c
 *    Microsoft Windows Win32 Security Support Functions
 *
 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *    $PostgreSQL$
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

/*
 * Returns nonzero if the current user has administrative privileges,
 * or zero if not.
 */
int pgwin32_is_admin(void) {
    HANDLE AccessToken;
    UCHAR InfoBuffer[1024];
    PTOKEN_GROUPS Groups = (PTOKEN_GROUPS)InfoBuffer; 
    DWORD InfoBufferSize;
    PSID AdministratorsSid;
    PSID PowerUsersSid;
    SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY }; 
    UINT x;
    BOOL success;

    if(!OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&AccessToken))
        ereport(FATAL,
                (errmsg_internal("Failed to open process token: %i",(int)GetLastError())));

    if (!GetTokenInformation(AccessToken,TokenGroups,InfoBuffer,
                             1024, &InfoBufferSize))
        ereport(FATAL,
                (errmsg_internal("Failed to get token information: %i",(int)GetLastError())));

    CloseHandle(AccessToken);

    if(!AllocateAndInitializeSid(&NtAuthority, 2,
                                 SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
                                 0,&AdministratorsSid))
        ereport(FATAL,
                (errmsg_internal("Failed to get SID for Administrators group: %i",(int)GetLastError())));

    if (!AllocateAndInitializeSid(&NtAuthority, 2,
                                  SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
                                  0, &PowerUsersSid))
        ereport(FATAL,
                (errmsg_internal("Failed to get SID for PowerUsers group: %i",(int)GetLastError())));

    success = FALSE;

    for (x=0; x<Groups->GroupCount; x++)
    {
        if( EqualSid(AdministratorsSid, Groups->Groups[x].Sid) ||
            EqualSid(PowerUsersSid, Groups->Groups[x].Sid))
        {
            success = TRUE;
            break;
        }
    }

    FreeSid(AdministratorsSid);
    FreeSid(PowerUsersSid);
    return success;
}

/*
 * We consider ourselves running as a service if one of the following is
 * true:
 *
 * 1) We are running as Local System (only used by services)
 * 2) Our token contains SECURITY_SERVICE_RID (automatically added to the
 *    process token by the SCM when starting a service)
 *
 * Return values:
 *   0 = Not service
 *   1 = Service
 *  -1 = Error (can't ereport error, this is called too early)
 */
int pgwin32_is_service(void) {
    static int _is_service = -1;
    HANDLE AccessToken;
    UCHAR InfoBuffer[1024];
    PTOKEN_GROUPS Groups = (PTOKEN_GROUPS)InfoBuffer;
    PTOKEN_USER User = (PTOKEN_USER)InfoBuffer;
    DWORD InfoBufferSize;
    PSID ServiceSid;
    PSID LocalSystemSid;
    SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY }; 
    UINT x;

    /* Only check the first time */
    if (_is_service != -1)
        return _is_service;

    if (!OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&AccessToken)) {
        fprintf(stderr,"Failed to open process token: %i\n",(int)GetLastError());
        return -1;
    }

    /* First check for local system */
    if (!GetTokenInformation(AccessToken,TokenUser,InfoBuffer,1024,&InfoBufferSize)) {
        fprintf(stderr,"Failed to get token information: %i\n",(int)GetLastError());
        return -1;
    }

    if (!AllocateAndInitializeSid(&NtAuthority,1,
                                  SECURITY_LOCAL_SYSTEM_RID,0,0,0,0,0,0,0,
                                  &LocalSystemSid)) {
        fprintf(stderr,"Failed to get SID for local system account\n");
        CloseHandle(AccessToken);
        return -1;
    }

    if (EqualSid(LocalSystemSid, User->User.Sid)) {
        CloseHandle(AccessToken);
        FreeSid(LocalSystemSid);
        _is_service = 1;
        return _is_service;
    }

    FreeSid(LocalSystemSid);


    /* Now check for group SID */
    if (!GetTokenInformation(AccessToken,TokenGroups,InfoBuffer,1024,&InfoBufferSize)) {
        fprintf(stderr,"Failed to get token information: %i\n",(int)GetLastError());
        return -1;
    }

    if (!AllocateAndInitializeSid(&NtAuthority,1,
                                  SECURITY_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0,
                                  &ServiceSid)) {
        fprintf(stderr,"Failed to get SID for service group\n");
        CloseHandle(AccessToken);
        return -1;
    }

    for (x = 0; x < Groups->GroupCount; x++)
    {
        if (EqualSid(ServiceSid, Groups->Groups[x].Sid)) 
        {
            _is_service = 1;
            break;
        }
    }

    FreeSid(ServiceSid);

    CloseHandle(AccessToken);


    if (_is_service == -1)
        _is_service = 0;

    return _is_service;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值