虽然主线程模拟了一个客户端,但是我的代码创建了一个线程,并使用SetThreadToken
向其分配了模拟令牌。然后主线程关闭令牌。
具体来说,主线程会这样做:
LogonUser
获取主令牌。DuplicateToken
从主要令牌中获得模拟令牌。ImpersonateLoggedOnUser
。SetThreadToken
。RevertToSelf
。CloseHandle
涉及模拟和主要令牌。这时,辅助线程仍在运行。即使令牌句柄已在主线程中关闭,模拟令牌仍可用于辅助线程吗?
答案 0 :(得分:0)
windows内核对对象使用引用计数。 TOKEN
也是对象。当您将标记分配给线程(通过SetThreadToken
)时,指向TOKEN
对象的指针存储在ETHREAD
对象中,并将附加引用添加到TOKEN
对象中。当然,内核不能依赖于关闭或不依赖TOKEN
对象的原始句柄(引用)。这是通用的指针计数规则-如果A
自身存储了指向B
的指针-它会添加对B
的引用,因为在A
使用{{1}之前它一直有效}。该令牌将一直有效,直到您的线程没有模拟另一个令牌,结束模拟或退出为止。无论如何,在为线程分配令牌后,您可以关闭它的句柄-令牌仍然有效
如果存在兴趣,内部B
的工作方式:
SetThreadToken
用SetThreadToken
信息类调用NtSetInformationThread
。从内核implementation到PsAssignImpersonationToken
的调用-此api在 ntifs.h 中声明。 implementation call PsImpersonateClient
,并引用所传递的令牌。结果,它成为分配给线程的有效util
服务器线程可能已经在模拟客户端 调用PsImpersonateClient。在这种情况下,参考 计数代表客户的令牌已减少。
但无论如何-我们不需要此内部知识-需要一般的思想理解-对象引用计数。如果在线程中保存了指向令牌的指针-这个令牌在线程使用之前当然必须是有效的。结果是它引用了。当线程停止使用此令牌(更改指针或退出)时-令牌已取消引用