原文链接
https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa379630(v=vs.85).aspx
- TOKEN_PRIVILEGES 结构体包含一个令牌的一系列的特权。
typedef struct _TOKEN_PRIVILEGES {
DWORD PrivilegeCount;
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
- PrivilegeCount
下面的特权数组的个数
Privileges
LUID_AND_ATTRIBUTES 结构数组。每一个结构包含一个标志特权身份的LUID 以及一个 属性。为了得到特权对应的名称,调用LookupPrivilegeName 函数。
LUID_AND_ATTRIBUTES
typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid;
DWORD Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
该结构仅仅定义了一个LUID 和 关联属性的结构体,这个属性的使用及其含义是此结构体使用的方法相关的。
TOKEN_PRIVILEGES 中可以使用的属性可以是以下值的组合
value | Meaning |
---|---|
SE_PRIVILEGE_ENABLE | 特权在使用 |
SE_PRIVILEGE_ENABLE_BY_DEFAULT | 默认启动 |
SE_PRIVILEGE_REMOVED | 移除特权 |
SE_PRIVILEGE_USED_FOR_ACCESS | 这个特权用来获得对于一个对象或者服务的访问。此标志标识了客户应用传入的特权集合中可能包含的不必要的特权 |
- Enable By Default 的意思是进程开始的时候就已经被设置了的权限, 如果特权设置ENABLED 但是没有ENABLED_BY_DEFAULT ,进程必须显示使其有效。
SE_PRIVILEGE_USED_FOR_ACCESS 标志在特特权被使用的时候被设置。可以使用此标志进行故障检查。比如,判断我们是否正在设置我们没有用到的特权,或者判断一个系统调用需要什么样的权限。
如果SE_PRIVILEGE_ENABLED 和 SE_PRIVILEGE_REMOVED 都没有被设置,特权在令牌中,没有被移除,但是也没有被实际的使用。可以调用AdjustTokenPrivileges 来使其有效或者移除它。
如果属性为0,特权在令牌中,但是没有被实际使用,没有被移除,没有被默认启用,还没被进程使用。
BOOL SetPrivilege(
HANDLE hToken, // token handle
LPCTSTR Privilege, // Privilege to enable/disable
BOOL bEnablePrivilege // TRUE to enable. FALSE to disable
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
TOKEN_PRIVILEGES tpPrevious;
DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
// 得到字符串对应的权限的LUID
if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
//
// 获得原来的权限
//
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;
//
// 设置
//
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
);
if (GetLastError() != ERROR_SUCCESS) return FALSE;
return TRUE;
}