问题
I'm writing a logging service that may collect privileges of a process and I'm trying to understand attributes for each process privilege. Let me explain with this code:
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);
}
So let's see the structure of TOKEN_PRIVILEGES and LUID_AND_ATTRIBUTES in particular:
#define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L)
#define SE_PRIVILEGE_ENABLED (0x00000002L)
#define SE_PRIVILEGE_REMOVED (0X00000004L)
#define SE_PRIVILEGE_USED_FOR_ACCESS (0x80000000L)
It looks like it is defined as a bitmask, but that brings up the following questions of interpreting these flags:
What is the difference between
ENABLEDandENABLED_BY_DEFAULT?What is
SE_PRIVILEGE_USED_FOR_ACCESSand how can it be used?What if both
SE_PRIVILEGE_ENABLEDandSE_PRIVILEGE_REMOVEDare set? Or, reset?I just ran a simple test and for my process the
SeShutdownPrivilegeprivilege had those attributes set as0. So what is that supposed to mean?
I'm more confused over this structure, but I'll keep it at just these points for now.
Thank you!
回答1:
To take your questions in order:
ENABLED_BY_DEFAULTmeans the privilege is one of those that is enabled when the process starts. If you haveENABLEDbut notENABLED_BY_DEFAULTthen the process has enabled the privilege explicitly. If you haveENABLED_BY_DEFAULTbut notENABLEDthen the process has disabled the privilege explicitly.According to the documentation,
SE_PRIVILEGE_USED_FOR_ACCESSis set whenever the privilege is actually used. You might use this for troubleshooting, e.g., to detect that you are setting privileges that you are not actually using, or to determine experimentally which privileges a particular system call needs. (I've never checked whether this actually behaves as documented, though I have no reason to think otherwise.)If both
SE_PRIVILEGE_ENABLEDandSE_PRIVILEGE_REMOVEDare set, you've found a bug in Windows. :-)If neither
SE_PRIVILEGE_ENABLEDnorSE_PRIVILEGE_REMOVEDare set, then the privilege is present in the token, and has not been removed, but is not currently enabled. You can enable it (or remove it) with AdjustTokenPrivileges().If the attribute is zero, then the privilege is present in the token but is not currently enabled, has not been removed, was not enabled by default, and has never been used by the process.
回答2:
What some of us may need to be told explicitly is that privileges have THREE possible states, not just two. As I began researching this stuff, I thought that a process would either have, or not have a privilege. But it turns out that even if the process has a privilege, it can be in a disabled state. In other words, disabled != doesn't have it.
The rest follows logically. If a privilege is not present in the process' access token, the process does not have that privilege. And vice versa, if the process does not have a privilege, the privilege will not be present in the token.
If the process has the privilege, the process can enable or disable it at will, right? Why is this useful? All right, I can guess that this allows you to call library functions without fully knowing what they do, and have them fail if they do more than you thought... Odd though.
来源:https://stackoverflow.com/questions/29453204/trying-to-understand-process-privilege-attributes