diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index dbdb9cf0..5af11022 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -154,7 +154,7 @@ namespace auto read_handler = [&, section, concise_logging](const uint64_t address, size_t, uint64_t) { const auto rip = win_emu.emu().read_instruction_pointer(); - if (win_emu.process.mod_manager.find_by_address(rip) != win_emu.process.executable) + if (win_emu.mod_manager.find_by_address(rip) != win_emu.process.executable) { return; } @@ -174,7 +174,7 @@ namespace const auto write_handler = [&, section, concise_logging](const uint64_t address, size_t, uint64_t) { const auto rip = win_emu.emu().read_instruction_pointer(); - if (win_emu.process.mod_manager.find_by_address(rip) != win_emu.process.executable) + if (win_emu.mod_manager.find_by_address(rip) != win_emu.process.executable) { return; } diff --git a/src/analyzer/object_watching.hpp b/src/analyzer/object_watching.hpp index a7dc3e61..e84685f8 100644 --- a/src/analyzer/object_watching.hpp +++ b/src/analyzer/object_watching.hpp @@ -13,7 +13,7 @@ emulator_hook* watch_object(windows_emulator& emu, const std::setname); if (!emu.verbose_calls && !is_main_access) diff --git a/src/windows-emulator-test/emulation_test_utils.hpp b/src/windows-emulator-test/emulation_test_utils.hpp index c65eeba7..be6e10fb 100644 --- a/src/windows-emulator-test/emulation_test_utils.hpp +++ b/src/windows-emulator-test/emulation_test_utils.hpp @@ -152,6 +152,6 @@ namespace test const auto rip = emu.emu().read_instruction_pointer(); printf("Diff detected after 0x%" PRIx64 " instructions at 0x%" PRIx64 " (%s)\n", lower_bound, rip, - emu.process.mod_manager.find_name(rip)); + emu.mod_manager.find_name(rip)); } } diff --git a/src/windows-emulator/emulator_utils.hpp b/src/windows-emulator/emulator_utils.hpp index b9b0b21f..dfe5e5c6 100644 --- a/src/windows-emulator/emulator_utils.hpp +++ b/src/windows-emulator/emulator_utils.hpp @@ -40,10 +40,12 @@ class object_wrapper }; class windows_emulator; +class module_manager; struct process_context; using x64_emulator_wrapper = object_wrapper; using memory_manager_wrapper = object_wrapper; +using module_manager_wrapper = object_wrapper; using process_context_wrapper = object_wrapper; using windows_emulator_wrapper = object_wrapper; diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 39dd1bd7..4c47c2f4 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -27,12 +27,11 @@ struct process_context { - process_context(x64_emulator& emu, memory_manager& memory, file_system& file_sys) + process_context(x64_emulator& emu, memory_manager& memory) : base_allocator(emu), peb(emu), process_params(emu), - kusd(memory, *this), - mod_manager(memory, file_sys) + kusd(memory, *this) { } @@ -49,8 +48,7 @@ struct process_context emulator_object process_params; kusd_mmio kusd; - module_manager mod_manager; - + // TODO: Remove this mapped_module* executable{}; mapped_module* ntdll{}; mapped_module* win32u{}; @@ -86,7 +84,6 @@ struct process_context buffer.write(this->peb); buffer.write(this->process_params); buffer.write(this->kusd); - buffer.write(this->mod_manager); buffer.write(this->executable->image_base); buffer.write(this->ntdll->image_base); @@ -124,15 +121,16 @@ struct process_context buffer.read(this->peb); buffer.read(this->process_params); buffer.read(this->kusd); - buffer.read(this->mod_manager); const auto executable_base = buffer.read(); const auto ntdll_base = buffer.read(); const auto win32u_base = buffer.read(); - this->executable = this->mod_manager.find_by_address(executable_base); - this->ntdll = this->mod_manager.find_by_address(ntdll_base); - this->win32u = this->mod_manager.find_by_address(win32u_base); + auto& mod_manager = buffer.read().get(); + + this->executable = mod_manager.find_by_address(executable_base); + this->ntdll = mod_manager.find_by_address(ntdll_base); + this->win32u = mod_manager.find_by_address(win32u_base); buffer.read(this->ldr_initialize_thunk); buffer.read(this->rtl_user_thread_start); diff --git a/src/windows-emulator/syscall_dispatcher.cpp b/src/windows-emulator/syscall_dispatcher.cpp index f0c0343a..b64acc27 100644 --- a/src/windows-emulator/syscall_dispatcher.cpp +++ b/src/windows-emulator/syscall_dispatcher.cpp @@ -88,7 +88,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu) return; } - const auto* mod = context.mod_manager.find_by_address(address); + const auto* mod = win_emu.mod_manager.find_by_address(address); if (mod != context.ntdll && mod != context.win32u) { win_emu.callbacks.inline_syscall(syscall_id, address, mod ? mod->name.c_str() : "", @@ -106,7 +106,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu) uint64_t return_address{}; c.emu.try_read_memory(rsp, &return_address, sizeof(return_address)); - const auto* mod_name = context.mod_manager.find_name(return_address); + const auto* mod_name = win_emu.mod_manager.find_name(return_address); win_emu.log.print(color::dark_gray, "Executing syscall: %s (0x%X) at 0x%" PRIx64 " via 0x%" PRIx64 " (%s)\n", @@ -114,7 +114,7 @@ void syscall_dispatcher::dispatch(windows_emulator& win_emu) } else { - const auto* previous_mod = context.mod_manager.find_by_address(context.previous_ip); + const auto* previous_mod = win_emu.mod_manager.find_by_address(context.previous_ip); win_emu.callbacks.outofline_syscall(syscall_id, address, mod ? mod->name.c_str() : "", entry->second.name, context.previous_ip, diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index ddd59d1b..ab246d8c 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -756,7 +756,7 @@ namespace if (section_entry->is_image()) { - const auto binary = c.proc.mod_manager.map_module(section_entry->file_name, c.win_emu.log); + const auto binary = c.win_emu.mod_manager.map_module(section_entry->file_name, c.win_emu.log); if (!binary) { return STATUS_FILE_INVALID; @@ -880,7 +880,7 @@ namespace return STATUS_BUFFER_OVERFLOW; } - const auto mod = c.proc.mod_manager.find_by_address(base_address); + const auto mod = c.win_emu.mod_manager.find_by_address(base_address); if (!mod) { c.win_emu.log.error("Bad address for memory image request: 0x%" PRIx64 "\n", base_address); @@ -3408,7 +3408,7 @@ namespace return STATUS_NOT_SUPPORTED; } - const auto* mod = c.proc.mod_manager.find_by_address(base_address); + const auto* mod = c.win_emu.mod_manager.find_by_address(base_address); if (!mod) { c.win_emu.log.error("Unmapping non-module section not supported!\n"); @@ -3416,7 +3416,7 @@ namespace return STATUS_NOT_SUPPORTED; } - if (c.proc.mod_manager.unmap(base_address, c.win_emu.log)) + if (c.win_emu.mod_manager.unmap(base_address, c.win_emu.log)) { return STATUS_SUCCESS; } diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 940b83a1..ae06004b 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -448,7 +448,8 @@ windows_emulator::windows_emulator(const emulator_settings& settings, std::uniqu 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) + mod_manager(memory, file_sys), + process(*this->emu_, memory) { #ifndef OS_WINDOWS if (this->emulation_root.empty()) @@ -483,18 +484,17 @@ void windows_emulator::setup_process(const application_settings& app_settings, c auto& emu = this->emu(); auto& context = this->process; - context.mod_manager = module_manager(this->memory, this->file_sys); // TODO: Cleanup module manager setup_context(*this, app_settings, emu_settings); - context.executable = context.mod_manager.map_module(app_settings.application, this->log, true); + context.executable = this->mod_manager.map_module(app_settings.application, this->log, true); context.peb.access([&](PEB64& peb) { peb.ImageBaseAddress = reinterpret_cast(context.executable->image_base); // }); - context.ntdll = context.mod_manager.map_module(R"(C:\Windows\System32\ntdll.dll)", this->log, true); - context.win32u = context.mod_manager.map_module(R"(C:\Windows\System32\win32u.dll)", this->log, true); + context.ntdll = this->mod_manager.map_module(R"(C:\Windows\System32\ntdll.dll)", this->log, true); + context.win32u = this->mod_manager.map_module(R"(C:\Windows\System32\win32u.dll)", this->log, true); const auto ntdll_data = emu.read_memory(context.ntdll->image_base, context.ntdll->size_of_image); const auto win32u_data = emu.read_memory(context.win32u->image_base, context.win32u->size_of_image); @@ -553,11 +553,11 @@ void windows_emulator::on_instruction_execution(const uint64_t address) this->process.current_ip = this->emu().read_instruction_pointer(); const auto binary = utils::make_lazy([&] { - return this->process.mod_manager.find_by_address(address); // + return this->mod_manager.find_by_address(address); // }); const auto previous_binary = utils::make_lazy([&] { - return this->process.mod_manager.find_by_address(this->process.previous_ip); // + return this->mod_manager.find_by_address(this->process.previous_ip); // }); const auto is_in_interesting_module = [&] { @@ -596,7 +596,7 @@ void windows_emulator::on_instruction_execution(const uint64_t address) uint64_t return_address{}; this->emu().try_read_memory(rsp, &return_address, sizeof(return_address)); - const auto* mod_name = this->process.mod_manager.find_name(return_address); + const auto* mod_name = this->mod_manager.find_name(return_address); log.print(is_interesting_call ? color::yellow : color::dark_gray, "Executing function: %s - %s (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n", binary->name.c_str(), @@ -687,7 +687,7 @@ void windows_emulator::setup_hooks() const memory_violation_type type) { const auto permission = get_permission_string(operation); const auto ip = this->emu().read_instruction_pointer(); - const char* name = this->process.mod_manager.find_name(ip); + const char* name = this->mod_manager.find_name(ip); if (type == memory_violation_type::protection) { @@ -773,6 +773,7 @@ void windows_emulator::serialize(utils::buffer_serializer& buffer) const buffer.write(this->use_relative_time_); this->emu().serialize_state(buffer, false); this->memory.serialize_memory_state(buffer, false); + this->mod_manager.serialize(buffer); this->process.serialize(buffer); this->dispatcher.serialize(buffer); } @@ -783,6 +784,10 @@ void windows_emulator::deserialize(utils::buffer_deserializer& buffer) return memory_manager_wrapper{this->memory}; // }); + buffer.register_factory([this] { + return module_manager_wrapper{this->mod_manager}; // + }); + buffer.register_factory([this] { return x64_emulator_wrapper{this->emu()}; // }); @@ -798,26 +803,30 @@ void windows_emulator::deserialize(utils::buffer_deserializer& buffer) this->emu().deserialize_state(buffer, false); this->memory.deserialize_memory_state(buffer, false); + this->mod_manager.deserialize(buffer); this->process.deserialize(buffer); this->dispatcher.deserialize(buffer); } void windows_emulator::save_snapshot() { - utils::buffer_serializer serializer{}; + throw std::runtime_error("Not supported"); + /*utils::buffer_serializer serializer{}; this->emu().serialize_state(serializer, true); this->memory.serialize_memory_state(serializer, true); + this->mod_manager.serialize(serializer); this->process.serialize(serializer); this->process_snapshot_ = serializer.move_buffer(); // TODO: Make process copyable - // this->process_snapshot_ = this->process; + // this->process_snapshot_ = this->process;*/ } void windows_emulator::restore_snapshot() { - if (this->process_snapshot_.empty()) + throw std::runtime_error("Not supported"); + /*if (this->process_snapshot_.empty()) { assert(false); return; @@ -826,6 +835,7 @@ void windows_emulator::restore_snapshot() utils::buffer_deserializer deserializer{this->process_snapshot_}; this->emu().deserialize_state(deserializer, true); this->memory.deserialize_memory_state(deserializer, true); + this->mod_manager.deserialize(deserializer); this->process.deserialize(deserializer); - // this->process = *this->process_snapshot_; + // this->process = *this->process_snapshot_;*/ } diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 1009c7ee..8e663858 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -66,6 +66,7 @@ class windows_emulator file_system file_sys; memory_manager memory; registry_manager registry{}; + module_manager mod_manager; process_context process; syscall_dispatcher dispatcher;