第一部分:
//
// Wait block
//
// begin_ntddk begin_wdm begin_nthal begin_ntifs begin_ntosp
typedef struct _KWAIT_BLOCK {
??? LIST_ENTRY WaitListEntry;
??? struct _KTHREAD *RESTRICTED_POINTER Thread;
??? PVOID Object;
??? struct _KWAIT_BLOCK *RESTRICTED_POINTER NextWaitBlock;
??? USHORT WaitKey;
??? USHORT WaitType;
} KWAIT_BLOCK, *PKWAIT_BLOCK, *RESTRICTED_POINTER PRKWAIT_BLOCK;
??????? WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
????????????????????????????????????? KWAIT_BLOCK,
????????????????????????????????????? WaitListEntry);
第二部分:等待塊0x8976d648對應的線程0x8976d5a8第一個等待,等待塊0x89124e40對應的線程0x89124da0第二個等待。
1: kd> dt kevent? 8984ed18
CSRSRV!KEVENT
?? +0x000 Header?????????? : _DISPATCHER_HEADER
1: kd> dx -id 0,0,89838358 -r1 (*((CSRSRV!_DISPATCHER_HEADER *)0x8984ed18))
(*((CSRSRV!_DISPATCHER_HEADER *)0x8984ed18))???????????????? [Type: _DISPATCHER_HEADER]
??? [+0x000] Type???????????? : 0x1 [Type: unsigned char]
??? [+0x001] Absolute???????? : 0x0 [Type: unsigned char]
??? [+0x002] Size???????????? : 0x4 [Type: unsigned char]
??? [+0x003] Inserted???????? : 0x0 [Type: unsigned char]
??? [+0x003] DebugActive????? : 0x0 [Type: unsigned char]
??? [+0x000] Lock???????????? : 262145 [Type: long]
??? [+0x004] SignalState????? : 0 [Type: long]
??? [+0x008] WaitListHead???? [Type: _LIST_ENTRY]
1: kd> dx -id 0,0,89838358 -r1 (*((CSRSRV!_LIST_ENTRY *)0x8984ed20))
(*((CSRSRV!_LIST_ENTRY *)0x8984ed20))???????????????? [Type: _LIST_ENTRY]
??? [+0x000] Flink??????????? : 0x8976d648 [Type: _LIST_ENTRY *]
??? [+0x004] Blink??????????? : 0x89124e40 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_LIST_ENTRY *)0x8976d648)
((CSRSRV!_LIST_ENTRY *)0x8976d648)???????????????? : 0x8976d648 [Type: _LIST_ENTRY *]
??? [+0x000] Flink??????????? : 0x89124e40 [Type: _LIST_ENTRY *]
??? [+0x004] Blink??????????? : 0x8984ed20 [Type: _LIST_ENTRY *]
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_LIST_ENTRY *)0x89124e40)
((CSRSRV!_LIST_ENTRY *)0x89124e40)???????????????? : 0x89124e40 [Type: _LIST_ENTRY *]
??? [+0x000] Flink??????????? : 0x8984ed20 [Type: _LIST_ENTRY *]
??? [+0x004] Blink??????????? : 0x8976d648 [Type: _LIST_ENTRY *]
第三部分:
1: kd> dt KWAIT_BLOCK 0x8976d648?? ??? ??? ??? ??? ??? ??? ?//Flink??????????? : 0x8976d648
CSRSRV!KWAIT_BLOCK
?? +0x000 WaitListEntry??? : _LIST_ENTRY [ 0x89124e40 - 0x8984ed20 ]
?? +0x008 Thread?????????? : 0x8976d5a8 _KTHREAD
?? +0x00c Object?????????? : 0x8984ed18 Void
?? +0x010 NextWaitBlock??? : 0x8976d648 _KWAIT_BLOCK
?? +0x014 WaitKey????????? : 0
?? +0x016 WaitType???????? : 1
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_KTHREAD *)0x8976d5a8)
((CSRSRV!_KTHREAD *)0x8976d5a8)???????????????? : 0x8976d5a8 [Type: _KTHREAD *]
??? [+0x000] Header?????????? [Type: _DISPATCHER_HEADER]
??? [+0x010] MutantListHead?? [Type: _LIST_ENTRY]
??? [+0x018] InitialStack???? : 0xba247000 [Type: void *]
??? [+0x01c] StackLimit?????? : 0xba244000 [Type: void *]
??? [+0x020] KernelStack????? : 0xba246c5c [Type: void *]
??? [+0x024] ThreadLock?????? : 0x0 [Type: unsigned long]
??? [+0x028] ContextSwitches? : 0x1 [Type: unsigned long]
??? [+0x02c] State??????????? : 0x5 [Type: unsigned char]
??? [+0x02d] NpxState???????? : 0xa [Type: unsigned char]
??? [+0x02e] WaitIrql???????? : 0x0 [Type: unsigned char]
??? [+0x02f] WaitMode???????? : 1 [Type: char]
??? [+0x030] Teb????????????? : 0x7ff98000 [Type: void *]
??? [+0x034] ApcState???????? [Type: _KAPC_STATE]
??? [+0x04c] ApcQueueLock???? : 0x0 [Type: unsigned long]
??? [+0x050] WaitStatus?????? : 0 [Type: long]
??? [+0x054] WaitBlockList??? : 0x8976d648 [Type: _KWAIT_BLOCK *]
? ?
1: kd> dt KWAIT_BLOCK? 0x89124e40
CSRSRV!KWAIT_BLOCK
?? +0x000 WaitListEntry??? : _LIST_ENTRY [ 0x8984ed20 - 0x8976d648 ]
?? +0x008 Thread?????????? : 0x89124da0 _KTHREAD
?? +0x00c Object?????????? : 0x8984ed18 Void
?? +0x010 NextWaitBlock??? : 0x89124e40 _KWAIT_BLOCK
?? +0x014 WaitKey????????? : 0
?? +0x016 WaitType???????? : 1
1: kd> dx -id 0,0,89838358 -r1 ((CSRSRV!_KTHREAD *)0x89124da0)
((CSRSRV!_KTHREAD *)0x89124da0)???????????????? : 0x89124da0 [Type: _KTHREAD *]
??? [+0x000] Header?????????? [Type: _DISPATCHER_HEADER]
??? [+0x010] MutantListHead?? [Type: _LIST_ENTRY]
??? [+0x018] InitialStack???? : 0xba2b7000 [Type: void *]
??? [+0x01c] StackLimit?????? : 0xba2b3000 [Type: void *]
??? [+0x020] KernelStack????? : 0xba2b681c [Type: void *]
??? [+0x024] ThreadLock?????? : 0x0 [Type: unsigned long]
??? [+0x028] ContextSwitches? : 0x4 [Type: unsigned long]
??? [+0x02c] State??????????? : 0x5 [Type: unsigned char]
??? [+0x02d] NpxState???????? : 0xa [Type: unsigned char]
??? [+0x02e] WaitIrql???????? : 0x0 [Type: unsigned char]
??? [+0x02f] WaitMode???????? : 1 [Type: char]
??? [+0x030] Teb????????????? : 0x7ff9a000 [Type: void *]
??? [+0x034] ApcState???????? [Type: _KAPC_STATE]
??? [+0x04c] ApcQueueLock???? : 0x0 [Type: unsigned long]
??? [+0x050] WaitStatus?????? : 0 [Type: long]
??? [+0x054] WaitBlockList??? : 0x89124e40 [Type: _KWAIT_BLOCK *]
? ?
第四部分:
LONG
KeSetEvent (
??? IN PRKEVENT Event,
??? IN KPRIORITY Increment,
??? IN BOOLEAN Wait
??? )
{
??? KIRQL OldIrql;
??? LONG OldState;
??? PRKTHREAD Thread;
??? ASSERT_EVENT(Event);
??? ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
??? //
??? // Collect call data.
??? //
#if defined(_COLLECT_SET_EVENT_CALLDATA_)
??? RECORD_CALL_DATA(&KiSetEventCallData);
#endif
??? //
??? // Raise IRQL to dispatcher level and lock dispatcher database.
??? //
??? KiLockDispatcherDatabase(&OldIrql);
??? //
??? // Capture the old state and set the new state to signaled.
??? //
??? // If the old state is not-signaled and the wait list is not empty,
??? // then satisfy as many waits as possible.
??? //
??? OldState = Event->Header.SignalState;
??? Event->Header.SignalState = 1;
??? if ((OldState == 0) &&
??????? (IsListEmpty(&Event->Header.WaitListHead) == FALSE)) {
??????? if (Event->Header.Type == EventNotificationObject) {
??????????? KiWaitTestWithoutSideEffects(Event, Increment);
第五部分:
FORCEINLINE
VOID
KiWaitTestWithoutSideEffects (
??? IN PVOID Object,
??? IN KPRIORITY Increment
??? )
{
??? PKEVENT Event = Object;
??? PLIST_ENTRY ListHead;
??? PRKTHREAD Thread;
??? PRKWAIT_BLOCK WaitBlock;
??? PLIST_ENTRY WaitEntry;
??? //
??? // Empty the entire list of waiters since the specified object has
??? // no side effects when a wait is satisfied.
??? //
??? ListHead = &Event->Header.WaitListHead;
??? ASSERT(IsListEmpty(&Event->Header.WaitListHead) == FALSE);
??? WaitEntry = ListHead->Flink;
??? do {
??????? //
??????? // Get the address of the wait block and the thread doing the wait.
??????? //
??????? WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
??????? Thread = WaitBlock->Thread;
??????? //
??????? // If the wait type is wait any, then unwait the thread with the
??????? // wait key status. Otherwise, unwait the thread with a kernel APC
??????? // status.
??????? //
??????? if (WaitBlock->WaitType == WaitAny) {
??????????? KiUnwaitThread(Thread, (NTSTATUS)WaitBlock->WaitKey, Increment);
??????? } else {
??????????? KiUnwaitThread(Thread, STATUS_KERNEL_APC, Increment);
??????? }
??????? WaitEntry = ListHead->Flink;//激活第一個線程后,第一個等待塊會脫鏈!!
??? } while (WaitEntry != ListHead);
??? return;
}
第六部分:
例子1:只有一個等待線程
1: kd> g
Breakpoint 22 hit
nt!KeSetEvent:
80a34206 55????????????? push??? ebp
0: kd> dv
????????? Event = 0xf78ce2f8
????? Increment = 0n0
?????????? Wait = 0x00 ''
?????? OldState = 0n8
??????? OldIrql = 0xf7 ''
0: kd> dx -r1 ((ntkrnlmp!_KEVENT *)0xf78ce2f8)
((ntkrnlmp!_KEVENT *)0xf78ce2f8)???????????????? : 0xf78ce2f8 [Type: _KEVENT *]
??? [+0x000] Header?????????? [Type: _DISPATCHER_HEADER]
0: kd> dx -r1 (*((ntkrnlmp!_DISPATCHER_HEADER *)0xf78ce2f8))
(*((ntkrnlmp!_DISPATCHER_HEADER *)0xf78ce2f8))???????????????? [Type: _DISPATCHER_HEADER]
??? [+0x000] Type???????????? : 0x0 [Type: unsigned char]
??? [+0x001] Absolute???????? : 0x0 [Type: unsigned char]
??? [+0x002] Size???????????? : 0x4 [Type: unsigned char]
??? [+0x003] Inserted???????? : 0x0 [Type: unsigned char]
??? [+0x003] DebugActive????? : 0x0 [Type: unsigned char]
??? [+0x000] Lock???????????? : 262144 [Type: long]
??? [+0x004] SignalState????? : 0 [Type: long]
??? [+0x008] WaitListHead???? [Type: _LIST_ENTRY]
0: kd> dx -r1 (*((ntkrnlmp!_LIST_ENTRY *)0xf78ce300))
(*((ntkrnlmp!_LIST_ENTRY *)0xf78ce300))???????????????? [Type: _LIST_ENTRY]
??? [+0x000] Flink??????????? : 0x8999e6c0 [Type: _LIST_ENTRY *]
??? [+0x004] Blink??????????? : 0x8999e6c0 [Type: _LIST_ENTRY *]
0: kd> g
Breakpoint 33 hit
nt!KiUnwaitThread:
80a402c6 55????????????? push??? ebp
0: kd> g
Breakpoint 32 hit
nt!KiReadyThread:
80a42c6c 8b4144????????? mov???? eax,dword ptr [ecx+44h]
?