mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-22 21:21:03 +00:00
@@ -12,7 +12,8 @@ namespace
|
||||
bool use_gdb{false};
|
||||
bool concise_logging{false};
|
||||
bool verbose_logging{false};
|
||||
std::string root_filesystem{"./root"};
|
||||
std::string registry_path{"./registry"};
|
||||
std::string emulation_root{};
|
||||
};
|
||||
|
||||
void watch_system_objects(windows_emulator& win_emu, const bool cache_logging)
|
||||
@@ -107,7 +108,8 @@ namespace
|
||||
|
||||
emulator_settings settings{
|
||||
.application = args[0],
|
||||
.root_filesystem = options.root_filesystem,
|
||||
.registry_directory = options.registry_path,
|
||||
.emulation_root = options.emulation_root,
|
||||
.arguments = parse_arguments(args),
|
||||
.silent_until_main = options.concise_logging,
|
||||
};
|
||||
@@ -209,14 +211,23 @@ namespace
|
||||
{
|
||||
options.concise_logging = true;
|
||||
}
|
||||
else if (arg == "-e")
|
||||
{
|
||||
if (args.size() < 2)
|
||||
{
|
||||
throw std::runtime_error("No emulation root path provided after -e");
|
||||
}
|
||||
arg_it = args.erase(arg_it);
|
||||
options.emulation_root = args[0];
|
||||
}
|
||||
else if (arg == "-r")
|
||||
{
|
||||
if (args.size() < 2)
|
||||
{
|
||||
throw std::runtime_error("No root path provided after -r");
|
||||
throw std::runtime_error("No registry path provided after -r");
|
||||
}
|
||||
arg_it = args.erase(arg_it);
|
||||
options.root_filesystem = args[0];
|
||||
options.registry_path = args[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace test
|
||||
inline windows_emulator create_sample_emulator(emulator_settings settings, emulator_callbacks callbacks = {})
|
||||
{
|
||||
settings.application = "c:/test-sample.exe";
|
||||
settings.root_filesystem = get_emulator_root();
|
||||
settings.emulation_root = get_emulator_root();
|
||||
return windows_emulator{std::move(settings), std::move(callbacks)};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
class file_system
|
||||
{
|
||||
public:
|
||||
file_system(std::filesystem::path root, windows_path working_dir)
|
||||
file_system(std::filesystem::path root, windows_path working_dir = "C:\\")
|
||||
: root_(std::move(root)),
|
||||
working_dir_(std::move(working_dir))
|
||||
{
|
||||
@@ -26,6 +26,7 @@ class file_system
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: Sanitize path to prevent traversal!
|
||||
return this->root_ / full_path.to_portable_path();
|
||||
}
|
||||
|
||||
|
||||
@@ -1530,7 +1530,7 @@ namespace
|
||||
if (!f->enumeration_state || query_flags & SL_RESTART_SCAN)
|
||||
{
|
||||
f->enumeration_state.emplace(file_enumeration_state{});
|
||||
f->enumeration_state->files = scan_directory(c.win_emu.file_sys.translate(f->name));
|
||||
f->enumeration_state->files = scan_directory(c.win_emu.file_sys().translate(f->name));
|
||||
}
|
||||
|
||||
auto& enum_state = *f->enumeration_state;
|
||||
@@ -2586,7 +2586,7 @@ namespace
|
||||
const emulator_object<LARGE_INTEGER> /*default_casing_table_size*/)
|
||||
{
|
||||
const auto locale_file =
|
||||
utils::io::read_file(c.win_emu.file_sys.translate(R"(C:\Windows\System32\locale.nls)"));
|
||||
utils::io::read_file(c.win_emu.file_sys().translate(R"(C:\Windows\System32\locale.nls)"));
|
||||
if (locale_file.empty())
|
||||
{
|
||||
return STATUS_FILE_INVALID;
|
||||
@@ -2826,14 +2826,14 @@ namespace
|
||||
if (create_disposition & FILE_CREATE)
|
||||
{
|
||||
std::error_code ec{};
|
||||
std::filesystem::create_directory(c.win_emu.file_sys.translate(f.name), ec);
|
||||
create_directory(c.win_emu.file_sys().translate(f.name), ec);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
return STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
else if (!std::filesystem::is_directory(c.win_emu.file_sys.translate(f.name)))
|
||||
else if (!std::filesystem::is_directory(c.win_emu.file_sys().translate(f.name)))
|
||||
{
|
||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
@@ -2855,7 +2855,7 @@ namespace
|
||||
|
||||
FILE* file{};
|
||||
|
||||
const auto error = open_unicode(&file, c.win_emu.file_sys.translate(f.name), mode);
|
||||
const auto error = open_unicode(&file, c.win_emu.file_sys().translate(f.name), mode);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
@@ -2900,7 +2900,7 @@ namespace
|
||||
|
||||
c.win_emu.log.print(color::dark_gray, "--> Querying file attributes: %s\n", u16_to_u8(filename).c_str());
|
||||
|
||||
const auto local_filename = c.win_emu.file_sys.translate(filename).string();
|
||||
const auto local_filename = c.win_emu.file_sys().translate(filename).string();
|
||||
|
||||
struct _stat64 file_stat{};
|
||||
if (_stat64(local_filename.c_str(), &file_stat) != 0)
|
||||
|
||||
@@ -216,7 +216,9 @@ namespace
|
||||
|
||||
setup_gdt(emu);
|
||||
|
||||
context.registry = registry_manager(win_emu.root_directory / "registry");
|
||||
context.registry =
|
||||
registry_manager(win_emu.get_emulation_root().empty() ? settings.registry_directory
|
||||
: win_emu.get_emulation_root() / "registry");
|
||||
|
||||
context.kusd.setup(settings.use_relative_time);
|
||||
|
||||
@@ -268,7 +270,7 @@ namespace
|
||||
|
||||
allocator.make_unicode_string(proc_params.CommandLine, command_line);
|
||||
allocator.make_unicode_string(proc_params.CurrentDirectory.DosPath,
|
||||
win_emu.file_sys.get_working_directory().u16string());
|
||||
win_emu.file_sys().get_working_directory().u16string());
|
||||
allocator.make_unicode_string(proc_params.ImagePathName, application_str);
|
||||
|
||||
const auto total_length = allocator.get_next_address() - context.process_params.value();
|
||||
@@ -280,7 +282,7 @@ namespace
|
||||
|
||||
apiset_location apiset_loc = apiset_location::file;
|
||||
|
||||
if (win_emu.root_directory.empty())
|
||||
if (win_emu.get_emulation_root().empty())
|
||||
{
|
||||
#ifdef OS_WINDOWS
|
||||
apiset_loc = apiset_location::host;
|
||||
@@ -292,7 +294,7 @@ namespace
|
||||
context.peb.access([&](PEB64& peb) {
|
||||
peb.ImageBaseAddress = nullptr;
|
||||
peb.ProcessParameters = context.process_params.ptr();
|
||||
peb.ApiSetMap = build_api_set_map(emu, allocator, apiset_loc, win_emu.root_directory).ptr();
|
||||
peb.ApiSetMap = build_api_set_map(emu, allocator, apiset_loc, win_emu.get_emulation_root()).ptr();
|
||||
|
||||
peb.ProcessHeap = nullptr;
|
||||
peb.ProcessHeaps = nullptr;
|
||||
@@ -825,15 +827,15 @@ std::unique_ptr<x64_emulator> create_default_x64_emulator()
|
||||
|
||||
windows_emulator::windows_emulator(const emulator_settings& settings, emulator_callbacks callbacks,
|
||||
std::unique_ptr<x64_emulator> emu)
|
||||
: windows_emulator(settings.root_filesystem, std::move(emu))
|
||||
: windows_emulator(settings.emulation_root, std::move(emu))
|
||||
{
|
||||
if (!settings.working_directory.empty())
|
||||
{
|
||||
this->file_sys.set_working_directory(settings.working_directory);
|
||||
this->file_sys().set_working_directory(settings.working_directory);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->file_sys.set_working_directory(settings.application.parent());
|
||||
this->file_sys().set_working_directory(settings.application.parent());
|
||||
}
|
||||
|
||||
this->silent_until_main_ = settings.silent_until_main && !settings.disable_logging;
|
||||
@@ -843,12 +845,19 @@ windows_emulator::windows_emulator(const emulator_settings& settings, emulator_c
|
||||
this->setup_process(settings);
|
||||
}
|
||||
|
||||
windows_emulator::windows_emulator(const std::filesystem::path& root_path, std::unique_ptr<x64_emulator> emu)
|
||||
: root_directory{absolute(root_path)},
|
||||
file_sys(root_directory / "filesys", u"C:\\"),
|
||||
windows_emulator::windows_emulator(const std::filesystem::path& emulation_root, std::unique_ptr<x64_emulator> emu)
|
||||
: emulation_root_{emulation_root.empty() ? emulation_root : absolute(emulation_root)},
|
||||
file_sys_(emulation_root_.empty() ? emulation_root_ : emulation_root_ / "filesys"),
|
||||
emu_(std::move(emu)),
|
||||
process_(*emu_, file_sys)
|
||||
process_(*emu_, file_sys_)
|
||||
{
|
||||
#ifndef OS_WINDOWS
|
||||
if (this->get_emulation_root().empty())
|
||||
{
|
||||
throw std::runtime_error("Emulation root directory can not be empty!");
|
||||
}
|
||||
#endif
|
||||
|
||||
this->setup_hooks();
|
||||
}
|
||||
|
||||
@@ -857,7 +866,7 @@ void windows_emulator::setup_process(const emulator_settings& settings)
|
||||
auto& emu = this->emu();
|
||||
|
||||
auto& context = this->process();
|
||||
context.mod_manager = module_manager(emu, this->file_sys); // TODO: Cleanup module manager
|
||||
context.mod_manager = module_manager(emu, this->file_sys()); // TODO: Cleanup module manager
|
||||
|
||||
setup_context(*this, settings);
|
||||
|
||||
@@ -1119,7 +1128,7 @@ void windows_emulator::start(std::chrono::nanoseconds timeout, size_t count)
|
||||
void windows_emulator::serialize(utils::buffer_serializer& buffer) const
|
||||
{
|
||||
buffer.write(this->use_relative_time_);
|
||||
this->file_sys.serialize(buffer);
|
||||
this->file_sys().serialize(buffer);
|
||||
this->emu().serialize(buffer);
|
||||
this->process_.serialize(buffer);
|
||||
this->dispatcher_.serialize(buffer);
|
||||
@@ -1136,7 +1145,7 @@ void windows_emulator::deserialize(utils::buffer_deserializer& buffer)
|
||||
});
|
||||
|
||||
buffer.read(this->use_relative_time_);
|
||||
this->file_sys.deserialize(buffer);
|
||||
this->file_sys().deserialize(buffer);
|
||||
|
||||
this->emu().deserialize(buffer);
|
||||
this->process_.deserialize(buffer);
|
||||
@@ -1148,7 +1157,7 @@ void windows_emulator::save_snapshot()
|
||||
this->emu().save_snapshot();
|
||||
|
||||
utils::buffer_serializer serializer{};
|
||||
this->file_sys.serialize(serializer);
|
||||
this->file_sys().serialize(serializer);
|
||||
this->process_.serialize(serializer);
|
||||
|
||||
this->process_snapshot_ = serializer.move_buffer();
|
||||
@@ -1168,7 +1177,7 @@ void windows_emulator::restore_snapshot()
|
||||
this->emu().restore_snapshot();
|
||||
|
||||
utils::buffer_deserializer deserializer{this->process_snapshot_};
|
||||
this->file_sys.deserialize(deserializer);
|
||||
this->file_sys().deserialize(deserializer);
|
||||
this->process_.deserialize(deserializer);
|
||||
// this->process_ = *this->process_snapshot_;
|
||||
}
|
||||
|
||||
@@ -29,14 +29,15 @@ struct emulator_settings
|
||||
{
|
||||
windows_path application{};
|
||||
windows_path working_directory{};
|
||||
std::filesystem::path root_filesystem{};
|
||||
std::filesystem::path registry_directory{"./registry"};
|
||||
std::filesystem::path emulation_root{};
|
||||
std::vector<std::u16string> arguments{};
|
||||
bool disable_logging{false};
|
||||
bool silent_until_main{false};
|
||||
bool use_relative_time{false};
|
||||
};
|
||||
|
||||
enum class apiset_location
|
||||
enum class apiset_location : uint8_t
|
||||
{
|
||||
host,
|
||||
file,
|
||||
@@ -47,7 +48,7 @@ enum class apiset_location
|
||||
class windows_emulator
|
||||
{
|
||||
public:
|
||||
windows_emulator(const std::filesystem::path& root_path,
|
||||
windows_emulator(const std::filesystem::path& emulation_root,
|
||||
std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
|
||||
windows_emulator(const emulator_settings& settings, emulator_callbacks callbacks = {},
|
||||
std::unique_ptr<x64_emulator> emu = create_default_x64_emulator());
|
||||
@@ -133,10 +134,25 @@ class windows_emulator
|
||||
return this->callbacks_;
|
||||
}
|
||||
|
||||
std::filesystem::path root_directory{};
|
||||
file_system file_sys;
|
||||
file_system& file_sys()
|
||||
{
|
||||
return this->file_sys_;
|
||||
}
|
||||
|
||||
const file_system& file_sys() const
|
||||
{
|
||||
return this->file_sys_;
|
||||
}
|
||||
|
||||
const std::filesystem::path& get_emulation_root()
|
||||
{
|
||||
return this->emulation_root_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::filesystem::path emulation_root_{};
|
||||
file_system file_sys_;
|
||||
|
||||
emulator_callbacks callbacks_{};
|
||||
bool use_relative_time_{false};
|
||||
bool silent_until_main_{false};
|
||||
|
||||
Reference in New Issue
Block a user