CreateProcessAsUser与1349失败:该类型的令牌不适合其企图使用

问题描述:

使用OpenThreadToken()创建一个令牌,然后将它传递给CreateProcessAsUser与失败:CreateProcessAsUser与1349失败:该类型的令牌不适合其企图使用

1349:类型的令牌是不合适的其企图使用。

它在一台机器上成功,但在其他win2008r2上失败。传递给OpenThreadToken

DesiredAccess是: TOKEN_QUERY|TOKEN_IMPERSONATE|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY

+0

不OpenThreadToken成功吗?如果不是GetLastError的结果是什么? –

+0

是的,OpenThreadToken成功了。 – user5327778

存在2 TOKEN_TYPE - TokenPrimaryTokenImpersonationCreateProcessAsUser只接受TokenPrimary。从另一面来看,线程如果有令牌 - 总是有令牌类型TokenImpersonation。所以令牌由OpenThreadToken返回是TokenImpersonation你需要调用DuplicateTokenEx(.., TokenPrimary,);,并通过这个新的令牌CreateProcessAsUser

---编辑---

真正从Windows 7开始,我们可以使用和TokenImpersonation作为参数传递给CreateProcessAsUser虽然在MSDN撰写有关主令牌的信息。但在XP/2003中使用另一个代码CreateProcessAsUser - 直接叫NtSetInformationProcess(,ProcessAccessToken,); - >PspSetPrimaryToken - >PspAssignPrimaryToken - >STATUS_BAD_TOKEN_TYPE

+0

但是我只在一台机器上看到这个问题,它传递给其他机器。是否有任何注册表项可能会在该机器上创建问题。 – user5327778

+0

这里的任何注册表项无关。由OpenThreadToken返回的标记不能在任何地方与CreateProcessAsUser一起使用(可能仅限于xp,其中CreateProcessAsUser的另一个实现 - 首先创建进程而不是尝试为其分配标记)。并且您不显示自己的代码 – RbMm

+0

除了DuplicateTokenEx()将模拟标记转换为主标记之外,还有其他方法吗? – user5327778

目标线程模拟在调用的时候,所以你得到了错误的令牌。使用OpenProcessToken()而不是OpenThreadToken()应该可以解决问题。如果由于某种原因您只有线程ID而不是进程ID,则GetProcessIdOfThread()将填补空白。

或者,如果您有某些原因希望使用模拟令牌,则必须使用DuplicateTokenEx()将其转换为主令牌。但是这不太可能是你想要做的,因为它引入了竞争条件,因为你通常无法知道目标线程何时冒充正确的用户。而且,如果线程变成匿名级别的模拟,它根本无法工作。

(这种争用情况大概也是为什么它似乎是工作在某些机器上,但不是别人,但它也可能是冒充只发生在特定的Windows版本。)