MDL中捕获到损坏的页表页

系统会遇到随机错误检查,内存损坏。有趣的是,腐败有一个非常特殊的模式——它看起来像是一个PFN地址,在这个过程中,标志被随机地放置在页面表页面的几个地方。内存管理器永远不会做这种事情,我怀疑驱动程序正在编辑用户页表页,这是不应该做的。

让我们看看堆栈:

kd> kb
*** Stack trace for last set context - .thread/.cxr resets it
ChildEBP RetAddr Args to Child
f15b1308 80523096 c00862d8 10c5b000 00000000 nt!MiDeletePte+0x198
f15b13d0 80519776 000001d8 10d20fff 00000000 nt!MiDeleteVirtualAddresses+0x164
f15b13ec 805b1d74 10c20000 10d20fff f15b14a4 nt!MiDeleteFreeVm+0x20
f15b148c 8054060c ffffffff 049c6aa8 049c6ab0 nt!NtFreeVirtualMemory+0x42e
f15b148c 7c90eb94 ffffffff 049c6aa8 049c6ab0 nt!KiFastCallEntry+0xfc
03e4a398 7c90da54 7c8209b3 ffffffff 049c6aa8 ntdll!KiFastSystemCallRet
03e4a39c 7c8209b3 ffffffff 049c6aa8 049c6ab0 ntdll!NtFreeVirtualMemory+0xc

以下是虚拟地址的页表条目:

kd> !pte 10c5b000
VA 10c5b000
PDE at 00000000C0600430 PTE at 00000000C00862D8
contains 000000003FC6F867 contains 0000000015E0086F
pfn 3fc6f ---DA--UWEV pfn 15e00 ---DA-TUWEV

这表明值15e0086f未正确放入页表页中。此错误值对应于通过调用MmAllocatePagesForMdl分配的范围的直写映射。

c00862d0 00000000 00000000 15e0086f 00000000
c00862e0 00000000 00000000 00000000 00000000
c00862f0 00000000 00000000 00000000 00000000
c0086300 00000000 00000000 00000000 00000000
c0086310 00000000 00000000 00000000 00000000
c0086320 00000000 00000000 00000000 00000000
c0086330 00000000 00000000 00000000 00000000
c0086340 00000000 00000000 00000000 00000000
c0086350 00000000 00000000 15e0086f 00000000
c0086360 00000000 00000000 00000000 00000000
c0086370 00000000 00000000 00000000 00000000
c0086380 00000000 00000000 00000000 00000000
c0086390 00000000 00000000 00000000 00000000
c00863a0 00000000 00000000 00000000 00000000
c00863b0 00000000 00000000 00000000 00000000
c00863c0 00000000 00000000 00000000 00000000
c00863d0 00000000 00000000 00000000 00000000
c00863e0 00000000 00000000 00000000 00000000
c00863f0 00000000 00000000 00000000 00000000
c0086400 00000000 00000000 00000000 00000000
c0086410 00000000 00000000 00000000 00000000
c0086420 00000000 00000000 00000000 00000000
c0086430 00000000 00000000 00000000 00000000
c0086440 00000000 00000000 00000000 00000000
c0086450 00000000 00000000 00000000 00000000
c0086460 15e0086f 00000000 00000000 00000000
c0086470 00000000 00000000 00000000 00000000
c0086480 00000000 00000000 00000000 00000000
c0086490 00000000 00000000 00000000 00000000
c00864a0 00000000 00000000 00000000 00000000
c00864b0 00000000 00000000 00000000 00000000
c00864c0 00000000 00000000 00000000 00000000
c00864d0 00000000 00000000 00000000 00000000
c00864e0 15e0086f 00000000 00000000 00000000
c00864f0 00000000 00000000 00000000 00000000
c0086500 00000000 00000000 00000000 00000000
c0086510 00000000 00000000 00000000 00000000
c0086520 00000000 00000000 00000000 00000000
c0086530 00000000 00000000 00000000 00000000
c0086540 00000000 00000000 00000000 00000000
c0086550 00000000 00000000 00000000 00000000
c0086560 15e0086f 00000000 00000000 00000000
c0086570 00000000 00000000 00000000 00000000
c0086580 00000000 00000000 00000000 00000000
c0086590 00000000 00000000 00000000 00000000
c00865a0 00000000 00000000 00000000 00000000
c00865b0 00000000 00000000 00000000 00000000
c00865c0 00000000 00000000 00000000 00000000
c00865d0 00000000 00000000 00000000 00000000
c00865e0 00000000 00000000 00000000 00000000
c00865f0 00000000 00000000 00000000 00000000
c0086600 00000000 00000000 00000000 00000000
c0086610 00000000 00000000 00000000 00000000
c0086620 00000000 00000000 00000000 00000000
c0086630 00000000 00000000 00000000 00000000
c0086640 00000000 00000000 00000000 00000000
c0086650 00000000 00000000 00000000 00000000
c0086660 00000000 00000000 15e0086f 00000000
c0086670 00000000 00000000 00000000 00000000
c0086680 00000000 00000000 00000000 00000000
c0086690 00000000 00000000 00000000 00000000
c00866a0 00000000 00000000 00000000 00000000
c00866b0 00000000 00000000 00000000 00000000
c00866c0 00000000 00000000 00000000 00000000
c00866d0 00000000 00000000 00000000 00000000
c00866e0 00000000 00000000 15e0086f 00000000
c00866f0 00000000 00000000 00000000 00000000
c0086700 00000000 00000000 00000000 00000000
c0086710 00000000 00000000 00000000 00000000
c0086720 00000000 00000000 00000000 00000000
c0086730 00000000 00000000 00000000 00000000
c0086740 00000000 00000000 00000000 00000000
c0086750 00000000 00000000 00000000 00000000
c0086760 00000000 00000000 15e0086f 00000000
c0086770 00000000 00000000 00000000 00000000
c0086780 00000000 00000000 00000000 00000000
c0086790 00000000 00000000 00000000 00000000
c00867a0 00000000 00000000 00000000 00000000
c00867b0 00000000 00000000 00000000 00000000
c00867c0 00000000 00000000 00000000 00000000
c00867d0 00000000 00000000 00000000 00000000
c00867e0 00000000 00000000 00000000 00000000




