Windows10 BSOD分析
近期突然曝出能够让Windows10系统拒绝服务的蓝屏符号链接:\.\globalroot\device\condrv\kernelconnect,只要在Google浏览器中输入这串字符串,电脑就会崩溃。上手就试,啪,很快啊~就崩溃了
注意到发生崩溃的驱动文件是
c
o
n
d
r
v
.
s
y
s
\textcolor{orange}{condrv.sys}
condrv.sys。打开内核调试器,重新尝试。
根据调用栈分析,在浏览器中输入这串字符串的时候,浏览器调用了
G
e
t
F
i
l
e
A
t
t
r
i
b
u
t
e
s
(
)
\textcolor{cornflowerblue}{GetFileAttributes()}
GetFileAttributes(),对应的内核函数为
N
t
Q
u
e
r
y
F
u
l
l
A
t
t
r
i
b
u
t
e
s
F
i
l
e
(
)
\textcolor{cornflowerblue}{NtQueryFullAttributesFile()}
NtQueryFullAttributesFile()并最终在
c
o
n
d
r
v
!
C
d
p
D
i
s
p
a
t
c
h
C
l
e
a
n
u
p
(
)
\textcolor{cornflowerblue}{condrv!CdpDispatchCleanup()}
condrv!CdpDispatchCleanup()中发生崩溃。
原因就是访问了空指针!对应的伪代码:
是什么导致这个空指针的出现?回过头来看到路径中的KernelConnect,通过交叉引用来到了
C
d
C
r
e
a
t
e
K
e
r
n
e
l
C
o
n
n
e
c
t
i
o
n
(
)
\textcolor{cornflowerblue}{CdCreateKernelConnection()}
CdCreateKernelConnection()中
动态调试后发现判断是UserMode的执行模式就会直接返回拒绝类型,关键是
C
d
C
r
e
a
t
e
K
e
r
n
e
l
C
o
n
n
e
c
t
i
o
n
(
)
\textcolor{cornflowerblue}{CdCreateKernelConnection()}
CdCreateKernelConnection()由
v1->MajorFunction[0] = (PDRIVER_DISPATCH)CdpDispatchCreate;
中调用的,而 C d p D i s p a t c h C r e a t e ( ) \textcolor{cornflowerblue}{CdpDispatchCreate()} CdpDispatchCreate()属于 R I P _ M J _ C R E A T E \textcolor{orange}{RIP\_MJ\_CREATE} RIP_MJ_CREATE类型的分发函数。在分发函数中,返回非成功类型的值前都应该进行如下操作:
...
(PRIP)a2->IoStatus.Status = 0;
(PRIP)a2->IoStatus.Information = 0i64;
IofCompleteRequest(a2, 0);//分发完成例程请求
这样就能避免在失败的返回后还能获取到设备的对象。而出问题的代码段中正好少了这一步,导致返回了拒绝访问后还能让调用者获取到设备的对象,此时这个对象并没有被初始化,所以调用者使用完该对象后在释放对象的过程中就访问到了一个野指针,可能是某处对该指针的内存进行了清零,从而导致了这场了灾难!
到这可以说该蓝屏的问题与浏览器没有直接的关系,通过下面这段代码也能触发BSOD:
#include<iostream>
#include<windows.h>
using namespace std;
int main() {
GetFileAttributesW(L"\\\\.\\globalroot\\device\\condrv\\kernelconnect");
return 0;
}