WinDbgは多数のコマンドを備えています。それらのコマンドのすべてを記憶することはできません。筆者は、解決すべき問題に応じて複数のコマンドをスクリプト化しています。次に紹介する出力情報は、WinDbgから動作中のMSPAINT.EXEにアタッチし、自作スクリプトファイル(WinDbgアプリケーション)の一つを実行した結果です。ここでは、MSPAINT.EXEのハンドル数を調べています。ハンドル数を調査するために必要なMSPAINT.EXE関連データは赤色で強調表示されています。
PROCESS 811db290 SessionId: 0 Cid: 0618 Peb: 7ffdf000 ParentCid: 0708
DirBase: 0ecc4000 ObjectTable: e1407b10 HandleCount: 129.
Image: mspaint.exe
struct _EPROCESS * 0x811db290
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
+0x070 CreateTime : _LARGE_INTEGER 0x1c90c8c`cd1ccb70
+0x078 ExitTime : _LARGE_INTEGER 0x0
+0x080 RundownProtect : _EX_RUNDOWN_REF
+0x084 UniqueProcessId : 0x00000618
+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0xff9a40b8 - 0xff94f0b8 ]
+0x090 QuotaUsage : [3] 0x1298
+0x09c QuotaPeak : [3] 0x3158
+0x0a8 CommitCharge : 0x2b2
+0x0ac PeakVirtualSize : 0x5449000
+0x0b0 VirtualSize : 0x5448000
+0x0b4 SessionProcessLinks : _LIST_ENTRY [ 0xff9a40e4 - 0xff94f0e4 ]
+0x0bc DebugPort : 0x811a66d0
+0x0c0 ExceptionPort : 0xe19a3bb8
+0x0c4 ObjectTable : 0xe1407b10 _HANDLE_TABLE
+0x0c8 Token : _EX_FAST_REF
+0x0cc WorkingSetLock : _FAST_MUTEX
+0x0ec WorkingSetPage : 0xcb87
+0x0f0 AddressCreationLock : _FAST_MUTEX
+0x110 HyperSpaceLock : 0
+0x114 ForkInProgress : (null)
+0x118 HardwareTrigger : 0
+0x11c VadRoot : 0xff93f5d8
+0x120 VadHint : 0xff933180
+0x124 CloneRoot : (null)
+0x128 NumberOfPrivatePages : 0x18c
+0x12c NumberOfLockedPages : 0
+0x130 Win32Process : 0xe118ba28
+0x134 Job : (null)
+0x138 SectionObject : 0xe23496a0
+0x13c SectionBaseAddress : 0x01000000
+0x140 QuotaBlock : 0x8123bfc0 _EPROCESS_QUOTA_BLOCK
+0x144 WorkingSetWatch : (null)
+0x148 Win32WindowStation : 0x0000002c
+0x14c InheritedFromUniqueProcessId : 0x00000708
+0x150 LdtInformation : (null)
+0x154 VadFreeHint : (null)
+0x158 VdmObjects : (null)
+0x15c DeviceMap : 0xe1723878
+0x160 PhysicalVadList : _LIST_ENTRY [ 0x811db3f0 - 0x811db3f0 ]
+0x168 PageDirectoryPte : _HARDWARE_PTE
+0x168 Filler : 0
+0x170 Session : 0xf97d7000
+0x174 ImageFileName : [16] "mspaint.exe"
+0x184 JobLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x18c LockedPagesList : (null)
+0x190 ThreadListHead : _LIST_ENTRY [ 0xff90b624 - 0xff71aa04 ]
+0x198 SecurityPort : (null)
+0x19c PaeTop : (null)
+0x1a0 ActiveThreads : 5
+0x1a4 GrantedAccess : 0x1f0fff
+0x1a8 DefaultHardErrorProcessing : 0
+0x1ac LastThreadExitStatus : 0
+0x1b0 Peb : 0x7ffdf000 _PEB
+0x1b4 PrefetchTrace : _EX_FAST_REF
+0x1b8 ReadOperationCount : _LARGE_INTEGER 0x6
+0x1c0 WriteOperationCount : _LARGE_INTEGER 0x3
+0x1c8 OtherOperationCount : _LARGE_INTEGER 0x23d
+0x1d0 ReadTransferCount : _LARGE_INTEGER 0xd8ce
+0x1d8 WriteTransferCount : _LARGE_INTEGER 0xd8
+0x1e0 OtherTransferCount : _LARGE_INTEGER 0x25496
+0x1e8 CommitChargeLimit : 0
+0x1ec CommitChargePeak : 0x2b2
+0x1f0 AweInfo : (null)
+0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
+0x1f8 Vm : _MMSUPPORT
+0x238 LastFaultCount : 0
+0x23c ModifiedPageCount : 0x191
+0x240 NumberOfVads : 0x77
+0x244 JobStatus : 0
+0x248 Flags : 0xd0803
+0x248 CreateReported : 0y1
+0x248 NoDebugInherit : 0y1
+0x248 ProcessExiting : 0y0
+0x248 ProcessDelete : 0y0
+0x248 Wow64SplitPages : 0y0
+0x248 VmDeleted : 0y0
+0x248 OutswapEnabled : 0y0
+0x248 Outswapped : 0y0
+0x248 ForkFailed : 0y0
+0x248 HasPhysicalVad : 0y0
+0x248 AddressSpaceInitialized : 0y10
+0x248 SetTimerResolution : 0y0
+0x248 BreakOnTermination : 0y0
+0x248 SessionCreationUnderway : 0y0
+0x248 WriteWatch : 0y0
+0x248 ProcessInSession : 0y1
+0x248 OverrideAddressSpace : 0y0
+0x248 HasAddressSpace : 0y1
+0x248 LaunchPrefetched : 0y1
+0x248 InjectInpageErrors : 0y0
+0x248 VmTopDown : 0y0
+0x248 Unused3 : 0y0
+0x248 Unused4 : 0y0
+0x248 VdmAllowed : 0y0
+0x248 Unused : 0y00000 (0)
+0x248 Unused1 : 0y0
+0x248 Unused2 : 0y0
+0x24c ExitStatus : 259
+0x250 NextPageColor : 0xb2be
+0x252 SubSystemMinorVersion : 0 ''
+0x253 SubSystemMajorVersion : 0x4 ''
+0x252 SubSystemVersion : 0x400
+0x254 PriorityClass : 0x2 ''
+0x255 WorkingSetAcquiredUnsafe : 0 ''
+0x258 Cookie : 0xcd5d3b1a
struct _HANDLE_TABLE * 0xe1407b10
+0x000 TableCode : 0xe12f6000
+0x004 QuotaProcess : 0x811db290 _EPROCESS
+0x008 UniqueProcessId : 0x00000618
+0x00c HandleTableLock : [4] _EX_PUSH_LOCK
+0x01c HandleTableList : _LIST_ENTRY [ 0xe210a34c - 0xe2b1a7dc ]
+0x024 HandleContentionEvent : _EX_PUSH_LOCK
+0x028 DebugInfo : (null)
+0x02c ExtraInfoPages : 0
+0x030 FirstFree : 0x18c
+0x034 LastFree : 0
+0x038 NextHandleNeedingPool : 0x800
+0x03c HandleCount : 129
+0x040 Flags : 0
+0x040 StrictFIFO : 0y0
実行したスクリプト内では、Windowsシステム内で活発に活動している多数のプロセスからMSPAINT.EXEプロセスのみを選び出し、最終的に、ハンドルテーブルの内容を表示しています。また、ユーザモードとカーネルモード間の切り替えも自動的に行い、カーネル空間にあるシステム(カーネル構造体インスタンス)情報を素早く取得しています。実稼働環境では目的のシステム情報を素早く取得することは必須条件です。
プロセスがオープンするハンドル数は時々刻々増減しますから、同じスクリプトやルーチンを一定の間隔をあけて複数回実行することにより、プロセスの挙動を監視し、問題がありそうな場合には、スクリプトに別のロジックを追加してより高精度な監視を行います。プロセスをはじめとするWindowsオブジェクトの監視は、「WinDbgアプリケーションを開発し、カーネルレベルで楽しく、かつ、効率的に」行う。これが時代の流れです。WinDbgアプリケーション開発は知的なソフトウェア開発行為であり、高度な想像力が要求されるたいへん魅力的な作業です。
WinDbgスクリプティングの利点とは何か。それは、Windowsシステムの奥深くまで分析できることです。Windowsシステムのプロになれることです。Windowsシステムの奥深くでは、カーネルが活発に動いています。そのカーネルは多数のシステム構造体を作成・管理し、膨大な数のフィールドの値を高速で更新しています。たとえば、あるスレッドが動作を終了すれば、その変化は特定のシステム構造体の関連するビットフィールドに反映されます。WindowsカーネルはUnix分野出身の開発者たちにより設計・開発されています。「データ構造」と「アルゴリズム」という視点に立てば、WindowsもLinuxも高度なシステムソフトウェアである点では同じです。