diff --git a/src/analyzer/main.cpp b/src/analyzer/main.cpp index 646be0d7..6dd04785 100644 --- a/src/analyzer/main.cpp +++ b/src/analyzer/main.cpp @@ -243,6 +243,7 @@ namespace bool run(const analysis_options& options, const std::span args) { const auto win_emu = setup_emulator(options, args); + win_emu->log.log("Using emulator: %s\n", win_emu->emu().get_name().c_str()); (void)&watch_system_objects; watch_system_objects(*win_emu, options.modules, options.concise_logging); diff --git a/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs b/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs index 77e6769c..d9b07b9f 100644 --- a/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs +++ b/src/backends/icicle-emulator/icicle-bridge/src/icicle.rs @@ -153,7 +153,7 @@ impl ExecutionHooks { } let mapping = self.address_mapping.get(&address); - if mapping.is_none(){ + if mapping.is_none() { return; } @@ -165,7 +165,7 @@ impl ExecutionHooks { } } - pub fn execute(&mut self,cpu: &mut icicle_cpu::Cpu, address: u64) { + pub fn execute(&mut self, cpu: &mut icicle_cpu::Cpu, address: u64) { self.run_hooks(address); if *self.stop.borrow() { @@ -188,7 +188,7 @@ impl ExecutionHooks { } pub fn remove_generic_hook(&mut self, id: u32) { - self.generic_hooks.remove_hook(id); + self.generic_hooks.remove_hook(id); } pub fn remove_specific_hook(&mut self, id: u32) { @@ -198,7 +198,7 @@ impl ExecutionHooks { }); self.specific_hooks.remove_hook(id); - } + } } pub struct IcicleEmulator { @@ -328,11 +328,12 @@ impl IcicleEmulator { fn handle_exception(&mut self, code: ExceptionCode, value: u64) -> bool { let continue_execution = match code { - ExceptionCode::Syscall => self.handle_syscall(), + ExceptionCode::Syscall => self.handle_syscall(value), ExceptionCode::ReadPerm => self.handle_violation(value, FOREIGN_READ, false), ExceptionCode::WritePerm => self.handle_violation(value, FOREIGN_WRITE, false), ExceptionCode::ReadUnmapped => self.handle_violation(value, FOREIGN_READ, true), ExceptionCode::WriteUnmapped => self.handle_violation(value, FOREIGN_WRITE, true), + ExceptionCode::SoftwareBreakpoint => self.handle_interrupt(3), ExceptionCode::InvalidInstruction => self.handle_interrupt(6), ExceptionCode::DivisionException => self.handle_interrupt(0), _ => false, @@ -356,7 +357,11 @@ impl IcicleEmulator { return continue_execution; } - fn handle_syscall(&mut self) -> bool { + fn handle_syscall(&mut self, value: u64) -> bool { + if value != 0 { + return self.handle_interrupt(value as i32); + } + for (_key, func) in self.syscall_hooks.get_hooks() { func(); } @@ -377,9 +382,12 @@ impl IcicleEmulator { let hook_id = self.violation_hooks.add_hook(callback); return qualify_hook_id(hook_id, HookType::Violation); } - - pub fn add_execution_hook(&mut self, address:u64, callback: Box) -> u32 { - let hook_id = self.execution_hooks.borrow_mut().add_specific_hook(address, callback); + + pub fn add_execution_hook(&mut self, address: u64, callback: Box) -> u32 { + let hook_id = self + .execution_hooks + .borrow_mut() + .add_specific_hook(address, callback); return qualify_hook_id(hook_id, HookType::ExecuteSpecific); } @@ -404,7 +412,9 @@ impl IcicleEmulator { end: u64, callback: Box, ) -> u32 { - let id = self.get_mem().add_read_after_hook(start, end, Box::new(MemoryHook { callback })); + let id = self + .get_mem() + .add_read_after_hook(start, end, Box::new(MemoryHook { callback })); if id.is_none() { return 0; } @@ -418,7 +428,9 @@ impl IcicleEmulator { end: u64, callback: Box, ) -> u32 { - let id = self.get_mem().add_write_hook(start, end, Box::new(MemoryHook { callback })); + let id = self + .get_mem() + .add_write_hook(start, end, Box::new(MemoryHook { callback })); if id.is_none() { return 0; } @@ -433,10 +445,22 @@ impl IcicleEmulator { HookType::Syscall => self.syscall_hooks.remove_hook(hook_id), HookType::Violation => self.violation_hooks.remove_hook(hook_id), HookType::Interrupt => self.interrupt_hooks.remove_hook(hook_id), - HookType::ExecuteGeneric => self.execution_hooks.borrow_mut().remove_generic_hook(hook_id), - HookType::ExecuteSpecific => self.execution_hooks.borrow_mut().remove_specific_hook(hook_id), - HookType::Read => {self.get_mem().remove_read_after_hook(hook_id);()}, - HookType::Write => {self.get_mem().remove_write_hook(hook_id);()}, + HookType::ExecuteGeneric => self + .execution_hooks + .borrow_mut() + .remove_generic_hook(hook_id), + HookType::ExecuteSpecific => self + .execution_hooks + .borrow_mut() + .remove_specific_hook(hook_id), + HookType::Read => { + self.get_mem().remove_read_after_hook(hook_id); + () + } + HookType::Write => { + self.get_mem().remove_write_hook(hook_id); + () + } _ => {} } } @@ -543,9 +567,7 @@ impl IcicleEmulator { return reg_node.size.into(); } - - fn read_flags(&mut self, data: &mut [u8]) -> usize - { + fn read_flags(&mut self, data: &mut [u8]) -> usize { const REAL_SIZE: usize = std::mem::size_of::(); let limit: usize = std::mem::size_of::(); let size = std::cmp::min(REAL_SIZE, limit); @@ -567,8 +589,7 @@ impl IcicleEmulator { } } - fn write_flags(&mut self, data: &[u8]) -> usize - { + fn write_flags(&mut self, data: &[u8]) -> usize { const REAL_SIZE: usize = std::mem::size_of::(); let limit: usize = std::mem::size_of::(); let size = std::cmp::min(REAL_SIZE, limit); diff --git a/src/common/platform/memory.hpp b/src/common/platform/memory.hpp index 13779235..bf213b91 100644 --- a/src/common/platform/memory.hpp +++ b/src/common/platform/memory.hpp @@ -126,8 +126,8 @@ typedef struct _MEMORY_REGION_INFORMATION std::int64_t RegionSize; std::int64_t CommitSize; - DWORD64 PartitionId; // 19H1 - DWORD64 NodePreference; // 20H1 + // DWORD64 PartitionId; // 19H1 + // DWORD64 NodePreference; // 20H1 } MEMORY_REGION_INFORMATION64, *PMEMORY_REGION_INFORMATION64; // NOLINTEND(modernize-use-using) diff --git a/src/windows-emulator/memory_manager.cpp b/src/windows-emulator/memory_manager.cpp index d879dee6..7c1a3de8 100644 --- a/src/windows-emulator/memory_manager.cpp +++ b/src/windows-emulator/memory_manager.cpp @@ -78,6 +78,7 @@ namespace utils static void serialize(buffer_serializer& buffer, const memory_manager::reserved_region& region) { buffer.write(region.is_mmio); + buffer.write(region.initial_permission); buffer.write(region.length); buffer.write_map(region.committed_regions); } @@ -85,6 +86,7 @@ namespace utils static void deserialize(buffer_deserializer& buffer, memory_manager::reserved_region& region) { buffer.read(region.is_mmio); + buffer.read(region.initial_permission); region.length = static_cast(buffer.read()); buffer.read_map(region.committed_regions); } @@ -258,6 +260,7 @@ bool memory_manager::allocate_memory(const uint64_t address, const size_t size, .try_emplace(address, reserved_region{ .length = size, + .initial_permission = permissions, }) .first; @@ -497,6 +500,7 @@ region_info memory_manager::get_region_info(const uint64_t address) result.start = MIN_ALLOCATION_ADDRESS; result.length = MAX_ALLOCATION_ADDRESS - result.start; result.permissions = memory_permission::none; + result.initial_permissions = memory_permission::none; result.allocation_base = {}; result.allocation_length = result.length; result.is_committed = false; @@ -532,6 +536,7 @@ region_info memory_manager::get_region_info(const uint64_t address) result.allocation_length = reserved_region.length; result.start = result.allocation_base; result.length = result.allocation_length; + result.initial_permissions = entry->second.initial_permission; if (committed_regions.empty()) { diff --git a/src/windows-emulator/memory_manager.hpp b/src/windows-emulator/memory_manager.hpp index 92daab60..4b5f087e 100644 --- a/src/windows-emulator/memory_manager.hpp +++ b/src/windows-emulator/memory_manager.hpp @@ -18,6 +18,7 @@ struct region_info : basic_memory_region size_t allocation_length{}; bool is_reserved{}; bool is_committed{}; + memory_permission initial_permissions{}; }; using mmio_read_callback = std::function; @@ -42,6 +43,7 @@ class memory_manager : public memory_interface struct reserved_region { size_t length{}; + memory_permission initial_permission{}; committed_region_map committed_regions{}; bool is_mmio{false}; }; diff --git a/src/windows-emulator/module/module_mapping.cpp b/src/windows-emulator/module/module_mapping.cpp index 2e20e6e9..939705e8 100644 --- a/src/windows-emulator/module/module_mapping.cpp +++ b/src/windows-emulator/module/module_mapping.cpp @@ -219,20 +219,22 @@ mapped_module map_module_from_data(memory_manager& memory, const std::span(region_info.start); image_info.AllocationBase = reinterpret_cast(region_info.allocation_base); - image_info.AllocationProtect = 0; image_info.PartitionId = 0; image_info.RegionSize = static_cast(region_info.length); image_info.Protect = map_emulator_to_nt_protection(region_info.permissions); + image_info.AllocationProtect = map_emulator_to_nt_protection(region_info.initial_permissions); image_info.Type = MEM_PRIVATE; }); @@ -91,7 +91,7 @@ namespace syscalls return_length.write(sizeof(MEMORY_REGION_INFORMATION64)); } - if (memory_information_length != sizeof(MEMORY_REGION_INFORMATION64)) + if (memory_information_length < sizeof(MEMORY_REGION_INFORMATION64)) { return STATUS_BUFFER_OVERFLOW; } @@ -108,8 +108,8 @@ namespace syscalls memset(&image_info, 0, sizeof(image_info)); image_info.AllocationBase = reinterpret_cast(region_info.allocation_base); - image_info.AllocationProtect = 0; - image_info.PartitionId = 0; + image_info.AllocationProtect = map_emulator_to_nt_protection(region_info.initial_permissions); + // image_info.PartitionId = 0; image_info.RegionSize = static_cast(region_info.allocation_length); image_info.Reserved = 0x10; });