diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 971fc5b0..6a6e9f12 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -183,6 +183,10 @@ namespace syscalls NTSTATUS handle_NtWaitForSingleObject(const syscall_context& c, handle h, BOOLEAN alertable, emulator_object timeout); NTSTATUS handle_NtSetInformationObject(); + NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, handle /*h*/, + SECURITY_INFORMATION /*security_information*/, + emulator_pointer security_descriptor, ULONG length, + emulator_object length_needed); // syscalls/port.cpp: NTSTATUS handle_NtConnectPort(const syscall_context& c, emulator_object client_port_handle, @@ -344,6 +348,7 @@ namespace syscalls emulator_object>> attribute_list); NTSTATUS handle_NtGetCurrentProcessorNumberEx(const syscall_context&, emulator_object processor_number); + ULONG handle_NtGetCurrentProcessorNumber(); NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, handle thread_handle, handle reserve_handle, uint32_t apc_flags, uint64_t apc_routine, uint64_t apc_argument1, uint64_t apc_argument2, uint64_t apc_argument3); @@ -361,8 +366,15 @@ namespace syscalls NTSTATUS handle_NtCreateTimer2(const syscall_context& c, emulator_object timer_handle, uint64_t reserved, emulator_object>> object_attributes, ULONG attributes, ACCESS_MASK desired_access); + NTSTATUS handle_NtCreateTimer(const syscall_context& c, emulator_object timer_handle, + ACCESS_MASK desired_access, + emulator_object>> object_attributes, + ULONG timer_type); + NTSTATUS handle_NtSetTimer(); + NTSTATUS handle_NtSetTimer2(); NTSTATUS handle_NtSetTimerEx(const syscall_context& c, handle timer_handle, uint32_t timer_set_info_class, uint64_t timer_set_information, ULONG timer_set_information_length); + NTSTATUS handle_NtCancelTimer(); // syscalls/token.cpp: NTSTATUS @@ -410,7 +422,17 @@ namespace syscalls NTSTATUS handle_NtCreateWorkerFactory() { - return STATUS_NOT_SUPPORTED; + return STATUS_SUCCESS; + } + + NTSTATUS handle_NtSetInformationWorkerFactory() + { + return STATUS_SUCCESS; + } + + NTSTATUS handle_NtShutdownWorkerFactory() + { + return STATUS_SUCCESS; } NTSTATUS handle_NtCreateIoCompletion( @@ -426,6 +448,21 @@ namespace syscalls return STATUS_NOT_SUPPORTED; } + NTSTATUS handle_NtRemoveIoCompletion( + const syscall_context& c, const emulator_object /*io_completion__handle*/, + const emulator_object key_context, const emulator_pointer /*apc_context*/, + const emulator_object>> /*io_status_block*/, + const emulator_object timeout) + { + if (timeout.value() && timeout.read().QuadPart == 0) + { + return STATUS_TIMEOUT; + } + + key_context.write_if_valid(-1); + return STATUS_SUCCESS; + } + NTSTATUS handle_NtCreateWaitCompletionPacket( const syscall_context& c, const emulator_object event_handle, const ACCESS_MASK desired_access, const emulator_object>> object_attributes) @@ -925,6 +962,21 @@ namespace syscalls return STATUS_SUCCESS; } + + NTSTATUS handle_NtAssociateWaitCompletionPacket() + { + return STATUS_SUCCESS; + } + + NTSTATUS handle_NtCancelWaitCompletionPacket() + { + return STATUS_SUCCESS; + } + + NTSTATUS handle_NtSetWnfProcessNotificationEvent() + { + return STATUS_NOT_SUPPORTED; + } } void syscall_dispatcher::add_handlers(std::map& handler_mapping) @@ -957,8 +1009,11 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtAllocateVirtualMemoryEx); add_handler(NtCreateIoCompletion); add_handler(NtSetIoCompletion); + add_handler(NtRemoveIoCompletion); add_handler(NtCreateWaitCompletionPacket); add_handler(NtCreateWorkerFactory); + add_handler(NtSetInformationWorkerFactory); + add_handler(NtShutdownWorkerFactory); add_handler(NtManageHotPatch); add_handler(NtOpenSection); add_handler(NtMapViewOfSection); @@ -1035,6 +1090,7 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtCreateKey); add_handler(NtNotifyChangeKey); add_handler(NtGetCurrentProcessorNumberEx); + add_handler(NtGetCurrentProcessorNumber); add_handler(NtQueryObject); add_handler(NtQueryAttributesFile); add_handler(NtWaitForMultipleObjects); @@ -1105,8 +1161,16 @@ void syscall_dispatcher::add_handlers(std::map& ha add_handler(NtQueryInformationByName); add_handler(NtUserSetCursor); add_handler(NtOpenMutant); + add_handler(NtCreateTimer); add_handler(NtCreateTimer2); + add_handler(NtSetTimer); + add_handler(NtSetTimer2); add_handler(NtSetTimerEx); + add_handler(NtCancelTimer); + add_handler(NtAssociateWaitCompletionPacket); + add_handler(NtCancelWaitCompletionPacket); + add_handler(NtSetWnfProcessNotificationEvent); + add_handler(NtQuerySecurityObject); #undef add_handler } diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index c01f5547..4e86649d 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -201,4 +201,109 @@ namespace syscalls { return STATUS_NOT_SUPPORTED; } + + NTSTATUS handle_NtQuerySecurityObject(const syscall_context& c, const handle /*h*/, + const SECURITY_INFORMATION security_information, + const emulator_pointer security_descriptor, const ULONG length, + const emulator_object length_needed) + { + if ((security_information & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION)) == 0) + { + return STATUS_INVALID_PARAMETER; + } + + // Owner SID: S-1-5-32-544 (Administrators) + const uint8_t owner_sid[] = {0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00}; + + // Group SID: S-1-5-18 (Local System) + const uint8_t group_sid[] = {0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x12, 0x00, 0x00, 0x00}; + + // DACL structure + const uint8_t dacl_data[] = { + 0x02, 0x00, 0x9C, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0F, 0x00, 0x02, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x0F, 0x00, 0x02, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0F, 0x00, + 0x0F, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, + 0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x20, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x0B, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00}; + + // SACL structure + const uint8_t sacl_data[] = {0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00, // ACL header + 0x11, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00}; + + ULONG total_size = sizeof(SECURITY_DESCRIPTOR_RELATIVE); + + if (security_information & OWNER_SECURITY_INFORMATION) + total_size += sizeof(owner_sid); + + if (security_information & GROUP_SECURITY_INFORMATION) + total_size += sizeof(group_sid); + + if (security_information & DACL_SECURITY_INFORMATION) + total_size += sizeof(dacl_data); + + if (security_information & LABEL_SECURITY_INFORMATION) + total_size += sizeof(sacl_data); + + length_needed.write(total_size); + + if (length < total_size) + { + return STATUS_BUFFER_TOO_SMALL; + } + + if (!security_descriptor) + { + return STATUS_INVALID_PARAMETER; + } + + SECURITY_DESCRIPTOR_RELATIVE sd = {}; + sd.Revision = SECURITY_DESCRIPTOR_REVISION; + sd.Control = SE_SELF_RELATIVE; + + constexpr ULONG header_size = sizeof(SECURITY_DESCRIPTOR_RELATIVE); + ULONG current_offset = header_size; + + if (security_information & OWNER_SECURITY_INFORMATION) + { + sd.Owner = current_offset; + c.emu.write_memory(security_descriptor + current_offset, owner_sid); + current_offset += sizeof(owner_sid); + } + + if (security_information & GROUP_SECURITY_INFORMATION) + { + sd.Group = current_offset; + c.emu.write_memory(security_descriptor + current_offset, group_sid); + current_offset += sizeof(group_sid); + } + + if (security_information & DACL_SECURITY_INFORMATION) + { + sd.Control |= SE_DACL_PRESENT; + sd.Dacl = current_offset; + c.emu.write_memory(security_descriptor + current_offset, dacl_data); + current_offset += sizeof(dacl_data); + } + + if (security_information & LABEL_SECURITY_INFORMATION) + { + sd.Control |= SE_SACL_PRESENT | SE_SACL_AUTO_INHERITED; + sd.Sacl = current_offset; + c.emu.write_memory(security_descriptor + current_offset, sacl_data); + current_offset += sizeof(sacl_data); + } + + assert(current_offset == total_size); + + c.emu.write_memory(security_descriptor, sd); + + return STATUS_SUCCESS; + } } diff --git a/src/windows-emulator/syscalls/thread.cpp b/src/windows-emulator/syscalls/thread.cpp index b34aa3d3..d8c24a66 100644 --- a/src/windows-emulator/syscalls/thread.cpp +++ b/src/windows-emulator/syscalls/thread.cpp @@ -584,6 +584,11 @@ namespace syscalls return STATUS_SUCCESS; } + ULONG handle_NtGetCurrentProcessorNumber() + { + return 0; + } + NTSTATUS handle_NtQueueApcThreadEx2(const syscall_context& c, const handle thread_handle, const handle /*reserve_handle*/, const uint32_t apc_flags, const uint64_t apc_routine, const uint64_t apc_argument1, diff --git a/src/windows-emulator/syscalls/timer.cpp b/src/windows-emulator/syscalls/timer.cpp index 2f683bed..a154e27f 100644 --- a/src/windows-emulator/syscalls/timer.cpp +++ b/src/windows-emulator/syscalls/timer.cpp @@ -69,10 +69,33 @@ namespace syscalls return STATUS_SUCCESS; } + NTSTATUS handle_NtCreateTimer(const syscall_context& c, const emulator_object timer_handle, + ACCESS_MASK desired_access, + const emulator_object>> object_attributes, + ULONG timer_type) + { + return handle_NtCreateTimer2(c, timer_handle, 0, object_attributes, timer_type, desired_access); + } + + NTSTATUS handle_NtSetTimer() + { + return STATUS_SUCCESS; + } + + NTSTATUS handle_NtSetTimer2() + { + return STATUS_SUCCESS; + } + NTSTATUS handle_NtSetTimerEx(const syscall_context& /*c*/, handle /*timer_handle*/, uint32_t /*timer_set_info_class*/, uint64_t /*timer_set_information*/, ULONG /*timer_set_information_length*/) { return STATUS_NOT_SUPPORTED; } + + NTSTATUS handle_NtCancelTimer() + { + return STATUS_SUCCESS; + } }