Detecting Hypervisor-assisted Hooking.

Max McNeal

Introduction

I've recently delved into the realm of hypervisors and their potential for circumventing commerical anti-cheat software and systems designed to prevent software tampering.

This article will outline the process of hypervisor-assisted hooking and introduce possible methods to detect these hooks.

Although the overall concept of hypervisors is expansive, a detailed discussion isn't necessary for the purpose of this overview, and we can simply define hypervisors as something that allows us to run virtual machines with hardware acceleration.

Virtualization via Hypervisors

Hypervisors facilitate virtualization by abstracting crucial components like privileged instructions or memory. This separation allows non-critical instructions to operate on actual hardware while privileged operations are intercepted and virtualized.

Using advanced technologies like Intel VT-X or AMD-V, modern hypervisors employ Second Level Address Translation (SLAT) to virtualize memory. This process involves a double translation of a virtual memory address to a physical location in RAM—first by the kernel and then by the hypervisor—allowing the host to control the memory of virtual machines.

These techniques are not limited to virtual machines; the CPU does not distinguish between the host OS and a virtualized OS, allowing the hypervisor to control the virtualization of all memory types, including the host OS.

Hypervisor-Assisted Hooking Mechanism

Hypervisor-assisted hooking manipulates code execution paths by redirecting code from a virtual page to a different physical page than the one used for reads or writes to that same virtual page. In this article, I'm just going to be focusing on Intel's EPT technology.

In short, address translation on x86 systems is managed through tables that define where virtual memory pages reside in physical memory. These pages are assigned various permissions (executable, readable, writable) which dictate their behavior:

We can exploit this system listed above to help us install our own stealth hooks.

  1. Clone the Physical Page: Create an original and a modified page.
  2. Adjust Permissions: Mark the entry in the page table of the original page as non-executable to intercept executions at the VM exit handler.
  3. Handler Intervention: The handler swaps the reference from the original to the modified page and reinitiates execution.
  4. Execute-only Permissions: Set the modified page to execute-only to ensure that reads and writes trigger a VM exit, allowing the hypervisor to continuously swap the original page back in, marked as non-executable. This swapping conceals the modified page from memory integrity checks.

Detecting These Hooks

Detecting hooks and other forms of memory manipulation typically involves reading memory and comparing it to its expected state, often through methods like hashing. However, with EPT hooks, any such reads will always reflect the original, unmodified page, rendering traditional integrity checks ineffective.

While it might be tempting to try detecting the hypervisor or driver itself, this approach has its limitations. Not all hypervisors are malicious or use EPT hooks for nefarious purposes. For instance, Microsoft's Hyper-V hypervisor actively maintains kernel integrity through HyperGuard on modern Windows systems, so detecting EPT hooks in this context might lead to false positives. Additionally, a hypervisor can conceal its presence from the list of loaded drivers using EPT hooks, rendering it invisible.

Given these challenges with traditional detection methods I explored other techniques to detect the presence of these EPT hooks:

The first check we can perform exploits the fact that VM exits and page swaps take some time. The idea is to create an execution pattern that triggers VM exits ude to EPT violations and measures the execution time.

  1. Setup: Find a return instruction (0xC3) in the target page and use it for the test.
  2. Execution Pattern: Measure the time for repeated readings of the instruction versus alternating between execution and reading.
  3. Measurement Tool: Use the RDTSC instruction to capture CPU ticks for timing.
  4. Analysis: Alternating between execution and reading should take significantly longer if an EPT hook is present, due to the induced VM exits and page swaps.

The only issue with the approach above is that the RDTSC instruction can be manipulated by a hypervisor, and external factors such as context switches can introduce to us false positives.

Improving upon the timing check, this method synchronizes two threads—one increments a counter, and the other performs the test—to reduce timing inaccuracies.

  1. Thread Management: Bind threads to different physical cores and adjust their priorities to minimize context switches.
  2. Repeated Measurements: Average the times from multiple tests to enhance reliability.

While this approach reduces the likelihood of false negatives, it's not entirely foolproof. Context switches affecting the counting thread but not the testing thread could still lead to false results.

Detecting These Hooks

In conclusion, hypervisors, while integral to modern computing for enabling efficient virtualization, can also be manipulated to create stealthy hooks that bypass many conventional security measures, such as commerical anti-cheat systems. Traditional detection methods prove ineffective against sophisticated EPT hooking techniques, as they fail to identify alterations made at the hypervisor level. However, through innovative side-channel detection methods such as timing and thread checks, it is possible to uncover these stealthy manipulations. Each method has its strengths and limitations, and while no single approach is foolproof, they collectively offer powerful tools for security experts to detect and mitigate unauthorized hypervisor activities, enhancing the integrity of systems against such advanced threats.

GO BACK HOME