カーネルデバッガー「WinDbg」は独自のスクリプトエンジンを搭載し、C++やMASMの影響を受けたスクリプト言語体系を持っています。マルウェアやパフォーマンス低下因子などは独自のWinDbgスクリプトコード(WinDbgアプリケーション)を作成・実行して自動検出する。これが時代の流れです。
Windowsのカーネルは休むことなく常に活発に動いています。Windowsの世界はいわば一種の仮想的な生態系と考えてしまうと分かりやすいかもしれません。気流の方向は常に変化し、生物体内の血流はさまざまな方向に栄養を運んでいます。便利そうに見えるプログラムをインストールすれば、気流と血流は何らかの影響を受けます。仮想生態系はもちろん完全なものではありません。資源は有限であり、複雑さは増すばかりです。このような生態系に完全性を求めるのは素人の発想です。
仮想とはいえWindowsシステムは一種の生態系をなしています。個々のWinDbgコマンドを一つひとつ手動で打ち込みながら、この仮想生態系の分析・診断を行うことは現実的ではありません。動いているカーネルに負担をかけることなく、必要情報を瞬時に取り出し、分析・診断作業を終了するのが理想です。たとえば、WinDbgスクリプトコード(WinDbgアプリケーション)を一度開発してしまえば、「system」プロセスの"終了済み"スレッドを検出し、そのスレッドに関する情報だけを表示させるようなことが簡単にできてしまいます。次の情報をご覧ください。
Opened log file 'd:\windbg\logs\applicationver00_1.log'
Alias Value
------- -------
$SafetyCheck "Written by Takashi Toyota";
$arg0 d:\\windbg\\scripts\\systemprocess.txt
--- ユーザモードへ ---
. 0 id: d60 attach name: C:\WINDOWS\SYSTEM32\mspaint.exe
0 Id: d60.dc4 Suspend: 1 Teb: 7ffde000 Unfrozen
1 Id: d60.d74 Suspend: 1 Teb: 7ffdd000 Unfrozen
2 Id: d60.d1c Suspend: 1 Teb: 7ffdc000 Unfrozen
3 Id: d60.d70 Suspend: 1 Teb: 7ffdb000 Unfrozen
4 Id: d60.d6c Suspend: 1 Teb: 7ffda000 Unfrozen
. 5 Id: d60.c44 Suspend: 1 Teb: 7ffaf000 Unfrozen
--- ユーザモードからカーネルモードへ ---
System
PROCESS 813417f8 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 00039000 ObjectTable: e1001d28 HandleCount: 265.
Image: System
THREAD 81341118 Cid 0004.000c Teb: 00000000 Win32Thread: 00000000 TERMINATED
Not impersonating
DeviceMap e10001c8
Owning Process 813417f8 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 3800 Ticks: 509244 (0:01:24:59.773)
Context Switch Count 497
UserTime 00:00:00.000
KernelTime 00:00:00.000
Start Address nt!InbvRotateGuiBootDisplay (0x8050aa31)
Stack Init 0 Current f9684c6c Base f9685000 Limit f9682000 Call 0
Priority 16 BasePriority 8 PriorityDecrement 0 DecrementCount 0
nt!_ETHREAD
+0x000 Tcb : _KTHREAD
+0x1c0 CreateTime : _LARGE_INTEGER 0x559280
+0x1c0 NestedFaultCount : 0y00
+0x1c0 ApcNeeded : 0y0
+0x1c8 ExitTime : _LARGE_INTEGER 0x1c954d0`0011c450
+0x1c8 LpcReplyChain : _LIST_ENTRY [ 0x11c450 - 0x1c954d0 ]
+0x1c8 KeyedWaitChain : _LIST_ENTRY [ 0x11c450 - 0x1c954d0 ]
+0x1d0 ExitStatus : 0
+0x1d0 OfsChain : (null)
+0x1d4 PostBlockList : _LIST_ENTRY [ 0x813412ec - 0x813412ec ]
+0x1dc TerminationPort : (null)
+0x1dc ReaperLink : (null)
+0x1dc KeyedWaitValue : (null)
+0x1e0 ActiveTimerListLock : 0
+0x1e4 ActiveTimerListHead : _LIST_ENTRY [ 0x813412fc - 0x813412fc ]
+0x1ec Cid : _CLIENT_ID
+0x1f4 LpcReplySemaphore : _KSEMAPHORE
+0x1f4 KeyedWaitSemaphore : _KSEMAPHORE
+0x208 LpcReplyMessage : (null)
+0x208 LpcWaitingOnPort : (null)
+0x20c ImpersonationInfo : (null)
+0x210 IrpList : _LIST_ENTRY [ 0x81341328 - 0x81341328 ]
+0x218 TopLevelIrp : 0
+0x21c DeviceToVerify : (null)
+0x220 ThreadsProcess : 0x813417f8 _EPROCESS
+0x224 StartAddress : 0x8050aa31
+0x228 Win32StartAddress : (null)
+0x228 LpcReceivedMessageId : 0
+0x22c ThreadListEntry : _LIST_ENTRY [ 0x8133efd4 - 0x8134179c ]
+0x234 RundownProtect : _EX_RUNDOWN_REF
+0x238 ThreadLock : _EX_PUSH_LOCK
+0x23c LpcReplyMessageId : 0
+0x240 ReadClusterSize : 7
+0x244 GrantedAccess : 0x1f03ff
+0x248 CrossThreadFlags : 0x11
+0x248 Terminated : 0y1
+0x248 DeadThread : 0y0
+0x248 HideFromDebugger : 0y0
+0x248 ActiveImpersonationInfo : 0y0
+0x248 SystemThread : 0y1
+0x248 HardErrorsAreDisabled : 0y0
+0x248 BreakOnTermination : 0y0
+0x248 SkipCreationMsg : 0y0
+0x248 SkipTerminationMsg : 0y0
+0x24c SameThreadPassiveFlags : 0
+0x24c ActiveExWorker : 0y0
+0x24c ExWorkerCanWaitUser : 0y0
+0x24c MemoryMaker : 0y0
+0x250 SameThreadApcFlags : 2
+0x250 LpcReceivedMsgIdValid : 0y0
+0x250 LpcExitThreadCalled : 0y1
+0x250 AddressSpaceOwner : 0y0
+0x254 ForwardClusterOnly : 0 ''
+0x255 DisablePageFaultClustering : 0 ''
nt!_KTHREAD
+0x000 Header : _DISPATCHER_HEADER
+0x010 MutantListHead : _LIST_ENTRY [ 0x81341128 - 0x81341128 ]
+0x018 InitialStack : (null)
+0x01c StackLimit : 0xf9682000
+0x020 Teb : (null)
+0x024 TlsArray : (null)
+0x028 KernelStack : 0xf9684c6c
+0x02c DebugActive : 0 ''
+0x02d State : 0x4 ''
+0x02e Alerted : [2] ""
+0x030 Iopl : 0 ''
+0x031 NpxState : 0xa ''
+0x032 Saturation : 0 ''
+0x033 Priority : 16 ''
+0x034 ApcState : _KAPC_STATE
+0x04c ContextSwitches : 0x1f1
+0x050 IdleSwapBlock : 0 ''
+0x051 Spare0 : [3] ""
+0x054 WaitStatus : 258
+0x058 WaitIrql : 0 ''
+0x059 WaitMode : 0 ''
+0x05a WaitNext : 0 ''
+0x05b WaitReason : 0x4 ''
+0x05c WaitBlockList : 0x813411d0 _KWAIT_BLOCK
+0x060 WaitListEntry : _LIST_ENTRY [ 0xffb37270 - 0x8055cae0 ]
+0x060 SwapListEntry : _SINGLE_LIST_ENTRY
+0x068 WaitTime : 0xed8
+0x06c BasePriority : 8 ''
+0x06d DecrementCount : 0 ''
+0x06e PriorityDecrement : 0 ''
+0x06f Quantum : 6 ''
+0x070 WaitBlock : [4] _KWAIT_BLOCK
+0x0d0 LegoData : (null)
+0x0d4 KernelApcDisable : 0
+0x0d8 UserAffinity : 1
+0x0dc SystemAffinityActive : 0 ''
+0x0dd PowerState : 0 ''
+0x0de NpxIrql : 0 ''
+0x0df InitialNode : 0 ''
+0x0e0 ServiceTable : 0x8055c220
+0x0e4 Queue : (null)
+0x0e8 ApcQueueLock : 0
+0x0f0 Timer : _KTIMER
+0x118 QueueListEntry : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x120 SoftAffinity : 1
+0x124 Affinity : 1
+0x128 Preempted : 0 ''
+0x129 ProcessReadyQueue : 0 ''
+0x12a KernelStackResident : 0x1 ''
+0x12b NextProcessor : 0 ''
+0x12c CallbackStack : (null)
+0x130 Win32Thread : (null)
+0x134 TrapFrame : (null)
+0x138 ApcStatePointer : [2] 0x8134114c _KAPC_STATE
+0x140 PreviousMode : 0 ''
+0x141 EnableStackSwap : 0x1 ''
+0x142 LargeStack : 0 ''
+0x143 ResourceIndex : 0 ''
+0x144 KernelTime : 0
+0x148 UserTime : 0
+0x14c SavedApcState : _KAPC_STATE
+0x164 Alertable : 0 ''
+0x165 ApcStateIndex : 0 ''
+0x166 ApcQueueable : 0 ''
+0x167 AutoAlignment : 0 ''
+0x168 StackBase : 0xf9685000
+0x16c SuspendApc : _KAPC
+0x19c SuspendSemaphore : _KSEMAPHORE
+0x1b0 ThreadListEntry : _LIST_ENTRY [ 0x8133ef58 - 0x81341720 ]
+0x1b8 FreezeCount : 0 ''
+0x1b9 SuspendCount : 0 ''
+0x1ba IdealProcessor : 0 ''
+0x1bb DisableBoost : 0 ''
--- カーネルモードからユーザモードへ ---
eax=7ffdf000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c94120f esp=03aaffcc ebp=03aafff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint+0x1:
7c94120f c3 ret
Detached
. 0 id: d60 attach name: C:\WINDOWS\SYSTEM32\mspaint.exe
0 Id: d60.dc4 Suspend: 1 Teb: 7ffde000 Unfrozen
1 Id: d60.d74 Suspend: 1 Teb: 7ffdd000 Unfrozen
2 Id: d60.d1c Suspend: 1 Teb: 7ffdc000 Unfrozen
3 Id: d60.d70 Suspend: 1 Teb: 7ffdb000 Unfrozen
4 Id: d60.d6c Suspend: 1 Teb: 7ffda000 Unfrozen
. 5 Id: d60.c44 Suspend: 1 Teb: 7ffaf000 Unfrozen
uf nt!InbvRotateGuiBootDisplay
nt!InbvRotateGuiBootDisplay:
8050aa31 8bff mov edi,edi
8050aa33 55 push ebp
8050aa34 8bec mov ebp,esp
8050aa36 51 push ecx
8050aa37 51 push ecx
8050aa38 834dfcff or dword ptr [ebp-4],0FFFFFFFFh
8050aa3c c745f800cbf3ff mov dword ptr [ebp-8],0FFF3CB00h
nt!InbvRotateGuiBootDisplay+0x12:
8050aa43 8d45f8 lea eax,[ebp-8]
8050aa46 50 push eax
8050aa47 6a00 push 0
8050aa49 6a00 push 0
8050aa4b e8b934fdff call nt!KeDelayExecutionThread (804ddf09)
8050aa50 e88fffffff call nt!InbvAcquireLock (8050a9e4)
8050aa55 e8baffffff call nt!InbvGetDisplayState (8050aa14)
8050aa5a 85c0 test eax,eax
8050aa5c 750d jne nt!InbvRotateGuiBootDisplay+0x3a (8050aa6b)
nt!InbvRotateGuiBootDisplay+0x2d:
8050aa5e a1a0515580 mov eax,dword ptr [nt!RotBarSelection (805551a0)]
8050aa63 48 dec eax
8050aa64 7505 jne nt!InbvRotateGuiBootDisplay+0x3a (8050aa6b)
nt!InbvRotateGuiBootDisplay+0x35:
8050aa66 e848000000 call nt!RotBarUpdate (8050aab3)
nt!InbvRotateGuiBootDisplay+0x3a:
8050aa6b e819000000 call nt!InbvReleaseLock (8050aa89)
8050aa70 e8aaffffff call nt!InbvCheckDisplayOwnership (8050aa1f)
8050aa75 84c0 test al,al
8050aa77 75ca jne nt!InbvRotateGuiBootDisplay+0x12 (8050aa43)
nt!InbvRotateGuiBootDisplay+0x48:
8050aa79 6a00 push 0
8050aa7b e8bb250700 call nt!PsTerminateSystemThread (8057d03b)
8050aa80 c9 leave
8050aa81 c20400 ret 4
WinDbgスクリプティングとは何か。それは、Windowsシステム(仮想生態系)を徹底的に分析・診断するためのアプリケーション開発技術です。高い優先度を持つ、いったん動作を終了したスレッドが再び動作を開始すれば、他の普通の優先度を持つ多数のスレッドが影響を受けることになります。カーネルスレッド構造体は終了動作だけではなく、「死滅したスレッド」を管理するビットも持っています。死滅ビットが立っているスレッドがCPU時間を何食わぬ顔で消費している場合、深刻な問題が発生しています。不完全な生態系では十分ありえることです。WinDbgアプリケーション開発に関する詳細については、こちらの情報が参考になるかもしれません。