mirror of
https://github.com/intelpt/WindowsIntelPT
synced 2026-06-08 14:50:14 +00:00
0ab296f21c
Implemented support for HyperV Root Partitions (finally)
194 lines
10 KiB
C
194 lines
10 KiB
C
/**********************************************************************
|
|
* Windows Intel Processor Trace (PT) Driver 0.4
|
|
* Filename: IntelPt.h
|
|
* Defines the Intel Processor Trace driver function prototypes
|
|
* Last revision: 01/06/2016
|
|
*
|
|
* Copyright© 2016 Andrea Allievi, Richard Johnson
|
|
* TALOS Research and Intelligence Group and Microsoft Ltd
|
|
* All right reserved
|
|
**********************************************************************/
|
|
#pragma once
|
|
#include "Intel_Defs.h"
|
|
|
|
// For "kernelTracing.h"
|
|
#define INTEL_PT_HDRS 1
|
|
|
|
struct INTEL_PT_CAPABILITIES {
|
|
UINT16 bCr3Filtering : 1; // [0] - CR3 Filtering Support (Indicates that IA32_RTIT_CTL.CR3Filter can be set to 1)
|
|
UINT16 bConfPsbAndCycSupported : 1; // [1] - Configurable PSB and Cycle-Accurate Mode Supported (IA32_RTIT_CTL.PSBFreq can be set to a non-zero value, IA32_RTIT_STATUS.PacketByteCnt can be set to a non-zero value)
|
|
UINT16 bIpFiltering : 1; // [2] - IP Filtering and TraceStop supported, and Preserve Intel PT MSRs across warm reset
|
|
UINT16 bMtcSupport : 1; // [3] - IA32_RTIT_CTL.MTCEn can be set to 1, and MTC packets will be generated (section 36.2.5)
|
|
UINT16 bPtWriteSupport : 1; // [4] - indicates support of PTWRITE
|
|
UINT16 bPETSupport : 1; // [5] - indicates support of Power Event Trace
|
|
UINT16 bVmxSupport : 1; // [6] - Indicates whether Intel PT can be used in VMX operations
|
|
UINT16 bTopaOutput : 1; // [7] - Tracing can be enabled with IA32_RTIT_CTL.ToPA = 1, hence utilizing the ToPA output scheme (section 36.2.4.2)
|
|
UINT16 bTopaMultipleEntries : 1; // [8] - ToPA tables can hold any number of output entries, up to the maximum allowed by the MaskOrTableOffset field of IA32_RTIT_OUTPUT_MASK_PTRS
|
|
UINT16 bSingleRangeSupport : 1; // [9] - Single-Range Output Supported
|
|
UINT16 bTransportOutputSupport : 1; // [10] - Output to Trace Transport Subsystem Supported (Setting IA32_RTIT_CTL.FabricEn to 1 is supported)
|
|
UINT16 bIpPcksAreLip : 1; // [11] - IP Payloads are LIP (Specifies if the generated packets that contain IP payloads have LIP values or RIP values) <-- Very important
|
|
SHORT numOfAddrRanges; // + 0x02 - Number of Address Ranges - specifies the number ADDRn_CFG field supported in IA32_RTIT_CTL for IP filtering and IP TraceStop
|
|
SHORT mtcPeriodBmp; // + 0x04 - Bitmap of supported MTC Period Encodings
|
|
SHORT cycThresholdBmp; // + 0x06 - Bitmap of supported Cycle Threshold values
|
|
SHORT psbFreqBmp; // + 0x08 - Bitmap of supported Configurable PSB Frequency encoding
|
|
};
|
|
|
|
enum PT_PROCESSOR_STATE {
|
|
PT_PROCESSOR_STATE_ERROR = -1,
|
|
PT_PROCESSOR_STATE_DISABLED = 0,
|
|
PT_PROCESSOR_STATE_STOPPED,
|
|
PT_PROCESSOR_STATE_TRACING,
|
|
PT_PROCESSOR_STATE_PAUSED
|
|
};
|
|
|
|
// Describe a processor trace range
|
|
struct PT_TRACE_RANGE {
|
|
LPVOID lpStartVa;
|
|
LPVOID lpEndVa;
|
|
BOOLEAN bStopTrace;
|
|
};
|
|
|
|
// Data structure that describe the trace type request
|
|
struct PT_TRACE_DESC {
|
|
PEPROCESS peProc; // Trace by CR3: The Process address space to trace (if any)
|
|
BOOLEAN bTraceKernel; // Trace by CPL: TRUE to trace Kernel mode components
|
|
BOOLEAN bTraceUser; // Trace by CPL: TRUE to trace User mode components
|
|
DWORD dwNumOfRanges; // Trace by IP: Number of range to trace
|
|
struct PT_TRACE_RANGE Ranges[4]; // Trace by IP: the VA ranges to trace
|
|
};
|
|
|
|
// The trace options Bitmask
|
|
union TRACE_OPTIONS {
|
|
struct {
|
|
BOOLEAN bTraceCycPcks : 1; // [0] - Enables/disables CYC Packet (Cycle Count Packet - default is 0)
|
|
BOOLEAN bTraceMtcPcks : 1; // [1] - Enables/disables MTC Packet (Wall-clock time packets - default is 0)
|
|
BOOLEAN bTraceTscPcks : 1; // [2] - Enables/disables TSC Packet (Time Stamp packets - default is 0)
|
|
BOOLEAN bTraceBranchPcks : 1; // [3] - Enables/disables COFI-based packets: FUP, TIP, TIP.PGE, TIP.PGD, TNT, MODE.Exec, MODE.TSX. (default is 1)
|
|
BOOLEAN bUseTopa : 1; // [4] - Enable/disable the usage of Table of Physical Address (if available, default is 1)
|
|
BOOLEAN bEnableRetCompression : 1; // [5] - Enables/disables RET compression (default is 1)
|
|
BOOLEAN bInitialized : 1; // [6] - Set to 1 if this structure is initialized
|
|
BOOLEAN Reserved : 1; // [7] - Reserved
|
|
BYTE MTCFreq : 4; // [8:11] - MTC packet Frequency, which is based on the core crystal clock, or Always Running Timer (ART)
|
|
BYTE CycThresh : 4; // [12:15] - CYC packet threshold. CYC packets will be sent with the first eligible packet after N cycles have passed since the last CYC packet
|
|
BYTE PSBFreq : 4; // [16:19] - The frequency of PSB packets. PSB packet frequency is based on the number of Intel PT packet bytes output
|
|
} Fields;
|
|
DWORD All;
|
|
};
|
|
|
|
// The descriptor of the Tracing buffer
|
|
typedef struct _PT_BUFFER_DESCRIPTOR {
|
|
union {
|
|
struct {
|
|
LPVOID lpTraceBuffVa; // + 0x00 - Kernel VA Pointer to a contiguous memory buffer
|
|
ULONG_PTR lpTraceBuffPhysAddr; // + 0x08 - The physical address of the contiguous memory buffer
|
|
} Simple;
|
|
struct {
|
|
LPVOID lpTopaVa; // + 0x00 - Kernel VA pointer to the ToPA
|
|
ULONG_PTR lpTopaPhysAddr; // + 0x08 - The Physical adress of the ToPA
|
|
} ToPA;
|
|
} u;
|
|
BOOLEAN bUseTopa; // + 0x10 - TRUE if this processor uses ToPa
|
|
BOOLEAN bDefaultPmiSet; // + 0x11 - TRUE if the default PMI is on
|
|
BOOLEAN bBuffIsFull; // + 0x12 - TRUE if the ToPa or Simple buffer is full
|
|
QWORD qwBuffSize; // + 0x18 - The physical buffer size
|
|
PMDL pTraceMdl; // + 0x20 - The MDL used for mapping pages
|
|
LPVOID lpKernelVa; // + 0x28 - The kernel-mode virtual address (never used, except for the tests)
|
|
}PT_BUFFER_DESCRIPTOR, *PPT_BUFFER_DESCRIPTOR;
|
|
|
|
// The custom PMI ISR routines
|
|
typedef VOID(*INTELPT_PMI_HANDLER)(DWORD dwCpuId, PT_BUFFER_DESCRIPTOR * ptBuffDesc);
|
|
|
|
struct PER_PROCESSOR_PT_DATA {
|
|
PT_BUFFER_DESCRIPTOR * pPtBuffDesc; // + 0x00 - The PT buffer descriptor associated to this CPU
|
|
TRACE_OPTIONS TraceOptions; // + 0x08 - The trace packets options bitmask
|
|
LPVOID lpUserVa; // + 0x28 - The User Mode VA
|
|
PEPROCESS lpMappedProc; // + 0x30 - The process the User VA belongs to (usually the user-mode controlling app)
|
|
PT_PROCESSOR_STATE curState; // + 0x38 - Current processor state
|
|
ULONGLONG PacketByteCount; // + 0x40 - The total number of TRACE packets acquired by this processor
|
|
|
|
LPVOID lpXSaveArea; // + 0x48 - [Experimantal] - XSave Area ptr
|
|
DWORD dwXSaveAreaSize; // + 0x50 - [Experimantal] - XSave area size for current processor
|
|
|
|
// Tracing state data:
|
|
PEPROCESS lpTargetProc; // + 0x58 - The target process to monitor (NULL if All process are going to be traced)
|
|
ULONG_PTR lpTargetProcCr3; // + 0x60 - The process to monitor CR3 (NULL if All process are going to be traced)
|
|
DWORD dwNumOfActiveRanges; // + 0x68 - Number of active ranges
|
|
PT_TRACE_RANGE IpRanges[4]; // + 0x70
|
|
};
|
|
|
|
// The user-mode PMI Callback descriptor
|
|
typedef struct _PMI_USER_CALLBACK_DESC {
|
|
LIST_ENTRY entry; // + 0x00 - The double linked list entry
|
|
PETHREAD pTargetThread; // + 0x10 - The target thread
|
|
KAFFINITY kAffinity; // + 0x18 - The target routine affinity mask
|
|
LPVOID lpUserAddress; // + 0x20 - The user-mode callback address
|
|
} PMI_USER_CALLBACK_DESC, *PPMI_USER_CALLBACK_DESC;
|
|
|
|
// Define the number of trailing zeroes in a page aligned virtual address.
|
|
// This is used as the shift count when shifting virtual addresses to
|
|
// virtual page numbers.
|
|
#define PAGE_SHIFT 12L
|
|
#define PAGE_SIZE 0x1000
|
|
|
|
// Check the Intel Processor Trace support on this processor
|
|
NTSTATUS CheckIntelPtSupport(INTEL_PT_CAPABILITIES * lpPtCap);
|
|
|
|
// Enable the Intel PT for current processor
|
|
NTSTATUS StartCpuTrace(PT_TRACE_DESC desc, PT_BUFFER_DESCRIPTOR * pPtBuffDesc);
|
|
// Allocate the buffer and start Intel PT for current processor
|
|
NTSTATUS StartCpuTrace(PT_TRACE_DESC trace_desc, QWORD qwBuffSize = 0ui64);
|
|
// Start the tracing for a Process
|
|
NTSTATUS StartProcessTrace(DWORD dwProcId, QWORD qwBuffSize = 0ui64);
|
|
// Disable Intel PT for the current processor
|
|
NTSTATUS StopAndDisablePt();
|
|
// Put the tracing in PAUSE mode
|
|
NTSTATUS PauseResumeTrace(BOOLEAN bPause);
|
|
// Map a physical page buffer to the current User-mode process
|
|
NTSTATUS MapTracePhysBuffToUserVa(DWORD dwCpuId);
|
|
// Unmap the memory-mapped physical memory from User mode
|
|
NTSTATUS UnmapTraceBuffToUserVa(DWORD dwCpuId);
|
|
// Allocate a Trace buffer for the current CPU
|
|
NTSTATUS AllocPtBuffer(PT_BUFFER_DESCRIPTOR ** lppBuffDesc, QWORD qwSize, BOOLEAN bUseTopa = TRUE);
|
|
// Free a PT trace buffer (use with caution, avoid BSOD please)
|
|
NTSTATUS FreePtBuffer(PT_BUFFER_DESCRIPTOR * ptBuffDesc);
|
|
// Allocate a Trace buffer for a specific CPU
|
|
NTSTATUS AllocCpuPtBuffer(DWORD dwCpuId, QWORD qwSize, BOOLEAN bUseToPA);
|
|
// Free the resources used by a CPU
|
|
NTSTATUS FreeCpuResources(DWORD dwCpuId);
|
|
// Get if the PT buffer is allocated and valid for a particular processor
|
|
QWORD IsPtBufferAllocatedAndValid(DWORD dwCpuId, BOOLEAN bTestUserVa = FALSE);
|
|
// Clear the PT buffer
|
|
NTSTATUS ClearCpuPtBuffer(DWORD dwCpuId);
|
|
// Get the active Trace options for a particular CPU
|
|
NTSTATUS GetTraceOptions(DWORD dwCpuId, TRACE_OPTIONS * pOptions);
|
|
// Set the trace options for a particular CPU
|
|
NTSTATUS SetTraceOptions(DWORD dwCpuId, TRACE_OPTIONS options);
|
|
// Set the default trace options for a particular CPU
|
|
NTSTATUS SetDefaultTraceOptions(DWORD dwCpuId);
|
|
// Allocate and set a ToPA (with the Windows API)
|
|
NTSTATUS AllocAndSetTopa(PT_BUFFER_DESCRIPTOR ** lppBuffDesc, QWORD qwReqBuffSize, BOOLEAN bSetPmiAndStop = TRUE);
|
|
// Register the LVT (Local Vector Table) PMI interrupt
|
|
NTSTATUS RegisterPmiInterrupt();
|
|
// Deregister and remove the LVT PMI interrupt
|
|
NTSTATUS UnregisterPmiInterrupt();
|
|
// Check and clean the dead PMI callbacks
|
|
NTSTATUS CheckUserPmiCallbackList();
|
|
// Clear the user PMI Callback list and free the memory
|
|
NTSTATUS ClearAndFreePmiCallbackList();
|
|
// The PMI LVT handler routine (Warning! This should run at very high IRQL)
|
|
VOID IntelPtPmiHandler(PKTRAP_FRAME pTrapFrame);
|
|
BOOLEAN PmiInterruptHandler(struct _KINTERRUPT *Interrupt, PVOID ServiceContext);
|
|
// The PMI DPC routine
|
|
VOID IntelPmiDpc(struct _KDPC *Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
|
|
// The PMI Work Item
|
|
VOID IntelPmiWorkItem(PVOID Parameter);
|
|
|
|
#pragma region Kernel Tracing Test Routines and IOCTLs
|
|
#ifdef _DEBUG
|
|
// Kernel Tracing Test IOCTL
|
|
#define IOCTL_PTDR_DO_KERNELDRV_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0xA0C, METHOD_BUFFERED, FILE_EXECUTE)
|
|
|
|
// Do a Kernel trace of a driver test:
|
|
NTSTATUS DoDriverTraceTest(LPTSTR lpDrvFileName, LPTSTR lpDumpFile = NULL, DWORD dwBuffSize = 0);
|
|
#endif
|
|
#pragma endregion |