我想要实现的是当进程在非管理员用户(用户登录的Windows)下以管理员身份运行时,会话ID中的实际令牌句柄。
DWORD dwSessionId = 0;
if (false == ProcessIdToSessionId(dwProcessId, &dwSessionId))
{
LOG_ERROR(L"Failed obtaining session id");
return false;
}
HANDLE hToken
if (false == WTSQueryUserToken(dwSessionId, &hToken))
{
LOG_ERROR(L"Failed to obtain session's handle");
return false;
}
当我调用WTSQueryUserToken时出现问题,它失败并显示错误1314,这意味着我需要授予具有SE_TCB_NAME权限的调用令牌。
所以我尝试使用以下代码:
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bool bSuccess = DynamicAPI::AdjustTokenPrivileges(
%%WHICH_TOKEN_EXACTLLY%%,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)nullptr,
(DWORD)nullptr);
但我不完全确定应该准确提供哪个令牌。我用 %% WHICH_TOKEN_EXACTLLY %% 占位符标记了它。对于我的测试,我尝试使用AdjustTokenPriviliges我的进程'令牌(管理员权限),但它也没有帮助。
答案 0 :(得分:1)
如果需要调整权限的线程模拟用户,请使用OpenThreadToken(GetCurrentThread())
获取模拟令牌。否则,使用OpenProcessToken(GetCurrentProcess())
获取调用进程的令牌。
答案 1 :(得分:0)
您通常需要在流程令牌中启用权限,您可以使用GetProcessToken()函数获取该权限。例外情况是,如果您打算在模拟时使用该权限,则应该在模拟令牌中启用该权限。
我使用此代码启用还原权限:
DWORD enable_restore()
{
// This allows us to override security to delete files
HANDLE token;
BOOL flag;
struct {
DWORD count;
LUID_AND_ATTRIBUTES privilege;
} token_privileges;
token_privileges.count = 1;
token_privileges.privilege.Attributes = SE_PRIVILEGE_ENABLED;
flag = LookupPrivilegeValue(0, SE_RESTORE_NAME, &token_privileges.privilege.Luid);
if (!flag) return GetLastError();
flag = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token);
if (!flag) return GetLastError();
flag = AdjustTokenPrivileges(token, 0, (PTOKEN_PRIVILEGES)&token_privileges, 0, 0, 0);
if (!flag) return GetLastError();
return 0;
}
请注意,此代码不会检查是否实际授予了权限。为此,请在调用AdjustTokenPrivileges()之后检查GetLastError() - 这是极少数情况下,即使函数报告成功,上一个错误代码也是有意义的。
NB:这是您尝试使用流程令牌失败的最可能原因;如果您没有将代码作为本地系统运行,并且没有重新配置Windows以授予您使用SE_TCB_NAME特权的帐户,则调用AdjustTokenPrivileges()将报告成功但不起作用。
另外,请记住,无论您是否具有SE_TCB_NAME权限,如果您在本地系统上下文中运行,则只能使用WTSQueryUserToken(),即通常只有系统服务或在上下文中运行的应用程序。系统服务可以使用它。 (我不确定是否足以冒充本地系统。我怀疑不是。)