本「
IT談話館」一般公開記事は、10年以上の実務経験を持つ上級Windowsエンジニアを想定しています。
本館は、Windowsカーネル深層を解析し、クラッシュ原因をはじめとするシステム内の「異様な動き」を検出・分析する
超高度な技術と実績を保有しています。
Windows 8.1/10のシステムワーカースレッド解析
本「IT談話館」の「一般公開記事」は、「Active Memory Dump とカーネルメモリダンプ」の解析結果を基に起草されています。「本館」主筆の「豊田孝」はDKOM(Direct Kernel Object Manipulation)ベースの解析手法の第一人者であり、Windowsカーネル空間の解析分野では世界の先頭を走っています。
現在、セキュリティー問題を無視することはできません。Microsoft社側の負担だけではなく、同社製品の利用者側の負担も増しています。困ったことではありますが、当面避けられません。セキュリティーの視点から「Windows10ソフトウェアセンサー」を見た場合、本「IT談話館」の確認範囲では、「カーネル層保護ロジック」に加え、次のような保護メカニズム階層が考案・実装されています。下記リンクはすべて本館記事を指しています。
- Silo/Server Silo
- Job
- Session
- Protected Process
- Mandatory Integrity Control(MIC)
- Windows API(+CPU)
- CPU
本稿は「Windows XP/7/8/10のシステムワーカースレッド解析(基礎)」の続編となります。システムワーカースレッドの仕様は、基礎編で触れたように、Windows 8.1出荷のタイミングで「大幅に変更」されました。本稿では、本「IT談話館」の独自解析コードを2種類の「カーネルメモリダンプとActive Memory Dump」に適応し、システムワーカースレッドの技術的な背景を探ります。なお、解析コードの開発知識の習得には、「時間と予算の投資」が必要です。
まずは、Windows 8.1環境で採取された次のようなカーネルメモリダンプを解析します。
1: kd> vertarget
Windows 8.1 Kernel Version 9600 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS Personal
Built by: 9600.17668.amd64fre.winblue_r8.150127-1500
Machine Name:
Kernel base = 0xfffff802`2ea8e000 PsLoadedModuleList = 0xfffff802`2ed67250
Debug session time: Sun Mar 22 03:49:45.996 2015 (UTC + 9:00)
System Uptime: 0 days 0:02:10.401
このダンプは、2015年3月に採取されています。本館の独自解析コードを実行すると、次のような結果が返されます。
0xffffe001eae56600->System
000 Thread->0xffffe001eae5a040 Queue->0xffffe001eaeba310 Qpriority->000 WR->15 Priority->16 QueueType->4
001 Thread->0xffffe001eae83880 Queue->0xfffff8022ed40300 Qpriority->268 WR->15 Priority->12 QueueType->21
002 Thread->0xffffe001eaeba880 Queue->0xfffff8022ed45e80 Qpriority->000 WR->15 Priority->15 QueueType->4
003 Thread->0xffffe001eae79040 Queue->0xfffff8022ed741e0 Qpriority->000 WR->15 Priority->16 QueueType->4
004 Thread->0xffffe001eae79880 Queue->0xfffff8022ed74220 Qpriority->000 WR->15 Priority->17 QueueType->4
005 Thread->0xffffe001eae77880 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->10 QueueType->21
006 Thread->0xffffe001eaeae040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
007 Thread->0xffffe001eaeae880 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->10 QueueType->21
008 Thread->0xffffe001eae61040 Queue->0xfffff8022ed72340 Qpriority->000 WR->15 Priority->16 QueueType->4
009 Thread->0xffffe001eae61880 Queue->0xfffff8022ed72340 Qpriority->000 WR->15 Priority->16 QueueType->4
010 Thread->0xffffe001eaf36040 Queue->0xfffff8022ed72340 Qpriority->000 WR->15 Priority->16 QueueType->4
011 Thread->0xffffe001eaf36880 Queue->0xfffff8022ed72340 Qpriority->000 WR->15 Priority->16 QueueType->4
012 Thread->0xffffe001eb20f880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
013 Thread->0xffffe001eb20c880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
014 Thread->0xffffe001eb327880 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->10 QueueType->21
015 Thread->0xffffe001eb340880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
016 Thread->0xffffe001eb342880 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->09 QueueType->21
017 Thread->0xffffe001eb383040 Queue->0xfffff80139f198a0 Qpriority->000 WR->15 Priority->08 QueueType->4
018 Thread->0xffffe001ee3f3880 Queue->0xfffff8022ed40300 Qpriority->271 WR->15 Priority->15 QueueType->21
019 Thread->0xffffe001ef480080 Queue->0xffffe001eae56dc0 Qpriority->000 WR->15 Priority->09 QueueType->4
020 Thread->0xffffe001efcc3880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
021 Thread->0xffffe001f015f880 Queue->0xffffe001f0161088 Qpriority->000 WR->15 Priority->08 QueueType->4
022 Thread->0xffffe001f0175880 Queue->0xffffe001efda7368 Qpriority->000 WR->15 Priority->09 QueueType->4
023 Thread->0xffffe001f016b880 Queue->0xffffe001efda7688 Qpriority->000 WR->15 Priority->09 QueueType->4
024 Thread->0xffffe001f0176040 Queue->0xffffe001efda79a8 Qpriority->000 WR->15 Priority->09 QueueType->4
025 Thread->0xffffe001f0176880 Queue->0xffffe001efda7cc8 Qpriority->000 WR->15 Priority->09 QueueType->4
026 Thread->0xffffe001f0177040 Queue->0xffffe001f0168028 Qpriority->000 WR->15 Priority->09 QueueType->4
027 Thread->0xffffe001f0177880 Queue->0xffffe001f0168348 Qpriority->000 WR->15 Priority->09 QueueType->4
028 Thread->0xffffe001f0178040 Queue->0xffffe001f0168668 Qpriority->000 WR->15 Priority->09 QueueType->4
029 Thread->0xffffe001f0178880 Queue->0xffffe001f0168988 Qpriority->000 WR->15 Priority->09 QueueType->4
030 Thread->0xffffe001f0179040 Queue->0xfffff8013d2668f8 Qpriority->000 WR->15 Priority->09 QueueType->4
031 Thread->0xffffe001f01ac040 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->09 QueueType->21
032 Thread->0xffffe001f01af640 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->10 QueueType->21
033 Thread->0xffffe001f01b5400 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
034 Thread->0xffffe001f01c7040 Queue->0xfffff8022ed40300 Qpriority->268 WR->15 Priority->12 QueueType->21
035 Thread->0xffffe001f01c8040 Queue->0xfffff8022ed40300 Qpriority->268 WR->15 Priority->12 QueueType->21
036 Thread->0xffffe001f07a5040 Queue->0xfffff8022ed40300 Qpriority->268 WR->15 Priority->12 QueueType->21
037 Thread->0xffffe001f07d3880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
038 Thread->0xffffe001f07f44c0 Queue->0xfffff8022ed40300 Qpriority->264 WR->15 Priority->08 QueueType->21
039 Thread->0xffffe001f07f1040 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->10 QueueType->21
040 Thread->0xffffe001f07f0880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
041 Thread->0xffffe001f07ed880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
042 Thread->0xffffe001f07eb040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
043 Thread->0xffffe001f07a0040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
044 Thread->0xffffe001efe1d880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
045 Thread->0xffffe001f0770040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
046 Thread->0xffffe001f076e880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
047 Thread->0xffffe001f0768300 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
048 Thread->0xffffe001f0766040 Queue->0xfffff8022ed40300 Qpriority->264 WR->15 Priority->09 QueueType->21
049 Thread->0xffffe001f0764040 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->10 QueueType->21
050 Thread->0xffffe001f0764880 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->09 QueueType->21
051 Thread->0xffffe001f075e040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
052 Thread->0xffffe001f0755040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
053 Thread->0xffffe001f0755880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
054 Thread->0xffffe001f0782740 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
055 Thread->0xffffe001f077f040 Queue->0xfffff8022ed40300 Qpriority->268 WR->15 Priority->12 QueueType->21
056 Thread->0xffffe001f0841040 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->09 QueueType->21
057 Thread->0xffffe001f083b880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
058 Thread->0xffffe001f083a880 Queue->0xfffff8022ed40300 Qpriority->268 WR->15 Priority->12 QueueType->21
059 Thread->0xffffe001f0839340 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
060 Thread->0xffffe001f0939040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
061 Thread->0xffffe001f0939880 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->10 QueueType->21
062 Thread->0xffffe001f0938040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
063 Thread->0xffffe001f0935040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
064 Thread->0xffffe001f0934040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
065 Thread->0xffffe001f0930880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
066 Thread->0xffffe001f092f880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
067 Thread->0xffffe001f092c880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
068 Thread->0xffffe001f092a040 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
069 Thread->0xffffe001f0929040 Queue->0xfffff8022ed40300 Qpriority->268 WR->15 Priority->12 QueueType->21
070 Thread->0xffffe001f0907880 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->13 QueueType->21
071 Thread->0xffffe001f09047c0 Queue->0xfffff8022ed40300 Qpriority->269 WR->15 Priority->14 QueueType->21
072 Thread->0xffffe001f0902040 Queue->0xfffff8022ed40300 Qpriority->265 WR->15 Priority->09 QueueType->21
073 Thread->0xffffe001f0964880 Queue->0xfffff8022ed40300 Qpriority->264 WR->15 Priority->15 QueueType->21
Windows 8.1出荷時の大幅な変更では、Queueタイプという概念が導入されました。この情報内の最右端の「QueueType」欄にQueueタイプが示されています。「QueueType」欄をみると、「4」と「21」の2種類のQueueタイプが存在することが分かります。結論を先取りすると、「4」は従来から存在するQueueタイプであり、「21」は新たに定義されたQueueタイプとなります。この違いは、次のようなコマンド操作で簡単に見い出すことができます。
1: kd> !thread 0xffffe001eae5a040
THREAD ffffe001eae5a040 Cid 0004.0018 Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: (WrQueue) KernelMode Non-Alertable
ffffe001eaeba310 QueueObject
Not impersonating
DeviceMap ffffc001b3e0c280
Owning Process ffffe001eae56600 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 736 Ticks: 7609 (0:00:01:58.890)
Context Switch Count 7 IdealProcessor: 0
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address nt!PopFxEmergencyWorker (0xfffff8022ebcc038)
Stack Init ffffd001683ffc90 Current ffffd001683ff890
Base ffffd00168400000 Limit ffffd001683fa000 Call 0000000000000000
Priority 16 BasePriority 16 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr : Args to Child : Call Site
ffffd001`683ff8d0 fffff802`2eb284fe : ffffd001`68480180 ffffe001`eae5a040 ffffd001`0000000d 00000000`00000007 : nt!KiSwapContext+0x76
ffffd001`683ffa10 fffff802`2eb27f79 : ffffe001`ef4f3260 ffffe001`ef4f3990 00000000`00000001 ffffd001`683ffb70 : nt!KiSwapThread+0x14e
ffffd001`683ffab0 fffff802`2eb26c4d : 00000000`00000000 00000000`00000000 ffffe001`eae5a040 fffff802`2ebb4205 : nt!KiCommitThreadWait+0x129
ffffd001`683ffb30 fffff802`2ebcc076 : ffffe001`eaeba310 ffffe001`eae5a000 ffffe001`eaeba300 00000000`00000000 : nt!KeRemoveQueueEx+0x26d
ffffd001`683ffbc0 fffff802`2eb66280 : 00000000`00000000 ffffe001`ef4f39a8 00000000`00000000 00000000`00000000 : nt!PopFxEmergencyWorker+0x3e
ffffd001`683ffc00 fffff802`2ebe4fc6 : ffffd001`6cc40180 ffffe001`eae5a040 ffffd001`6cc4c2c0 00000000`00000000 : nt!PspSystemThreadStartup+0x58
ffffd001`683ffc60 00000000`00000000 : ffffd001`68400000 ffffd001`683fa000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x16
1: kd> !thread 0xffffe001eae83880
THREAD ffffe001eae83880 Cid 0004.0020 Teb: 0000000000000000 Win32Thread: 0000000000000000 WAIT: (WrQueue) KernelMode Non-Alertable
fffff8022ed40300 PriQueueObject
Not impersonating
DeviceMap ffffc001b3e0c280
Owning Process ffffe001eae56600 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 8341 Ticks: 4 (0:00:00:00.062)
Context Switch Count 3669 IdealProcessor: 3
UserTime 00:00:00.000
KernelTime 00:00:00.468
Win32 Start Address nt!ExpWorkerThread (0xfffff8022eb39120)
Stack Init ffffd0016850dc90 Current ffffd0016850d8b0
Base ffffd0016850e000 Limit ffffd00168508000 Call 0000000000000000
Priority 12 BasePriority 12 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP RetAddr : Args to Child : Call Site
ffffd001`6850d8f0 fffff802`2eb284fe : ffffd001`68480180 ffffe001`eae83880 ffffc001`00000008 ffffc001`c27e8010 : nt!KiSwapContext+0x76
ffffd001`6850da30 fffff802`2eb27f79 : 00000000`00000001 00000000`00000001 ffffe001`eae66530 fffff802`2eed9733 : nt!KiSwapThread+0x14e
ffffd001`6850dad0 fffff802`2eb3932d : ffffe001`eae83880 ffffe001`eae839c0 ffffe001`eae83880 ffffe001`eae83880 : nt!KiCommitThreadWait+0x129
ffffd001`6850db50 fffff802`2eb66280 : 9a147812`06495c6b ffffe001`eae83880 00000000`00000080 ffffe001`eae83880 : nt!ExpWorkerThread+0x20d
ffffd001`6850dc00 fffff802`2ebe4fc6 : ffffd001`6cc40180 ffffe001`eae83880 ffffd001`6cc4c2c0 2af149e9`cbc50a71 : nt!PspSystemThreadStartup+0x58
ffffd001`6850dc60 00000000`00000000 : ffffd001`6850e000 ffffd001`68508000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x16
この解析対象ダンプでは、新しく導入されたQueueが「fffff8022ed40300」に置かれ、複数のスレッドで共有されています。Priority値を吟味してみると、Queue「fffff8022ed40300」には異なる値が割り当てられています。その数値を分解してみると、「256+スレッド優先度」と「255+スレッド優先度」となっていますが、「256」と「255」の違いの解析は割愛します。
Queue「fffff8022ed40300」はどれほどの数のスレッドが登録されているのかを確認する場合には、次のようなコマンド操作を行います。
1: kd> !validatelist 0xfffff8022ed40300+8
Found list end after 54 entries
このコマンド操作は、本稿末で触れるように、従来の知識を基に行われています。つまり、新しい技術は古い技術を基礎としている、ということになります。新しい技術に沿ったコマンド操作は次のようになります。
1: kd> dt _ex_work_queue 0xfffff8022ed40300
nt!_EX_WORK_QUEUE
+0x000 WorkPriQueue : _KPRIQUEUE
+0x2b0 Node : 0xfffff802`2ed40200 _ENODE
+0x2b8 WorkItemsProcessed : 0x8456
+0x2bc WorkItemsProcessedLastPass : 0x811f
+0x2c0 ThreadCount : 0n54
+0x2c4 MinThreads : 0y0000000000000000000000000000000 (0)
+0x2c4 TryFailed : 0y0
+0x2c8 MaxThreads : 0n4096
+0x2cc QueueIndex : 0 ( ExPoolUntrusted )
1: kd> dt _KPRIQUEUE 0xfffff8022ed40300
nt!_KPRIQUEUE
+0x000 Header : _DISPATCHER_HEADER
+0x018 EntryListHead : [32] _LIST_ENTRY [ 0xfffff802`2ed40318 - 0xfffff802`2ed40318 ]
+0x218 CurrentCount : [32] 0n0
+0x298 MaximumCount : 4
+0x2a0 ThreadListHead : _LIST_ENTRY [ 0xffffe001`eae83a88 - 0xffffe001`f0964a88 ]
1: kd> !validatelist 0xfffff8022ed40300+2a0
Found list end after 54 entries
54個のスレッドが実行を待っているようです。実務解析では、54個のスレッドを列挙し、詳細な解析を加えますが、本稿では割愛します。
次にWindows 10環境で採取された次のようなActive Memory Dumpを解析します。解析には同一の解析コードを使用しています。
0: kd> vertarget
Windows 10 Kernel Version 18362 MP (2 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 18362.1.amd64fre.19h1_release.190318-1202
Machine Name:
Kernel base = 0xfffff802`6e400000 PsLoadedModuleList = 0xfffff802`6e848130
Debug session time: Thu Dec 26 15:26:37.338 2019 (UTC + 9:00)
System Uptime: 3 days 5:48:09.082
解析コードを実行すると、次のような結果が返されます。
0xffffa80faae68040->System
000 Thread->0xffffa80faaf35080 Queue->0xfffff8026e8467c0 Qpriority->000 WR->15 Priority->16 QueueType->4
001 Thread->0xffffa80faaf3b040 Queue->0xfffff8026e831300 Qpriority->000 WR->15 Priority->15 QueueType->4
002 Thread->0xffffa80fab05c040 Queue->0xfffff8026e865100 Qpriority->000 WR->15 Priority->16 QueueType->4
003 Thread->0xffffa80fab05d040 Queue->0xfffff8026e865140 Qpriority->000 WR->15 Priority->17 QueueType->4
004 Thread->0xffffa80faae64040 Queue->0xfffff8026e863140 Qpriority->000 WR->15 Priority->16 QueueType->4
005 Thread->0xffffa80faae65040 Queue->0xfffff8026e863140 Qpriority->000 WR->15 Priority->16 QueueType->4
006 Thread->0xffffa80faae66040 Queue->0xfffff8026e863140 Qpriority->000 WR->15 Priority->16 QueueType->4
007 Thread->0xffffa80fab4e8040 Queue->0xfffff8026e863140 Qpriority->000 WR->15 Priority->16 QueueType->4
008 Thread->0xffffa80faed0c080 Queue->0xffffa80fae4960c0 Qpriority->000 WR->15 Priority->09 QueueType->4
009 Thread->0xffffa80fb0250040 Queue->0xfffff8026c4fc0c8 Qpriority->000 WR->15 Priority->12 QueueType->4
010 Thread->0xffffa80fae6f2040 Queue->0xffffa80faaf13ce0 Qpriority->268 WR->15 Priority->12 QueueType->21
011 Thread->0xffffa80fab84f040 Queue->0xffffa80faaf24ce0 Qpriority->262 WR->15 Priority->06 QueueType->21
012 Thread->0xffffa80faaf11040 Queue->0xffffa80faaf24ce0 Qpriority->262 WR->15 Priority->06 QueueType->21
013 Thread->0xffffa80fbd8c2040 Queue->0xffffa80faaf13ce0 Qpriority->268 WR->15 Priority->12 QueueType->21
014 Thread->0xffffa80fb8da1040 Queue->0xffffa80faaf24ce0 Qpriority->272 WR->15 Priority->16 QueueType->21
015 Thread->0xffffa80fb92f1040 Queue->0xffffa80faaf24ce0 Qpriority->269 WR->15 Priority->13 QueueType->21
016 Thread->0xffffa80fb9674040 Queue->0xffffa80faaf24ce0 Qpriority->271 WR->15 Priority->15 QueueType->21
017 Thread->0xffffa80fb94612c0 Queue->0xffffa80faaf24ce0 Qpriority->264 WR->15 Priority->09 QueueType->21
018 Thread->0xffffa80fbb0ee040 Queue->0xffffa80fb7d78cd0 Qpriority->279 WR->15 Priority->23 QueueType->21
このケースでは3種類の優先度付きQueueが使用されています。先のケースと同じように、簡単なコマンド操作を行い、Queue「0xffffa80faaf24ce0」に登録されているスレッド数を調査します。
0: kd> !validatelist 0xffffa80faaf24ce0+8
Found list end after 6 entries
0: kd> dt _ex_work_queue 0xffffa80faaf24ce0
nt!_EX_WORK_QUEUE
+0x000 WorkPriQueue : _KPRIQUEUE
+0x2b0 Partition : 0xffffa80f`aae50600 _EX_PARTITION
+0x2b8 Node : 0xfffff802`6e98f240 _ENODE
+0x2c0 WorkItemsProcessed : 0x301ffb
+0x2c4 WorkItemsProcessedLastPass : 0x2fc6aa
+0x2c8 ThreadCount : 0n6
+0x2cc MinThreads : 0y0000000000000000000000000000000 (0)
+0x2cc TryFailed : 0y1
+0x2d0 MaxThreads : 0n4096
+0x2d4 QueueIndex : 0 ( ExPoolUntrusted )
+0x2d8 AllThreadsExitedEvent : (null)
0: kd> dt _KPRIQUEUE 0xffffa80faaf24ce0
nt!_KPRIQUEUE
+0x000 Header : _DISPATCHER_HEADER
+0x018 EntryListHead : [32] _LIST_ENTRY [ 0xffffa80f`aaf24cf8 - 0xffffa80f`aaf24cf8 ]
+0x218 CurrentCount : [32] 0n0
+0x298 MaximumCount : 2
+0x2a0 ThreadListHead : _LIST_ENTRY [ 0xffffa80f`ab84f248 - 0xffffa80f`b94614c8 ]
0: kd> !validatelist 0xffffa80faaf24ce0+2a0
Found list end after 6 entries
結果を見ると、登録スレッド数は6個のようです。が、試行失敗があった!、模様です。試行失敗の原因が気になりますが、本稿ではその解析工程の説明は割愛します。また、Queueの優先度値の算出ロジックの検討も必要になりますが、本稿では割愛します。
本稿で割愛した解析工程を自力で実施したい場合には、次のようなコマンド操作を行います。
0: kd> x nt!*pri*queue*
fffff802`6e509a30 nt!KiPriQueueThreadPriorityChanged (void)
fffff802`6e509d5c nt!KiActivateWaiterPriQueue (void)
fffff802`6e530690 nt!KiSwitchPriQueue (void)
fffff802`6e509dd0 nt!KiAttemptFastRemovePriQueue (void)
fffff802`6e595360 nt!KeInitializePriQueue (void)
fffff802`6e4beaa0 nt!KeInsertPriQueue (void)
fffff802`6e4bd2f0 nt!KeRemovePriQueue (void)
fffff802`6e509eac nt!KiWakePriQueueWaiter ()
fffff802`6e6b3e8c nt!KeSetMaximumCountPriQueue ()
fffff802`6e6b3de0 nt!KeRundownPriQueue ()
この情報から解析対象関数を選択し、リバースエンジニアリング(RE)を行います。REを行う際には、本稿で紹介した基本的な解析結果が役に立ちます。つまり、まずREの入り口を見つけ出します。たとえば、新しく導入されたQueueタイプの識別数値は10進数の「21」ですが、16進数では次のように「15」となります。
0: kd> uf nt!KeInitializePriQueue
nt!KeInitializePriQueue:
fffff802`6e595360 4053 push rbx
fffff802`6e595362 4883ec20 sub rsp,20h
fffff802`6e595366 66c7011500 mov word ptr [rcx],15h
fffff802`6e59536b 488d4108 lea rax,[rcx+8]
fffff802`6e59536f c64102ac mov byte ptr [rcx+2],0ACh
fffff802`6e595373 4533c9 xor r9d,r9d
fffff802`6e595376 44894904 mov dword ptr [rcx+4],r9d
fffff802`6e59537a 488bd9 mov rbx,rcx
fffff802`6e59537d 48894008 mov qword ptr [rax+8],rax
fffff802`6e595381 488900 mov qword ptr [rax],rax
fffff802`6e595384 488d81a0020000 lea rax,[rcx+2A0h]
fffff802`6e59538b 48894008 mov qword ptr [rax+8],rax
fffff802`6e59538f 458d4120 lea r8d,[r9+20h]
fffff802`6e595393 488900 mov qword ptr [rax],rax
fffff802`6e595396 4881c118020000 add rcx,218h
fffff802`6e59539d 488d4318 lea rax,[rbx+18h]
[---]
数値の「15h」は[rcx」に転送されていますから、この関数が受け取っている引数の正体を特定するのは容易です。[rcx+8]は「0xffffa80faaf24ce0+8」の機械語表現です。