Windows Kernel是否可以免受用户模式中可能发生的损坏

Ste*_*and 3 c++ windows kernel windbg corruption

我目前正在使用liveKD执行内核调试.

在我发生阻塞的所有情况下(一个::CloseHandle()永不返回的函数调用)我碰巧有一个堆栈跟踪,它在内核中阻塞了synchronisationEvent.

但是当我这样做时,!object 12345678如果123456789是我synchronisationEvent在流程的线程信息中报告的,它说Not a valid object (ObjectType invalid).

我担心在用户模式下我们的应用程序级别的损坏是否会破坏内核?Windows是否能保证内存空间的分离能阻止类似内容的发生?

应用程序的代码密集使用C++,COM/DCOM和Win32.


一条评论要求提供有关stacktrace和句柄类型的更多信息.在这种情况下,它与串行COM端口有关.但我想我也有它用于文件句柄(尚未调试那些情况)这是我有的堆栈跟踪:

        THREAD 856a2d48  Cid 0660.0350  Teb: 7ff25000 Win32Thread: ffaaedd8 WAIT: (Executive) KernelMode Non-Alertable
            860c6f9c  SynchronizationEvent
        IRP List:
            babea5d8: (0006,01d8) Flags: 00000404  Mdl: 00000000
        Not impersonating
        DeviceMap                 89809fc8
        Owning Process            86212d40       Image:         DataCaptorIS.exe
        Attached Process          N/A            Image:         N/A
        Wait Start TickCount      27315407       Ticks: 6067021 (1:02:17:26.134)
        Context Switch Count      2259           IdealProcessor: 0
        UserTime                  00:00:04.976
        KernelTime                00:00:02.184
        Win32 Start Address 0x775c03e9
        Stack Init 8aa0dfd0 Current 8aa0da98 Base 8aa0e000 Limit 8aa0b000 Call 0
        Priority 9 BasePriority 8 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5
        ChildEBP RetAddr  Args to Child
        8aa0dab0 824bfced 856a2d48 00000000 8ab00120 nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4])
        8aa0dae8 824beb4b 856a2e08 856a2d48 860c6f9c nt!KiSwapThread+0x266
        8aa0db10 824b856f 856a2d48 856a2e08 00000000 nt!KiCommitThreadWait+0x1df
        8aa0db88 914539fb 860c6f9c 00000000 00000000 nt!KeWaitForSingleObject+0x393
        8aa0dbcc 82478c1e 860c6f98 babea5d8 babea73c serial!SerialClose+0x332 (FPO: [Non-Fpo])
        8aa0dbe4 886206b9 babea5d8 861986d0 bc859308 nt!IofCallDriver+0x63
        8aa0dc08 82478c1e 861986d0 860c6890 00000800 serenum!Serenum_CreateClose+0x77 (FPO: [Non-Fpo])
        8aa0dc20 82673be6 84aa7a00 bc8592f0 00000000 nt!IofCallDriver+0x63
        8aa0dc64 826647c9 bc859308 bc859308 bc8592f0 nt!IopDeleteFile+0x10c
        8aa0dc7c 824ba1e0 00000000 856a2d48 bc8592f0 nt!ObpRemoveObjectRoutine+0x59
        8aa0dc90 824ba150 bc859308 82687556 960a5578 nt!ObfDereferenceObjectWithTag+0x88 (FPO: [0,0,3])
        8aa0dc98 82687556 960a5578 856a2d48 00000c80 nt!ObfDereferenceObject+0xd (FPO: [0,1,0])
        8aa0dcdc 8268727c 960a5578 a7d21900 86212d40 nt!ObpCloseHandleTableEntry+0x21d
        8aa0dd0c 82687616 86212d40 856a2d01 0763f3b4 nt!ObpCloseHandle+0x7f
        8aa0dd28 8247f8a6 00000c80 0763f3b8 775d7094 nt!NtClose+0x4e
        8aa0dd28 775d7094 00000c80 0763f3b8 775d7094 nt!KiSystemServicePostCall (FPO: [0,3] TrapFrame @ 8aa0dd34)
WARNING: Frame IP not in any known module. Following frames may be wrong.
        0763f3b8 00000000 00000000 00000000 00000000 0x775d7094

synchronisationEvent堆栈跟踪表明线程正在等待860c6f9c.

该命令kd> !object 860c6f9c返回Not a valid object (ObjectType invalid).我不知道这是否意味着synchronisationEvent内核中的损坏.当我在该进程的其他synchronisationEvent上应用该命令时,我得到一个输出,如下所示:

0: kd> !object 95369c68
Object: 95369c68  Type: (84aa6378) Event
    ObjectHeader: 95369c50 (new version)
    HandleCount: 1  PointerCount: 2

在应用程序级别,在usermode中,这种情况发生在应该取消并清除任何IRP的那种代码之后:

::CancelIoEx(m_handle_to_serial_port_com);
WaitForRequestToComplete(); // our function calls ::GetOverlappedResult(..., bWait) for any OVERLAPPED that was pending, with bWait == TRUE

::PurgeComm(m_handle_to_serial_port_com);
WaitForRequestToComplete(); // our function calls ::GetOverlappedResult(..., bWait) for any OVERLAPPED that was pending, with bWait == TRUE

::CloseHandle(m_handle_to_serial_port_com); // the closeHandle which never returns
Run Code Online (Sandbox Code Playgroud)

问题真的是随机发生的.有时它需要几天才能重现.


显示synchronisationEvent对象的内存地址86184f9c(在另一台具有相同错误的计算机上):

0: kd> dp 86184f9c - @@c++(sizeof(nt!_object_header) - #RTL_FIELD_SIZE(nt!_object_header, Body)) 
86184f84  00000006 00000000 00000000 00000000
86184f94  00000000 00000001 00040001 00000000
86184fa4  85917420 85917420 00000000 00000000
86184fb4  00000000 00000000 00000000 0000000d
86184fc4  86184890 00000040 00000000 00000800
86184fd4  00000000 85747a68 00000000 00000000
86184fe4  00000000 00000000 86184fec 86184fec
86184ff4  86184ff4 86184ff4 96d4c000 040d0000

并尝试显示对象标题:

0: kd> dt nt!_object_header 86184f9c - @@c++(sizeof(nt!_object_header) - #RTL_FIELD_SIZE(nt!_object_header, Body))
Cannot find specified field members.

atk*_*atk 5

这绝对应该是.如果内核在用户模式下可以破坏,那么您将遇到可能会影响计算机上所有用户的安全漏洞.您可以通过使内核崩溃来拒绝服务.您可以通过利用内核缓冲区溢出来提升权限.您可以通过使用内核信息泄露漏洞窃取其他人的数据.

仅仅因为你给内核提供了不好的数据并不意味着它有这样的缺点.内核可能足够智能以检测和防止此类问题,或者它可能执行任何可能遭受用户空间中的用户态输入损坏的代码.

如果您确实发现了一个让您崩溃内核的错误,请读取传递给内核的其他人的数据或类似内容,那么您应该将其报告给Microsoft.如果您怀疑自己找到了某些内容,请尝试与MS支持人员联系,看看他们是否可以提供帮助.他们是操作系统的专家,并且最有可能确定您的可疑缺陷是否是真正的缺陷.