The Executive Profile Object

The EPROFILE structure is the kernel’s representation of an executive profile object such as can be created from user mode by the NtCreateProfile and NtCreateProfileEx functions and worked with through the NtStartProfile and NtStopProfile functions.

The name EPROFILE is hypothesised, Microsoft’s name not being known even from symbol files. That is some measure of the structure’s being internal to the kernel. Against that, however, is that the structure does model a formal object that exists precisely so that a handle can be obtained from user mode. As for any handle, it can be useful to inspect the corresponding object when doing kernel-mode debugging. Indeed, any user-mode program that knows the handle can obtain the kernel-mode address of the object via NtQuerySystemInformation without needing unusual privilege and can even read from the address with the help of a kernel-mode driver (which sounds more demanding than it often is).


Though the EPROFILE is too internal to be described even in symbol files, it is almost as stable as many a documented structure, presumably as a side-effect of its very tightly constrained use. After version 3.51 allowed for specification of the profile source and of which processors will have their execution profiled, the only formal change is for Windows 7 to support more than 32 or 64 processors by way of processor groups. That the size then increases for 64-bit Windows 8 is simply from allowing for more processor groups.

Version Size (x86) Size (x64)
3.10 to 3.50 0x28  
3.51 to 6.0 0x30 0x50
6.1 0x38 0x70
6.2 to 10.0 0x38 0xF0

The layout below does not attempt any C-language definition of members as if such things can be inferred from type information in symbol files. Types in a fixed-pitch font as if for programming are ventured only where the member is copied from a function argument such that Microsoft’s choice of formal type is known and plausibly (but not certainly) passes into the structure.

Offset (x86) Offset (x64) Type Description
0x00 0x00 pointer address of EPROCESS for process whose address space is profiled;
else NULL if profiling globally
0x04 0x08
start address of profiled area;
else NULL if profiling a segment (x86 only)
0x08 0x10
size, in bytes, of profiled area
0x0C 0x18
user-supplied address of buffer that is to receive execution counts
0x10 0x20
size, in bytes, of buffer that is to receive execution counts
0x14 0x24
logarithm base 2 of size, in bytes, of bucket for sampling the profiled area
0x18 0x28 pointer while profiling is started:
address of kernel profile object
0x1C 0x30 pointer address of buffer that is to receive execution counts;
as locked into physical memory and mapped into system address space;
else NULL while profiling is not started
0x20 0x38 pointer while profiling is started:
address of MDL for buffer that is to receive execution counts
0x24 0x40 dword segment address of profiled area (x86 only);
else zero

Appended for Version 3.51

Offset (x86) Offset (x64) Type Description
0x28 0x44
profile source for generation of profile interrupt
0x2C 0x48 KAFFINITY (3.51 to 6.0);
KAFFINITY_EX (6.1 and higher)
processors to be profiled