OK, мы выяснили это после размещения оригинального вопроса. Нам действительно нужно попытаться установить привилегии «отладочные программы» для текущего процесса. Если мы сможем включить эту привилегию, то это означает, что текущий пользователь, включенный в систему, имеет эту привилегию для них в локальном редакторе политики безопасности (gpedit.msc на XP ...)
См. Ниже пример кода, в случае кому-то еще нужно решить эту проблему! Важными частями являются:
- Используйте LookupPrivilegeValue(), чтобы найти LUID для SeDebugPrivilege. (Для всех API-интерфейсов для этого требуется LUID ...)
- Используйте GetTokenInformation(), чтобы узнать, какие привилегии включены в этот процесс уже. Если процесс имеет уже включенную привилегию, это означает, что процесс, скорее всего, выполняется под отладчиком и что текущий вход в систему пользователя имеет привилегию.
- Если процесс не имеет набора привилегий, используйте функцию AdjustTokenPrivileges(), чтобы попытаться установить привилегию. Это наш метод AttemptToAddDebugPrivilegeToProcess() ниже; мы возвращаем true, если привилегия может быть установлена (что означает, что у текущего пользователя, имеющего вход в систему, есть привилегия «отладочные программы») или false, если это невозможно.
#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;
}
Существует вещь, называемая запретная маркер, так что процесс работает как пользователь X может на самом деле имеют меньше привилегий, чем то, что обычно имеет пользователь (Большой пример UAC с раздельным маркеров модели, но Безопаснее API, добавленный в XP, тоже делает это, а IIRC - фактическое ограничение токена api было добавлено в 2000) – Anders