Add KSecDD device and support for devices in NtQueryObject

This commit is contained in:
Igor Pissolati
2025-06-01 19:39:52 -03:00
parent cc2266d934
commit db1588623b
5 changed files with 103 additions and 11 deletions

View File

@@ -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<USHORT>(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<EmulatorTraits<Emu64>> block{};
block.Information = sizeof(output_data);
c.io_status_block.write(block);
}
}
return STATUS_SUCCESS;
}
};
}
std::unique_ptr<io_device> create_security_support_provider()
{
return std::make_unique<security_support_provider>();
}

View File

@@ -0,0 +1,4 @@
#pragma once
#include "../io_device.hpp"
std::unique_ptr<io_device> create_security_support_provider();

View File

@@ -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<io_device> 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<io_device> 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));
}

View File

@@ -175,13 +175,25 @@ class io_device_container : public io_device
template <typename T = io_device>
requires(std::is_base_of_v<io_device, T> || std::is_same_v<io_device, T>)
T* get_internal_device()
T* get_internal_device() const
{
this->assert_validity();
auto* value = this->device_.get();
return dynamic_cast<T*>(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<io_device> device_{};

View File

@@ -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<EmulatorTraits<Emu64>>) + (device_path.size() + 1) * 2;
return_length.write(static_cast<ULONG>(required_size));