在KB131065中使用AdjustTokenPrivileges是正确的吗?

时间:2010-08-25 19:03:21

标签: security winapi

KB131065演示了如何激活SeDebugPrivilege以打开任何进程的句柄。它有一个名为SetPrivilege的函数调用AdjustTokenPrivileges,但有两个实现,没有提到原因。

第一个实现在两次传递中调用ATP:

// 
// first pass.  get current privilege setting
// 
tp.PrivilegeCount           = 1;
tp.Privileges[0].Luid       = luid;
tp.Privileges[0].Attributes = 0;

AdjustTokenPrivileges(
        hToken,
        FALSE,
        &tp,
        sizeof(TOKEN_PRIVILEGES),
        &tpPrevious,
        &cbPrevious
        );

if (GetLastError() != ERROR_SUCCESS) return FALSE;

// 
// second pass.  set privilege based on previous setting
// 
tpPrevious.PrivilegeCount       = 1;
tpPrevious.Privileges[0].Luid   = luid;

if(bEnablePrivilege) {
    tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
}
else {
    tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
        tpPrevious.Privileges[0].Attributes);
}

AdjustTokenPrivileges(
        hToken,
        FALSE,
        &tpPrevious,
        cbPrevious,
        NULL,
        NULL
        );

这看起来有点矫枉过正。我没有在文档中看到任何内容,表明previous-state参数的Attributes字段接收到需要保留的任何其他标志。看起来更像是代码从禁用特权开始,然后它返回并重新启用它或再次禁用它。我有正确的解释吗?别人推荐这种技术吗?

SetPrivilege的第二个实现看起来更像我期望的那样:

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if(bEnablePrivilege) {
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
} else {
    tp.Privileges[0].Attributes = 0;
}
AdjustTokenPrivileges( hToken, FALSE, &tp, cb, NULL, NULL );

第二个版本是否过于简化?我注意到它与Enabling and Disabling Privileges in C++中演示的内容基本相同,只是KB文章忽略了API的返回值并直接转到GetLastError来检测成功和失败。

1 个答案:

答案 0 :(得分:1)

我一直使用第二个例子。

在第一个例子中我完全看不到任何意义。例如,GetWindowLong\SetWindowLong函数是有意义的,但对于特权,根本没有可以组合的持久设置,因此需要检索以前的状态。

是的,他们实际上是为了获得当前状态而禁用该权限,这是错误的 然而,遗憾的是,MSDN上有许多可怕的代码。