Winapi 如何检测“是否”;“调试程序”;是否设置了Windows权限?

Winapi 如何检测“是否”;“调试程序”;是否设置了Windows权限?,winapi,Winapi,安装SQL Server 2008时,如果未为执行安装的用户启用此权限,则安装将不正常地失败。因此,在我的应用程序中,在安装SQL Server(使用其静默安装)之前,我想检测当前运行的用户是否设置了“调试程序”权限(即SeDebugPrivilege、SE_Debug_NAME…) 我不想知道当前进程是否设置了它(因为,很明显,大多数时候它没有设置,即使在系统上启用了特权)。我原本以为“PrivilegeCheck”API可以工作,但事实并非如此。如果您在VS调试器下运行此代码,则它会告诉您该

安装SQL Server 2008时,如果未为执行安装的用户启用此权限,则安装将不正常地失败。因此,在我的应用程序中,在安装SQL Server(使用其静默安装)之前,我想检测当前运行的用户是否设置了“调试程序”权限(即SeDebugPrivilege、SE_Debug_NAME…)

我不想知道当前进程是否设置了它(因为,很明显,大多数时候它没有设置,即使在系统上启用了特权)。我原本以为“PrivilegeCheck”API可以工作,但事实并非如此。如果您在VS调试器下运行此代码,则它会告诉您该权限已启用。如果从命令行运行它,它会告诉您权限已禁用。我应该如何更正此程序以实际检查特权是否可用


拉赫托肯

// Get the calling thread's access token.
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken)) 
{
    if (GetLastError() != ERROR_NO_TOKEN)
    {
        printf("CAN'T GET THREAD TOKEN!!!\n");
        return -1;
    }

    // Retry against process token if no thread token exists.
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
    {
        printf("CAN'T GET PROCESS TOKEN!!!\n");
        return -1;
    }
}

//Find the LUID for the debug privilege token
LUID luidDebugPrivilege;
if ( !LookupPrivilegeValue( 
    NULL,            // lookup privilege on local system
    "SeDebugPrivilege",   // privilege to lookup 
    &luidDebugPrivilege ) )        // receives LUID of privilege
{
    printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
    return -1; 
}

PRIVILEGE_SET privs; 
privs.PrivilegeCount = 1;
privs.Control = PRIVILEGE_SET_ALL_NECESSARY;

privs.Privilege[0].Luid = luidDebugPrivilege;
privs.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; 

BOOL bResult;
::PrivilegeCheck(hToken, &privs, &bResult);

if(bResult)
{
    printf("DEBUG ENABLED!\n");
}
else
{
    printf("DEBUG NOT ENABLED!\n");
}

如果我理解您的意思是正确的,您可以使用它来获取用户拥有的特权列表。

可以使用函数
GetTokenInformation
来检索进程的特权列表
PrivilegeCheck
检查权限是否已启用或禁用,用户未持有的权限将始终被禁用。用户拥有的权限可以被禁用,也可以不被禁用(某些权限在默认情况下被禁用)


根据您的问题,我认为您真正想要检查的是用户是否是管理员

好的,我们在发布原始问题后解决了这个问题。我们实际上需要做的是尝试为当前进程设置“调试程序”权限。如果我们可以启用该权限,则意味着当前登录用户在本地安全策略编辑器(XP上的gpedit.msc…)中为他们启用了该权限

请参阅下面的示例代码,以防其他人需要解决此问题!重要的是:

  • 使用LookupPrivilegeValue()查找SeDebugPrivilege的LUID。(所有这些东西的API都需要LUIDs…)
  • 使用GetTokenInformation()可以了解此进程上已启用了哪些权限。如果该进程已经启用了特权,这意味着该进程很可能正在调试器下运行,并且当前登录的用户确实启用了特权
  • 如果进程未设置权限,请使用AdjustTokenPrivileges()尝试设置权限。这是在我们下面的方法attemptoddebugprivilegetoprocess()中;如果可以设置权限(意味着当前登录用户启用了“调试程序”权限),则返回true;如果不能,则返回false

