diff --git a/src/fuzzer/main.cpp b/src/fuzzer/main.cpp index 9623f7e9..1b762eb6 100644 --- a/src/fuzzer/main.cpp +++ b/src/fuzzer/main.cpp @@ -20,7 +20,7 @@ namespace win_emu.log.disable_output(true); win_emu.start(); - if (win_emu.process.exception_rip.has_value()) + if (win_emu.process.exception_ip.has_value()) { throw std::runtime_error("Exception!"); } diff --git a/src/windows-emulator/emulator_thread.cpp b/src/windows-emulator/emulator_thread.cpp index e3628706..4f900958 100644 --- a/src/windows-emulator/emulator_thread.cpp +++ b/src/windows-emulator/emulator_thread.cpp @@ -29,7 +29,7 @@ namespace emu.reg(x86_register::rsp, stack_end); } - bool is_object_signaled(process_context& c, const handle h, const uint32_t current_thread_id) + bool is_object_signaled(process_context64& c, const handle h, const uint32_t current_thread_id) { const auto type = h.value.type; @@ -83,7 +83,7 @@ namespace } } -emulator_thread::emulator_thread(memory_manager& memory, const process_context& context, const uint64_t start_address, +emulator_thread::emulator_thread(memory_manager& memory, const process_context64& context, const uint64_t start_address, const uint64_t argument, const uint64_t stack_size, const bool suspended, const uint32_t id) : memory_ptr(&memory), @@ -139,7 +139,7 @@ bool emulator_thread::is_terminated() const return this->exit_status.has_value(); } -bool emulator_thread::is_thread_ready(process_context& process, utils::clock& clock) +bool emulator_thread::is_thread_ready(process_context64& process, utils::clock& clock) { if (this->is_terminated() || this->suspended > 0) { @@ -208,7 +208,7 @@ bool emulator_thread::is_thread_ready(process_context& process, utils::clock& cl return true; } -void emulator_thread::setup_registers(x86_64_emulator& emu, const process_context& context) const +void emulator_thread::setup_registers(x86_64_emulator& emu, const process_context64& context) const { if (!this->gs_segment) { diff --git a/src/windows-emulator/emulator_thread.hpp b/src/windows-emulator/emulator_thread.hpp index e9907d08..91fb6cd7 100644 --- a/src/windows-emulator/emulator_thread.hpp +++ b/src/windows-emulator/emulator_thread.hpp @@ -6,7 +6,7 @@ #include -struct process_context; +struct process_context64; struct pending_apc { @@ -48,7 +48,7 @@ class emulator_thread : public ref_counted_object { } - emulator_thread(memory_manager& memory, const process_context& context, uint64_t start_address, uint64_t argument, + emulator_thread(memory_manager& memory, const process_context64& context, uint64_t start_address, uint64_t argument, uint64_t stack_size, bool suspended, uint32_t id); emulator_thread(const emulator_thread&) = delete; @@ -103,7 +103,7 @@ class emulator_thread : public ref_counted_object bool is_terminated() const; - bool is_thread_ready(process_context& process, utils::clock& clock); + bool is_thread_ready(process_context64& process, utils::clock& clock); void save(x86_64_emulator& emu) { @@ -115,7 +115,7 @@ class emulator_thread : public ref_counted_object emu.restore_registers(this->last_registers); } - void setup_if_necessary(x86_64_emulator& emu, const process_context& context) + void setup_if_necessary(x86_64_emulator& emu, const process_context64& context) { if (!this->executed_instructions) { @@ -211,7 +211,7 @@ class emulator_thread : public ref_counted_object } private: - void setup_registers(x86_64_emulator& emu, const process_context& context) const; + void setup_registers(x86_64_emulator& emu, const process_context64& context) const; void release() { diff --git a/src/windows-emulator/exception_dispatch.cpp b/src/windows-emulator/exception_dispatch.cpp index e4626cf2..fa5d69ec 100644 --- a/src/windows-emulator/exception_dispatch.cpp +++ b/src/windows-emulator/exception_dispatch.cpp @@ -140,7 +140,7 @@ namespace } } -void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const DWORD status, +void dispatch_exception(x86_64_emulator& emu, const process_context64& proc, const DWORD status, const std::vector::ULONG_PTR>& parameters) { CONTEXT64 ctx{}; @@ -172,7 +172,7 @@ void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const dispatch_exception_pointers(emu, proc.ki_user_exception_dispatcher, pointers); } -void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, const uint64_t address, +void dispatch_access_violation(x86_64_emulator& emu, const process_context64& proc, const uint64_t address, const memory_operation operation) { dispatch_exception(emu, proc, STATUS_ACCESS_VIOLATION, @@ -182,22 +182,22 @@ void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc }); } -void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc) +void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context64& proc) { dispatch_exception(emu, proc, STATUS_ILLEGAL_INSTRUCTION, {}); } -void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc) +void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context64& proc) { dispatch_exception(emu, proc, STATUS_INTEGER_DIVIDE_BY_ZERO, {}); } -void dispatch_single_step(x86_64_emulator& emu, const process_context& proc) +void dispatch_single_step(x86_64_emulator& emu, const process_context64& proc) { dispatch_exception(emu, proc, STATUS_SINGLE_STEP, {}); } -void dispatch_breakpoint(x86_64_emulator& emu, const process_context& proc) +void dispatch_breakpoint(x86_64_emulator& emu, const process_context64& proc) { dispatch_exception(emu, proc, STATUS_BREAKPOINT, {}); } diff --git a/src/windows-emulator/exception_dispatch.hpp b/src/windows-emulator/exception_dispatch.hpp index 4a717c3d..b3bd1a70 100644 --- a/src/windows-emulator/exception_dispatch.hpp +++ b/src/windows-emulator/exception_dispatch.hpp @@ -5,21 +5,21 @@ #include #include -struct process_context; +struct process_context64; -void dispatch_exception(x86_64_emulator& emu, const process_context& proc, DWORD status, +void dispatch_exception(x86_64_emulator& emu, const process_context64& proc, DWORD status, const std::vector::ULONG_PTR>& parameters); template requires(std::is_integral_v && !std::is_same_v) -void dispatch_exception(x86_64_emulator& emu, const process_context& proc, const T status, +void dispatch_exception(x86_64_emulator& emu, const process_context64& proc, const T status, const std::vector::ULONG_PTR>& parameters) { dispatch_exception(emu, proc, static_cast(status), parameters); } -void dispatch_access_violation(x86_64_emulator& emu, const process_context& proc, uint64_t address, +void dispatch_access_violation(x86_64_emulator& emu, const process_context64& proc, uint64_t address, memory_operation operation); -void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context& proc); -void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context& proc); -void dispatch_single_step(x86_64_emulator& emu, const process_context& proc); -void dispatch_breakpoint(x86_64_emulator& emu, const process_context& proc); +void dispatch_illegal_instruction_violation(x86_64_emulator& emu, const process_context64& proc); +void dispatch_integer_division_by_zero(x86_64_emulator& emu, const process_context64& proc); +void dispatch_single_step(x86_64_emulator& emu, const process_context64& proc); +void dispatch_breakpoint(x86_64_emulator& emu, const process_context64& proc); diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index bb0dd610..bf856e51 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -27,9 +27,9 @@ namespace } } -void process_context::setup(x86_64_emulator& emu, memory_manager& memory, const application_settings& app_settings, - const mapped_module& executable, const mapped_module& ntdll, - const apiset::container& apiset_container) +void process_context64::setup(x86_64_emulator& emu, memory_manager& memory, const application_settings& app_settings, + const mapped_module& executable, const mapped_module& ntdll, + const apiset::container& apiset_container) { setup_gdt(emu, memory); @@ -125,7 +125,7 @@ void process_context::setup(x86_64_emulator& emu, memory_manager& memory, const this->default_register_set = emu.save_registers(); } -void process_context::serialize(utils::buffer_serializer& buffer) const +void process_context64::serialize(utils::buffer_serializer& buffer) const { buffer.write(this->current_ip); buffer.write(this->previous_ip); @@ -133,7 +133,7 @@ void process_context::serialize(utils::buffer_serializer& buffer) const buffer.write(this->shared_section_size); buffer.write(this->dbwin_buffer); buffer.write(this->dbwin_buffer_size); - buffer.write_optional(this->exception_rip); + buffer.write_optional(this->exception_ip); buffer.write_optional(this->exit_status); buffer.write(this->base_allocator); buffer.write(this->peb); @@ -163,7 +163,7 @@ void process_context::serialize(utils::buffer_serializer& buffer) const buffer.write(this->threads.find_handle(this->active_thread).bits); } -void process_context::deserialize(utils::buffer_deserializer& buffer) +void process_context64::deserialize(utils::buffer_deserializer& buffer) { buffer.read(this->current_ip); buffer.read(this->previous_ip); @@ -171,7 +171,7 @@ void process_context::deserialize(utils::buffer_deserializer& buffer) buffer.read(this->shared_section_size); buffer.read(this->dbwin_buffer); buffer.read(this->dbwin_buffer_size); - buffer.read_optional(this->exception_rip); + buffer.read_optional(this->exception_ip); buffer.read_optional(this->exit_status); buffer.read(this->base_allocator); buffer.read(this->peb); @@ -207,7 +207,7 @@ void process_context::deserialize(utils::buffer_deserializer& buffer) this->active_thread = this->threads.get(buffer.read()); } -generic_handle_store* process_context::get_handle_store(const handle handle) +generic_handle_store* process_context64::get_handle_store(const handle handle) { switch (handle.value.type) { @@ -234,8 +234,8 @@ generic_handle_store* process_context::get_handle_store(const handle handle) } } -handle process_context::create_thread(memory_manager& memory, const uint64_t start_address, const uint64_t argument, - const uint64_t stack_size, const bool suspended) +handle process_context64::create_thread(memory_manager& memory, const uint64_t start_address, const uint64_t argument, + const uint64_t stack_size, const bool suspended) { emulator_thread t{memory, *this, start_address, argument, stack_size, suspended, ++this->spawned_thread_count}; auto [h, thr] = this->threads.store_and_get(std::move(t)); @@ -243,7 +243,9 @@ handle process_context::create_thread(memory_manager& memory, const uint64_t sta return h; } -uint16_t process_context::add_or_find_atom(std::u16string name) +// --[ process_context_common ]----------------------------------------------------------------------------------------- + +uint16_t process_context_common::add_or_find_atom(std::u16string name) { uint16_t index = 0; if (!atoms.empty()) @@ -286,7 +288,7 @@ uint16_t process_context::add_or_find_atom(std::u16string name) return index; } -bool process_context::delete_atom(const std::u16string& name) +bool process_context_common::delete_atom(const std::u16string& name) { for (auto it = atoms.begin(); it != atoms.end(); ++it) { @@ -303,7 +305,7 @@ bool process_context::delete_atom(const std::u16string& name) return false; } -bool process_context::delete_atom(uint16_t atom_id) +bool process_context_common::delete_atom(uint16_t atom_id) { const auto it = atoms.find(atom_id); if (it == atoms.end()) @@ -319,7 +321,7 @@ bool process_context::delete_atom(uint16_t atom_id) return true; } -const std::u16string* process_context::get_atom_name(uint16_t atom_id) const +const std::u16string* process_context_common::get_atom_name(uint16_t atom_id) const { const auto it = atoms.find(atom_id); if (it == atoms.end()) diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index 293b7d03..6f0b1e14 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -28,7 +28,7 @@ struct emulator_settings; struct application_settings; -struct process_context +struct process_context_common { struct callbacks { @@ -50,7 +50,44 @@ struct process_context atom_entry() = default; }; - process_context(x86_64_emulator& emu, memory_manager& memory, utils::clock& clock, callbacks& cb) + std::map atoms{}; + uint16_t add_or_find_atom(std::u16string name); + bool delete_atom(const std::u16string& name); + bool delete_atom(uint16_t atom_id); + const std::u16string* get_atom_name(uint16_t atom_id) const; + + uint64_t current_ip{0}; + uint64_t previous_ip{0}; + + uint64_t shared_section_address{0}; + uint64_t shared_section_size{0}; + uint64_t dbwin_buffer{0}; + uint64_t dbwin_buffer_size{0}; + + std::optional exit_status{}; + + uint64_t ntdll_image_base{}; + uint64_t ldr_initialize_thunk{}; + uint64_t rtl_user_thread_start{}; + uint64_t ki_user_apc_dispatcher{}; + uint64_t ki_user_exception_dispatcher{}; + + std::optional exception_ip{}; + + handle_store events{}; + handle_store files{}; + handle_store sections{}; + handle_store semaphores{}; + handle_store ports{}; + handle_store mutants{}; + handle_store registry_keys{}; + + std::vector default_register_set{}; +}; + +struct process_context64 final : process_context_common +{ + process_context64(x86_64_emulator& emu, memory_manager& memory, utils::clock& clock, callbacks& cb) : callbacks_(&cb), base_allocator(emu), peb(emu), @@ -65,11 +102,6 @@ struct process_context handle create_thread(memory_manager& memory, uint64_t start_address, uint64_t argument, uint64_t stack_size, bool suspended); - uint16_t add_or_find_atom(std::u16string name); - bool delete_atom(const std::u16string& name); - bool delete_atom(uint16_t atom_id); - const std::u16string* get_atom_name(uint16_t atom_id) const; - void serialize(utils::buffer_serializer& buffer) const; void deserialize(utils::buffer_deserializer& buffer); @@ -77,40 +109,13 @@ struct process_context callbacks* callbacks_{}; - uint64_t current_ip{0}; - uint64_t previous_ip{0}; - - uint64_t shared_section_address{0}; - uint64_t shared_section_size{0}; - uint64_t dbwin_buffer{0}; - uint64_t dbwin_buffer_size{0}; - - std::optional exception_rip{}; - std::optional exit_status{}; - emulator_allocator base_allocator; emulator_object peb; emulator_object process_params; kusd_mmio kusd; - uint64_t ntdll_image_base{}; - uint64_t ldr_initialize_thunk{}; - uint64_t rtl_user_thread_start{}; - uint64_t ki_user_apc_dispatcher{}; - uint64_t ki_user_exception_dispatcher{}; - - handle_store events{}; - handle_store files{}; - handle_store sections{}; handle_store devices{}; - handle_store semaphores{}; - handle_store ports{}; - handle_store mutants{}; - handle_store registry_keys{}; - std::map atoms{}; - - std::vector default_register_set{}; uint32_t spawned_thread_count{0}; handle_store threads{}; diff --git a/src/windows-emulator/syscall_utils.hpp b/src/windows-emulator/syscall_utils.hpp index 392daa89..28e912ee 100644 --- a/src/windows-emulator/syscall_utils.hpp +++ b/src/windows-emulator/syscall_utils.hpp @@ -8,7 +8,7 @@ struct syscall_context { windows_emulator& win_emu; x86_64_emulator& emu; - process_context& proc; + process_context64& proc; mutable bool write_status{true}; mutable bool retrigger_syscall{false}; }; diff --git a/src/windows-emulator/syscalls/exception.cpp b/src/windows-emulator/syscalls/exception.cpp index 42362bc3..a23bfbd0 100644 --- a/src/windows-emulator/syscalls/exception.cpp +++ b/src/windows-emulator/syscalls/exception.cpp @@ -18,7 +18,7 @@ namespace syscalls } c.proc.exit_status = error_status; - c.proc.exception_rip = c.emu.read_instruction_pointer(); + c.proc.exception_ip = c.emu.read_instruction_pointer(); c.emu.stop(); return STATUS_SUCCESS; @@ -36,7 +36,7 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } - c.proc.exception_rip = thread_context.read().Rip; + c.proc.exception_ip = thread_context.read().Rip; c.emu.stop(); return STATUS_SUCCESS; diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index c5f90080..cc71c195 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -68,7 +68,7 @@ namespace } } - emulator_thread* get_thread_by_id(process_context& process, const uint32_t id) + emulator_thread* get_thread_by_id(process_context64& process, const uint32_t id) { for (auto& t : process.threads | std::views::values) { @@ -540,7 +540,7 @@ void windows_emulator::setup_hooks() if (this->fuzzing || true) // TODO: Fix { - this->process.exception_rip = rip; + this->process.exception_ip = rip; this->emu().stop(); } }); @@ -564,7 +564,7 @@ void windows_emulator::setup_hooks() if (this->fuzzing) { - this->process.exception_rip = ip; + this->process.exception_ip = ip; this->emu().stop(); return memory_violation_continuation::stop; } diff --git a/src/windows-emulator/windows_emulator.hpp b/src/windows-emulator/windows_emulator.hpp index 965d0037..70dad472 100644 --- a/src/windows-emulator/windows_emulator.hpp +++ b/src/windows-emulator/windows_emulator.hpp @@ -15,7 +15,7 @@ std::unique_ptr create_default_x86_64_emulator(); -struct emulator_callbacks : module_manager::callbacks, process_context::callbacks +struct emulator_callbacks : module_manager::callbacks, process_context64::callbacks { utils::optional_function @@ -69,7 +69,7 @@ class windows_emulator memory_manager memory; registry_manager registry{}; module_manager mod_manager; - process_context process; + process_context64 process; syscall_dispatcher dispatcher; windows_emulator(const emulator_settings& settings = {}, emulator_callbacks callbacks = {},