Monitors Windows API function calls in a guest by setting breakpoints on specified library/function names. Demonstrates breakpoint creation and event handling for a target process.
#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:
return;
std::cout << "[" << event.task().pid() << ':' << event.task().tid() << "] "
<< event.task().process_name() << '\n';
std::cout <<
" Hit breakpoint " <<
name_ <<
'\n';
const auto& vcpu = event.vcpu();
const auto& regs = vcpu.registers();
auto test = ppreturn_address.get();
this, std::placeholders::_1));
std::cout.flush();
}
return;
std::cout << " BAD return RSP 0x" << std::hex << event.vcpu().registers().rsp()
<< std::dec <<
" for " <<
name_ <<
"\n";
return;
}
std::cout << "[" << event.task().pid() << ':' << event.task().tid() << "] "
<< event.task().process_name() << '\n';
std::cout <<
" Return hit for " <<
name_ << std::endl;
}
:
domain_(src.domain_),
bp_(std::move(src.bp_)),
name_(std::move(src.name_)),
}
bp_ = std::move(src.bp_);
name_ = std::move(src.name_);
return *this;
}
uint64_t pid)
}
public:
std::shared_ptr<Breakpoint>
bp_;
};
public:
case EventType::EVENT_CR_WRITE:
return;
break;
default:
std::cout << "Unhandled event: " << event.type() << '\n';
break;
}
std::lock_guard<std::mutex> lock(mtx_);
if (ready_)
return;
auto& process =
static_cast<WindowsEvent&
>(event).task().pcr().CurrentThread().Process();
auto vadroot = process.VadRoot();
if (!vadroot)
return;
for (auto entry : vadroot->VadTreeInOrder()) {
if (!entry->Protection().isExecutable())
continue;
auto file_object = entry->FileObject();
if (!file_object)
continue;
if (boost::algorithm::ends_with(file_object->FileName(), "ntdll.dll")) {
auto lib =
auto& pdb = lib->pdb();
for (const auto& symbol : pdb.global_symbols()) {
if (symbol->function() || symbol->code()) {
if (!boost::starts_with(symbol->name(), "Nt"))
continue;
if (symbol->name() == "KiUserCallbackDispatch" ||
symbol->name() == "KiUserCallbackDispatcher")
continue;
std::cout << "Adding breakpoint for " << symbol->name() << '\n';
try {
entry->StartingAddress() + symbol->image_offset());
breakpoints_.emplace_back(event.
domain(), ptr, symbol->
name(),
process.UniqueProcessId());
std::cout << " Not present!\n";
}
}
}
if (flush_)
std::cout.flush();
event.domain().intercept_cr_writes(3, false);
ready_ = true;
return;
}
}
}
private:
std::mutex mtx_;
const bool flush_;
bool ready_ = false;
std::vector<BreakpointHandler> breakpoints_;
};
int main(
int argc,
char** argv) {
po::options_description desc("Options");
std::string domain_name;
std::string process_name;
desc.add_options()
("domain,D", po::value<std::string>(&domain_name)->required(), "The domain name or ID attach to")
("procname", po::value<std::string>(&process_name)->required(), "A process name to filter for")
("no-flush", "Don't flush the output buffer after each event")
("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;
}
if (!process_name.empty())
domain->task_filter().add_name(process_name);
domain->intercept_cr_writes(3,
true);
return 0;
}
po::variables_map& vm) {
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("help")) {
std::cout << "ivcallmon - Watch guest library calls" << '\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 ivcallmon.cc:51
void return_hit(Event &event)
Definition ivcallmon.cc:84
Domain * domain_
Definition ivcallmon.cc:127
std::shared_ptr< Breakpoint > return_bp_
Definition ivcallmon.cc:129
~BreakpointHandler()=default
std::shared_ptr< Breakpoint > bp_
Definition ivcallmon.cc:128
std::string name_
Definition ivcallmon.cc:130
uint64_t return_rsp_
Definition ivcallmon.cc:132
uint64_t return_tid_
Definition ivcallmon.cc:133
BreakpointHandler & operator=(BreakpointHandler &&src) noexcept
Definition ivcallmon.cc:108
uint64_t pid_
Definition ivcallmon.cc:131
void breakpoint_hit(Event &event)
Definition ivcallmon.cc:53
Definition ivcallmon.cc:136
~CallMonitor()
Definition ivcallmon.cc:202
void process_event(Event &event) override
Process an incoming event.
Definition ivcallmon.cc:138
virtual int index() const =0
A class representing a single Domain.
Definition Domain.hh:44
virtual std::string name() const =0
Get the name of the Domain, if it exists.
virtual std::shared_ptr< Breakpoint > create_breakpoint(const guest_ptr< void > &address, std::function< void(Event &)> callback)=0
Create an execution breakpoint.
Interface for an event poller callback.
Definition EventCallback.hh:29
Interface class for hypervisor events.
Definition Event.hh:43
virtual Domain & domain()=0
Get the Domain that the event is for.
virtual EventTaskInformation & task()=0
Get the task information.
virtual EventType type() const =0
Get the type of event.
virtual ControlRegisterEvent & cr()=0
Get control register access event information.
virtual Vcpu & vcpu()=0
Get the Vcpu that triggered the event.
virtual Registers & registers()=0
Get the processor's registers.
Thrown when translating a guest virtual address is marked as not present.
Definition VirtualAddressNotPresentException.hh:31
Definition guest_ptr.hh:88
auto get() const
Definition guest_ptr.hh:246
Definition WindowsEvent.hh:26
virtual uint64_t rsp() const =0
Get the rsp register value.
std::unique_ptr< Domain > domain
Definition ivcallmon.cc:44
bool interrupted
Definition ivcallmon.cc:43
int main(int argc, char **argv)
Definition main.c:35
Classes related to Microsoft Windows guests.
Definition LanguageId.hh:21
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