diff --git a/src/windows-emulator/emulator_thread.hpp b/src/windows-emulator/emulator_thread.hpp index 0a646092..eab80c8c 100644 --- a/src/windows-emulator/emulator_thread.hpp +++ b/src/windows-emulator/emulator_thread.hpp @@ -10,7 +10,7 @@ struct process_context; struct pending_apc { - ULONG flags{}; + uint32_t flags{}; uint64_t apc_routine{}; uint64_t apc_argument1{}; uint64_t apc_argument2{}; diff --git a/src/windows-emulator/process_context.cpp b/src/windows-emulator/process_context.cpp index f604eacd..bb720ec4 100644 --- a/src/windows-emulator/process_context.cpp +++ b/src/windows-emulator/process_context.cpp @@ -119,6 +119,7 @@ void process_context::setup(x64_emulator& emu, memory_manager& memory, const app this->ntdll_image_base = ntdll.image_base; this->ldr_initialize_thunk = ntdll.find_export("LdrInitializeThunk"); this->rtl_user_thread_start = ntdll.find_export("RtlUserThreadStart"); + this->ki_user_apc_dispatcher = ntdll.find_export("KiUserApcDispatcher"); this->ki_user_exception_dispatcher = ntdll.find_export("KiUserExceptionDispatcher"); this->default_register_set = emu.save_registers(); @@ -139,6 +140,7 @@ void process_context::serialize(utils::buffer_serializer& buffer) const buffer.write(this->ntdll_image_base); buffer.write(this->ldr_initialize_thunk); buffer.write(this->rtl_user_thread_start); + buffer.write(this->ki_user_apc_dispatcher); buffer.write(this->ki_user_exception_dispatcher); buffer.write(this->events); @@ -173,6 +175,7 @@ void process_context::deserialize(utils::buffer_deserializer& buffer) buffer.read(this->ntdll_image_base); buffer.read(this->ldr_initialize_thunk); buffer.read(this->rtl_user_thread_start); + buffer.read(this->ki_user_apc_dispatcher); buffer.read(this->ki_user_exception_dispatcher); buffer.read(this->events); diff --git a/src/windows-emulator/process_context.hpp b/src/windows-emulator/process_context.hpp index f01647b4..1be428b3 100644 --- a/src/windows-emulator/process_context.hpp +++ b/src/windows-emulator/process_context.hpp @@ -75,6 +75,7 @@ struct process_context 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{}; diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 480b4834..5675d0da 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -292,7 +292,7 @@ namespace syscalls NTSTATUS handle_NtGetCurrentProcessorNumberEx(const syscall_context&, emulator_object processor_number); NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, handle thread_handle, handle reserve_handle, - ULONG apc_flags, uint64_t apc_routine, uint64_t apc_argument1, + uint32_t apc_flags, uint64_t apc_routine, uint64_t apc_argument1, uint64_t apc_argument2, uint64_t apc_argument3); // syscalls/timer.cpp: diff --git a/src/windows-emulator/syscalls/thread.cpp b/src/windows-emulator/syscalls/thread.cpp index 25ebd1ba..3c7a90b5 100644 --- a/src/windows-emulator/syscalls/thread.cpp +++ b/src/windows-emulator/syscalls/thread.cpp @@ -565,7 +565,7 @@ namespace syscalls } NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, const handle thread_handle, - const handle /*reserve_handle*/, const ULONG apc_flags, + const handle /*reserve_handle*/, const uint32_t apc_flags, const uint64_t apc_routine, const uint64_t apc_argument1, const uint64_t apc_argument2, const uint64_t apc_argument3) { @@ -576,6 +576,13 @@ namespace syscalls return STATUS_INVALID_HANDLE; } + if (apc_flags) + { + c.win_emu.log.error("Unsupported APC flags: %X\n", apc_flags); + c.emu.stop(); + return STATUS_NOT_SUPPORTED; + } + thread->pending_apcs.push_back({ .flags = apc_flags, .apc_routine = apc_routine,