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




メモリ解析サービス



WinDbgとWindowsカーネルアーキテクチャー


 Windowsシステムは時代の要請を受けながらインターネット越しに随時更新されます。更新の多くはカーネル空間の変更を伴いますが、いろいろな事情から、変更内容の技術的な背景説明がなされることはほとんどありません。Windowsカーネルアーキテクチャーの"あのコンポーネント"の位置付けが分からない!経験豊富なWindowsエンジニアーでさえも、このような疑問、そして、不安を日々抱いています。"Windows 10のアップデートの影響を評価できない"などの疑問や不安を抱えた場合には、「Active Memory Dump」を採取し、「WinDbg」環境で解析することにより、自力でそのような疑問や不安を払拭することができます。

 まずは次のようなWindowsアーキテクチャーをおさらいしておきます。



 このアーキテクチャー図には、ALPCではなくLPCという旧式の用語が登場しており、一見すると、情報の賞味期限が切れている印象を受けますが、Windowsアーキテクチャーの骨格そのものが劇的に変更されているわけではありません。Windows 10システム環境で採取した「Active Memory Dump」を解析すると、次のようなWindowsカーネルアーキテクチャー内部情報を取得することができます。
Pcr->0xfffff8005a350000	Prcb->0xfffff8005a350180	Process->0xffffd88dffb3c080	Thread->0xffffd88dfef55080	notmyfault64.e
 この情報は、Device、Device Driver、VAD、Session、Section、Token、Job、VM、あるいは、IRPなどの基本概念の多くを捨象し、まさに、Windowsカーネルアーキテクチャーの中心概念のみを示しています。上のWindowsアーキテクチャー図でいえば、左から右に向かって、最下位層のHardware Abstraction Layer(HAL)から最上位層のApplicationに相当します。本「IT談話館」は、上記のようなオブジェクト間の微妙な関係性を解析し、Windowsシステムの健康度を診断したり、システムクラッシュ発生原因を特定する高度な技術力を保有しています。

 上のWindowsアーキテクチャー図には、System ServicesやCritical servicesという概念が含まれています。System ServicesはServices.exe(SCM)プロセスの子プロセスですから、その特定は容易ですが、Critical servicesとはいったいなんでしょう?正直に言えば、本「IT談話館」も確かなことは分かりません。しかし、次のような仮説を設定し、WinDbg環境でその仮説を実証することにより、それらしい情報を取得することができます。  これらの仮説を組み入れた解析コードを作成し、Windows 10 Professional環境で採取した「Active Memory Dump」を解析してみると、次のような情報が返されてきます。
No.001: Parent: 0x002ac	Child: 0x00378	SessionId->0	Critical->1	svchost.exe(0xffffd88dfe647080)
No.002: Parent: 0x002ac	Child: 0x003a0	SessionId->0	Critical->1	svchost.exe(0xffffd88dfd92a080)
No.003: Parent: 0x002ac	Child: 0x004e0	SessionId->0	Critical->1	svchost.exe(0xffffd88dfe9a7080)

TotalProcesses->160
 すべての条件をクリアーしたのは、160個のプロセス中、3個だけです。3個のプロセスはすべて「svchost.exe」サービスプロセスですから、なんとなく納得できそうな感じですが、実務解析作業では、「0xffffd88dfe647080」などのプロセス識別情報を頼りにさらに解析作業を進めることになります。たとえば、とりあえず、上記3個の「svchost.exe」プロセスが受け取っているコマンドラインパラメータを調査してみるのも一案です。

+0xFFFFD88DFE647080	svchost.exe
	CommandLine->C:\WINDOWS\system32\svchost.exe -k DcomLaunch -p

+0xFFFFD88DFD92A080	svchost.exe
	CommandLine->c:\windows\system32\svchost.exe -k rpcss -p

