Я пишу сервис регистрации, который может собирать привилегии процесса, и я пытаюсь понять атрибуты для каждой привилегии процесса. Позвольте мне объяснить с этим кодом:
HANDLE hToken;
if(OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
DWORD dwSize = 0;
if(!GetTokenInformation(hToken, TokenPrivileges, NULL, dwSize, &dwSize) &&
::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
BYTE* pb = new (std::nothrow) BYTE[dwSize];
if(pb)
{
TOKEN_PRIVILEGES* pTPs = (TOKEN_PRIVILEGES*)pb;
DWORD dwSize2;
if(GetTokenInformation(hToken, TokenPrivileges, pTPs, dwSize, &dwSize2) &&
dwSize2 <= dwSize)
{
for(UINT i = 0; i < pTPs->PrivilegeCount; i++)
{
//Analyze privilege attributes to understand if it's enabled or disabled?
DWORD dwPrivAttr = pTPs->Privileges[i].Attributes;
//...
}
}
delete[] pb;
}
}
CloseHandle(hToken);
}
Итак, давайте посмотрим на структуру TOKEN_PRIVILEGES а также LUID_AND_ATTRIBUTES
особенно:
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L)
#define SE_PRIVILEGE_ENABLED (0x00000002L)
#define SE_PRIVILEGE_REMOVED (0X00000004L)
#define SE_PRIVILEGE_USED_FOR_ACCESS (0x80000000L)
Похоже, это определено как битовая маска, но это поднимает следующие вопросы интерпретации этих флагов:
В чем разница между ENABLED
а также ENABLED_BY_DEFAULT
?
Что такое SE_PRIVILEGE_USED_FOR_ACCESS
и как это можно использовать?
Что если оба SE_PRIVILEGE_ENABLED
а также SE_PRIVILEGE_REMOVED
установлены? Или сброс?
Я только что провел простой тест и для моего процесса SeShutdownPrivilege
привилегия была установлена эти атрибуты как 0
, Так что это должно означать?
Я больше запутался в этой структуре, но пока буду держать ее только в этих точках.
Спасибо!
Чтобы ответить на ваши вопросы по порядку:
ENABLED_BY_DEFAULT
означает, что привилегия является одной из тех, которые активируются при запуске процесса. Если у вас есть ENABLED
но нет ENABLED_BY_DEFAULT
тогда процесс явно разрешил эту привилегию. Если у вас есть ENABLED_BY_DEFAULT
но нет ENABLED
тогда процесс явно отключил привилегию.
Согласно документации, SE_PRIVILEGE_USED_FOR_ACCESS
устанавливается всякий раз, когда привилегия фактически используется. Вы можете использовать это для устранения неполадок, например, чтобы обнаружить, что вы устанавливаете привилегии, которые вы на самом деле не используете, или для экспериментального определения, какие привилегии нужны конкретному системному вызову. (Я никогда не проверял, действительно ли это ведет себя как задокументировано, хотя у меня нет оснований думать иначе.)
Если оба SE_PRIVILEGE_ENABLED
а также SE_PRIVILEGE_REMOVED
установлены, вы нашли ошибку в Windows. 🙂
Если ни SE_PRIVILEGE_ENABLED
ни SE_PRIVILEGE_REMOVED
установлены, то привилегия присутствует в токене и не была удалена, но в настоящее время не включена. Вы можете включить (или удалить) с помощью AdjustTokenPrivileges ().
Если атрибут равен нулю, то привилегия присутствует в токене, но в настоящее время не включена, не была удалена, не была включена по умолчанию и никогда не использовалась процессом.
Некоторым из нас, возможно, нужно сказать прямо, что привилегии имеют ТРИ возможных состояния, а не только два. Когда я начал исследовать этот материал, я подумал, что процесс будет иметь или не иметь привилегии. Но оказывается, что даже если у процесса есть привилегия, он может находиться в отключенном состоянии. Другими словами, отключено! = Не имеет его.
Остальное следует по логике. Если привилегия отсутствует в маркере доступа процесса, процесс не имеет этой привилегии. И наоборот, если у процесса нет привилегии, эта привилегия не будет присутствовать в токене.
Если у процесса есть привилегия, он может включить или отключить его по своему желанию, верно? Почему это полезно? Хорошо, я могу предположить, что это позволяет вам вызывать библиотечные функции, не зная полностью, что они делают, и заставлять их отказывать, если они делают больше, чем вы думали … Странно, хотя.