diff --git a/src/common/platform/process.hpp b/src/common/platform/process.hpp index 1234f900..e8d8cd07 100644 --- a/src/common/platform/process.hpp +++ b/src/common/platform/process.hpp @@ -785,6 +785,43 @@ 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; +}; + +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 +{ + EMULATOR_CAST(EmulatorTraits::PVOID, PACL) DefaultDacl; +}; + struct TOKEN_BNO_ISOLATION_INFORMATION64 { EmulatorTraits::PVOID IsolationPrefix; @@ -796,6 +833,11 @@ struct TOKEN_MANDATORY_LABEL64 SID_AND_ATTRIBUTES64 Label; }; +struct TOKEN_PROCESS_TRUST_LEVEL64 +{ + EMULATOR_CAST(EmulatorTraits::PVOID, PSID) TrustLevelSid; +}; + #ifndef OS_WINDOWS typedef enum _TOKEN_TYPE @@ -852,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 new file mode 100644 index 00000000..9796246f --- /dev/null +++ b/src/windows-emulator/devices/security_support_provider.cpp @@ -0,0 +1,58 @@ +#include "../std_include.hpp" +#include "security_support_provider.hpp" + +#include "../windows_emulator.hpp" + +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, + 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/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/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.cpp b/src/windows-emulator/syscalls.cpp index 971fc5b0..9e327b19 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&, 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 && 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/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; } diff --git a/src/windows-emulator/syscalls/object.cpp b/src/windows-emulator/syscalls/object.cpp index db66de02..71ab7b28 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)); @@ -187,4 +201,120 @@ 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) + // 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, + 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 + // 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); + + 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; + + ULONG current_offset = sizeof(sd); + + 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; + } } diff --git a/src/windows-emulator/syscalls/token.cpp b/src/windows-emulator/syscalls/token.cpp index b917bf14..f53a37dc 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 = 2; // 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 = 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; + + 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_LEVEL64); + 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_LEVEL64{ + .TrustLevelSid = 0, + }); + return STATUS_SUCCESS; }