【发布时间】:2015-04-05 01:27:12
【问题描述】:
我正在编写一个日志服务,它可能会收集进程的权限,并且我正在尝试了解每个进程权限的属性。让我用这段代码解释一下:
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。那是什么意思呢?
我对这个结构比较困惑,但我暂时只讨论这些问题。
谢谢!
【问题讨论】:
-
默认启用意味着它在创建令牌时启用,而不是稍后通过
AdjustTokenPrivileges。如果它从令牌中删除,那么您应该无法启用它。 -
某些 API 会为您切换所需的权限,如果它存在于令牌中,但通常您必须手动启用它。
ExitWindowsEx和SeShutdownPrivilege就是这种情况。 -
@eryksun:所以当属性设置为0时,这意味着权限关闭,对吗?在那种情况下,
GetTokenInformationAPI 让我SeShutdownPrivilege和 attr0而不给我其余的特权有什么意义?我的意思是,SeTcbPrivilege可能也与其他 20 个人一起关闭,但它不会返回它。抱歉,我只是想理解这里的逻辑。 -
@eryksun:还要检查权限是打开还是关闭,我需要做
bool bEnabled = !!(dwAtt & SE_PRIVILEGE_ENABLED);或bool bEnabled = !(dwAtt & SE_PRIVILEGE_REMOVED);还是什么? -
SeTcbPrivilege不只是关闭。除非您作为系统服务运行,否则它根本不应该出现在令牌中。您不能添加权限;您只能启用、禁用或删除它们。最好仅在需要时启用特权,特别是因为特权的状态会被子进程继承。
标签: c++ windows winapi windows-kernel