dump 只是出错点的记录,不是破坏的第一现场。
能看出的大致信息是,问题出在 WRK \ntos\ex\pool.c 的 2391 行。
2391 : Block = PrivateRemoveHeadList (ListHead);
宏 PrivateRemoveHeadList 会去取、操作 ListHead,而:
0: kd> dd 8b5ad938 8b5ad938 00000000 e4ff63b0 8b5ad940 8b5ad940 8b5ad948 8b5ad948 8b5ad948 8b5ad950 8b5ad950 8b5ad958 8b5ad958 8b5ad958 8b5ad960 8b5ad960 8b5ad968 8b5ad968 8b5ad968 8b5ad970 8b5ad970 8b5ad978 8b5ad978 8b5ad978 8b5ad980 8b5ad980
这个 e4ff63b0 是不对的。简单说一下:
出错前的上一条指令是:
808933b5 8906 mov dword ptr [esi],eax
可以想象那时内存的情况是:
0: kd> dd 8b5ad938 8b5ad938
e4ff63b0 e4ff63b0 8b5ad940 8b5ad940
此时,eax=00000000 esi=8b5ad938 edi=e4ff63b0
指令执行完之后,内存的状况是:
0: kd> dd 8b5ad938 8b5ad938 00000000 e4ff63b0 8b5ad940 8b5ad940
可是继续执行下一句(FAULTING_IP)时,相当于写了零地址:
808933b7 897004 mov dword ptr [eax+4],esi
结合上下文,可以得出 e4ff63b0 内部不应该是零:
0: kd> dd e4ff63b0 e4ff63b0 00000000 00000000 00000000 00000000 e4ff63c0 00000000 00000000 00000000 00000000 e4ff63d0 00000000 00000000 00000000 00000000
但是至于为什么会是零,这就不是 dump 里能轻易看出的了(dump 只是出错点的记录,而不是破坏时的第一现场)
上述 ListHead 源自:
ListHead = &PoolDesc->ListHeads[ListNumber];
而 PPOOL_DESCRIPTOR 指针 PoolDesc 源自:
if ((PoolType & SESSION_POOL_MASK) == 0) { PoolDesc = PoolVector[CheckType]; } else { PoolDesc = ExpSessionPoolDescriptor; }
至于 PoolDesc 究竟是从 PoolVector 取值,还是从 ExpSessionPoolDescriptor 取值,以及值是什么,minidump 已经不得而知了:
0: kd> ln PoolVector (808aea88) nt!PoolVector | (808aeaa0) nt!ExpNonPagedPoolDescriptor Exact matches:
0: kd> dd 808aea88 808aea88 ???????? ???????? ???????? ???????? 808aea98 ???????? ???????? ???????? ????????
0: kd> ln ExpSessionPoolDescriptor (808afbe8) nt!ExpSessionPoolDescriptor | (808afbf0) nt!ExpSystemResourcesList Exact matches:
0: kd> dd 808afbe8 808afbe8 ???????? ???????? ???????? ???????? 808afbf8 ???????? ???????? ???????? ????????
|