<<Windows核心编程>>6.8节中提到了一个线程“伪句柄“概念,同时指出线程的伪句柄是当前线程的句柄,也就是调用函数的线程的句柄。
感觉单从概念上还不能充分的理解,必须深入分析。Windows就是隐藏了太多的东西,你越不分析透,就越不能理解,内心就越不踏实。
显然,GetCurrentThread()返回的是一个伪句柄,那就从它开始。
通过实验,发现不管如何调用,GetCurrentThread()返回的伪句柄都是一个固定值0xfffffffe(-2),这显然不是一个有效句柄(地址)。其实,GetCurrentThread()仅简单的调用了NTCurrentThread(),而后者是一个宏#define NTCurrentThread() (HANDLE)(LONG_PRT)-2).
显然,GetCurrentThread()并不会影响到Thread Object ,例如引用计数。这个结果意义不大。
API函数是如何应用伪句柄的?
以GetThreadTimes()为例,第一个传入参数hThread,API文档并不要求这是一个实或伪句柄。它的调用链为:GetThreadTimes()->NTQueryInformationThread()->ObReferenceObjectByHandle()->PsGetCurrentThread()->KeGetCurrentThread(),最后KeGetCurrentThread()通过{mov eax, fs:[0] KPCR.PrcbData.CurrentThread}返回了指向线程_KTHREAD 的指针。这其中比较关键的地方就是ObReferenceObjectByHandle(),它根据传入的Handle类型判断是否一个实或伪句柄,如是是一个伪句柄,则接着调用PsGetCurrentThread()。最终,实现了伪到实的转换。
至此,也算对伪句有点理解,但Windows为什么要用伪句柄机制呢?为了安全?但有GetCurrentThreadID()啊。一时想不明。。。