线程等待与唤醒 以及用到的数据结构
_KTHREAD + 0x5c的结构
kd> dt _KWAIT_BLOCK
nt!_KWAIT_BLOCK
+0x000 WaitListEntry : _LIST_ENTRY
+0x008 Thread : Ptr32 _KTHREAD //指向_KTHREAD
+0x00c Object : Ptr32 Void //表示下面其中任意一个对象的指针,如创建的是事件等待对象那么就是指向_KEVENT中_DISPATCHER_HEADER
+0x010 NextWaitBlock : Ptr32 _KWAIT_BLOCK //单向循环链表 如果在多个等待对象中 指向下一个链表
+0x014 WaitKey : Uint2B //表示当前这个结构在链表中的索引以0开始 比如 在链表1就是0 链表2的位置就是1
+0x016 WaitType : Uint2B //线程是否可以唤醒 如果为1可以唤醒,只要其中一个对象为1这里就会置为1
object:
dt _KPROCESS 进程
dt _KTHREAD 线程
dt _KTIMER 定时器
dt _KSEMAPHORE 信号量
dt _KEVENT 事件
dt _KMUTANT 互斥体
dt _FILE_OBJECT 文件
kd> dt _DISPATCHER_HEADER
nt!_DISPATCHER_HEADER
+0x000 Type : UChar
+0x001 Absolute : UChar
+0x002 Size : UChar
+0x003 Inserted : UChar
+0x004 SignalState : Int4B
+0x008 WaitListHead : _LIST_ENTRY //双向循环链表 指向_KWAIT_BLOCK结构
实例:
1.获得进程地址
2.获得线程地址
3.获得_KTHREAD结构
4.获得_KWAIT_BLOCK结构
5.获得等待事件地址
总结:
可以看到_DISPATCHER_HEADER中的WaitListHead正好指向上面的_KWAIT_BLOCK结构的头