How to Extract the Trapframe Address from Kernel Dump Using dbgeng

"I would like to ask if anyone knows how to extract the address of the trapframe from a kernel dump using dbgeng. I am working on an automated kernel dump analysis tool, and one of its functions is to use the instruction pointer (eip or rip) from the trapframe to determine which module the pointer is located in, in order to identify which module caused the crash. Using the Windbg UI, I can analyze the current stack and trapframe with the !thread command. I know the data structure is _KTRAP_FRAME, but I'm currently facing an issue. I don't know how to find the address of the trapframe using dbgeng. Can anyone tell me how to retrieve the address where the trapframe is stored using dbgeng's interface?" Thank you

When trap frames are available, they are often one of the bugcheck parameters. For example, in bugcheck 0x8E (KERNEL_MODE_EXCEPTION_NOT_HANDLED), parameter 3 represents the trap frame. Then, there are also context records and exception records. Also, a bugcheck parameter can just point to the faulting IP without any of these constructs.

Back on the x86 the debugger would determine if there's a trap frame on the stack based on the function name (i.e. the debugger "knew" KiTrap0E built a trap frame and where it would be on the stack relative to the function).

On the x64/ARM64 the fact that there's a trap frame is encoded in the unwind data:

nt!KiPageFault + 0x16e (TrapFrame @ fffff880`06678370)
nt!RtlDeleteNoSplay + 0x2a
fltmgr!TreeUnlinkNoBalance + 0x13
fltmgr!TreeUnlinkMulti + 0x148
fltmgr!DeleteNameCacheNodes + 0x9f
fltmgr!PurgeStreamNameCache + 0x8e
fltmgr!FltpPurgeVolumeNameCache + 0x7f

3: kd> .fnent nt!KiPageFault
Debugger function entry 00000218`8b474080 for:
(fffff800`02a7ce80)   nt!KiPageFault   |  (fffff800`02a7d240)   nt!KiFloatingErrorFault
Exact matches:
    nt!KiPageFault (KiPageFault)

BeginAddress      = 00000000`0006fe80
EndAddress        = 00000000`0007021c
UnwindInfoAddress = 00000000`001c00d8

Unwind info at fffff800`02bcd0d8, e bytes
  version 1, flags 0, prolog 10, codes 5
  frame reg 5 (rbp), frame offs 80h
...
  04: offs 0, unwind op a, op info 1	UWOP_PUSH_MACHFRAME.

Going that route is like real work though...I'd go with Daniel's suggestion of using the trap frame from the bugcheck arguments. Sure, there can be other trap frames on the stack, but they're not always useful.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.