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