我正在编写一个可以收集进程权限的日志记录服务,而我正在尝试了解每个进程权限的属性。让我用这段代码解释一下:
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
。那应该是什么意思呢?
我对这个结构更加困惑,但我现在暂时将其保留在这些点上。
谢谢!
答案 0 :(得分:4)
按顺序提出问题:
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()启用它(或删除它)。
如果该属性为零,则该权限存在于令牌中,但当前未启用,尚未删除,默认情况下未启用,且该进程从未使用过该权限。
答案 1 :(得分:0)
我们可能需要明确告诉我们,特权有三种可能的状态,而不仅仅是两种状态。当我开始研究这些东西时,我认为一个过程要么拥有,要么没有特权。但事实证明,即使进程具有特权,它也可能处于禁用状态。换句话说,禁用!=没有。
其余部分遵循逻辑。如果流程中没有特权,那么#39;访问令牌,该进程没有该权限。反之亦然,如果进程没有权限,则权限将不会出现在令牌中。
如果进程具有该权限,则该进程可以随意启用或禁用它,对吧?为什么这有用?好吧,我猜这可以让你在不完全知道他们做什么的情况下调用库函数,并且如果他们做的比你想象的要多,那就让它们失败......但奇怪的是。