From cc4064611ffb7f0d9d4459dd8885e7687276c32b Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Tue, 4 Feb 2025 20:34:53 +0100 Subject: [PATCH 1/2] Fix thread handles --- src/windows-emulator/process_context.hpp | 2 +- src/windows-emulator/syscalls.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index a21ac6da..567a9d00 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -347,7 +347,7 @@ class moved_marker bool was_moved_{false}; }; -class emulator_thread : ref_counted_object +class emulator_thread : public ref_counted_object { public: emulator_thread(x64_emulator& emu) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 7dafe4ef..e97e51fb 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -3519,10 +3519,11 @@ namespace } bool return_next_thread = thread_handle == NULL_HANDLE; - for (const auto& t : c.proc.threads) + for (auto& t : c.proc.threads) { if (return_next_thread && !t.second.is_terminated()) { + ++t.second.ref_count; new_thread_handle.write(c.proc.threads.make_handle(t.first)); return STATUS_SUCCESS; } From 85180a51f07946872308ee3e4d18d9daaaed983b Mon Sep 17 00:00:00 2001 From: Maurice Heumann Date: Tue, 4 Feb 2025 20:43:43 +0100 Subject: [PATCH 2/2] Prevent destroying active thread --- src/windows-emulator/syscalls.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index e97e51fb..7df12fd7 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -430,6 +430,16 @@ namespace return STATUS_SUCCESS; } + if (h.value.type == handle_types::thread) + { + const auto t = c.proc.threads.get(h); + if (t == c.proc.active_thread && t->ref_count == 1) + { + // TODO: Better handle ref counting + return STATUS_SUCCESS; + } + } + auto* handle_store = get_handle_store(c.proc, h); if (handle_store && handle_store->erase(h)) {