
HANDLE hToken; //存放获得的令牌
TOKEN_PRIVILEGES tp; //令牌权限结构体
/*
一个LUID_AND_ATTRIBUTES结构体. 每个结构体包括LUID和特权的属性
typedef struct _TOKEN_PRIVILEGES
{
ULONG PrivilegeCount; //数组元素的个数
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; //数组.类型为LUID_AND_ATTRIBUTES
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
一个LUID_AND_ATTRIBUTES结构体. 每个结构体包括LUID和特权的属性. 特权的属性可以是下列值的组合:
SE_PRIVILEGE_ENABLED_BY_DEFAULT 特权默认启用
SE_PRIVILEGE_ENABLED 特权启用
SE_PRIVILEGE_USED_FOR_ACCESS 特权被用来访问一个对象或服务
typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid;
DWORD Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
Luid 指定 LUID 值
Attributes 指定 LUID 的属性。 此值最多包含 32 个一位标志。 其含义取决于 LUID 的定义和使用
typedef struct _LUID {
DWORD LowPart;
LONG HighPart;
} LUID, *PLUID;
*/
BOOL b = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);//获取当前进程的令牌
/*
参数1:HANDLE ProcessHandle 要修改访问权限的进程句柄
参数2:DWORD DesiredAccess 进程对获得的令牌有哪些操作权限
TOKEN_ADJUST_PRIVILEGES = 0x0020H 要修改访问令牌的特权
TOKEN_ADJUST_GROUPS
TOKEN_ADJUST_DEFAULT
TOKEN_EXECUTE
TOKEN_QUERY=0x0008H 查询
TOKEN_READ
TOKEN_WRITE
TOKEN_ALL_ACCESS
参数3:PHANDLE TokenHandle 存放令牌的句柄的地址
返回值:非零表示成功,零表示失败
*/
if (!b) {
AfxMessageBox(_T("获取进程的令牌句柄失败"));
}
BOOL b1 = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);//获取本地系统的指定权限
/*
LUID存储在tp结构体里
参数1:LPCTSTR lpSystemName 表示所要查看的系统,本地系统直接用NULL
参数2:LPCTSTR lpName 指向一个以零结尾的字符串,指定权限的名称
SE_DEBUG_NAME 调试权限,这个权限应该是进程所能具有的最大权限
其他:https://learn.microsoft.com/zh-cn/windows/win32/secauthz/privilege-constants
参数3:PLUID lpLuid 指向接收 LUID 的变量的指针【LUID保存权限值】
返回值:如果函数成功,该函数将返回非零
如果函数失败,它将返回零
*/
if (!b1) {
AfxMessageBox(_T("获取系统权限的特权值失败"));
}
//下面开始激活当前令牌的调试权限,调试权限一般是不开通的,因为权限太大了
//一定要用完了就关掉
tp.PrivilegeCount = 1; //只启动调试权限,所以权限的个数是一个
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //属性设置
/*
当Attributes = SE_PRIVILEGE_ENABLE 时,激活权限
当Attributes = 0 时,关闭权限
权限是LookupPrivilegeValue函数获得的
*/
BOOL b2 = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);//修改访问令牌的权限
/*
【必须以管理员身份运行程序】
参数1:HANDLE TokenHandle 包含特权的令牌句柄
参数2:BOOL 是否禁用所有令牌的权限
FALSE 则不禁用,以NewState参数指针的信息为基础来修改特权
TRUE 禁用所有特权,NewState参数无效
参数3:PTOKEN_PRIVILEGES NewState 新特权信息的指针(结构体)【令牌指针】
参数4:DWORD BufferLength 缓冲数据大小,以字节为单位 【令牌占用字节数】
参数5:PTOKEN_PRIVILEGES PreviousState 接收被改变特权当前状态的Buffer
参数6:PDWORD ReturnLength 接收PreviousState缓存区要求的大小
如果PreviousState为NULL,这个参数可以为NULL
返回值:如果这个函数成功,返回非0.为了确定这个函数是否修改了所有指定的特权,
可以调用GetLastError函数,当这个函数返回下面的值之一时就代表函数成功:
ERROR_SUCCESS 这个函数修改了所有指定的特权。
ERROR_NOT_ALL_ASSIGNED 这个令牌没有参数NewState里指定一个或多个的权限。(一个或多个没有修改成功)
如果这个函数失败,返回0
*/
DWORD d = GetLastError();
if (d != ERROR_SUCCESS) {
AfxMessageBox(_T("权限修改失败"));
}
if (d == ERROR_SUCCESS) {
AfxMessageBox(_T("权限修改成功"));
}
CloseHandle(hToken);
