「Windowsメモリダンプ解析サービス」のご案内
豊田孝の「IT談話館」 Windowsメモリダンプ解析を依頼する




本記事は、書籍 「インサイド Microsoft Windows」 程度の基礎知識をお持ちの方を想定しています。

講演申し込み



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


 WindowsはSaaSとして提供される時代に入り、その内部は頻繁に更新されています。更新内容の多くは、いろいろな事情と理由から、公にされることはほとんどありません。
 Windows 10の短周期の内部更新は、性能向上と互換性維持に加え、ML/DL/AI時代への対応と位置付けられています。簡単に表現すれば、Windows 10はCloudサービスと連携しながらBig Dataを収集・蓄積する「ソフトウェアセンサー」、という役割を担っています。本「IT談話館」は、そのソフトウェアセンサーのユーザー空間とカーネル空間を独自の解析コードで詳しく解析する技術を保有し、「Windowsメモリダンプ解析サービス」を提供しています。
 メモリダンプを解析すると、システム内の「異様な動き」を検出・解析することができます。「異様な動き」の中には、システムパフォーマンスの低下、既存アプリの動作異常、あるいは、セキュリティー脅威なども含まれます。本館サービスをご利用の際には、所属チーム内でご協議の上、「ご連絡」ください。

 セキュリティーの視点からWindows10ソフトウェアセンサーを見た場合、本「IT談話館」の確認範囲では、次のような保護メカニズム階層が考案・実装されています。下記リンクはすべて本館記事を指しています。
  1. Silo/Server Silo
  2. Job
  3. Session
  4. Protected Process
  5. Mandatory Integrity Control(MIC)
  6. Windows API(+CPU)
  7. CPU

 本稿は「WinDbgとWindowsカーネルアーキテクチャー(基礎)」の続編であり、上記のJobオブジェクトとWindows Siloの関係を解析します。その他のオブジェクトやアーキテクチャーの基礎に関しては、本「IT談話館」の別稿「プロ向けのWindowsメモリ内部解析技術資料(応用)」や「基礎編」に目を通すとよろしいかもしれません。

 Siloという用語は、Server Silo、Container、Docker、Jobオブジェクト、プロセスオブジェクト、スレッドオブジェクト、セッションオブジェクトなどの多くの用語との関係の中で使用されています。実を言いますと、本館はSiloの実装実情を知りません。また、Siloに起因するクラッシュダンプ解析やシステム異常分析などの経験もありません。ただ、次のようなカーネル内部情報を見ると、SiloとJobオブジェクトの微妙な関係を推察することはできます。
3: kd> vertarget
Windows 10 Kernel Version 14393 MP (4 procs) Free x64
Product: Server, suite: TerminalServer SingleUserTS
Built by: 14393.2068.amd64fre.rs1_release.180209-1727
Machine Name:
Kernel base = 0xfffff803`c381d000 PsLoadedModuleList = 0xfffff803`c3b251a0
Debug session time: Mon Jun 25 16:16:23.767 2018 (UTC + 9:00)
System Uptime: 2 days 20:12:55.966
3: kd> dt _ejob parent*
nt!_EJOB
   +0x420 ParentJob : Ptr64 _EJOB
   +0x428 ParentSilo : Ptr64 _EJOB
 
 3: kd> dt _ejob server*
nt!_EJOB
   +0x4e8 ServerSiloGlobals : Ptr64 _ESERVERSILO_GLOBALS
 この内部情報は、SiloとJobオブジェクトの間に微妙な関係のあることを示唆しています。また、SiloにはServer Siloという異なる概念を持つSiloが存在していることも分かります。これらの前提は自然に導き出せるものですが、このメモリダンプが採取されたWindows 10ビルド環境よりも新しいビルド環境で採取されたメモリダンプには次のような異なる情報が記録されています。
1: kd> vertarget
Windows 10 Kernel Version 17134 MP (2 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 17134.1.amd64fre.rs4_release.180410-1804
Machine Name:
Kernel base = 0xfffff802`9ea1b000 PsLoadedModuleList = 0xfffff802`9edc9150
Debug session time: Sun Mar 10 06:57:53.854 2019 (UTC + 9:00)
System Uptime: 2 days 22:17:18.721
1: kd> dt _ejob parent*
ntdll!_EJOB
   +0x430 ParentJob : Ptr64 _EJOB
   +0x51c ParentLocked : Pos 0, 1 Bit

1: kd> dt _ejob server*
ntdll!_EJOB
   +0x4e8 ServerSiloGlobals : Ptr64 _ESERVERSILO_GLOBALS
 ご覧のように、「ParentSilo」というフィールドの姿が消えています。念のため、さらに新しいビルド環境で採取されたメモリダンプの内部を見てみます。
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
0: kd> dt _ejob parent*
nt!_EJOB
   +0x430 ParentJob : Ptr64 _EJOB
   +0x51c ParentLocked : Pos 0, 1 Bit
   
0: kd> dt _ejob server*
nt!_EJOB
   +0x4e8 ServerSiloGlobals : Ptr64 _ESERVERSILO_GLOBALS
 「ParentSilo」フィールドの姿はありません。この事実から、「ParentSilo」という概念は今後使用しない方針が確定したことが推察されます。ここで、次のような基本的な疑問が沸きます。  この疑問は自然に湧き出た基本的なものです。基本的な疑問への回答を見い出すのは意外と骨が折れるものですが、Windowsカーネル内部の解析に慣れると、次のようなカーネル関数の内容を覗き見る癖が身に付きます。
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

0: kd> uf nt!PsGetCurrentSilo
nt!PsGetCurrentSilo:
fffff802`6e43e610 65488b0c2588010000 mov   rcx,qword ptr gs:[188h]
fffff802`6e43e619 488b81d8070000  mov     rax,qword ptr [rcx+7D8h]
fffff802`6e43e620 4883f8fd        cmp     rax,0FFFFFFFFFFFFFFFDh
fffff802`6e43e624 7513            jne     nt!PsGetCurrentSilo+0x29 (fffff802`6e43e639)  Branch

nt!PsGetCurrentSilo+0x16:
fffff802`6e43e626 488b8120020000  mov     rax,qword ptr [rcx+220h]
fffff802`6e43e62d 488b80b8030000  mov     rax,qword ptr [rax+3B8h]
fffff802`6e43e634 4885c0          test    rax,rax
fffff802`6e43e637 7507            jne     nt!PsGetCurrentSilo+0x30 (fffff802`6e43e640)  Branch

nt!PsGetCurrentSilo+0x29:
fffff802`6e43e639 c3              ret  Branch

nt!PsGetCurrentSilo+0x30:
fffff802`6e43e640 f7801805000000000040 test dword ptr [rax+518h],40000000h
fffff802`6e43e64a 75ed            jne     nt!PsGetCurrentSilo+0x29 (fffff802`6e43e639)  Branch

