04月08, 2013

Dump分析系列二:Boot Camp和某文件系统过滤驱动冲突导致的蓝屏

前段时间,360蓝屏分析哥(@360蓝屏分析专家)给笔者发了个Dump,说发现很多某安全软件和苹果电脑的Boot Camp共存的时候出现蓝屏的案例,看上去是冲突的问题,但不能100%确定原因,于是我们就一起来分析一下。 这是在Win7 X64系统上的产生蓝屏Dump,故障堆栈如下:

2: kd> k
Child-SP RetAddr Call Site
fffff880`0d2a0da8 fffff800`04555cb0 nt!KeBugCheckEx
fffff880`0d2a0db0 fffff800`044d5d6e nt! ?? ::FNODOBFM::`string'+0x4518f
fffff880`0d2a0f10 fffff880`0154f3b4 nt!KiPageFault+0x16e
fffff880`0d2a10a8 fffff880`01555149 AppleHFS+0x23b4
fffff880`0d2a10b0 fffff880`01555054 AppleHFS+0x8149
fffff880`0d2a1130 fffff880`010fbbcf AppleHFS+0x8054
fffff880`0d2a1170 fffff880`010feaea fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x24f
fffff880`0d2a1200 fffff880`011344f2 fltmgr!FltPerformSynchronousIo+0x2ca
fffff880`0d2a12a0 fffff880`086cb7c9 fltmgr!FltQueryInformationFile+0x52
fffff880`0d2a12e0 fffff880`086cd295 <安软模块>+0x117c9
fffff880`0d2a1380 fffff880`086ccb2a <安软模块>+0x13295
fffff880`0d2a1410 fffff880`010fb067 <安软模块>+0x12b2a
fffff880`0d2a1440 fffff880`010fd9aa fltmgr!FltpPerformPreCallbacks+0x2f7
fffff880`0d2a1540 fffff880`0111b2a3 fltmgr!FltpPassThroughInternal+0x4a
fffff880`0d2a1570 fffff800`047da0fc fltmgr!FltpCreate+0x293
fffff880`0d2a1620 fffff800`047d5a78 nt!IopParseDevice+0x14d3
fffff880`0d2a1780 fffff800`047d6c96 nt!ObpLookupObjectName+0x588
fffff880`0d2a1870 fffff800`047d859c nt!ObOpenObjectByName+0x306
fffff880`0d2a1940 fffff800`047e3b64 nt!IopCreateFile+0x2bc
fffff880`0d2a19e0 fffff800`044d6ed3 nt!NtCreateFile+0x78

可以看到,最终蓝屏故障发生在AppleHFS.sys这个驱动上,这是MAC电脑的Boot Camp里的文件系统驱动,用于在Windows操作系统下访问苹果文件系统(HFS)分区。 从Dump上可以看到,出问题的AppleHFS是2012年8月的,还算比较新:

2: kd> lmvm applehfs
start end module name
fffff880`0154d000 fffff880`01560000 AppleHFS (no symbols) 
Loaded symbol image file: AppleHFS.sys
Image path: SystemRootSystem32DriversAppleHFS.sys
Image name: AppleHFS.sys
Timestamp: Thu Aug 02 06:12:18 2012 (5019A9C2)

我们来看出问题的故障代码:

2: kd> ub applehfs+23b4+6 l8
AppleHFS+0x239c:
fffff880`0154f39c 488902 mov qword ptr [rdx],rax
fffff880`0154f39f 813805baecfd cmp dword ptr [rax],0FDECBA05h
fffff880`0154f3a5 7429 je AppleHFS+0x23d0 (fffff880`0154f3d0)
fffff880`0154f3a7 eb13 jmp AppleHFS+0x23bc (fffff880`0154f3bc)
fffff880`0154f3a9 488b4118 mov rax,qword ptr [rcx+18h]
fffff880`0154f3ad 4883c0f8 add rax,0FFFFFFFFFFFFFFF8h
fffff880`0154f3b1 488902 mov qword ptr [rdx],rax
fffff880`0154f3b4 813803baecfd cmp dword ptr [rax],0FDECBA03h

最后一行就是发生故障的代码,代码的意图是rcx+0x18取出到rax,然后rax + fffffffffffffff8 (即减去8),然后再访问rax所在地址 通过查看trap frame内的寄存器状况,我们可以看到 rax=fffffffffffffff8 rbx=0000000000000000 rcx=fffffa800790a490 rax= fffffffffffffff8,所以就访问到无效的地址了,因此也可以知道rax在做减法之前即rcx+0x18的地方=0 再验证一下rcx+0x18是否为0,果然没错:

2: kd> dq fffffa800790a490+18 l1
fffffa80`0790a4a8 00000000`00000000

通过分析AppleHFS.SYS的代码可知,蓝屏的位置是在处理IRP_MJ_QUERY_VOLUME_INFORMATION的例程中,出问题的这个函数的参数rcx是从发送的IO请求包中,通过 IoGetCurrentStackLocation(Irp)->FileObject,获得当前StackLocation中的FileObject。 rcx= FileObject,可以通过!thread获得当前线程Irp后,验证一下:

2: kd> !thread
THREAD fffffa8007fefb50 Cid 11d0.15b0 Teb: 000000007efdb000 Win32Thread: fffff900c2628c20 RUNNING on processor 2
IRP List:
fffffa80083aa4d0: (0006,03a0) Flags: 00000884 Mdl: 00000000

2: kd> !irp fffffa80083aa4d0
Irp is active with 10 stacks 10 is current (= 0xfffffa80083aa828)
No Mdl: No System Buffer: Thread fffffa8007fefb50: Irp stack trace. 
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[ 0, 0] 0 1 fffffa8008fad310 **fffffa800790a490** 00000000-00000000 pending
FileSystemFltMgr
Args: fffff8800d2a1728 05000060 00000082 00000000

我们可以看到,当前的IrpStackLocation的FileObject确实是fffffa800790a490 接着我们看一下这个FileObject的结构和数据:

kd> dt _FILE_OBJECT fffffa800790a490
nt!_FILE_OBJECT
+0x000 Type : 0n5
+0x002 Size : 0n216
+0x008 DeviceObject : 0xfffffa80`08606cd0 _DEVICE_OBJECT
+0x010 Vpb : (null) 
**+0x018 FsContext : (null)** 
+0x020 FsContext2 : (null) 
+0x028 SectionObjectPointer : (null) 
+0x030 PrivateCacheMap : (null) 
+0x038 FinalStatus : 0n0
+0x040 RelatedFileObject : (null) 
+0x048 LockOperation : 0 ''
+0x049 DeletePending : 0 ''
+0x04a ReadAccess : 0 ''
+0x04b WriteAccess : 0 ''
+0x04c DeleteAccess : 0 ''
+0x04d SharedRead : 0 ''
+0x04e SharedWrite : 0 ''
+0x04f SharedDelete : 0 ''
+0x050 Flags : 2
+0x058 FileName : _UNICODE_STRING "data.txt"
+0x068 CurrentByteOffset : _LARGE_INTEGER 0x0
+0x070 Waiters : 0
+0x074 Busy : 0
+0x078 LastLock : (null) 
+0x080 Lock : _KEVENT
+0x098 Event : _KEVENT
+0x0b0 CompletionContext : (null) 
+0x0b8 IrpListLock : 0
+0x0c0 IrpList : _LIST_ENTRY [ 0xfffffa80`0790a550 - 0xfffffa80`0790a550 ]
+0x0d0 FileObjectExtension : (null)

0x18这个位置(也就是FileObject->FsContext)果然为空,那么为什么这个地方为空会导致AppleHFS蓝屏呢,简单分析AppleHFS的代码可知,苹果的这个驱动程序的IRP_MJ_CREATE会为每个创建在其磁盘上的文件对象都设置FsContext以索引FCB(文件控制块)相关数据,因此在其IRP_MJ_QUERY_VOLUME_INFORMATION认为,创建的文件对象既然来自AppleHFS,那么这里FsContext一定不会空。 在通常的情况下,这样的假设是没问题的,但是这个Dump的问题是,安全软件的驱动程序在中间拦截了一道,导致了文件系统未能预期的情况发生。这个驱动是安全软件的监控驱动,会注册MiniFilter(文件系统微过滤驱动),并在PreCreate(预创建)的例程中,直接对文件对象调用FltQueryInformationFile,最终发送IRP_MJ_QUERY_VOLUME_INFORMATION到文件系统驱动上。 由于这个时间点是在Create请求发生之前,Windows内核的IO管理器刚刚为这个文件请求创建了文件对象,文件对象还未真正送达文件系统,因此这个文件对象也就不会有FsContext的存在,其他一些数据例如VPB也都没有填充,对这个文件对象发送QueryVolumeInformation请求是没有什么意义的,不过在通常我们使用的,微软编写的比较健壮的文件系统驱动上(例如Ntfs/FastFat),这样请求并没有什么负面的影响,但是对于AppleHFS这类编写得不那么谨慎的文件系统驱动,就会导致蓝屏的结果。 从这个问题本身来说,苹果和安全软件的驱动开发者都有一定的问题,编写的代码不够严谨,最终引发兼容的问题,双方都有一定责任,但这里,应该说安全软件的责任更多一些,AppleHFS毕竟是用户使用的文件系统驱动,作为第三方的安全软件,应该尽量兼容系统级的驱动。

本文链接:http://blogs.360.cn/post/dump-analyze-2-boot-camp-and-fsfilter-bosd.html

-- EOF --

Comments