+0xFFFFD88DFE9A7080	svchost.exe
	CommandLine->C:\WINDOWS\system32\svchost.exe -k LocalServiceNoNetwork -p
 赤色で強調されている引数はそれぞれの「svchost.exe」サービスプロセスの役割(Service)を指定しています。DcomはDistributed COM、rpcはRemote Procedure Callをそれぞれ示していますから、これらのサービスプロセスが動作を停止した場合、Windowsシステムの運用に深刻(Critical)な影響が出ます。逆に、この2つのプロセスの動作は実質的に停止することはできませんから、内外からのシステム侵入者に「横展開」され、セキュリティー面での危険性が残されていることになります。便利な機能は誰にとっても便利なわけですね。

 最後のLocalServiceNoNetworkは依然意味不明ですが、次のような「プロセスとオブジェクト名前空間」の間に成立している関係を解析してみると、LRPC(Local rpc)であることがはっきり分かります。
HandleCount->0502	svchost.exe	ffffd88dfe9a7080
	015: Object->0xffffc70ebd13a640	Name->KnownDlls
	046: Object->0xffffc70ebcfc9ea0	Name->BaseNamedObjects
	061: Object->0xffffd88dfd10adb0	Name->Service-0x0-3e5$
	062: Object->0xffffd88dfcf41260	Name->Default
	063: Object->0xffffd88dfd10adb0	Name->Service-0x0-3e5$
	105: Object->0xffffd88dfe7b64d0	Name->LRPC-1e04123d1c6dafcb51
	108: Object->0xffffd88dfe7cda20	Name->CoreMessagingRegistrar
	110: Object->0xffffd88dfe7cd550	Name->CoreUISystemWindowIDManager
	174: Object->0xffffd88dfdf50970	Name->LRPC-0478b56f5966a113be
	184: Object->0xffffd88dfdf28fe0	Name->BFE_Notify_Event_{f53b9da8-b2b0-4953-ae43-04e69107a58c}
	187: Object->0xffffd88dfdf958c0	Name->BFE_Notify_Event_{0cafbc46-b5ab-4c15-8971-dfda7deb763f}
	191: Object->0xffffd88dfdf98a20	Name->BFE_Notify_Event_{5a40686c-db98-416e-aa26-2f12369eed56}
	193: Object->0xffffd88dfdf95550	Name->BFE_Notify_Event_{7ec53fd7-a69f-4f72-a8f8-be819f2dca7b}
	195: Object->0xffffd88dfdf98400	Name->BFE_Notify_Event_{646dbf31-a7c9-48f1-b3c5-1c9b46d4f9e0}
	212: Object->0xffffc70ec8662fc0	Name->__ComCatalogCache__
	229: Object->0xffffd88dfeaf7b40	Name->BFE_Notify_Event_{bc107dad-a0b3-4993-8525-3244e00dcbf5}
	230: Object->0xffffd88dfb2f6de0	Name->MaximumCommitCondition
	233: Object->0xffffd88dfeaf7b40	Name->BFE_Notify_Event_{bc107dad-a0b3-4993-8525-3244e00dcbf5}
	247: Object->0xffffd88dfdee66c0	Name->BFE_Notify_Event_{3aab5344-00d6-4166-8201-552775602cb5}
	248: Object->0xffffd88dfdee66c0	Name->BFE_Notify_Event_{3aab5344-00d6-4166-8201-552775602cb5}

0: kd> !object 0xffffd88dfe7b64d0
Object: ffffd88dfe7b64d0  Type: (ffffd88dfb31acf0) ALPC Port
    ObjectHeader: ffffd88dfe7b64a0 (new version)
    HandleCount: 1  PointerCount: 32768
    Directory Object: ffffc70ebd466520  Name: LRPC-1e04123d1c6dafcb51
 この解析結果は、LRPCがALPCの応用メカニズムであることを示していますから、LocalServiceNoNetworkの意味がここではっきりします。LRPCは、ローカルシステム上で動作するプロセス間にのみ適応される相互通信メカニズムであり、ネットワークサービスを提供していません(NoNetwork)。このALPCポートオブジェクトを調査したい場合には、たとえば、「!alpc /p 0xffffd88dfe7b64d0」などのWinDbgコマンドを次のように実行します。
