diff --git a/src/windows-emulator/module/mapped_module.hpp b/src/windows-emulator/module/mapped_module.hpp index 29ff878f..b058a2b2 100644 --- a/src/windows-emulator/module/mapped_module.hpp +++ b/src/windows-emulator/module/mapped_module.hpp @@ -32,6 +32,8 @@ struct mapped_module std::vector sections{}; + bool is_static{false}; + bool is_within(const uint64_t address) const { return address >= this->image_base && address < (this->image_base + this->size_of_image); diff --git a/src/windows-emulator/module/module_manager.cpp b/src/windows-emulator/module/module_manager.cpp index 935c2a43..dd36834d 100644 --- a/src/windows-emulator/module/module_manager.cpp +++ b/src/windows-emulator/module/module_manager.cpp @@ -34,6 +34,8 @@ namespace utils buffer.write_vector(mod.exports); buffer.write_map(mod.address_names); + + buffer.write(mod.is_static); } static void deserialize(buffer_deserializer& buffer, mapped_module& mod) @@ -47,6 +49,8 @@ namespace utils buffer.read_vector(mod.exports); buffer.read_map(mod.address_names); + + buffer.read(mod.is_static); } } @@ -56,12 +60,13 @@ module_manager::module_manager(emulator& emu, file_system& file_sys) { } -mapped_module* module_manager::map_module(const windows_path& file, const logger& logger) +mapped_module* module_manager::map_module(const windows_path& file, const logger& logger, const bool is_static) { - return this->map_local_module(this->file_sys_->translate(file), logger); + return this->map_local_module(this->file_sys_->translate(file), logger, is_static); } -mapped_module* module_manager::map_local_module(const std::filesystem::path& file, const logger& logger) +mapped_module* module_manager::map_local_module(const std::filesystem::path& file, const logger& logger, + const bool is_static) { auto local_file = canonical(absolute(file)); @@ -76,6 +81,7 @@ mapped_module* module_manager::map_local_module(const std::filesystem::path& fil try { auto mod = map_module_from_file(*this->emu_, std::move(local_file)); + mod.is_static = is_static; logger.log("Mapped %s at 0x%" PRIx64 "\n", mod.path.generic_string().c_str(), mod.image_base); @@ -105,7 +111,7 @@ void module_manager::deserialize(utils::buffer_deserializer& buffer) buffer.read_map(this->modules_); } -bool module_manager::unmap(const uint64_t address) +bool module_manager::unmap(const uint64_t address, const logger& logger) { const auto mod = this->modules_.find(address); if (mod == this->modules_.end()) @@ -113,6 +119,13 @@ bool module_manager::unmap(const uint64_t address) return false; } + if (mod->second.is_static) + { + return true; + } + + logger.log("Unmapping %s (0x%" PRIx64 ")\n", mod->second.path.generic_string().c_str(), mod->second.image_base); + unmap_module(*this->emu_, mod->second); this->modules_.erase(mod); diff --git a/src/windows-emulator/module/module_manager.hpp b/src/windows-emulator/module/module_manager.hpp index 418c3d10..918b18a9 100644 --- a/src/windows-emulator/module/module_manager.hpp +++ b/src/windows-emulator/module/module_manager.hpp @@ -12,8 +12,8 @@ class module_manager using module_map = std::map; module_manager(emulator& emu, file_system& file_sys); - mapped_module* map_module(const windows_path& file, const logger& logger); - mapped_module* map_local_module(const std::filesystem::path& file, const logger& logger); + mapped_module* map_module(const windows_path& file, const logger& logger, bool is_static = false); + mapped_module* map_local_module(const std::filesystem::path& file, const logger& logger, bool is_static = false); mapped_module* find_by_address(const uint64_t address) { @@ -40,7 +40,7 @@ class module_manager void serialize(utils::buffer_serializer& buffer) const; void deserialize(utils::buffer_deserializer& buffer); - bool unmap(const uint64_t address); + bool unmap(const uint64_t address, const logger& logger); const module_map& modules() const { return modules_; diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 90a10b5b..622298fa 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -3267,7 +3267,7 @@ namespace return STATUS_NOT_SUPPORTED; } - if (c.proc.mod_manager.unmap(base_address)) + if (c.proc.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 e4ba9ab6..a5e11bb2 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -887,14 +887,14 @@ void windows_emulator::setup_process(const emulator_settings& settings) setup_context(*this, settings); - context.executable = context.mod_manager.map_module(settings.application, this->log); + context.executable = context.mod_manager.map_module(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); - context.win32u = context.mod_manager.map_module(R"(C:\Windows\System32\win32u.dll)", this->log); + 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); 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);