From ad3046466ead34208e9c204615c20e5ed4a622e7 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Sun, 1 Jun 2025 19:26:53 -0300 Subject: [PATCH 1/6] Improvements to NtQueryInformationToken --- src/common/platform/process.hpp | 26 ++++++ src/windows-emulator/syscalls/token.cpp | 104 ++++++++++++++++++++++-- 2 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/common/platform/process.hpp b/src/common/platform/process.hpp index 1234f900..5acc2451 100644 --- a/src/common/platform/process.hpp +++ b/src/common/platform/process.hpp @@ -785,6 +785,27 @@ struct TOKEN_OWNER64 EMULATOR_CAST(EmulatorTraits::PVOID, PSID) Owner; }; +struct TOKEN_PRIMARY_GROUP64 +{ + EMULATOR_CAST(EmulatorTraits::PVOID, PSID) PrimaryGroup; +}; + +#ifndef OS_WINDOWS +struct ACL +{ + BYTE AclRevision; + BYTE Sbz1; + WORD AclSize; + WORD AceCount; + WORD Sbz2; +}; +#endif + +struct TOKEN_DEFAULT_DACL64 +{ + EMULATOR_CAST(EmulatorTraits::PVOID, PACL) DefaultDacl; +}; + struct TOKEN_BNO_ISOLATION_INFORMATION64 { EmulatorTraits::PVOID IsolationPrefix; @@ -796,6 +817,11 @@ struct TOKEN_MANDATORY_LABEL64 SID_AND_ATTRIBUTES64 Label; }; +struct TOKEN_PROCESS_TRUST_LEVEL +{ + EMULATOR_CAST(EmulatorTraits::PVOID, PSID) TrustLevelSid; +}; + #ifndef OS_WINDOWS typedef enum _TOKEN_TYPE diff --git a/src/windows-emulator/syscalls/token.cpp b/src/windows-emulator/syscalls/token.cpp index b917bf14..98f3f506 100644 --- a/src/windows-emulator/syscalls/token.cpp +++ b/src/windows-emulator/syscalls/token.cpp @@ -58,7 +58,7 @@ namespace syscalls if (token_information_class == TokenUser) { - constexpr auto required_size = sizeof(sid) + 0x10; + constexpr auto required_size = sizeof(TOKEN_USER64) + sizeof(sid); return_length.write(required_size); if (required_size > token_information_length) @@ -68,10 +68,10 @@ namespace syscalls TOKEN_USER64 user{}; user.User.Attributes = 0; - user.User.Sid = token_information + 0x10; + user.User.Sid = token_information + sizeof(TOKEN_USER64); emulator_object{c.emu, token_information}.write(user); - c.emu.write_memory(token_information + 0x10, sid, sizeof(sid)); + c.emu.write_memory(token_information + sizeof(TOKEN_USER64), sid, sizeof(sid)); return STATUS_SUCCESS; } @@ -113,6 +113,65 @@ namespace syscalls return STATUS_SUCCESS; } + if (token_information_class == TokenPrimaryGroup) + { + constexpr auto required_size = sizeof(sid) + sizeof(TOKEN_PRIMARY_GROUP64); + return_length.write(required_size); + + if (required_size > token_information_length) + { + return STATUS_BUFFER_TOO_SMALL; + } + + TOKEN_PRIMARY_GROUP64 primary_group{}; + primary_group.PrimaryGroup = token_information + sizeof(TOKEN_PRIMARY_GROUP64); + + emulator_object{c.emu, token_information}.write(primary_group); + c.emu.write_memory(token_information + sizeof(TOKEN_PRIMARY_GROUP64), sid, sizeof(sid)); + return STATUS_SUCCESS; + } + + if (token_information_class == TokenDefaultDacl) + { + constexpr auto acl_size = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sid) - sizeof(ULONG); + constexpr auto required_size = sizeof(TOKEN_DEFAULT_DACL64) + acl_size; + return_length.write(required_size); + + if (required_size > token_information_length) + { + return STATUS_BUFFER_TOO_SMALL; + } + + TOKEN_DEFAULT_DACL64 default_dacl{}; + default_dacl.DefaultDacl = token_information + sizeof(TOKEN_DEFAULT_DACL64); + + emulator_object{c.emu, token_information}.write(default_dacl); + + const auto acl_offset = token_information + sizeof(TOKEN_DEFAULT_DACL64); + ACL acl{}; + acl.AclRevision = ACL_REVISION; + acl.Sbz1 = 0; + acl.AclSize = static_cast(acl_size); + acl.AceCount = 1; + acl.Sbz2 = 0; + + c.emu.write_memory(acl_offset, acl); + + const auto ace_offset = acl_offset + sizeof(ACL); + ACCESS_ALLOWED_ACE ace{}; + ace.Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + ace.Header.AceFlags = 0; + ace.Header.AceSize = static_cast(sizeof(ACCESS_ALLOWED_ACE) + sizeof(sid) - sizeof(ULONG)); + ace.Mask = GENERIC_ALL; + + c.emu.write_memory(ace_offset, ace); + + const auto sid_offset = ace_offset + sizeof(ACCESS_ALLOWED_ACE) - sizeof(ULONG); + c.emu.write_memory(sid_offset, sid, sizeof(sid)); + + return STATUS_SUCCESS; + } + if (token_information_class == TokenType) { constexpr auto required_size = sizeof(TOKEN_TYPE); @@ -209,7 +268,14 @@ namespace syscalls return STATUS_BUFFER_TOO_SMALL; } - c.emu.write_memory(token_information, TOKEN_STATISTICS{}); + TOKEN_STATISTICS stats{}; + stats.TokenType = get_token_type(token_handle); + stats.ImpersonationLevel = + stats.TokenType == TokenImpersonation ? SecurityImpersonation : SecurityAnonymous; + stats.GroupCount = 1; + stats.PrivilegeCount = 0; + + c.emu.write_memory(token_information, stats); return STATUS_SUCCESS; } @@ -236,7 +302,13 @@ namespace syscalls if (token_information_class == TokenIntegrityLevel) { - constexpr auto required_size = sizeof(sid) + sizeof(TOKEN_MANDATORY_LABEL64); + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + const uint8_t medium_integrity_sid[] = { + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + constexpr auto required_size = sizeof(medium_integrity_sid) + sizeof(TOKEN_MANDATORY_LABEL64); return_length.write(required_size); if (required_size > token_information_length) @@ -245,11 +317,29 @@ namespace syscalls } TOKEN_MANDATORY_LABEL64 label{}; - label.Label.Attributes = 0; + label.Label.Attributes = 0x60; label.Label.Sid = token_information + sizeof(TOKEN_MANDATORY_LABEL64); emulator_object{c.emu, token_information}.write(label); - c.emu.write_memory(token_information + sizeof(TOKEN_MANDATORY_LABEL64), sid, sizeof(sid)); + c.emu.write_memory(token_information + sizeof(TOKEN_MANDATORY_LABEL64), medium_integrity_sid, + sizeof(medium_integrity_sid)); + return STATUS_SUCCESS; + } + + if (token_information_class == TokenProcessTrustLevel) + { + constexpr auto required_size = sizeof(TOKEN_PROCESS_TRUST_LEVEL); + return_length.write(required_size); + + if (required_size > token_information_length) + { + return STATUS_BUFFER_TOO_SMALL; + } + + c.emu.write_memory(token_information, TOKEN_PROCESS_TRUST_LEVEL{ + .TrustLevelSid = 0, + }); + return STATUS_SUCCESS; } From cc2266d9341d3affbe2a03633ae0b35ebeb1ec8f Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Sun, 1 Jun 2025 19:36:30 -0300 Subject: [PATCH 2/6] Add new pseudo-handles --- src/windows-emulator/handles.hpp | 2 ++ src/windows-emulator/syscalls/event.cpp | 6 ++++++ src/windows-emulator/syscalls/file.cpp | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/src/windows-emulator/handles.hpp b/src/windows-emulator/handles.hpp index d105fbc4..bfea23f1 100644 --- a/src/windows-emulator/handles.hpp +++ b/src/windows-emulator/handles.hpp @@ -408,6 +408,7 @@ constexpr auto NULL_HANDLE = make_handle(0ULL); constexpr auto KNOWN_DLLS_DIRECTORY = make_pseudo_handle(0x1, handle_types::directory); constexpr auto BASE_NAMED_OBJECTS_DIRECTORY = make_pseudo_handle(0x2, handle_types::directory); +constexpr auto RPC_CONTROL_DIRECTORY = make_pseudo_handle(0x3, handle_types::directory); constexpr auto KNOWN_DLLS_SYMLINK = make_pseudo_handle(0x1, handle_types::symlink); constexpr auto SHARED_SECTION = make_pseudo_handle(0x1, handle_types::section); @@ -417,6 +418,7 @@ constexpr auto WER_PORT_READY = make_pseudo_handle(0x1, handle_types::event); constexpr auto DBWIN_DATA_READY = make_pseudo_handle(0x2, handle_types::event); constexpr auto DBWIN_BUFFER_READY = make_pseudo_handle(0x3, handle_types::event); constexpr auto SVCCTRL_START_EVENT = make_pseudo_handle(0x4, handle_types::event); +constexpr auto LSA_AUTHENTICATION_INITIALIZED = make_pseudo_handle(0x5, handle_types::event); constexpr auto CONSOLE_HANDLE = make_pseudo_handle(0x1, handle_types::file); constexpr auto STDOUT_HANDLE = make_pseudo_handle(0x2, handle_types::file); diff --git a/src/windows-emulator/syscalls/event.cpp b/src/windows-emulator/syscalls/event.cpp index c2f6b757..b53c0910 100644 --- a/src/windows-emulator/syscalls/event.cpp +++ b/src/windows-emulator/syscalls/event.cpp @@ -114,6 +114,12 @@ namespace syscalls return STATUS_SUCCESS; } + if (name == u"\\SECURITY\\LSA_AUTHENTICATION_INITIALIZED") + { + event_handle.write(LSA_AUTHENTICATION_INITIALIZED.bits); + return STATUS_SUCCESS; + } + if (name == u"DBWIN_DATA_READY") { event_handle.write(DBWIN_DATA_READY.bits); diff --git a/src/windows-emulator/syscalls/file.cpp b/src/windows-emulator/syscalls/file.cpp index 033f7d11..a6d84a7b 100644 --- a/src/windows-emulator/syscalls/file.cpp +++ b/src/windows-emulator/syscalls/file.cpp @@ -1022,6 +1022,12 @@ namespace syscalls return STATUS_SUCCESS; } + if (object_name == u"\\RPC Control") + { + directory_handle.write(RPC_CONTROL_DIRECTORY); + return STATUS_SUCCESS; + } + return STATUS_NOT_SUPPORTED; } From db1588623bd79d4baa6c8d5e8e364bbff2d5c5c0 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Sun, 1 Jun 2025 19:39:52 -0300 Subject: [PATCH 3/6] Add KSecDD device and support for devices in NtQueryObject --- .../devices/security_support_provider.cpp | 57 +++++++++++++++++++ .../devices/security_support_provider.hpp | 4 ++ src/windows-emulator/io_device.cpp | 7 ++- src/windows-emulator/io_device.hpp | 14 ++++- src/windows-emulator/syscalls/object.cpp | 32 ++++++++--- 5 files changed, 103 insertions(+), 11 deletions(-) create mode 100644 src/windows-emulator/devices/security_support_provider.cpp create mode 100644 src/windows-emulator/devices/security_support_provider.hpp diff --git a/src/windows-emulator/devices/security_support_provider.cpp b/src/windows-emulator/devices/security_support_provider.cpp new file mode 100644 index 00000000..717ae566 --- /dev/null +++ b/src/windows-emulator/devices/security_support_provider.cpp @@ -0,0 +1,57 @@ +#include "../std_include.hpp" +#include "security_support_provider.hpp" + +#include "../windows_emulator.hpp" + +namespace +{ + struct security_support_provider : stateless_device + { + // RNG Microsoft Primitive Provider + std::uint8_t output_data[216] = // + {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x00, 0x4E, 0x00, 0x47, + 0x00, 0x00, 0x00, 0x4D, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x6F, 0x00, + 0x66, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x69, 0x00, 0x74, + 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x76, 0x00, + 0x69, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, + 0x63, 0x00, 0x72, 0x00, 0x79, 0x00, 0x70, 0x00, 0x74, 0x00, 0x70, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6D, + 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x73, 0x00, 0x2E, 0x00, 0x64, 0x00, + 0x6C, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + NTSTATUS io_control(windows_emulator& win_emu, const io_device_context& c) override + { + win_emu.log.print(color::dark_gray, "--> KSEC IOCTL: 0x%X\n", c.io_control_code); + + if (c.io_control_code != 0x390400) + { + return STATUS_NOT_SUPPORTED; + } + + const auto operation = win_emu.emu().read_memory(c.input_buffer + 6); + + if (operation == 2) + { + win_emu.emu().write_memory(c.output_buffer, output_data); + + if (c.io_status_block) + { + IO_STATUS_BLOCK> block{}; + block.Information = sizeof(output_data); + c.io_status_block.write(block); + } + } + + return STATUS_SUCCESS; + } + }; +} + +std::unique_ptr create_security_support_provider() +{ + return std::make_unique(); +} diff --git a/src/windows-emulator/devices/security_support_provider.hpp b/src/windows-emulator/devices/security_support_provider.hpp new file mode 100644 index 00000000..35b41229 --- /dev/null +++ b/src/windows-emulator/devices/security_support_provider.hpp @@ -0,0 +1,4 @@ +#pragma once +#include "../io_device.hpp" + +std::unique_ptr create_security_support_provider(); diff --git a/src/windows-emulator/io_device.cpp b/src/windows-emulator/io_device.cpp index dc8c86cd..b1803824 100644 --- a/src/windows-emulator/io_device.cpp +++ b/src/windows-emulator/io_device.cpp @@ -2,6 +2,7 @@ #include "io_device.hpp" #include "devices/afd_endpoint.hpp" #include "devices/mount_point_manager.hpp" +#include "devices/security_support_provider.hpp" namespace { @@ -19,7 +20,6 @@ std::unique_ptr create_device(const std::u16string_view device) if (device == u"CNG" // || device == u"Nsi" // || device == u"RasAcd" // - || device == u"KsecDD" // || device == u"PcwDrv" // || device == u"DeviceApi\\CMApi" // || device == u"ConDrv\\Server") @@ -42,5 +42,10 @@ std::unique_ptr create_device(const std::u16string_view device) return create_mount_point_manager(); } + if (device == u"KsecDD") + { + return create_security_support_provider(); + } + throw std::runtime_error("Unsupported device: " + u16_to_u8(device)); } diff --git a/src/windows-emulator/io_device.hpp b/src/windows-emulator/io_device.hpp index 1ff9faf1..970b5053 100644 --- a/src/windows-emulator/io_device.hpp +++ b/src/windows-emulator/io_device.hpp @@ -175,13 +175,25 @@ class io_device_container : public io_device template requires(std::is_base_of_v || std::is_same_v) - T* get_internal_device() + T* get_internal_device() const { this->assert_validity(); auto* value = this->device_.get(); return dynamic_cast(value); } + std::u16string_view get_device_name() const + { + this->assert_validity(); + return this->device_name_; + } + + std::u16string get_device_path() const + { + this->assert_validity(); + return u"\\Device\\" + this->device_name_; + } + private: std::u16string device_name_{}; std::unique_ptr device_{}; diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index db66de02..c01f5547 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -70,21 +70,35 @@ namespace syscalls { if (object_information_class == ObjectNameInformation) { - if (handle.value.type != handle_types::file) + std::u16string device_path; + switch (handle.value.type) { + case handle_types::file: { + const auto* file = c.proc.files.get(handle); + if (!file) + { + return STATUS_INVALID_HANDLE; + } + + device_path = windows_path(file->name).to_device_path(); + break; + } + case handle_types::device: { + const auto* device = c.proc.devices.get(handle); + if (!device) + { + return STATUS_INVALID_HANDLE; + } + + device_path = device->get_device_path(); + break; + } + default: c.win_emu.log.error("Unsupported handle type for name information query: %X\n", handle.value.type); c.emu.stop(); return STATUS_NOT_SUPPORTED; } - const auto* file = c.proc.files.get(handle); - if (!file) - { - return STATUS_INVALID_HANDLE; - } - - const auto device_path = windows_path(file->name).to_device_path(); - const auto required_size = sizeof(UNICODE_STRING>) + (device_path.size() + 1) * 2; return_length.write(static_cast(required_size)); From c67146ee45d4a58c3993fd21aedc7bbfcf457e37 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Sun, 1 Jun 2025 19:41:49 -0300 Subject: [PATCH 4/6] Add new syscalls --- src/windows-emulator/syscalls.cpp | 66 +++++++++++++- src/windows-emulator/syscalls/object.cpp | 105 +++++++++++++++++++++++ src/windows-emulator/syscalls/thread.cpp | 5 ++ src/windows-emulator/syscalls/timer.cpp | 23 +++++ 4 files changed, 198 insertions(+), 1 deletion(-) 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; + } } From 9f326202201ddf9264322f8f1523249085dfdb15 Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Sun, 1 Jun 2025 19:45:22 -0300 Subject: [PATCH 5/6] Fix failing checks --- src/common/platform/process.hpp | 64 ++++++++++++++++++- .../devices/security_support_provider.cpp | 1 + src/windows-emulator/syscalls.cpp | 2 +- src/windows-emulator/syscalls/object.cpp | 21 ++++-- src/windows-emulator/syscalls/token.cpp | 10 +-- 5 files changed, 86 insertions(+), 12 deletions(-) diff --git a/src/common/platform/process.hpp b/src/common/platform/process.hpp index 5acc2451..e8d8cd07 100644 --- a/src/common/platform/process.hpp +++ b/src/common/platform/process.hpp @@ -799,6 +799,22 @@ struct ACL WORD AceCount; WORD Sbz2; }; + +struct ACE_HEADER +{ + BYTE AceType; + BYTE AceFlags; + WORD AceSize; +}; + +typedef DWORD ACCESS_MASK; + +struct ACCESS_ALLOWED_ACE +{ + ACE_HEADER Header; + ACCESS_MASK Mask; + DWORD SidStart; +}; #endif struct TOKEN_DEFAULT_DACL64 @@ -817,7 +833,7 @@ struct TOKEN_MANDATORY_LABEL64 SID_AND_ATTRIBUTES64 Label; }; -struct TOKEN_PROCESS_TRUST_LEVEL +struct TOKEN_PROCESS_TRUST_LEVEL64 { EMULATOR_CAST(EmulatorTraits::PVOID, PSID) TrustLevelSid; }; @@ -878,6 +894,52 @@ typedef struct _TOKEN_SECURITY_ATTRIBUTES_INFORMATION } Attribute; } TOKEN_SECURITY_ATTRIBUTES_INFORMATION, *PTOKEN_SECURITY_ATTRIBUTES_INFORMATION; +#ifndef OS_WINDOWS +#define SECURITY_DESCRIPTOR_REVISION 1 +#define SECURITY_DESCRIPTOR_REVISION1 1 + +typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL; + +#define SE_OWNER_DEFAULTED 0x0001 +#define SE_GROUP_DEFAULTED 0x0002 +#define SE_DACL_PRESENT 0x0004 +#define SE_DACL_DEFAULTED 0x0008 +#define SE_SACL_PRESENT 0x0010 +#define SE_SACL_DEFAULTED 0x0020 +#define SE_DACL_AUTO_INHERIT_REQ 0x0100 +#define SE_SACL_AUTO_INHERIT_REQ 0x0200 +#define SE_DACL_AUTO_INHERITED 0x0400 +#define SE_SACL_AUTO_INHERITED 0x0800 +#define SE_DACL_PROTECTED 0x1000 +#define SE_SACL_PROTECTED 0x2000 +#define SE_RM_CONTROL_VALID 0x4000 +#define SE_SELF_RELATIVE 0x8000 + +struct SECURITY_DESCRIPTOR_RELATIVE +{ + BYTE Revision; + BYTE Sbz1; + SECURITY_DESCRIPTOR_CONTROL Control; + DWORD Owner; + DWORD Group; + DWORD Sacl; + DWORD Dacl; +}; + +typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION; + +#define OWNER_SECURITY_INFORMATION 0x00000001L +#define GROUP_SECURITY_INFORMATION 0x00000002L +#define DACL_SECURITY_INFORMATION 0x00000004L +#define SACL_SECURITY_INFORMATION 0x00000008L +#define LABEL_SECURITY_INFORMATION 0x00000010L +#define ATTRIBUTE_SECURITY_INFORMATION 0x00000020L +#define SCOPE_SECURITY_INFORMATION 0x00000040L +#define PROCESS_TRUST_LABEL_SECURITY_INFORMATION 0x00000080L +#define ACCESS_FILTER_SECURITY_INFORMATION 0x00000100L +#define BACKUP_SECURITY_INFORMATION 0x00010000L +#endif + struct GDI_HANDLE_ENTRY64 { union diff --git a/src/windows-emulator/devices/security_support_provider.cpp b/src/windows-emulator/devices/security_support_provider.cpp index 717ae566..9796246f 100644 --- a/src/windows-emulator/devices/security_support_provider.cpp +++ b/src/windows-emulator/devices/security_support_provider.cpp @@ -8,6 +8,7 @@ namespace struct security_support_provider : stateless_device { // RNG Microsoft Primitive Provider + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) std::uint8_t output_data[216] = // {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, 0x00, diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index 6a6e9f12..e113455d 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -449,7 +449,7 @@ namespace syscalls } NTSTATUS handle_NtRemoveIoCompletion( - const syscall_context& c, const emulator_object /*io_completion__handle*/, + const syscall_context&, 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) diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index 4e86649d..71ab7b28 100644 --- a/src/windows-emulator/syscalls/object.cpp +++ b/src/windows-emulator/syscalls/object.cpp @@ -214,13 +214,16 @@ namespace syscalls } // Owner SID: S-1-5-32-544 (Administrators) + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 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) + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) const uint8_t group_sid[] = {0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x12, 0x00, 0x00, 0x00}; // DACL structure + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 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, @@ -233,23 +236,32 @@ namespace syscalls 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}; + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) + const uint8_t sacl_data[] = {0x02, 0x00, 0x1C, 0x00, 0x01, 0x00, 0x00, 0x00, 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); @@ -267,8 +279,7 @@ namespace syscalls sd.Revision = SECURITY_DESCRIPTOR_REVISION; sd.Control = SE_SELF_RELATIVE; - constexpr ULONG header_size = sizeof(SECURITY_DESCRIPTOR_RELATIVE); - ULONG current_offset = header_size; + ULONG current_offset = sizeof(sd); if (security_information & OWNER_SECURITY_INFORMATION) { diff --git a/src/windows-emulator/syscalls/token.cpp b/src/windows-emulator/syscalls/token.cpp index 98f3f506..f53a37dc 100644 --- a/src/windows-emulator/syscalls/token.cpp +++ b/src/windows-emulator/syscalls/token.cpp @@ -149,7 +149,7 @@ namespace syscalls const auto acl_offset = token_information + sizeof(TOKEN_DEFAULT_DACL64); ACL acl{}; - acl.AclRevision = ACL_REVISION; + acl.AclRevision = 2; // ACL_REVISION acl.Sbz1 = 0; acl.AclSize = static_cast(acl_size); acl.AceCount = 1; @@ -159,7 +159,7 @@ namespace syscalls const auto ace_offset = acl_offset + sizeof(ACL); ACCESS_ALLOWED_ACE ace{}; - ace.Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + ace.Header.AceType = 0; // ACCESS_ALLOWED_ACE_TYPE ace.Header.AceFlags = 0; ace.Header.AceSize = static_cast(sizeof(ACCESS_ALLOWED_ACE) + sizeof(sid) - sizeof(ULONG)); ace.Mask = GENERIC_ALL; @@ -305,7 +305,7 @@ namespace syscalls // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) const uint8_t medium_integrity_sid[] = { 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; constexpr auto required_size = sizeof(medium_integrity_sid) + sizeof(TOKEN_MANDATORY_LABEL64); @@ -328,7 +328,7 @@ namespace syscalls if (token_information_class == TokenProcessTrustLevel) { - constexpr auto required_size = sizeof(TOKEN_PROCESS_TRUST_LEVEL); + constexpr auto required_size = sizeof(TOKEN_PROCESS_TRUST_LEVEL64); return_length.write(required_size); if (required_size > token_information_length) @@ -336,7 +336,7 @@ namespace syscalls return STATUS_BUFFER_TOO_SMALL; } - c.emu.write_memory(token_information, TOKEN_PROCESS_TRUST_LEVEL{ + c.emu.write_memory(token_information, TOKEN_PROCESS_TRUST_LEVEL64{ .TrustLevelSid = 0, }); From 4fecea3aff6812fa54d644c30c5c9c50a0c7eada Mon Sep 17 00:00:00 2001 From: Igor Pissolati Date: Mon, 2 Jun 2025 14:34:12 -0300 Subject: [PATCH 6/6] Apply review suggested change --- src/windows-emulator/syscalls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/windows-emulator/syscalls.cpp b/src/windows-emulator/syscalls.cpp index e113455d..9e327b19 100644 --- a/src/windows-emulator/syscalls.cpp +++ b/src/windows-emulator/syscalls.cpp @@ -454,7 +454,7 @@ namespace syscalls const emulator_object>> /*io_status_block*/, const emulator_object timeout) { - if (timeout.value() && timeout.read().QuadPart == 0) + if (timeout && timeout.read().QuadPart == 0) { return STATUS_TIMEOUT; }