Prints the Windows guest service table (dispatch table). Demonstrates attaching to a domain, guest detection, and reading kernel structures to enumerate services.
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;
namespace po = boost::program_options;
po::variables_map& vm);
int main(
int argc,
char** argv) {
po::options_description desc("Options");
std::string domain_name;
std::vector<std::string> names;
std::vector<uint64_t> pids;
desc.add_options()
("domain,D", po::value<std::string>(&domain_name)->required(), "The domain name or ID attach to")
("help", "Display program help");
po::variables_map vm;
auto hypervisor = Hypervisor::instance();
auto domain = hypervisor->attach_domain(domain_name);
if (!
domain->detect_guest()) {
std::cerr << "Failed to detect guest operating system\n";
return 1;
}
auto* guest =
domain->guest();
if (guest->os() != OS::Windows) {
std::cerr << "Unsupported OS: " << guest->os() << '\n';
return 2;
}
const auto& pdb = kernel.
pdb();
std::cout << std::hex;
for (unsigned int i = 0; i < nt_table.length(); ++i) {
const auto& entry = nt_table.
entry(i);
std::cout << "0x" << std::setw(4) << std::setfill('0') << i << " " << entry << " ";
const uint64_t rva = entry.address() - kernel.
ptr().address();
const auto* symbol = pdb.rva_to_symbol(rva);
if (!symbol)
continue;
std::cout << ": " << symbol->name() << '\n';
}
for (auto& module : kernel.PsLoadedModuleList()) {
if (module->BaseDllName() == "win32k.sys") {
pWin32k = kernel.
ptr().clone(module->DllBase());
break;
}
}
std::cout << "Failed to find Win32k module\n";
return 1;
}
const auto& win32k_table = service_table.entry(1).service_table();
bool success = false;
for (auto& entry : CidTable->open_handles()) {
std::unique_ptr<nt::OBJECT_HEADER> header(entry->ObjectHeader());
if (header->type() == nt::ObjectType::Process) {
auto process = kernel.
process(header->Body());
if (process->Win32Process()) {
try {
pWin32k.
domain(), pWin32k.
address(), process->DirectoryTableBase()));
std::cout << std::hex;
for (unsigned int i = 0; i < win32k_table.length(); ++i) {
const auto& entry = win32k_table.entry(i);
std::cout << "0x" << std::setw(4) << std::setfill('0') << (i + 0x1000)
<< " " << entry << " ";
const uint64_t rva = entry.address() - pWin32k.
address();
const auto* symbol = win32k->pdb().rva_to_symbol(rva);
std::cout << ": " << symbol->name() << '\n';
}
success = true;
break;
}
}
}
}
if (!success) {
std::cout << "Failed to parse win32k service table\n";
return 1;
}
return 0;
}
po::variables_map& vm) {
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("help")) {
std::cout << "ivprocinfo - Display process information" << '\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);
}
}
Base class for exceptions with stack unwinding.
Definition TraceableException.hh:31
Definition guest_ptr.hh:88
uint64_t address() const
Functions for getting the underlying address.
Definition guest_ptr.hh:124
const Domain & domain() const
Definition guest_ptr.hh:144
virtual const ServiceTable & service_table() const =0
Get the ServiceTable this entry points to.
virtual const ServiceDescriptorTableEntry & entry(unsigned int index) const =0
Get the service descriptor table entry at the given index.
virtual guest_ptr< void > entry(unsigned int index) const =0
Get the address for the specified entry.
A representation of a Windows Guest OS.
Definition WindowsGuest.hh:33
Abstraction for the Windows NT kernel.
Definition NtKernel.hh:37
virtual std::unique_ptr< HANDLE_TABLE > CidTable()=0
Get the PspCidTable from the kernel.
virtual const guest_ptr< void > & ptr() const =0
Get the base address of the kernel.
virtual const ServiceDescriptorTable & KeServiceDescriptorTableShadow() const =0
Get the KeServiceDescriptorTableShadow.
virtual std::shared_ptr< PROCESS > process(const guest_ptr< void > &ptr) const =0
Get the PROCESS at the given address.
virtual const mspdb::PDB & pdb() const =0
Get the PDB file for this type container.
#define unlikely(x)
Definition compiler.hh:27
int main(int argc, char **argv)
Definition main.c:35
Classes related to the Windows NT kernel.
Definition APPHELPCACHESERVICECLASS.hh:23
Classes related to parsing the PE file format in memory.
Definition FileFlags.hh:22
Classes related to Microsoft Windows guests.
Definition LanguageId.hh:21
Core IntroVirt classes.
Definition Cr0.hh:20
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