Bareflank: Counting the number of CPUID instructions (Part #1)

Counting the number of CPUID instructions using Bareflank is simple. There are two different ways to do this: modifying Bareflank itself, and creating an extension. In this post, we will focus on the first approach. Before we begin, we will need a working version of Bareflank:

cd ~/ git clone mkdir ~/hypervisor/build cd ~/hypervisor/build cmake .. make

Once the hypervisor is compiled, test it to make sure it is working before we attempt to modify it to count the number of CPUID instructions:

make driver_quick make quick make dump make unload

The easiest way to count CPUID instructions is to directly modify the following file in Bareflank. First, add the following to the top of the file to create a "count" variable that can be atomically incremented:

#include <atomic> std::atomic count = 0;
Next, increment the count variable in the "handle_cpuid" function:

void exit_handler_intel_x64::handle_cpuid() { auto ret = x64::cpuid::get(gsl::narrow_cast(m_state_save->rax), gsl::narrow_cast(m_state_save->rbx), gsl::narrow_cast(m_state_save->rcx), gsl::narrow_cast(m_state_save->rdx)); m_state_save->rax = ret.rax; m_state_save->rbx = ret.rbx; m_state_save->rcx = ret.rcx; m_state_save->rdx = ret.rdx; count.fetch_add(1); // Added to existing code advance_rip(); }
Finally, print the count when disabling the hypervisor:

void exit_handler_intel_x64::promote(gsl::not_null guest_gdt) { std::cout << "count: " << count << '\n'; // Added to existing code m_vmcs->promote(guest_gdt); }