Registers (A Short Story)

Vir Gnarus

BSOD Kernel Dump Expert
Joined
Mar 2, 2012
Posts
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:



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:
Back
Top