Monitors CR3 (page-directory base) writes in the guest. Demonstrates control-register write events (EVENT_CR_WRITE) and logging context switches.
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <csignal>
#include <iostream>
#include <mutex>
#include <string>
namespace po = boost::program_options;
po::variables_map& vm);
std::unique_ptr<Domain>
domain;
}
public:
case EventType::EVENT_CR_WRITE:
return;
break;
default:
std::cout << "Unhandled event: " << event.type() << '\n';
break;
}
const Vcpu& vcpu =
event.vcpu();
const auto cr3 = regs.
cr3();
const auto pid = event.task().pid();
const auto tid = event.task().tid();
const auto name = event.task().process_name();
std::lock_guard lock(mtx_);
if (!json_) {
std::cout <<
"Vcpu " << vcpu.
id() <<
": 0x" << std::hex << cr3 <<
" -> 0x"
<< event.cr().value() << std::dec << '\n';
std::cout << " [" << pid << ':' << tid << "] ";
std::cout << name << '\n';
} else {
std::cout << event.json() << '\n';
}
if (flush_)
std::cout.flush();
}
CR3Monitor(
bool flush,
bool json) : flush_(flush), json_(json) {}
private:
std::mutex mtx_;
const bool flush_;
const bool json_;
};
int main(
int argc,
char** argv) {
po::options_description desc("Options");
std::string domain_name;
desc.add_options()
("domain,D", po::value<std::string>(&domain_name)->required(), "The domain name or ID attach to")
("no-flush", "Don't flush the output buffer after each event")
("json", "Output JSON format")
("help", "Display program help");
std::cout.sync_with_stdio(false);
po::variables_map vm;
auto hypervisor = Hypervisor::instance();
domain = hypervisor->attach_domain(domain_name);
if (!
domain->detect_guest()) {
std::cerr << "Failed to detect guest OS\n";
return 1;
}
domain->intercept_cr_writes(3,
true);
CR3Monitor monitor(!vm.count(
"no-flush"), vm.count(
"json"));
return 0;
}
po::variables_map& vm) {
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("help")) {
std::cout << "ivcr3mon - Watch guest CR3 writes" << '\n';
std::cout << desc << '\n';
exit(0);
}
po::notify(vm);
} catch (po::error& e) {
std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
std::cerr << desc << std::endl;
exit(1);
}
}
Definition ivcr3mon.cc:50
~CR3Monitor()
Definition ivcr3mon.cc:88
void process_event(Event &event) override
Process an incoming event.
Definition ivcr3mon.cc:52
virtual int index() const =0
Interface for an event poller callback.
Definition EventCallback.hh:29
Interface class for hypervisor events.
Definition Event.hh:43
virtual EventType type() const =0
Get the type of event.
virtual ControlRegisterEvent & cr()=0
Get control register access event information.
A class representing a single virtual processor.
Definition Vcpu.hh:33
virtual Registers & registers()=0
Get the processor's registers.
virtual uint32_t id() const =0
Get the number of this Vcpu.
A class for holding x86 register state.
Definition Registers.hh:33
virtual uint64_t cr3() const =0
Get control register 3.
bool interrupted
Definition ivcallmon.cc:43
int main(int argc, char **argv)
Definition main.c:35
Core IntroVirt classes.
Definition Cr0.hh:20
void sig_handler(int signum)
Definition vmcall_interface.cc:571
void parse_program_options(int argc, char **argv, po::options_description &desc, po::variables_map &vm)
Definition vmcall_interface.cc:581
unique_ptr< Domain > domain
Definition vmcall_interface.cc:48