Reads a file from the guest into the host. Uses injected NtOpenFile and NtReadFile (or equivalent) to copy guest file contents. Demonstrates guest allocation (inject::allocate), system-call injection, and EventCallback-based waiting.
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#include <csignal>
#include <cstring>
#include <iostream>
#include <memory>
#include <sys/types.h>
using namespace std;
namespace po = boost::program_options;
po::variables_map& vm);
std::unique_ptr<Domain>
domain;
}
public:
result_ = 1;
auto src_path = inject::allocate<nt::UNICODE_STRING>("\\??\\" + src_path_);
auto object_attributes = inject::allocate<nt::OBJECT_ATTRIBUTES>();
auto io_status_block = inject::allocate<nt::IO_STATUS_BLOCK>();
object_attributes->ObjectNamePtr(src_path);
object_attributes->Attributes(OBJECT_ATTRIBUTES::OBJ_CASE_INSENSITIVE);
uint64_t src_file;
src_file,
object_attributes,
io_status_block,
nullptr,
nullptr,
0
);
std::cout <<
"Failed to open source file: " <<
result <<
'\n';
return;
}
FILE* dst_file = fopen(dst_path_.c_str(), "w");
if (!dst_file) {
std::cout << "Failed to open destination file: " << strerror(errno) << '\n';
return;
}
while (true) {
inject::system_call<nt::NtReadFile>(src_file, 0, nullptr, nullptr, io_status_block,
if (fwrite(buffer.ptr().get(), 1, io_status_block->Information(), dst_file) < 0) {
std::cout << "Failed to write to destination file: " << strerror(errno) << '\n';
break;
}
continue;
}
result_ = 0;
break;
}
std::cout <<
"Failed to read from source file: " <<
result <<
'\n';
break;
}
result = inject::system_call<NtClose>(src_file);
std::cout <<
"Failed to close source file: " <<
result <<
'\n';
}
fclose(dst_file);
}
event.
type() == EventType::EVENT_REBOOT)) {
exit(64);
}
if (event.
type() == EventType::EVENT_FAST_SYSCALL) {
if (copy_started_.test_and_set() == 0) {
event.domain().interrupt();
}
}
}
ReadFileTool(
const std::string& src_path,
const std::string& dst_path)
: src_path_(src_path), dst_path_(dst_path) {}
int result()
const {
return result_; }
private:
const std::string src_path_;
const std::string dst_path_;
int result_;
std::atomic_flag copy_started_ = false;
};
int main(
int argc,
char** argv) {
po::options_description desc("Options");
std::string domain_name;
std::string process_name;
std::string source_file;
std::string dest_file;
desc.add_options()
("domain,D", po::value<std::string>(&domain_name)->required(), "The domain name or ID attach to")
("source_file,s", po::value<std::string>(&source_file)->required(), "The path to the source file in the guest")
("dest_file,d", po::value<std::string>(&dest_file)->required(), "The destination file to write")
("process_name,P", po::value<std::string>(&process_name)->default_value("explorer"), "The name of a process to hijack")
("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 (
domain->guest()->os() != OS::Windows) {
std::cerr <<
"Unsupported OS: " <<
domain->guest()->os() <<
'\n';
return 1;
}
domain->task_filter().add_name(process_name);
domain->intercept_system_calls(
true);
return tool.result();
}
po::variables_map& vm) {
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
if (vm.count("help")) {
std::cout << "ivreadfile - Write a file into the guest" << '\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);
}
}
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.
Definition FILE_SHARE_ACCESS.hh:31
Status codes returned by Windows NT system calls.
Definition NTSTATUS.hh:34
#define unlikely(x)
Definition compiler.hh:27
bool interrupted
Definition ivcallmon.cc:43
int main(int argc, char **argv)
Definition main.c:35
#define BUFFER_SIZE
Definition main.c:16
Classes related to the Windows NT kernel.
Definition APPHELPCACHESERVICECLASS.hh:23
@ STATUS_END_OF_FILE
Definition NTSTATUS_CODE.hh:229
@ GENERIC_READ
Generic read access.
Definition ACCESS_MASK.hh:79
@ SYNCHRONIZE
Definition ACCESS_MASK.hh:52
@ FILE_NON_DIRECTORY_FILE
Definition FileCreateOptions.hh:32
@ FILE_SYNCHRONOUS_IO_NONALERT
Definition FileCreateOptions.hh:31
@ FILE_ATTRIBUTE_NORMAL
Definition FILE_ATTRIBUTES.hh:35
@ FILE_OPEN
Definition CreateFileDisposition.hh:26
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