#包括“stdafx.h”
#包括
void ShowLastError(LPTSTR lpsz函数){
//检索最后一个错误代码的系统错误消息
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw=GetLastError();
格式化消息(
格式化消息分配缓冲区
格式化来自\u系统的\u消息\u|
格式化\u消息\u忽略\u插入,
无效的
dw,
MAKELANGID(LANG_中立,SUBLANG_默认),
(LPTSTR)和lpMsgBuf,
0,空);
//显示错误消息并退出进程
lpDisplayBuf=(LPVOID)LocalAlloc(LMEM_zeronit,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf)/sizeof(TCHAR),
文本(“%s失败,错误为%d:%s”),
lpsz函数、dw、lpMsgBuf);
printf((LPTSTR)lpDisplayBuf);
本地免费(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
布尔路易斯马特(路易斯l1,路易斯l2)
{
返回l1.LowPart==l2.LowPart&&l1.HighPart==l2.HighPart;}
bool尝试添加调试权限(HANDLE hToken){
//查找调试特权令牌的LUID
路易德·路易德;
如果(!LookupPrivilegeValue(
NULL,//本地系统上的查找权限
“SeDebugPrivilege”,//查找权限
&luidDebugPrivilege))//接收特权的LUID
{
printf(“LookupPrivilegeValue错误:%u\n”,GetLastError());
返回false;
}
TOKEN_特权newState;
newState.privilegecont=1;
newState.Privileges[0]。Luid=luidDebugPrivilege;
newState.Privileges[0]。属性=SE_PRIVILEGE_已启用;
如果(调整)特权(
赫托肯,
假,,
&纽斯塔特,
sizeof(新闻状态),
NULL,//&previousState,
0))
{
如果(GetLastError()==未分配所有错误)
{
printf(“无法设置调试!!!”;
返回false;
}
//*************************************************************
//如果您在此处创建,则用户具有调试程序权限
//*************************************************************
printf(“调试正常!!!”;
返回true;
}
printf(“AdjustTokenPrivileges returned false!!!”;
ShowLastError(“AdjustTokenPrivileges”);
返回false;
}
int _tmain(int argc,_TCHAR*argv[]
{
拉赫托肯;
//获取调用线程的访问令牌。
if(!OpenThreadToken(GetCurrentThread(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,TRUE,&hToken))
{
如果(GetLastError()!=错误\u无\u标记)
{
printf(“无法获取线程令牌!!!\n”);
返回-1;
}
//如果不存在线程令牌,请重试进程令牌。
if(!OpenProcessToken(GetCurrentProcess()、标记调整特权、标记查询和hToken))
{
printf(“无法获取进程令牌!!!\n”);
返回-1;
}
}
//查找调试特权令牌的LUID
路易德·路易德;
如果(!LookupPrivilegeValue(
NULL,//本地系统上的查找权限
“SeDebugPrivilege”,//查找权限
&路易德(特权)

#include "stdafx.h"
#include <strsafe.h>

void ShowLastError(LPTSTR lpszFunction) { 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    printf((LPTSTR)lpDisplayBuf);

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}



bool LuidsMatch(LUID l1, LUID l2)
{
    return l1.LowPart == l2.LowPart && l1.HighPart == l2.HighPart; }

bool AttemptToAddDebugPrivilegeToProcess(HANDLE hToken) {
    //Find the LUID for the debug privilege token
    LUID luidDebugPrivilege;
    if ( !LookupPrivilegeValue( 
        NULL,            // lookup privilege on local system
        "SeDebugPrivilege",   // privilege to lookup 
        &luidDebugPrivilege ) )        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return false; 
    }

    TOKEN_PRIVILEGES newState;
    newState.PrivilegeCount = 1;
    newState.Privileges[0].Luid = luidDebugPrivilege;
    newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if(AdjustTokenPrivileges(
        hToken,
        FALSE,
        &newState,
        sizeof(newState),
        NULL, //&previousState, 
        0))
    {
        if(GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            printf("Couldn't set debug!!!");
            return false;
        }

        //*************************************************************
        //IF YOU MADE IT HERE, THE USER HAS THE DEBUG PROGRAMS PRIVILEGE
        //*************************************************************
        printf("DEBUG OK!!!");
        return true;
    }

    printf("AdjustTokenPrivileges returned false!!!");
    ShowLastError("AdjustTokenPrivileges");
    return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hToken;

    // Get the calling thread's access token.
    if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, TRUE, &hToken)) 
    {
        if (GetLastError() != ERROR_NO_TOKEN)
        {
            printf("CAN'T GET THREAD TOKEN!!!\n");
            return -1;
        }

        // Retry against process token if no thread token exists.
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken))
        {
            printf("CAN'T GET PROCESS TOKEN!!!\n");
            return -1;
        }
    }

    //Find the LUID for the debug privilege token
    LUID luidDebugPrivilege;
    if ( !LookupPrivilegeValue( 
        NULL,            // lookup privilege on local system
        "SeDebugPrivilege",   // privilege to lookup 
        &luidDebugPrivilege ) )        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return -1; 
    }


    //Find if the "debug programs" privilege is already assigned to this process
    DWORD dwReturnedDataSize;
    GetTokenInformation(
        hToken,
        TokenPrivileges,
        NULL,
        0,
        &dwReturnedDataSize);

    BYTE* pData = new BYTE[dwReturnedDataSize];
    GetTokenInformation(
        hToken,
        TokenPrivileges,
        pData,
        dwReturnedDataSize,
        &dwReturnedDataSize);

    TOKEN_PRIVILEGES* pPrivileges = (TOKEN_PRIVILEGES*)pData;

    bool bFound = false;

    for(unsigned int count = 0; count PrivilegeCount; count++)
    {
        LUID_AND_ATTRIBUTES& luidAndAttrs = pPrivileges->Privileges[count];

        if(LuidsMatch(luidAndAttrs.Luid, luidDebugPrivilege))
        {
            bFound = true;
            if((luidAndAttrs.Attributes & SE_PRIVILEGE_ENABLED) == SE_PRIVILEGE_ENABLED)
            {
                //**************************************************************
                //IF YOU MADE IT HERE, THE USER HAS THE DEBUG PROGRAMS PRIVILEGE
                //**************************************************************
            }
            else
            {
                printf("THIS PROCESS DOES NOT HAVE THE DEBUG PROGRAMS PRIVILEGE ENABLED\n");                                AttemptToAddDebugPrivilegeToProcess(hToken);
            }
        }
    }

    if(!bFound)
    {
        printf("THIS PROCESS DOES NOT HAVE THE DEBUG PROGRAMS PRIVILEGE ENABLED\n");
        AttemptToAddDebugPrivilegeToProcess(hToken);
    }

    return 0;
}