Windows蓝屏分析
蓝屏死机(英语:Blue Screen of Death,缩写为:BSoD)指的是微软Windows 操作系统在无法从一个系统错误中恢复过来时所显示的屏幕图像。
先抛出来解决方案:
- 卸载最近一次的Windows更新,并尝试加载最近一次正常启动时的注册表
- 卸载最近安装的驱动程序或者尝试升级/降级该驱动
- 移除最近添加的硬件设备
- 将QQ更换为Windows Store的UWP版本并移除所有第三方杀毒软件
- 运行sfc /scannow以检查系统镜像
- 重装系统
- 重买电脑
若无法正常启动,请尝试进入安全模式或者PE进行操作。
所以定期备份是个很好的习惯!本文中需要额外下载的示例或者资料,均可与此处下载。
背景
首先需要说明的是,Windows蓝屏是一种系统保护机制(可以把Windows蓝屏比喻成感冒/发烧),是Windows为保护硬件及数据的策略,当发生诸如内存非法访问,堆栈溢出等错误而Windows无法处理时,Windows将主动崩溃。虽然蓝屏的原因有很多,但其一定发生在内核层(Ring 0)。
crash type:
0x01: High IRQL fault (Kernel-mode)
0x02: Buffer overflow
0x03: Code overwrite
0x04: Stack trash
0x05: High IRQL fault (User-mode)
0x06: Stack overflow
0x07: Hardcoded breakpoint
0x08: Double Free
以上是NotMyFault列举的常见Windows崩溃原因。
崩溃分析
当Windows崩溃时,显示器会切换至低分辨率下的VGA显示模式,显示蓝色背景并给出停止代码与建议,当Dump文件转存完毕后,系统将自动进行重启。
蓝屏代码
我们可以根据Windows蓝屏时候的错误代码进行初步判断,但无法将错误定位到具体驱动或者进程。蓝屏恢复方法可以参考微软官方指引,具体错误代码可以查阅此网站或者查阅前文资料中的Code Lists。至于我为什么不贴中文译版,因为翻译实在太烂了。
Dump分析
很不幸的是,很多时候蓝屏代码并不能帮助你准确定位问题,以便解决具体的进程或者驱动。这个时候我们需要分析Windows的内存崩溃转储文件来得出具体结论,这里的内核Dump文件即为发生崩溃时内存的部分/完整内容拷贝,具体步骤如下文所述。
创建转储文件
在Control Panel\System and Security\System的Advanced system settings选项,Advanced选项卡,Startup and Recovery选项下便可设置。
拉开Write debugging information选项即可查看转储内存类型:None/Small/Kernel/Complete/Automatic/Active。
类型 | 含义 |
---|---|
None | 不创建转储日志 |
Small | 仅保留基本信息,引起崩溃的线程内核栈与关联内存栈 |
Kernel | 保留当前运行时的进程列表,堆栈以及驱动程序列表 |
Complete | 记录Windows崩溃时能够访问的所有内存 |
Automatic | 类似Kernel,但在Paging file大小存在差异 |
Active | 类似Complete,但初步筛选故障Pages |
下载工具
WinDbg
目前微软发布WinDbg主要借助Windows SDK,安装可以参考文档,或者使用我提供的离线包。
WinDbg Preview
预览版为UWP应用,可直接于Microsoft Store直接下载。
Tips:如果你需要参考其它指南的话,建议安装前者,网络上大多资料均介绍此版本,不过二者差距较小,当然我很喜欢后者。
Symbols配置
When applications, libraries, drivers, or operating systems are linked, the linker that creates the .exe and .dll files also creates a number of additional files known as symbol files.
在崩溃分析中,我们可以使用Symbols来定位Windows原生应用或者内容发生崩溃时的具体进程,驱动,函数。配置Symbols有若干方法,以下推荐两种,请根据实际条件选择:
- 配置环境变量在本地缓存并指向Symbols公共服务器,新建系统系统变量,名称设置为_NT_SYMBOL_PATH,变量值为SRV*c:\symbol*http://msdl.microsoft.com/download/symbols ,其中SRV*与*http://… 之间的路径为Symbols文件在本地的缓存路径,例如我的缓存路径为c:\symbol。
该句的意思即告诉WinDbg,Symbols文件位于c:\symbol,当在该路径下无法寻找到目标Symbols时,主动从http://msdl.microsoft.com/download/symbols 下载缓存。
重启系统后生效,在这里分享一个技能点,在cmd中输入set PATH=C:
后关闭cmd即可使环境变量在Windows不重启的情况下生效。 - 借助dbgcmd(注意不是cmd),输入
.symfix+ c:\symbol
即可将当前Workspace的Symbols指向c:\symbol,之后再使用.sympath
即可输出当前Symbols的配置路径,最后reload
便可开始根据当前系统版本同步Symbols,如果一切正常,你会在C:\symbol目录下看到下载的文件。
1 | 0: kd> .symfix c:\symbol |
配置好的测试页面会出现类似下图的提示,Symbol search path is: SRV\*c:\symbol\* http://msdl.microsoft.com/download/symbols。
Tips:
- !目前msdl服务器似乎被墙了,请将代理置为全局。
- 下载Symbols的过程中左下角会提示当前下载的任务名称,右侧会出现进度条,如果没有,请检查网络。
- !!!网络问题很重要
- 如果安装过程中遇到困难,请尝试将WinDbg的安装目录添加到环境变量中,以便寻找到SYMSRV.DLL和SYMSTORE.EXE。然而,我无法寻找到UWP版本的安装目录,请安装上文提到的第一个版本的WinDbg。
Dump分析
把文件丢进WinDbg等待Symbols下载完成后便可开始分析,如果你运气够好,初步的分析下,你可能会看到“Probably caused by *”的文本,基本上即为出现问题的具体驱动/进程了。
如果没有分析结果,或者全部指向ntoskrnl类似的内核程序时,我们需要考虑进一步分析。在dbgcmd中输入!analyze -v
便可开始进一步分析,我们可能会看到类似如下的Stack_text调用情况。
计算机中的Stack向低地址方向生长,于是从下至上分析,可以看到是nvlddmkm先后调用了dxgkrnl的DpiDispatchPower,DpiFdoDispatchPower,DpiFdoHandleDevicePower函数,在调用DpiFdoHandleDevicePower后即引发了watchdog.exe,随后NT内核的KeBugCheckEx启动,引发蓝屏。我们可以推测出出错的程序可能是dxgkrnl或者nvlddmkm,即DirectX程序,nVidia驱动程序。因此建议对DX进行修复,对N卡驱动进行升/降级。
从文件末尾的MODULE_NAME可以看到端倪,基本判断问题为DirectX程序与nVidia驱动的不兼容。
我们随后又进行了验证,dbgcmd中输入!process
即可开始验证。
在这里我们较为关注Image: System
这句与ReadMemory error: Cannot get nt!KeMaximumIncrement value.
fffff78000000000: Unable to get shared data
基本判断为栈溢出。
驱动判断
你可以使用Google来搜索该驱动属于何种设备,并尝试更新/回退。当Google搜索不到一些冷门硬件时,我们需要使用lm(list module),使用命令lm kv m nvlddmkm
(k——kernel,内核;v——verbose,详细;m——match,匹配)来列出该模块的具体信息。上图中,我们可以看到列出了该模块的时间戳,路径,名称,校验码等。同时,通过查阅主机的注册表我们也可以得出具体路径以及设备。
作死之路
如果你想要更多的Dump来分析,请左转Microsoft Community,我在我的附件里(前文可下载)附上了9份Dump文件,本次分析的文件结果也已导出为html格式,于附件中。
。
。
。
。
。
。
如果你想变得更强大,欢迎阅读书籍《深入解析Windows操作系统》,绝对是一本好书,就是有“点”厚?!
本文标题:Windows蓝屏分析
文章作者:Raincorn
发布时间:2019-12-21
最后更新:2020-07-28
原始链接:https://blog.raincorn.top/2019/12/21/Windows_Blue_Screen_Of_Death/
版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可