在給各位朋友免費分析 .NET程序 各種故障的同時,往往也會收到各種其他類型的dump,比如:Windows 崩潰,C++ 崩潰,Mono 崩潰,真的是啥都有,由于基礎知識的相對缺乏,分析起來并不是那么的順利,今天就聊一個 Windows 崩潰的內核dump 吧,這個 dump 是前幾天有位朋友給到我的,讓我幫忙看一下,有了dump之后上 windbg 分析。
只要是 Windows 平臺上的崩潰,操作系統都會維護一個 EXCEPTION_POINTERS 結構體,這個結構體的解讀對分析問題非常重要,使用 !analyze -v 命令簡要輸出如下:
2: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
UNEXPECTED_STORE_EXCEPTION (154)
The store component caught an unexpected exception.
Arguments:
Arg1: ffffb402b9851000, Pointer to the store context or data manager
Arg2: ffffe607bc53df30, Exception information
Arg3: 0000000000000002, Reserved
Arg4: 0000000000000000, Reserved
...
EXCEPTION_RECORD: ffffe607bc53eeb8 -- (.exr 0xffffe607bc53eeb8)
ExceptionAddress: fffff80025b04bd0 (nt!RtlDecompressBufferXpressLz+0x0000000000000050)
ExceptionCode: c0000006 (In-page I/O error)
ExceptionFlags: 00000000
NumberParameters: 3
Parameter[0]: 0000000000000000
Parameter[1]: 0000023f30ee99f0
Parameter[2]: 00000000c0000185
Inpage operation failed at 0000023f30ee99f0, due to I/O error 00000000c0000185
EXCEPTION_PARAMETER1: 0000000000000000
EXCEPTION_PARAMETER2: 0000023f30ee99f0
CONTEXT: ffffe607bc53e6f0 -- (.cxr 0xffffe607bc53e6f0)
rax=fffff80025b04b80 rbx=ffff9d808d7fa000 rcx=ffff9d808d7fa000
rdx=ffff9d808d7fa000 rsi=0000000000000002 rdi=0000023f30ee99f0
rip=fffff80025b04bd0 rsp=ffffe607bc53f0f8 rbp=0000023f30eea2fe
r8=0000023f30ee99f0 r9=0000000000000964 r10=ffff9d808d7faea0
r11=0000023f30eea354 r12=ffffe607bc53f368 r13=ffffb402d84d8000
r14=ffff9d808d7fb000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0000 ds=002b es=002b fs=0053 gs=002b efl=00050246
nt!RtlDecompressBufferXpressLz+0x50:
fffff800`25b04bd0 418b08 mov ecx,dword ptr [r8] ds:002b:0000023f`30ee99f0=????????
Resetting default scope
...
從卦中信息看,是由于將地址 0000023f30ee99f0 所映射的物理內存頁換入到內存中,拋了一個IO錯誤,從匯編指令 ecx,dword ptr [r8] ds:002b:0000023f30ee99f0=???????? 上也能看的出來。
如果大家不信,可以用 !vtop 和 !pte 觀察下它們對應的物理地址和物理頁號,都是找不到的。
2: kd> !vtop 0 000000006d34aca0
Amd64VtoP: Virt 000000006d34aca0, pagedir 00000003d81fb002
Amd64VtoP: PML4E 00000003d81fb002
Amd64VtoP: PML4E read error 0x8000FFFF
Virtual address 6d34aca0 translation fails, error 0x8000FFFF.
2: kd> !pte 000000006d34aca0
VA 000000006d34aca0
PXE at FFFF86432190C000 PPE at FFFF864321800008 PDE at FFFF864300001B48 PTE at FFFF860000369A50
contains 0000000000000000
contains 0000000000000000
not valid
有了這個初步信息之后,接下來就來觀察異常時的寄存器上下文和線程棧信息,輸出如下:
2: kd> .cxr 0xffffe607bc53e6f0 ; k
rax=fffff80025b04b80 rbx=ffff9d808d7fa000 rcx=ffff9d808d7fa000
rdx=ffff9d808d7fa000 rsi=0000000000000002 rdi=0000023f30ee99f0
rip=fffff80025b04bd0 rsp=ffffe607bc53f0f8 rbp=0000023f30eea2fe
r8=0000023f30ee99f0 r9=0000000000000964 r10=ffff9d808d7faea0
r11=0000023f30eea354 r12=ffffe607bc53f368 r13=ffffb402d84d8000
r14=ffff9d808d7fb000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0000 ds=002b es=002b fs=0053 gs=002b efl=00050246
nt!RtlDecompressBufferXpressLz+0x50:
fffff800`25b04bd0 418b08 mov ecx,dword ptr [r8] ds:002b:0000023f`30ee99f0=????????
*** Stack trace for last set context - .thread/.cxr resets it
# Child-SP RetAddr Call Site
00 ffffe607`bc53f0f8 fffff800`25a5bc10 nt!RtlDecompressBufferXpressLz+0x50
01 ffffe607`bc53f110 fffff800`25a5bb14 nt!RtlDecompressBufferEx+0x60
02 ffffe607`bc53f160 fffff800`25a5b9a1 nt!ST_STORE<SM_TRAITS>::StDmSinglePageCopy+0x150
03 ffffe607`bc53f220 fffff800`25b56ff0 nt!ST_STORE<SM_TRAITS>::StDmSinglePageTransfer+0xa5
04 ffffe607`bc53f270 fffff800`25b57904 nt!ST_STORE<SM_TRAITS>::StDmpSinglePageRetrieve+0x180
05 ffffe607`bc53f310 fffff800`25b57aed nt!ST_STORE<SM_TRAITS>::StDmPageRetrieve+0xc8
06 ffffe607`bc53f3c0 fffff800`25a5c071 nt!SMKM_STORE<SM_TRAITS>::SmStDirectReadIssue+0x85
07 ffffe607`bc53f440 fffff800`25aad478 nt!SMKM_STORE<SM_TRAITS>::SmStDirectReadCallout+0x21
08 ffffe607`bc53f470 fffff800`25a5cb57 nt!KeExpandKernelStackAndCalloutInternal+0x78
09 ffffe607`bc53f4e0 fffff800`25a5713c nt!SMKM_STORE<SM_TRAITS>::SmStDirectRead+0xc7
0a ffffe607`bc53f5b0 fffff800`25a56b70 nt!SMKM_STORE<SM_TRAITS>::SmStWorkItemQueue+0x1ac
0b ffffe607`bc53f600 fffff800`25b58727 nt!SMKM_STORE_MGR<SM_TRAITS>::SmIoCtxQueueWork+0xc0
0c ffffe607`bc53f690 fffff800`25b2b94b nt!SMKM_STORE_MGR<SM_TRAITS>::SmPageRead+0x167
0d ffffe607`bc53f700 fffff800`25ad1020 nt!SmPageRead+0x33
0e ffffe607`bc53f750 fffff800`25ad023d nt!MiIssueHardFaultIo+0x10c
0f ffffe607`bc53f7a0 fffff800`25a6e818 nt!MiIssueHardFault+0x29d
10 ffffe607`bc53f860 fffff800`25c0b6d8 nt!MmAccessFault+0x468
11 ffffe607`bc53fa00 00007ff8`c3089fa2 nt!KiPageFault+0x358
12 00000067`4ca7f270 00000000`00000000 0x00007ff8`c3089fa2
從卦中的調用棧信息看,代碼的源頭是 用戶態 (0x00007ff8c3089fa2) 過來的,應該是訪問用戶態地址 0000023f30ee99f0 上的內容,由于對應的物理頁不在內存中,觸發了 nt!KiPageFault 中斷,也就是 idt 表中的 0xe號標記的 缺頁中斷, 輸出如下:
lkd> !idt
Dumping IDT: fffff8050ce87000
00: fffff80506206400 nt!KiDivideErrorFault
...
0e: fffff80506209980 nt!KiPageFault
在缺頁中斷中觸發了 IO 操作 MiIssueHardFaultIo 要從pagefiles 中撈頁面,接下來就是頁讀取邏輯 SmPageRead,最后在 RtlDecompressBufferXpressLz 中引發了藍屏。
如果心比較細的話,你會發現有一個關鍵詞 Decompress ,對,就是解壓縮,為什么換入的page還要解壓縮呢? 這就是我們的突破點。
要找到這個問題的答案,需要觀察下這個異常線程的詳細信息,可以用 .thread 切到異常的線程上下文,再用 !thread 觀察。
2: kd> .thread
Implicit thread is now ffffb402`be04a080
2: kd> !thread ffffb402`be04a080
THREAD ffffb402be04a080 Cid 0594.2228 Teb: 000000674c5b8000 Win32Thread: 0000000000000000 RUNNING on processor 2
Not impersonating
GetUlongFromAddress: unable to read from fffff8002641152c
Owning Process ffffb402b8d58080 Image: <Invalid process>
Attached Process ffffb402b984a040 Image: MemCompression
fffff78000000000: Unable to get shared data
Wait Start TickCount 649763
Context Switch Count 9 IdealProcessor: 0
ReadMemory error: Cannot get nt!KeMaximumIncrement value.
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address 0x00007ff8c808afb0
Stack Init ffffe607bc53fb90 Current ffffe607bc53e800
Base ffffe607bc540000 Limit ffffe607bc539000 Call 0000000000000000
Priority 8 BasePriority 7 PriorityDecrement 0 IoPriority 2 PagePriority 2
Child-SP RetAddr : Args to Child : Call Site
ffffe607`bc53de78 fffff800`25d9856e : 00000000`00000154 ffffb402`b9851000 ffffe607`bc53df30 00000000`00000002 : nt!KeBugCheckEx
ffffe607`bc53de80 fffff800`25c189db : ffffb402`b9851000 ffffe607`bc53df30 ffffe607`00000002 ffffe607`bc53dfe0 : nt!SMKM_STORE<SM_TRAITS>::SmStUnhandledExceptionFilter+0x7e
ffffe607`bc53ded0 fffff800`25bcfb1f : fffff800`00000002 fffff800`258d905c ffffe607`bc539000 ffffe607`bc540000 : nt!`SMKM_STORE<SM_TRAITS>::SmStDirectReadIssue'::`1'::filt$0+0x22
ffffe607`bc53df00 fffff800`25c062ff : fffff800`258d905c ffffe607`bc53e4e0 fffff800`25bcfa80 00000000`00000000 : nt!_C_specific_handler+0x9f
...
從卦中信息看,異常線程還有一個附加的進程 ffffb402b984a040,來自于 MemCompression 模塊,從名字上看所謂的 壓縮解壓縮 邏輯應該和它有關系,接下來到網上去搜一下,有一篇文章說的非常好: https://www.howtogeek.com/319933/what-is-memory-compression-in-windows-10/
大意:這是 Windows10 新增的一個功能,用內存壓縮技術讓RAM中可以存儲更多的內存頁,相比傳統的交換到 PageFiles.sys 有更高的性能,缺點就是需要耗費一些解壓縮需要的 CPU 時間。
在 Windows10 上也能窺探一二:
解決辦法很簡單,學 4S 店的問題解決之道,能換的就堅決不修,讓朋友把 內存壓縮 給關掉,這樣就不走
RtlDecompressBufferXpressLz 邏輯,理論上就不會有什么問題了。
關閉之后,據朋友反饋,這幾天沒有崩潰了。
分析內核態相比用戶態難度要大的多,需要對操作系統以及CPU的相關知識有一個比較深度的理解,任重道遠。。。
日前,有報道稱Windows系統出現大面積藍屏現象,隨即沖上熱搜榜首。
本次藍屏事件涉及多個版本的操作系統,用戶在使用過程中,系統突然崩潰,屏幕顯示藍色錯誤信息,導致無法正常工作。這種現象不僅影響了個人用戶,也對企業用戶造成了不小的困擾。日本的列車行駛位置信息因Windows系統故障導致無法獲取,航空、銀行、政府、企業網絡均受到影響。這很容易讓人聯想多年前的永恒之藍事件,再次引發大眾對Windows系統安全性的擔憂。
藍屏原因在于軟件更新
據用戶反饋,本次藍屏事件是新安裝的硬件設備、更新系統版本、更新的驅動程序后出現的。
有人將微軟全球范圍內發生的藍屏問題被確認與CrowdStrike的軟件有關。在CrowdStrike Falcon的Sensor更新之后,內核驅動文件csagent.sys導致全球大面積用戶的 Windows 系統出現藍屏。
就藍屏問題Crowdstrike公司在自動回復中表示:
“Crowdstrike發現Windows主機上出現與Falcon有關的崩潰報告。癥狀包括主機出現與 Falcon 相關的 bugcheckblue 屏幕錯誤。目前我們的工程團隊正在積極解決此問題,無需開立支持工單。我們將在獲得更多信息(包括問題解決的時間)后發布狀態更新。”
微軟的聲明則表示,一部分客戶可能遇到美國中部服務區的多個 Azure 服務出現的問題,包括服務管理操作和服務的連接性或可用性方面的故障。
微軟還表示,我們已經意識到這個問題,已派多個團隊處理問題。我們現已確定了根本原因。一個后端集群管理工作流程部署了一處配置更改,因而導致一部分 Azure 存儲集群和美國中部服務區的計算資源之間的后端訪問被阻止。這導致了與虛擬磁盤失去連接時自動重新啟動計算資源。
簡言之,就是CrowdStrike通過azure云服務獲取配置發布推送,CrowdStrike無法獲取正確的配置文件,然后推送了一份錯誤的更新,錯誤的更新導致藍屏。
其實,這并非微軟云服務首次遭遇大規模宕機。今年1月,微軟云服務就曾發生全球性宕機,影響范圍覆蓋了從Outlook到Teams等一系列服務,
相對于多年前的永恒之藍事件,本次微軟大規模藍屏事件更像是正常軟件更新維護過程中不小心翻車的“事故”。
Windows四處漏風
雖然微軟聲明本次藍屏事件和黑客惡意攻擊無關,但這并不意味著Windows就可以高枕無憂。
根據斯諾登披露的資料,微軟、雅虎、Google、Facebook、Paltalk、YouTube、Skype、美國在線、蘋果等公司先后加入了棱鏡項目為美國政府收集情報。因此,如果在基礎軟硬件上依賴美國科技公司提供的產品,就很難保證國外的軟件或者硬件里沒有刻意植入的后門。像上次的永恒之藍事件就折射出,微軟的操作系統很可能就事先預留了后門。
其實,掌握在美國情報部門手中的殺手锏還有很多。根據維基解密資料,CIA針對從Windows XP覆蓋至Windows 10的間諜攻擊計劃——優先組代號雅典娜,后備組代號赫拉。雅典娜和赫拉由CIA和著名主動式安全軟件公司Siege Technologies合作開發。雅典娜的攻擊范圍從Windows XP至Windows 10;赫拉的的攻擊范圍從Windows 8到Windows10。
根據維基解密介紹:雅典娜和赫拉可以在用戶毫無知覺的情況下取得控制設備的最高權限,并且竊取、或者是刪除特定的文件,亦或者將特定的文件傳送至CIA的服務器。而且雅典娜和赫拉可以無視諸如卡巴斯基這類殺毒軟件或安全工具。
也正是因此,早在2018年,俄羅斯《消息報》發表題為《俄軍對Windows說再見》的報道稱,俄羅斯國防部日前作出正式決定,所有辦公電腦皆將操作系統改為Astra Linux。
關鍵在提升本土技術實力
Windows在過去幾十年里確實服務于中國IT基礎設施建設,廣泛運用于黨政、金融、教育、交通、能源、電信等各個行業,但就當下的國際環境而言,在操作系統上實現國產替代是大勢所趨,特別是在川普被槍擊后,其當選美國下一任總統已經是板上釘釘的事情。一旦川普上臺,勢必進一步強化技術脫鉤。國人必須未雨綢繆,居安思危,加快麒麟等國產操作系統的替換進程。
從根源上說,本次藍屏事件并非Windows獨有,因為這次的問題主要是因為軟件更新導致的。哪怕是使用國產操作系統,只要系統版本更新、驅動更新出了岔子,也會遭遇類似的問題,這就要求我們必須不斷提升自己的能力。安全是一個系統工程,只有不斷提升能力,才能夠在風云詭決的國際環境下巋然不動。