0: kd> !alpc /p 0xffffd88dfe7b64d0
Port  ffffd88dfe7b64d0
  Type                      : ALPC_CONNECTION_PORT
  CommunicationInfo         : ffffc70ec8a08c30
    ConnectionPort          : ffffd88dfe7b64d0 (LRPC-1e04123d1c6dafcb51)
    ClientCommunicationPort : 0000000000000000
    ServerCommunicationPort : 0000000000000000
  OwnerProcess              : ffffd88dfe9a7080 (svchost.exe)
  SequenceNo                : 0x00000000 (0)
  CompletionPort            : ffffd88dfe9cf3c0
  CompletionList            : 0000000000000000
  ConnectionPending         : No
  ConnectionRefused         : No
  Disconnected              : No
  Closed                    : No
  FlushOnClose              : Yes
  ReturnExtendedInfo        : No
  Waitable                  : No
  Security                  : Static
  Wow64CompletionList       : No

  10 thread(s) are registered with port IO completion object:

    THREAD ffffd88dfd842080  Cid 04e0.1984  Teb: 00000007c7d36000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88dfffc0700  Cid 04e0.1b3c  Teb: 00000007c7dbe000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88dfe850080  Cid 04e0.1e68  Teb: 00000007c7c04000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88dfc469040  Cid 04e0.1c10  Teb: 00000007c7c18000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88e00161080  Cid 04e0.1ff8  Teb: 00000007c7c3e000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88dffc22340  Cid 04e0.18ec  Teb: 00000007c7c40000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88dff5bc1c0  Cid 04e0.177c  Teb: 00000007c7c42000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88e00127200  Cid 04e0.199c  Teb: 00000007c7c44000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88dff868080  Cid 04e0.1d7c  Teb: 00000007c7c46000 Win32Thread: 0000000000000000 WAIT
    THREAD ffffd88dff89a700  Cid 04e0.048c  Teb: 00000007c7c48000 Win32Thread: 0000000000000000 WAIT

  Main queue is empty.


  Direct message queue is empty.


  Large message queue is empty.


  Pending queue is empty.


  Canceled queue is empty.
 この出力情報を見ると、ほとんどのキューは「空」ですが、IO完了キューには10個のスレッドが入っています。ここで示されている「10個」という数値は正しいのでしょうか?キューが破損している可能性はないでしょうか?次のようなコマンド操作をすると、これらの疑問への回答を探すことができます。
0: kd> !thread ffffd88dff89a700
THREAD ffffd88dff89a700  Cid 04e0.048c  Teb: 00000007c7c48000 Win32Thread: 0000000000000000 WAIT: (WrQueue) UserMode Alertable
    ffffd88dfe9cf3c0  QueueObject
