试图了解进程权限属性

时间:2015-04-05 01:27:13

标签: c++ windows winapi windows-kernel

我正在编写一个可以收集进程权限的日志记录服务,而我正在尝试了解每个进程权限的属性。让我用这段代码解释一下:

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_PRIVILEGESLUID_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)

看起来它被定义为一个位掩码,但这会带来以下解释这些标志的问题:

  1. ENABLEDENABLED_BY_DEFAULT有什么区别?

  2. 什么是SE_PRIVILEGE_USED_FOR_ACCESS以及如何使用?

  3. 如果SE_PRIVILEGE_ENABLEDSE_PRIVILEGE_REMOVED都设置了怎么办?或者,重置?

  4. 我刚刚运行了一个简单的测试,对于我的流程,SeShutdownPrivilege权限将这些属性设置为0。那应该是什么意思呢?

  5. 我对这个结构更加困惑,但我现在暂时将其保留在这些点上。

    谢谢!

2 个答案:

答案 0 :(得分:4)

按顺序提出问题:

  1. ENABLED_BY_DEFAULT表示权限是进程启动时启用的权限之一。如果您有ENABLED但没有ENABLED_BY_DEFAULT,则该进程已明确启用该权限。如果您有ENABLED_BY_DEFAULT但没有ENABLED,则该流程已明确禁用该权限。

  2. 根据文档,只要实际使用了权限,就会设置SE_PRIVILEGE_USED_FOR_ACCESS。您可以使用它进行故障排除,例如,检测您是否正在设置您实际未使用的权限,或者通过实验确定特定系统调用所需的权限。 (我从来没有检查过这是否真的有记录,尽管我没有理由不这么认为。)

  3. 如果同时设置了SE_PRIVILEGE_ENABLEDSE_PRIVILEGE_REMOVED,则表示您在Windows中发现了一个错误。 : - )

    如果未设置SE_PRIVILEGE_ENABLEDSE_PRIVILEGE_REMOVED,则权限存在于令牌中,并且尚未删除,但当前未启用。您可以使用AdjustTokenPrivileges()启用它(或删除它)。

  4. 如果该属性为零,则该权限存在于令牌中,但当前未启用,尚未删除,默认情况下未启用,且该进程从未使用过该权限。

答案 1 :(得分:0)

我们可能需要明确告诉我们,特权有三种可能的状态,而不仅仅是两种状态。当我开始研究这些东西时,我认为一个过程要么拥有,要么没有特权。但事实证明,即使进程具有特权,它也可能处于禁用状态。换句话说,禁用!=没有。

其余部分遵循逻辑。如果流程中没有特权,那么#39;访问令牌,该进程没有该权限。反之亦然,如果进程没有权限,则权限将不会出现在令牌中。

如果进程具有该权限,则该进程可以随意启用或禁用它,对吧?为什么这有用?好吧,我猜这可以让你在不完全知道他们做什么的情况下调用库函数,并且如果他们做的比你想象的要多,那就让它们失败......但奇怪的是。