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));