使用OpenThreadToken()
创建令牌,然后将其传递给CreateProcessAsUser
失败:
1349:令牌的类型不适合其尝试使用。
在一台机器上运行成功,但在另一台win2008r2上运行失败。
传递给OpenThreadToken
的DesiredAccess
为:TOKEN_QUERY|TOKEN_IMPERSONATE|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY
exist 2 TOKEN_TYPE - TokenPrimary
and TokenImpersonation
。CreateProcessAsUser只接受TokenPrimary
。从另一方面来说,线程如果有令牌-总是有TokenImpersonation
令牌类型。所以OpenThreadToken返回的令牌是TokenImpersonation
,你需要调用DuplicateTokenEx
(.., TokenPrimary, );
并将这个新令牌传递给CreateProcessAsUser
—EDIT—
从Windows 7开始,我们可以使用TokenImpersonation
作为CreateProcessAsUser
的参数,尽管在MSDN中写的是主令牌。但在xp/2003中使用CreateProcessAsUser
的另一种代码直接称为NtSetInformationProcess(,ProcessAccessToken,);
-> PspSetPrimaryToken
-> PspAssignPrimaryToken
-> STATUS_BAD_TOKEN_TYPE
在调用时目标线程正在模拟,因此您得到了错误的令牌。使用OpenProcessToken()代替OpenThreadToken()应该可以解决这个问题。如果由于某种原因,您只有线程ID而没有进程ID, GetProcessIdOfThread()将弥补这一差距。
或者,如果出于某种原因想要使用模拟令牌,则必须使用DuplicateTokenEx()将其转换为主令牌。但是这不太可能是您想要做的,因为它引入了一个竞争条件,因为您通常无法知道目标线程何时在模拟正确的用户。此外,如果线程被证明是在匿名级别进行模拟,则它将根本不起作用。
(这个竞争条件可能也是为什么它似乎在某些机器上工作而不是在其他机器上工作的原因,尽管也可能是模拟只发生在某些Windows版本上。)