From 7ae36a6452da5caae74fd127a600915bdfbb45b1 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Mon, 10 Feb 2025 16:37:33 +0100 Subject: [PATCH] Move registry manager into windows emulator --- src/analyzer/main.cpp | 2 +- src/fuzzer/main.cpp | 2 +- .../serialization_test.cpp | 4 +- src/windows-emulator/process_context.hpp | 4 -- .../registry/registry_manager.cpp | 19 ++------ .../registry/registry_manager.hpp | 3 -- src/windows-emulator/syscalls.cpp | 4 +- src/windows-emulator/windows_emulator.cpp | 44 +++++++++---------- src/windows-emulator/windows_emulator.hpp | 5 ++- 9 files changed, 32 insertions(+), 55 deletions(-) diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index 37063aaf..dbdb9cf0 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -119,8 +119,8 @@ namespace }; const emulator_settings settings{ - .registry_directory = options.registry_path, .emulation_root = options.emulation_root, + .registry_directory = options.registry_path, .verbose_calls = options.verbose_logging, .disable_logging = options.silent, .silent_until_main = options.concise_logging, diff --git a/src/fuzzer/main.cpp b/src/fuzzer/main.cpp index a76980c0..464c3fa6 100644 --- a/src/fuzzer/main.cpp +++ b/src/fuzzer/main.cpp @@ -42,7 +42,7 @@ namespace struct fuzzer_executer : fuzzer::executer { - windows_emulator emu{"./"}; // TODO: Fix root directory + windows_emulator emu{{.emulation_root = "./"}}; // TODO: Fix root directory std::span emulator_data{}; std::unordered_set visited_blocks{}; const std::function* handler{nullptr}; diff --git a/src/windows-emulator-test/serialization_test.cpp b/src/windows-emulator-test/serialization_test.cpp index 8ac40a42..97060080 100644 --- a/src/windows-emulator-test/serialization_test.cpp +++ b/src/windows-emulator-test/serialization_test.cpp @@ -49,7 +49,7 @@ namespace test utils::buffer_deserializer deserializer{serializer1.get_buffer()}; - windows_emulator new_emu{get_emulator_root()}; + windows_emulator new_emu{{.emulation_root = get_emulator_root()}}; new_emu.deserialize(deserializer); utils::buffer_serializer serializer2{}; @@ -92,7 +92,7 @@ namespace test utils::buffer_deserializer deserializer{serializer.get_buffer()}; - windows_emulator new_emu{get_emulator_root()}; + windows_emulator new_emu{{.emulation_root = get_emulator_root()}}; new_emu.log.disable_output(true); new_emu.deserialize(deserializer); diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index dec59678..39dd1bd7 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -36,8 +36,6 @@ struct process_context { } - registry_manager registry{}; - uint64_t executed_instructions{0}; uint64_t current_ip{0}; uint64_t previous_ip{0}; @@ -79,7 +77,6 @@ struct process_context void serialize(utils::buffer_serializer& buffer) const { - buffer.write(this->registry); buffer.write(this->executed_instructions); buffer.write(this->current_ip); buffer.write(this->previous_ip); @@ -118,7 +115,6 @@ struct process_context void deserialize(utils::buffer_deserializer& buffer) { - buffer.read(this->registry); buffer.read(this->executed_instructions); buffer.read(this->current_ip); buffer.read(this->previous_ip); diff --git a/src/windows-emulator/registry/registry_manager.cpp b/src/windows-emulator/registry/registry_manager.cpp index 2b9fb544..7f64b1d1 100644 --- a/src/windows-emulator/registry/registry_manager.cpp +++ b/src/windows-emulator/registry/registry_manager.cpp @@ -60,30 +60,17 @@ void registry_manager::setup() this->add_path_mapping(machine / "system" / "CurrentControlSet", machine / "system" / "ControlSet001"); } -void registry_manager::serialize(utils::buffer_serializer& buffer) const -{ - buffer.write(this->hive_path_); -} - -void registry_manager::deserialize(utils::buffer_deserializer& buffer) -{ - buffer.read(this->hive_path_); - this->setup(); -} - utils::path_key registry_manager::normalize_path(const utils::path_key& path) const { - const utils::path_key canonical_path = path; - for (const auto& mapping : this->path_mapping_) { - if (is_subpath(mapping.first.get(), canonical_path.get())) + if (is_subpath(mapping.first.get(), path.get())) { - return mapping.second.get() / canonical_path.get().lexically_relative(mapping.first.get()); + return mapping.second.get() / path.get().lexically_relative(mapping.first.get()); } } - return canonical_path.get(); + return path; } void registry_manager::add_path_mapping(const utils::path_key& key, const utils::path_key& value) diff --git a/src/windows-emulator/registry/registry_manager.hpp b/src/windows-emulator/registry/registry_manager.hpp index c5160d76..c041d2f2 100644 --- a/src/windows-emulator/registry/registry_manager.hpp +++ b/src/windows-emulator/registry/registry_manager.hpp @@ -46,9 +46,6 @@ class registry_manager registry_manager(const registry_manager&) = delete; registry_manager& operator=(const registry_manager&) = delete; - void serialize(utils::buffer_serializer& buffer) const; - void deserialize(utils::buffer_deserializer& buffer); - std::optional get_key(const utils::path_key& key); std::optional get_value(const registry_key& key, std::string name); diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 5fdf1aca..ddd59d1b 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -84,7 +84,7 @@ namespace c.win_emu.log.print(color::dark_gray, "--> Registry key: %s\n", u16_to_u8(key).c_str()); - auto entry = c.proc.registry.get_key({key}); + auto entry = c.win_emu.registry.get_key({key}); if (!entry.has_value()) { return STATUS_OBJECT_NAME_NOT_FOUND; @@ -187,7 +187,7 @@ namespace const auto query_name = read_unicode_string(c.emu, value_name); - const auto value = c.proc.registry.get_value(*key, u16_to_u8(query_name)); + const auto value = c.win_emu.registry.get_value(*key, u16_to_u8(query_name)); if (!value) { return STATUS_OBJECT_NAME_NOT_FOUND; diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 3666fa32..940b83a1 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -218,10 +218,6 @@ namespace setup_gdt(emu, memory); - // TODO: Move that out - context.registry = registry_manager(win_emu.emulation_root.empty() ? emu_settings.registry_directory - : win_emu.emulation_root / "registry"); - context.kusd.setup(emu_settings.use_relative_time); context.base_allocator = create_allocator(memory, PEB_SEGMENT_SIZE); @@ -438,9 +434,28 @@ std::unique_ptr create_default_x64_emulator() windows_emulator::windows_emulator(application_settings app_settings, const emulator_settings& settings, emulator_callbacks callbacks, std::unique_ptr emu) - : windows_emulator(settings.emulation_root, std::move(emu)) + : windows_emulator(settings, std::move(emu)) { + this->callbacks = std::move(callbacks); + fixup_application_settings(app_settings); + this->setup_process(app_settings, settings); +} + +windows_emulator::windows_emulator(const emulator_settings& settings, std::unique_ptr emu) + : emu_(std::move(emu)), + emulation_root{settings.emulation_root.empty() ? settings.emulation_root : absolute(settings.emulation_root)}, + file_sys(emulation_root.empty() ? emulation_root : emulation_root / "filesys"), + memory(*this->emu_), + registry(emulation_root.empty() ? settings.registry_directory : emulation_root / "registry"), + process(*this->emu_, memory, file_sys) +{ +#ifndef OS_WINDOWS + if (this->emulation_root.empty()) + { + throw std::runtime_error("Emulation root directory can not be empty!"); + } +#endif for (const auto& mapping : settings.path_mappings) { @@ -456,27 +471,8 @@ windows_emulator::windows_emulator(application_settings app_settings, const emul this->silent_until_main_ = settings.silent_until_main && !settings.disable_logging; this->use_relative_time_ = settings.use_relative_time; this->log.disable_output(settings.disable_logging || this->silent_until_main_); - this->callbacks = std::move(callbacks); this->modules_ = settings.modules; - this->setup_process(app_settings, settings); -} - -windows_emulator::windows_emulator(const std::filesystem::path& emulation_root_directory, - std::unique_ptr emu) - : emu_(std::move(emu)), - emulation_root{emulation_root_directory.empty() ? emulation_root_directory : absolute(emulation_root_directory)}, - file_sys(emulation_root.empty() ? emulation_root : emulation_root / "filesys"), - memory(*this->emu_), - process(*this->emu_, memory, file_sys) -{ -#ifndef OS_WINDOWS - if (this->emulation_root.empty()) - { - throw std::runtime_error("Emulation root directory can not be empty!"); - } -#endif - this->setup_hooks(); } diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 3f6b3653..1009c7ee 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -34,8 +34,8 @@ struct application_settings struct emulator_settings { - std::filesystem::path registry_directory{"./registry"}; std::filesystem::path emulation_root{}; + std::filesystem::path registry_directory{"./registry"}; bool verbose_calls{false}; bool disable_logging{false}; @@ -65,10 +65,11 @@ class windows_emulator logger log{}; file_system file_sys; memory_manager memory; + registry_manager registry{}; process_context process; syscall_dispatcher dispatcher; - windows_emulator(const std::filesystem::path& emulation_root, + windows_emulator(const emulator_settings& settings = {}, std::unique_ptr emu = create_default_x64_emulator()); windows_emulator(application_settings app_settings, const emulator_settings& settings = {}, emulator_callbacks callbacks = {},