nt!PsGetCurrentSilo+0x3c:
fffff802`6e43e64c 488b8030040000  mov     rax,qword ptr [rax+430h]
fffff802`6e43e653 4885c0          test    rax,rax
fffff802`6e43e656 74e1            je      nt!PsGetCurrentSilo+0x29 (fffff802`6e43e639)  Branch

nt!PsGetCurrentSilo+0x48:
fffff802`6e43e658 ebe6            jmp     nt!PsGetCurrentSilo+0x30 (fffff802`6e43e640)  Branch
 この関数は、次のような経路をたどりながら、目的の「CurrentSilo」を探し出しています。
0: kd> dt _ethread silo*
ntdll!_ETHREAD
   +0x7d8 Silo : Ptr64 _EJOB
 
 0: kd> dt _kthread process*
ntdll!_KTHREAD
   +0x074 ProcessDetachActive : Pos 11, 1 Bit
   +0x078 ProcessStackCountDecremented : Pos 20, 1 Bit
   +0x220 Process : Ptr64 _KPROCESS

0: kd> dt _eprocess job*
ntdll!_EPROCESS
   +0x308 JobNotReallyActive : Pos 0, 1 Bit
   +0x3b8 Job : Ptr64 _EJOB
   +0x470 JobLinks : _LIST_ENTRY
   +0x6fc JobVadsAreTracked : Pos 3, 1 Bit
   
0: kd> dt _ejob parent*
ntdll!_EJOB
   +0x430 ParentJob : Ptr64 _EJOB
   +0x51c ParentLocked : Pos 0, 1 Bit
 最終的には、Jobオブジェクトの「ParentJob」フィールド値を「CurrentSilo」として返しています。

 以上の結果を見ますと、SiloとはJobオブジェクトの「ParentJob」フィールドに設定されるオブジェクトであることが分かりました。また、SiloはServer Siloとは異なるオブジェクトであることも同時に分かりました。

 SiloやServer Siloに起因する障害の解析や動作異常分析を進める場合には、次のようなカーネル関数を調査しておくとよいでしょう。本「IT談話館」はすでに調査済みであり、解析依頼の到着を待っている状態です。
0: kd>  x nt!*process*silo*
fffff802`6e468658 nt!PsIsProcessInSilo (void)
fffff802`6ea10450 nt!PspEstimateNewProcessServerSilo (void)
fffff802`6ecc5fd0 nt!PsIsProcessInAppSilo ()
fffff802`6e467ed0 nt!PsGetProcessServerSilo ()
fffff802`6e707820 nt!PsGetProcessSilo ()

0: kd>  x nt!*thread*silo*
fffff802`6e468674 nt!PsIsThreadInSilo (void)
fffff802`6e402880 nt!PsIsCurrentThreadInServerSilo ()
fffff802`6e4024f0 nt!PsGetThreadServerSilo ()

0: kd>  x nt!*job*silo*
fffff802`6ea6cc10 nt!PspValidateJobAssignmentSiloPolicy (void)
fffff802`6e595fec nt!EtwTraceJobServerSiloMonitorCallback (void)
fffff802`6e4cc990 nt!PspJobIsSilo ()
fffff802`6ecc9a00 nt!PspSetJobSiloThreadImpersonationPolicy ()
fffff802`6ecf53b0 nt!EtwTraceJobServerSiloStateChange ()
fffff802`6e708350 nt!PsGetJobSilo ()
fffff802`6e797940 nt!JobServerSiloStateChange = 
fffff802`6e70744c nt!PspJobIsAppSilo ()
fffff802`6e708320 nt!PsGetJobServerSilo ()
fffff802`6e70737c nt!PspGetJobSilo ()

0: kd>  x nt!*session*silo*
fffff802`6ea73134 nt!SepReferenceLogonSessionSilo (void)
fffff802`6ece25bc nt!SepDeleteUnreferencedLogonSessionsInSilo ()
fffff802`6e566b3c nt!MmIsSessionInCurrentServerSilo ()
 従来はこのレベルの技術の習得には海外の資料や人材に頼る必要がありましたが、本「IT談話館」主筆の「豊田孝」はBlackHatなどのカンファレンスでプレゼンする海外の先端技術者に助言を与えています。時代が求める人材の育成と技術の習得には、「時間と予算の投資」が必要です。

Windowsセキュリティーメカニズム




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

講演申し込み




本「IT談話館」は書籍 「インサイド Microsoft Windows」 程度の基礎知識をお持ちの方々を想定しています。
プロ向けのWindowsメモリ内部解析技術資料

Copyright©豊田孝 2004- 2020
本日は2020-04-07です。