オンサイトセミナー
豊田孝の「IT談話館」 Windowsメモリダンプ解析を依頼する WinDbgとシステム分析




 本「IT談話館」一般公開記事は、10年以上の実務経験を持つ上級Windowsエンジニアを想定しています。
 本館は、Windowsカーネル深層を解析し、クラッシュ原因をはじめとするシステム内の「異様な動き」を検出・分析する
超高度な技術と実績を保有しています。



Windows 8.1/10のシステムワーカースレッド解析


 本「IT談話館」の「一般公開記事」は、「Active Memory Dump とカーネルメモリダンプ」の解析結果を基に起草されています。公開内容はあくまでも本館ビジネスに支障の出ない範囲に制限されていますが、Windowsビジネスを展開する上で必要となる、新規「商材」の発掘や同業他社との「差異」を確保し、人材と予算をはじめとする所有資源を適切に配置・投資する一助にはなるかもしれません。本「IT談話館」主筆の「豊田孝」はDKOM(Direct Kernel Object Manipulation)ベースの解析手法の第一人者であり、Windowsカーネル空間の解析分野では世界の先頭を走っています。

 現在、セキュリティー問題を無視することはできません。Microsoft社側の負担だけではなく、同社製品の利用者側の負担も増しています。困ったことではありますが、当面避けられません。セキュリティーの視点から「Windows10ソフトウェアセンサー」を見た場合、本「IT談話館」の確認範囲では、「カーネル層保護ロジック」に加え、次のような保護メカニズム階層が考案・実装されています。下記リンクはすべて本館記事を指しています。
  1. Silo/Server Silo
  2. Job
  3. Session
  4. Protected Process
  5. Mandatory Integrity Control(MIC)
  6. Windows API(+CPU)
  7. 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」の機械語表現です。



ビジネスメニュー




「Windowsメモリダンプ解析サービス」のご案内
Windowsメモリダンプ解析技術

Copyright©豊田孝 2004- 2024
本日は2024-04-19です。