kd> !pfn 15e00
PFN 00015E00 at address 81BCA800
flink 00000000 blink / share count 00000001 pteaddress 000AF001
reference count 0002 Cached color 0
restore pte 00000080 containing page FFEDCB Active RW
ReadInProgress WriteInProgress

在引用计数为2的页面上,驱动程序还有一个未完成的调用MmProbeAndLockPages调用。认为这个pfn值不正确,我决定搜索这个值,看看能找到什么。

kd> s -d 80000000 l?7fffffff 00015e00
8022d534 00015e00 0001f190 00041d50 0001f140 .^......P...@...
86cacbf4 00015e00 0000cd1c 0000cc27 0000cc08 .^......'.......
86e25cdc 00015e00 0a130005 e56c6946 00000000 .^......Fil.....

我找到了一些条目,但是中间的条目看起来可能是MDL分配。所以我核实了一下:

kd> !pool 86cacbf4 2
Pool page 86cacbf4 region is Nonpaged pool
*86cacbd0 size: 80 previous size: 28 (Allocated) *Mdl
Pooltag Mdl : Io, Mdls

是的,这是MDL,让我们检查一下:

kd> dt nt!_MDL 86cacbd8
+0x000 Next : (null)
+0x004 Size : 32
+0x006 MdlFlags : 138
+0x008 Process : (null)
+0x00c MappedSystemVa : 0x00004000
+0x010 StartVa : 0xf7baa000
+0x014 ByteCount : 0xfff
+0x018 ByteOffset : 0

请注意,页面15e00位于MDL的页面列表中。

kd> dd 86cacbd8+1c
86cacbf4 00015e00 0000cd1c 0000cc27 0000cc08
86cacc04 0000cc09 0000cc0a 0000cc0b 0000cbec
86cacc14 0000cbed 0000cbee 0000cbef 0000cbd0
86cacc24 0000cbd1 0000cbd2 0000cbd3 0000cbd4
86cacc34 0000cbd5 0000cbd6 00000000 00000000
86cacc44 00000000 00000000 00000000 00010010

接下来,我想看看是否可以找到一个驱动程序,它可能引用了这个MDL,我找到了两个:

kd> s -d 80000000 l?7fffffff 86cacbd8
86f9c6a0 86cacbd8 0000003d 00000000 0000636a ....=.......jc..
86fc7e68 86cacbd8 00000001 00000001 00000000 ................

现在让我们看看谁拥有这些

    kd> !pool 86f9c6a0 2
    Pool page 86f9c6a0 region is Nonpaged pool
    *86f9c618 size: d8 previous size: 30 (Allocated) *Crpt
    Pooltag Crpt : Memory corruption driver

    kd> !pool 86fc7e68 2
    Pool page 86fc7e68 region is Nonpaged pool
    *86fc7e00 size: 98 previous size: 40 (Allocated) *Crpt
    Pooltag Crpt : Memory corruption driver

这给了我们一个很有说服力的可能性,这个司机有过错。所以现在您可能会问,“为什么这个问题是在应用了ServicePack2之后才出现的?”默认情况下,安装Server Pack 2时,支持它的系统上会启用数据执行保护(DEP)。对DEP的支持在PAE内核中,它使用额外的位来描述页表条目。在这次崩溃中,解决方案是禁用DEP,直到驱动程序被纠正为止。驱动程序错误地使用了内存映射,忽略了页码中的额外位,并通过写入错误的页导致内存损坏。

上一篇:oracle利用job实现存储过程异步执行


下一篇:原码、反码、补码三者之间的转换