Not impersonating
DeviceMap                 ffffc70ec7468e30
Owning Process            ffffd88dfe9a7080       Image:         svchost.exe
Attached Process          N/A            Image:         N/A
Wait Start TickCount      4947807        Ticks: 13689 (0:00:03:33.890)
Context Switch Count      1              IdealProcessor: 1             
UserTime                  00:00:00.000
KernelTime                00:00:00.000
Win32 Start Address ntdll!TppWorkerThread (0x00007fff20c642c0)
Stack Init ffffd70a80e0cd90 Current ffffd70a80e0c540
Base ffffd70a80e0d000 Limit ffffd70a80e07000 Call 0000000000000000
Priority 8 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
Child-SP          RetAddr           : Args to Child                                                           : Call Site
ffffd70a`80e0c580 fffff800`5b4b1070 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSwapContext+0x76
ffffd70a`80e0c6c0 fffff800`5b4b09ee : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSwapThread+0x190
ffffd70a`80e0c780 fffff800`5b4af87f : ffffd88d`ff89a700 00000000`00000000 ffffd88d`fe9a7000 ffffd88d`fe9cf3c0 : nt!KiCommitThreadWait+0x10e
ffffd70a`80e0c820 fffff800`5b4af379 : 00000000`00000000 00000000`00000001 00000000`00000001 00000000`00000000 : nt!KeRemoveQueueEx+0x24f
ffffd70a`80e0c8c0 fffff800`5b4aef05 : 00000000`00000000 00000000`00000000 000004e8`fffffb30 000004d0`fffffb30 : nt!IoRemoveIoCompletion+0x99
ffffd70a`80e0c9e0 fffff800`5b596203 : 00000000`00000000 fffff800`5b52062b ffffd88d`fe9cf190 00000000`00000000 : nt!NtWaitForWorkViaWorkerFactory+0x305
ffffd70a`80e0cb90 00007fff`20cd3784 : 00007fff`20c649dd 00000007`c7c9b000 00000000`00000000 00000000`00000000 : nt!KiSystemServiceCopyEnd+0x13 (TrapFrame @ ffffd70a`80e0cc00)
00000007`d107f4e8 00007fff`20c649dd : 00000007`c7c9b000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!NtWaitForWorkViaWorkerFactory+0x14
00000007`d107f4f0 00007fff`201d1fe4 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!TppWorkerThread+0x71d
00000007`d107f880 00007fff`20c9efb1 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x14
00000007`d107f8b0 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x21

0: kd> dt _kqueue ffffd88dfe9cf3c0
ntdll!_KQUEUE
   +0x000 Header           : _DISPATCHER_HEADER
   +0x018 EntryListHead    : _LIST_ENTRY [ 0xffffd88d`fe9cf3d8 - 0xffffd88d`fe9cf3d8 ]
   +0x028 CurrentCount     : 0
   +0x02c MaximumCount     : 4
   +0x030 ThreadListHead   : _LIST_ENTRY [ 0xffffd88d`fd842288 - 0xffffd88d`ff89a908 ]

0: kd> !validatelist ffffd88dfe9cf3c0+30
Found list end after 10 entries
 10個のスレッド数を確認するだけでしたら、このコマンド操作で十分ですが、実務解析作業では次のようなコマンド操作を行い、さらに深層に踏み込むこともあります。
0: kd> dt _io_workitem ffffd88dfe9cf3c0
nt!_IO_WORKITEM
   +0x000 WorkItem         : _WORK_QUEUE_ITEM
   +0x020 Routine          : 0xffffd88d`fe9cf3d8     void  +ffffd88dfe9cf3d8
   +0x028 IoObject         : 0x00000004`00000000 Void
   +0x030 Context          : 0xffffd88d`fd842288 Void
   +0x038 WorkOnBehalfThread : 0xffffd88d`ff89a908 _ETHREAD
   +0x040 Type             : 0
   +0x044 ActivityId       : _GUID {00000000-1000-8948-7c24-184c0e000d02}

0: kd> dt _WORK_QUEUE_ITEM ffffd88dfe9cf3c0
ntdll!_WORK_QUEUE_ITEM
   +0x000 List             : _LIST_ENTRY [ 0x00000000`00100204 - 0xffffd88d`ff5bc300 ]
   +0x010 WorkerRoutine    : 0xffffd88d`ff89a840     void  +ffffd88dff89a840
   +0x018 Parameter        : 0xffffd88d`fe9cf3d8 Void

0: kd> !validatelist poi(0xffffd88dff89a840)
Found list end after 10 entries
 このコマンド操作は、Windowsカーネルアーキテクチャー知識、C++のポインター、および、キャスト(型変換)を応用しています。

 従来はこのレベルの技術習得には海外に頼る必要がありましたが、本「IT談話館」主筆の「豊田孝」はBlackHatなどのカンファレンスでプレゼンする海外の先端技術者に助言を与えています。

 WindowsはSaaSとして提供される時代に入り、その内部は頻繁に更新されています。更新内容の多くは、いろいろな事情から、公にされることはほとんどありません。最新のユーザー空間とカーネル空間に関する信頼できる情報を取得するには、インターネットなどでは語られない高度な内部解析技術が必須とされています。時代が求める人材の育成と技術の習得には、「時間と予算の投資」が必要です。


ビジネスメニュー
Windowsクラッシュダンプ解析サービス 技術資料

Copyright©豊田孝 2004- 2018
本日は2018-12-19です。