15 #define UNWIND_HISTORY_TABLE_NONE 0 16 #define UNWIND_HISTORY_TABLE_GLOBAL 1 17 #define UNWIND_HISTORY_TABLE_LOCAL 2 19 #define UWOP_PUSH_NONVOL 0 20 #define UWOP_ALLOC_LARGE 1 21 #define UWOP_ALLOC_SMALL 2 22 #define UWOP_SET_FPREG 3 23 #define UWOP_SAVE_NONVOL 4 24 #define UWOP_SAVE_NONVOL_FAR 5 25 #if 0 // These are deprecated / not for x64 26 #define UWOP_SAVE_XMM 6 27 #define UWOP_SAVE_XMM_FAR 7 30 #define UWOP_SPARE_CODE 7 32 #define UWOP_SAVE_XMM128 8 33 #define UWOP_SAVE_XMM128_FAR 9 34 #define UWOP_PUSH_MACHFRAME 10 120 OUT PUNWIND_HISTORY_TABLE HistoryTable)
124 ULONG IndexLo, IndexHi, IndexMid;
136 ControlPc -= *ImageBase;
140 IndexHi = TableLength;
141 while (IndexHi > IndexLo)
143 IndexMid = (IndexLo + IndexHi) / 2;
146 if (ControlPc < FunctionEntry->BeginAddress)
151 else if (ControlPc >= FunctionEntry->EndAddress)
154 IndexLo = IndexMid + 1;
159 return FunctionEntry;
207 static const UCHAR UnwindOpExtraSlotTable[] =
224 (UnwindCode.OpInfo != 0))
230 return UnwindOpExtraSlotTable[UnwindCode.UnwindOp] + 1;
250 _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers,
255 if (ContextPointers !=
NULL)
257 ContextPointers->IntegerContext[Reg] = ValuePointer;
276 _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers,
299 _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers,
304 if (ContextPointers !=
NULL)
306 ContextPointers->FloatingContext[Reg] = ValuePointer;
333 _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers,
346 InstrPtr = (
BYTE*)LocalContext.Rip;
349 Instr = *(
DWORD*)InstrPtr;
350 if ( (Instr & 0x00fffdff) == 0x00c48148 )
352 if ( (Instr & 0x0000ff00) == 0x8300 )
355 LocalContext.Rsp += Instr >> 24;
361 LocalContext.Rsp += *(
DWORD*)(InstrPtr + 3);
366 else if ( (Instr & 0x38fffe) == 0x208d48 )
369 Reg = ((Instr << 8) | (Instr >> 16)) & 0x7;
371 LocalContext.Rsp =
GetReg(&LocalContext, Reg);
374 Mod = (Instr >> 22) & 0x3;
383 LocalContext.Rsp += Instr >> 24;
389 LocalContext.Rsp += *(
DWORD*)(InstrPtr + 3);
395 EndAddress = FunctionEntry->EndAddress + ImageBase - 1;
396 while ((
DWORD64)InstrPtr < EndAddress)
398 Instr = *(
DWORD*)InstrPtr;
401 if ( (Instr & 0xf8) == 0x58 )
405 PopReg(&LocalContext, ContextPointers, Reg);
411 if ( (Instr & 0xf8fb) == 0x5841 )
414 Reg = ((Instr >> 8) & 0x7) + 8;
415 PopReg(&LocalContext, ContextPointers, Reg);
429 if ((
DWORD64)InstrPtr != EndAddress)
437 if (*InstrPtr != 0xc3)
444 LocalContext.Rip = *(
DWORD64*)LocalContext.Rsp;
445 LocalContext.Rsp +=
sizeof(
DWORD64);
465 if (UnwindInfo->FrameRegister == 0)
471 if ((CodeOffset >= UnwindInfo->SizeOfProlog) ||
475 UnwindInfo->FrameOffset * 16;
480 i < UnwindInfo->CountOfCodes;
487 UnwindInfo->FrameOffset * 16;
504 _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
514 ControlPc -= ImageBase;
517 if ( (ControlPc < FunctionEntry->BeginAddress) ||
518 (ControlPc >= FunctionEntry->EndAddress) )
524 UnwindInfo =
RVA(ImageBase, FunctionEntry->UnwindData);
528 *HandlerData = (LanguageHandler + 1);
531 CodeOffset = ControlPc - FunctionEntry->BeginAddress;
547 while ((i < UnwindInfo->CountOfCodes) &&
556 while (i < UnwindInfo->CountOfCodes)
650 UnwindInfo =
RVA(ImageBase, FunctionEntry->UnwindData);
652 goto RepeatChainedInfo;
667 return RVA(ImageBase, *LanguageHandler);
692 _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable,
707 if (TargetFrame !=
NULL)
709 StackHigh = (
ULONG64)TargetFrame + 1;
725 if (FunctionEntry ==
NULL)
729 UnwindContext.Rip = *(
DWORD64*)UnwindContext.Rsp;
730 UnwindContext.Rsp +=
sizeof(
DWORD64);
763 if (ExceptionRoutine !=
NULL)
891 _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable)
899 if (ExceptionRecord ==
NULL)
906 ExceptionRecord = &LocalExceptionRecord;
944 DPRINT(
"Enter RtlWalkFrameChain\n");
947 FramesToSkip =
Flags >> 8;
964 for (
i = 0;
i < FramesToSkip +
Count;
i++)
993 if (!(
Flags & 1) && (
Context.Rip < 0xFFFF800000000000ULL))
1001 if ((
Context.Rip < 0x10000) ||
1002 (
Context.Rip > 0x000007FFFFFEFFFFULL))
1018 if (
i >= FramesToSkip)
1020 Callers[
i - FramesToSkip] = (
PVOID)ControlPc;
1026 DPRINT1(
"Exception while getting callers!\n");
1031 DPRINT(
"RtlWalkFrameChain returns %ld\n",
i);
1038 #undef RtlGetCallersAddress 1052 *CallersAddress = (
Number >= 3) ? Callers[2] :
NULL;
1053 *CallersCaller = (
Number == 4) ? Callers[3] :
NULL;
1061 _Out_ PKNONVOLATILE_CONTEXT_POINTERS NonvolatileContextPointers,
1071 RtlZeroMemory(NonvolatileContextPointers,
sizeof(*NonvolatileContextPointers));
1090 NonvolatileContextPointers);
1108 KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
1114 *ContextPointers.R12 =
Context->R12;
1115 *ContextPointers.R13 =
Context->R13;
1116 *ContextPointers.R14 =
Context->R14;
1117 *ContextPointers.R15 =
Context->R15;
1118 *ContextPointers.Xmm6 =
Context->Xmm6;
1119 *ContextPointers.Xmm7 =
Context->Xmm7;
1120 *ContextPointers.Xmm8 =
Context->Xmm8;
1121 *ContextPointers.Xmm9 =
Context->Xmm9;
1122 *ContextPointers.Xmm10 =
Context->Xmm10;
1123 *ContextPointers.Xmm11 =
Context->Xmm11;
1124 *ContextPointers.Xmm12 =
Context->Xmm12;
1125 *ContextPointers.Xmm13 =
Context->Xmm13;
1126 *ContextPointers.Xmm14 =
Context->Xmm14;
1127 *ContextPointers.Xmm15 =
Context->Xmm15;
#define STATUS_UNWIND_CONSOLIDATE
#define EXCEPTION_NONCONTINUABLE_EXCEPTION
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
KPROCESSOR_MODE NTAPI RtlpGetMode(VOID)
_In_ ULONG _In_ ULONG _In_ ULONG Length
PRUNTIME_FUNCTION NTAPI RtlLookupFunctionTable(IN DWORD64 ControlPc, OUT PDWORD64 ImageBase, OUT PULONG Length)
Locates the table of RUNTIME_FUNCTION entries for a code address.
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
BOOLEAN NTAPI RtlpUnwindInternal(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue, _In_ PCONTEXT ContextRecord, _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable, _In_ ULONG HandlerType)
static __inline BOOLEAN RtlpTryToUnwindEpilog(_Inout_ PCONTEXT Context, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, _In_ ULONG64 ImageBase, _In_ PRUNTIME_FUNCTION FunctionEntry)
Helper function that tries to unwind epilog instructions.
PEXCEPTION_ROUTINE NTAPI RtlVirtualUnwind(_In_ ULONG HandlerType, _In_ ULONG64 ImageBase, _In_ ULONG64 ControlPc, _In_ PRUNTIME_FUNCTION FunctionEntry, _Inout_ PCONTEXT Context, _Outptr_ PVOID *HandlerData, _Out_ PULONG64 EstablisherFrame, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
NTSYSAPI NTSTATUS NTAPI ZwRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context, _In_ BOOLEAN SearchFrames)
#define EXCEPTION_NONCONTINUABLE
struct _UNWIND_INFO UNWIND_INFO
IN PVOID IN PVOID IN USHORT IN USHORT Size
static ULONG64 GetEstablisherFrame(_In_ PCONTEXT Context, _In_ PUNWIND_INFO UnwindInfo, _In_ ULONG_PTR CodeOffset)
static __inline DWORD64 GetReg(_In_ PCONTEXT Context, _In_ BYTE Reg)
PVOID NTAPI RtlPcToFileHeader(IN PVOID PcValue, PVOID *BaseOfImage)
NTSYSAPI VOID NTAPI RtlCaptureContext(_Out_ PCONTEXT ContextRecord)
void __cdecl __debugbreak(void)
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
static __inline M128A GetXmmReg(PCONTEXT Context, BYTE Reg)
#define STATUS_BAD_FUNCTION_TABLE
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE ACPI_HANDLE ACPI_HANDLE *OutHandle ACPI_HANDLE *OutHandle void *Context void *Context ACPI_EVENT_HANDLER Handler UINT32 UINT32 ACPI_GPE_HANDLER void *Context UINT32 HandlerType
UINT32 void void ** ReturnValue
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
#define STATUS_INVALID_DISPOSITION
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT _In_ PVOID DispatcherContext
#define EXCEPTION_TARGET_UNWIND
#define UWOP_SAVE_XMM128_FAR
union _UNWIND_CODE UNWIND_CODE
BOOLEAN NTAPI RtlAddFunctionTable(IN PRUNTIME_FUNCTION FunctionTable, IN DWORD EntryCount, IN DWORD64 BaseAddress)
#define UWOP_PUSH_MACHFRAME
VOID NTAPI RtlUnwindEx(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue, _In_ PCONTEXT ContextRecord, _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable)
#define EXCEPTION_STACK_INVALID
EXCEPTION_ROUTINE * PEXCEPTION_ROUTINE
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
union _UNWIND_CODE * PUNWIND_CODE
_Must_inspect_result_ _In_ ULONG Flags
static __inline void SetXmmRegFromStackValue(_Out_ PCONTEXT Context, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, _In_ BYTE Reg, _In_ M128A *ValuePointer)
#define EXCEPTION_EXECUTE_HANDLER
#define EXCEPTION_COLLIDED_UNWIND
static __inline ULONG UnwindOpSlots(_In_ UNWIND_CODE UnwindCode)
struct _RUNTIME_FUNCTION RUNTIME_FUNCTION
struct _RUNTIME_FUNCTION * PRUNTIME_FUNCTION
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
#define RtlImageDirectoryEntryToData
#define ALIGN_UP_POINTER_BY(ptr, align)
VOID RtlSetUnwindContext(_In_ PCONTEXT Context, _In_ DWORD64 TargetFrame)
VOID NTAPI RtlpGetStackLimits(PULONG_PTR StackBase, PULONG_PTR StackLimit)
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
UNWIND_CODE UnwindCode[1]
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
struct _EXCEPTION_RECORD * ExceptionRecord
_In_ ULONG _In_ ULONG Offset
struct _UNWIND_INFO * PUNWIND_INFO
static __inline void PopReg(_Inout_ PCONTEXT Context, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, _In_ BYTE Reg)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
static __inline void SetReg(_Inout_ PCONTEXT Context, _In_ BYTE Reg, _In_ DWORD64 Value)
BOOLEAN NTAPI RtlDeleteFunctionTable(IN PRUNTIME_FUNCTION FunctionTable)
#define UWOP_SAVE_NONVOL_FAR
VOID NTAPI RtlUnwind(IN PVOID TargetFrame, IN PVOID TargetIp, IN PEXCEPTION_RECORD ExceptionRecord, IN PVOID ReturnValue)
struct tagContext Context
VOID NTAPI RtlGetCallersAddress(OUT PVOID *CallersAddress, OUT PVOID *CallersCaller)
VOID NTAPI RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN PVOID ContextData, IN ULONG Size)
enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION
#define RtlZeroMemory(Destination, Length)
static __inline void SetRegFromStackValue(_Inout_ PCONTEXT Context, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers, _In_ BYTE Reg, _In_ PDWORD64 ValuePointer)
static WLX_DISPATCH_VERSION_1_4 FunctionTable
unsigned __int64 * PULONG64
#define _SEH2_EXCEPT(...)
ULONG NTAPI RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags)
PRUNTIME_FUNCTION NTAPI RtlLookupFunctionEntry(IN DWORD64 ControlPc, OUT PDWORD64 ImageBase, OUT PUNWIND_HISTORY_TABLE HistoryTable)
Locates the RUNTIME_FUNCTION entry corresponding to a code address. http://msdn.microsoft....
static VOID RtlpCaptureNonVolatileContextPointers(_Out_ PKNONVOLATILE_CONTEXT_POINTERS NonvolatileContextPointers, _In_ ULONG64 TargetFrame)
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
BOOLEAN NTAPI RtlInstallFunctionTableCallback(IN DWORD64 TableIdentifier, IN DWORD64 BaseAddress, IN DWORD Length, IN PGET_RUNTIME_FUNCTION_CALLBACK Callback, IN PVOID Context, IN PCWSTR OutOfProcessCallbackDll)
#define UNW_FLAG_NHANDLER
static __inline void SetXmmReg(_Inout_ PCONTEXT Context, _In_ BYTE Reg, _In_ M128A Value)