I have a user mode dump from Win 8.1/64, the dump was taken by attaching Windbg when the Wer dialogue. The .ecxr shows then ntdll!DbgBreakPoint for the Windbg injected thread. (As normal)
I have identified the thread by examine all stack, and finding the one which has :
# Call Site
00 ntdll!NtWaitForMultipleObjects
01 KERNELBASE!WaitForMultipleObjectsEx
02 kernel32!WerpReportFaultInternal
03 kernel32!WerpReportFault
04 KERNELBASE!UnhandledExceptionFilter
05 ntdll!RtlUserThreadStart$filt$0
06 ntdll!_C_specific_handler
07 ntdll!RtlpExecuteHandlerForException
08 ntdll!RtlDispatchException
09 ntdll!KiUserExceptionDispatch
10 <My faulty code which generated the exception>
The kvn aslo dispays a TrapFrame @ 00000000`0379ed28)
09 00000000`0379e900 00000000`00250bc8 : 00000000`00000000 00000000`0026ca09 00000000`0379f160 00000000`0379f168 : ntdll!KiUserExceptionDispatch+0x2e (TrapFrame @ 00000000`0379ed28)
Is there a way to use the trap frame to get the context record to feed into .cxr ? Or is it other possibilities to find the exception context?
I see a KERNELBASE!UnhandledExceptionFilter
on the stack. That seems like a good thing to focus on.
If this were x86, you could easily get an EXCEPTION_POINTERS
struct out of the first parameter to KERNELBASE!UnhandledExceptionFilter
. From there, you would have access to the EXCEPTION_RECORD
and CONTEXT
. The procedure is described in this KB article.
The same method works for x64 processes with one caveat. Due to the nature of the x64 calling convention, it is harder to retrieve the actual argument to KERNELBASE!UnhandledExceptionFilter
since it is stored in a register rather than on the stack.
I recently found a debugger extension called CMKD
that automates the task of hunting for the first 4 args in the x64 calling convention rather than blindly displaying stack values like kb
and kv
. This can be done by hand but it is a rather lengthy and error-prone process -- better to let an extension take a crack at it first.
With it, you can do something like this:
0:000> !cmkd.stack -p
Call Stack : 15 frames
## Stack-Pointer Return-Address Call-Site
[...]
03 000000aea3dae7e0 00007fff1e906b14 KERNELBASE!UnhandledExceptionFilter+196
Parameter[0] = 000000aea3dae930
Parameter[1] = (unknown)
Parameter[2] = (unknown)
Parameter[3] = (unknown)
[...]
And, now we have an EXCEPTION_POINTERS*
in Parameter[0]
.
0:000> dt 000000ae`a3dae930 EXCEPTION_POINTERS
ConsoleApplication2!EXCEPTION_POINTERS
+0x000 ExceptionRecord : 0x000000ae`a3daf850 _EXCEPTION_RECORD
+0x008 ContextRecord : 0x000000ae`a3daf240 _CONTEXT
We can see in my example that a C++ exception was thrown...
0:000> .exr 000000ae`a3daf850
ExceptionAddress: 00007fff1bfeab78 (KERNELBASE!RaiseException+0x0000000000000068)
ExceptionCode: e06d7363 (C++ EH exception)
ExceptionFlags: 00000001
NumberParameters: 4
Parameter[0]: 0000000019930520
Parameter[1]: 000000aea3daf9b0
Parameter[2]: 00007ff6f50024a8
Parameter[3]: 00007ff6f5000000
pExceptionObject: 000000aea3daf9b0
_s_ThrowInfo : 00007ff6f50024a8
Hopefully this helps. Good luck. :)