

Internally, this function calls KeQueryIntervalProfile(), which is shown in the next code snippet (taken from the 32-bit version of Windows):Ĩ09a1b27 ff157c408980 call dword ptr Ĩ09a1b37 8b45fc mov eax,dword ptr Īs we can see from the snippet the function ends up hitting an indirect CALL using the pointer stored at (the second entry of the HalDispatchTable). This entry is used by an undocumented system call ( NtQueryIntervalProfile()) that is not frequently used. The second entry within the HalDispatchTable fits our needs. Since the payload exists only in the current process address space, trying to execute it while in a different process will likely trigger a kernel crash. When overwriting a function pointer with a user-land address (for example when the payload is located in user space like in our case) we have to take care that no other processes will ever execute the routine addressed by the overwritten pointer. After gathering its base address we have to find a suitable entry that is called by a low-frequency routine. This technique was originally used by Ruben Santamarta and described in his excellent paper, “Exploiting Common Flaws in Drivers.” 5 This technique has been chosen among the others mainly for a few reasons: it doesn't need a mandatory recovery, it is stable, and at the time of writing it can also be successfully used on the 圆4 Windows platform.įirst, the HalDispatchTable is located in the Kernel Executive and owns a corresponding exported symbol that can be found using the method presented in the “Kernel Information Gathering” section.


This section will show how to overwrite the HalDispatchTable to execute code at Ring 0. We can think, for example, of the main System Call Table ( KiServiceTable) used to invoke kernel system calls (based on an system call index given by the user-land process), or of the Hardware Abstraction Layer (HAL) dispatch table ( HalDispatchTable), which is stored in the Kernel Executive and holds the addresses of a few HAL routines. They are mainly used to add a level of indirection between two or more layers (either within or outside the same kernel component/driver).

Kernel dispatch tables usually hold function pointers. Enrico Perla, Massimiliano Oldani, in A Guide to Kernel Exploitation, 2011 Overwriting Kernel Dispatch Tables
