Vir Gnarus
BSOD Kernel Dump Expert
- Mar 2, 2012
- 474
Hi all,
Even though it's incomplete and won't ever be complete (minidumps...), I caved in and figured it'd be wasteful to let this pass by, as it's caught a few people's attention (like JC, thanks). The following is a copy from this. It covers a wee bit of a couple things. Hope you enjoy! Ask questions if puzzled.
First, !analyze -v:
As typical of any approach, first thing to do is to check the bugcheck, then the offending instruction, all of which is present in the !analyze -v output:
Now to figure out where it got the bad memory address. It was reading from both rdi and rcx registers. Let's check both (again, in the !analyze -v output):
So it's the rcx register that has the erroneous memory address. However, look at it. There's something peculiar about it. If you are perceptive, you'll notice that it's actually a legitimate address that had a "d0" value pushed at the front of it (or end, however you look at it). So it looks like whatever tried to save an address in the rcx register was off by 1 byte. Let's see where the value in rcx originated from by doing a disassembly, starting from the faulting instruction and walking back to whenever rcx got filled with a value. You can use the Disassembly window in Windbg and have the offset set to the faulting instruction's address. A snippet of the result:
Most instances having to trace back origins of register contents can be a royal pain, but fortunately for us this one happened soon before the fault, and its interpretation is rather simple: it's using the r9 register as a memory address to point too, and the memory at that address has the contents it needs to shove into the rcx register. So all we need to do is look at whatever that memory address has in it:
Interesting, there's nothing here at all. Let's verify if this is valid and available memory:
This is where our journey ends. Evidently, the minidump (and typically all minidumps) don't save this information. We cannot verify if this really was illegitimate memory it was pointing too, because the minidump does not record this information (and most likely the contents of the memory don't exist either in the memory dump, hence all the question marks). We cannot progress from here. Was worth a try though.
Even though it's incomplete and won't ever be complete (minidumps...), I caved in and figured it'd be wasteful to let this pass by, as it's caught a few people's attention (like JC, thanks). The following is a copy from this. It covers a wee bit of a couple things. Hope you enjoy! Ask questions if puzzled.
First, !analyze -v:
Code:
2: kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************
SYSTEM_SERVICE_EXCEPTION (3b)
An exception happened while executing a system service routine.
Arguments:
Arg1: 00000000c0000005, Exception code that caused the bugcheck
Arg2: fffff800030c1c25, Address of the instruction which caused the bugcheck
Arg3: fffff88007818ae0, Address of the context record for the exception that caused the bugcheck
Arg4: 0000000000000000, zero.
Debugging Details:
------------------
EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
FAULTING_IP:
nt!RtlEnumerateEntryHashTable+bf
fffff800`030c1c25 48897908 mov qword ptr [rcx+8],rdi
CONTEXT: fffff88007818ae0 -- (.cxr 0xfffff88007818ae0)
rax=fffffa8007c872d1 rbx=fffffa8007c7a088 rcx=d0fffffa8007c872
rdx=fffffa8007c872d0 rsi=fffffa80079c1088 rdi=fffff88007819518
rip=fffff800030c1c25 rsp=fffff880078194c8 rbp=fffffa80079c20d8
r8=000000000000002c r9=fffffa8007c872d1 r10=fffffa8007b653a0
r11=0000000000000000 r12=fffffa80079c20d8 r13=fffff88007819738
r14=fffffa80079c1d38 r15=fffffa8007cc6980
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00010202
nt!RtlEnumerateEntryHashTable+0xbf:
fffff800`030c1c25 48897908 mov qword ptr [rcx+8],rdi ds:002b:d0fffffa`8007c87a=????????????????
Resetting default scope
CUSTOMER_CRASH_COUNT: 1
DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT
BUGCHECK_STR: 0x3B
PROCESS_NAME: LMS.exe
CURRENT_IRQL: 2
LAST_CONTROL_TRANSFER: from 0000000000000000 to fffff800030c1c25
STACK_TEXT:
fffff880`078194c8 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!RtlEnumerateEntryHashTable+0xbf
FOLLOWUP_IP:
nt!RtlEnumerateEntryHashTable+bf
fffff800`030c1c25 48897908 mov qword ptr [rcx+8],rdi
SYMBOL_STACK_INDEX: 0
SYMBOL_NAME: nt!RtlEnumerateEntryHashTable+bf
FOLLOWUP_NAME: MachineOwner
MODULE_NAME: nt
IMAGE_NAME: ntkrnlmp.exe
DEBUG_FLR_IMAGE_TIMESTAMP: 4e02aaa3
STACK_COMMAND: .cxr 0xfffff88007818ae0 ; kb
FAILURE_BUCKET_ID: X64_0x3B_nt!RtlEnumerateEntryHashTable+bf
BUCKET_ID: X64_0x3B_nt!RtlEnumerateEntryHashTable+bf
Followup: MachineOwner
---------
As typical of any approach, first thing to do is to check the bugcheck, then the offending instruction, all of which is present in the !analyze -v output:
Code:
SYSTEM_SERVICE_EXCEPTION (3b)
An exception happened while executing a system service routine.
Arguments:
Arg1: [COLOR=#ff0000]00000000c0000005[/COLOR], Exception code that caused the bugcheck
Arg2: fffff800030c1c25, Address of the instruction which caused the bugcheck
Arg3: fffff88007818ae0, Address of the context record for the exception that caused the bugcheck
Arg4: 0000000000000000, zero.
EXCEPTION_CODE: (NTSTATUS) 0x[COLOR=#ff0000]c0000005[/COLOR] - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.
nt!RtlEnumerateEntryHashTable+0xbf:
fffff800`030c1c25 48897908 mov qword ptr [rcx+8],rdi ds:002b:[COLOR=#ff0000]d0fffffa`8007c87a[/COLOR]=????????????????
Now to figure out where it got the bad memory address. It was reading from both rdi and rcx registers. Let's check both (again, in the !analyze -v output):
Code:
CONTEXT: fffff88007818ae0 -- (.cxr 0xfffff88007818ae0)
rax=fffffa8007c872d1 rbx=fffffa8007c7a088 rcx=[COLOR=#ff0000]d0fffffa8007c872[/COLOR]
rdx=fffffa8007c872d0 rsi=fffffa80079c1088 rdi=fffff88007819518
rip=fffff800030c1c25 rsp=fffff880078194c8 rbp=fffffa80079c20d8
r8=000000000000002c r9=fffffa8007c872d1 r10=fffffa8007b653a0
r11=0000000000000000 r12=fffffa80079c20d8 r13=fffff88007819738
r14=fffffa80079c1d38 r15=fffffa8007cc6980
iopl=0 nv up ei pl nz na pe nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b
So it's the rcx register that has the erroneous memory address. However, look at it. There's something peculiar about it. If you are perceptive, you'll notice that it's actually a legitimate address that had a "d0" value pushed at the front of it (or end, however you look at it). So it looks like whatever tried to save an address in the rcx register was off by 1 byte. Let's see where the value in rcx originated from by doing a disassembly, starting from the faulting instruction and walking back to whenever rcx got filled with a value. You can use the Disassembly window in Windbg and have the offset set to the faulting instruction's address. A snippet of the result:
Code:
...
fffff800`030c1c09 7527 jne nt!RtlEnumerateEntryHashTable+0xcc (fffff800`030c1c32)
fffff800`030c1c0b 488b5c2408 mov rbx,qword ptr [rsp+8]
fffff800`030c1c10 44894720 mov dword ptr [rdi+20h],r8d
fffff800`030c1c14 48895718 mov qword ptr [rdi+18h],rdx
fffff800`030c1c18 498b09 mov rcx,qword ptr [r9] [COLOR=#006400][I]< contents of what r9 points too moved into rcx register[/I][/COLOR]
fffff800`030c1c1b 4c894f08 mov qword ptr [rdi+8],r9
fffff800`030c1c1f 498bc1 mov rax,r9
fffff800`030c1c22 48890f mov qword ptr [rdi],rcx
fffff800`030c1c25 48897908 mov qword ptr [rcx+8],rdi [COLOR=#006400][I]< faulting instruction[/I][/COLOR]
Most instances having to trace back origins of register contents can be a royal pain, but fortunately for us this one happened soon before the fault, and its interpretation is rather simple: it's using the r9 register as a memory address to point too, and the memory at that address has the contents it needs to shove into the rcx register. So all we need to do is look at whatever that memory address has in it:
Code:
2: kd> dq @r9
fffffa80`07c872d1 ????????`???????? ????????`????????
fffffa80`07c872e1 ????????`???????? ????????`????????
fffffa80`07c872f1 ????????`???????? ????????`????????
fffffa80`07c87301 ????????`???????? ????????`????????
fffffa80`07c87311 ????????`???????? ????????`????????
fffffa80`07c87321 ????????`???????? ????????`????????
fffffa80`07c87331 ????????`???????? ????????`????????
fffffa80`07c87341 ????????`???????? ????????`????????
Interesting, there's nothing here at all. Let's verify if this is valid and available memory:
Code:
2: kd> !pte @r9
VA fffffa8007c872d1
PXE at FFFFF6FB7DBEDFA8 PPE at FFFFF6FB7DBF5000 PDE at FFFFF6FB7EA001F0 PTE at FFFFF6FD4003E438
Unable to get PXE FFFFF6FB7DBEDFA8
This is where our journey ends. Evidently, the minidump (and typically all minidumps) don't save this information. We cannot verify if this really was illegitimate memory it was pointing too, because the minidump does not record this information (and most likely the contents of the memory don't exist either in the memory dump, hence all the question marks). We cannot progress from here. Was worth a try though.
Last edited: