Fix more handles

This commit is contained in:
Maurice Heumann
2025-02-05 07:01:06 +01:00
parent 3e4380e149
commit a182657733
6 changed files with 92 additions and 66 deletions

View File

@@ -474,7 +474,7 @@ namespace
this->clear_pending_state();
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read_optional(this->creation_data);
this->setup();
@@ -484,7 +484,7 @@ namespace
buffer.read_optional(this->timeout_);
}
void serialize(utils::buffer_serializer& buffer) const override
void serialize_object(utils::buffer_serializer& buffer) const override
{
buffer.write_optional(this->creation_data);
buffer.write_optional(this->require_poll_);

View File

@@ -111,14 +111,44 @@ namespace handle_detail
};
}
class ref_counted_object
{
public:
virtual ~ref_counted_object() = default;
uint32_t ref_count{1};
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->ref_count);
this->serialize_object(buffer);
}
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->ref_count);
this->deserialize_object(buffer);
}
static bool deleter(ref_counted_object& e)
{
return --e.ref_count == 0;
}
private:
virtual void serialize_object(utils::buffer_serializer& buffer) const = 0;
virtual void deserialize_object(utils::buffer_deserializer& buffer) = 0;
};
struct generic_handle_store
{
virtual ~generic_handle_store() = default;
virtual bool erase(handle h) = 0;
virtual std::optional<handle> duplicate(handle h) = 0;
};
template <handle_types::type Type, typename T, uint32_t IndexShift = 0>
requires(utils::Serializable<T>)
requires(utils::Serializable<T> && std::is_base_of_v<ref_counted_object, T>)
class handle_store : public generic_handle_store
{
public:
@@ -189,6 +219,18 @@ class handle_store : public generic_handle_store
return this->store_.size();
}
std::optional<handle> duplicate(const handle h) override
{
auto* entry = this->get(h);
if (!entry)
{
return std::nullopt;
}
++static_cast<ref_counted_object*>(entry)->ref_count;
return h;
}
bool erase(const typename value_map::iterator& entry)
{
if (this->block_mutation_)

View File

@@ -76,10 +76,10 @@ inline void write_io_status(const emulator_object<IO_STATUS_BLOCK<EmulatorTraits
}
}
struct io_device
struct io_device : ref_counted_object
{
io_device() = default;
virtual ~io_device() = default;
~io_device() override = default;
io_device(io_device&&) = default;
io_device& operator=(io_device&&) = default;
@@ -100,9 +100,6 @@ struct io_device
(void)win_emu;
}
virtual void serialize(utils::buffer_serializer& buffer) const = 0;
virtual void deserialize(utils::buffer_deserializer& buffer) = 0;
NTSTATUS execute_ioctl(windows_emulator& win_emu, const io_device_context& c)
{
if (c.io_status_block)
@@ -122,11 +119,11 @@ struct stateless_device : io_device
{
}
void serialize(utils::buffer_serializer&) const override
void serialize_object(utils::buffer_serializer&) const override
{
}
void deserialize(utils::buffer_deserializer&) override
void deserialize_object(utils::buffer_deserializer&) override
{
}
};
@@ -157,7 +154,7 @@ class io_device_container : public io_device
return this->device_->work(win_emu);
}
void serialize(utils::buffer_serializer& buffer) const override
void serialize_object(utils::buffer_serializer& buffer) const override
{
this->assert_validity();
@@ -165,7 +162,7 @@ class io_device_container : public io_device
this->device_->serialize(buffer);
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read_string(this->device_name_);
this->setup();

View File

@@ -27,26 +27,6 @@
class windows_emulator;
struct ref_counted_object
{
uint32_t ref_count{1};
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->ref_count);
}
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->ref_count);
}
static bool deleter(ref_counted_object& e)
{
return --e.ref_count == 0;
}
};
struct event : ref_counted_object
{
bool signaled{};
@@ -65,22 +45,18 @@ struct event : ref_counted_object
return res;
}
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const override
{
buffer.write(this->signaled);
buffer.write(this->type);
buffer.write(this->name);
ref_counted_object::serialize(buffer);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read(this->signaled);
buffer.read(this->type);
buffer.read(this->name);
ref_counted_object::deserialize(buffer);
}
};
@@ -121,22 +97,18 @@ struct mutant : ref_counted_object
return {old_count, true};
}
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const override
{
buffer.write(this->locked_count);
buffer.write(this->owning_thread_id);
buffer.write(this->name);
ref_counted_object::serialize(buffer);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read(this->locked_count);
buffer.read(this->owning_thread_id);
buffer.read(this->name);
ref_counted_object::deserialize(buffer);
}
};
@@ -173,7 +145,7 @@ struct file_enumeration_state
}
};
struct file
struct file : ref_counted_object
{
utils::file_handle handle{};
std::u16string name{};
@@ -189,14 +161,14 @@ struct file
return !this->is_file();
}
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const override
{
// TODO: Serialize handle
buffer.write(this->name);
buffer.write_optional(this->enumeration_state);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read(this->name);
buffer.read_optional(this->enumeration_state);
@@ -204,7 +176,7 @@ struct file
}
};
struct section
struct section : ref_counted_object
{
std::u16string name{};
std::u16string file_name{};
@@ -217,7 +189,7 @@ struct section
return this->allocation_attributes & SEC_IMAGE;
}
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const override
{
buffer.write(this->name);
buffer.write(this->file_name);
@@ -226,7 +198,7 @@ struct section
buffer.write(this->allocation_attributes);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read(this->name);
buffer.read(this->file_name);
@@ -267,37 +239,33 @@ struct semaphore : ref_counted_object
return {old_count, true};
}
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const override
{
buffer.write(this->name);
buffer.write(this->current_count);
buffer.write(this->max_count);
ref_counted_object::serialize(buffer);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read(this->name);
buffer.read(this->current_count);
buffer.read(this->max_count);
ref_counted_object::deserialize(buffer);
}
};
struct port
struct port : ref_counted_object
{
std::u16string name{};
uint64_t view_base{};
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const override
{
buffer.write(this->name);
buffer.write(this->view_base);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read(this->name);
buffer.read(this->view_base);
@@ -439,7 +407,7 @@ class emulator_thread : public ref_counted_object
}
}
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const
{
if (this->marker.was_moved())
{
@@ -470,7 +438,7 @@ class emulator_thread : public ref_counted_object
buffer.write_vector(this->last_registers);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer)
{
if (this->marker.was_moved())
{

View File

@@ -3,19 +3,20 @@
#include "../std_include.hpp"
#include "hive_parser.hpp"
#include "serialization_helper.hpp"
#include "../handles.hpp"
struct registry_key
struct registry_key : ref_counted_object
{
utils::path_key hive{};
utils::path_key path{};
void serialize(utils::buffer_serializer& buffer) const
void serialize_object(utils::buffer_serializer& buffer) const override
{
buffer.write(this->hive);
buffer.write(this->path);
}
void deserialize(utils::buffer_deserializer& buffer)
void deserialize_object(utils::buffer_deserializer& buffer) override
{
buffer.read(this->hive);
buffer.read(this->path);

View File

@@ -1108,8 +1108,20 @@ namespace
return STATUS_SUCCESS;
}
c.win_emu.log.error("Duplicating non-pseudo object not supported yet!\n");
return STATUS_NOT_SUPPORTED;
auto* store = get_handle_store(c.proc, source_handle);
if (!store)
{
return STATUS_NOT_SUPPORTED;
}
const auto new_handle = store->duplicate(source_handle);
if (!new_handle)
{
return STATUS_INVALID_HANDLE;
}
target_handle.write(*new_handle);
return STATUS_SUCCESS;
}
NTSTATUS handle_NtQuerySystemInformationEx(const syscall_context& c, const uint32_t info_class,
@@ -3302,6 +3314,11 @@ namespace
return handle_NtUserGetDCEx();
}
NTSTATUS handle_NtUserGetWindowDC()
{
return 1;
}
NTSTATUS handle_NtUserReleaseDC()
{
return STATUS_SUCCESS;
@@ -3734,6 +3751,7 @@ void syscall_dispatcher::add_handlers(std::map<std::string, syscall_handler>& ha
add_handler(NtUserModifyUserStartupInfoFlags);
add_handler(NtUserGetDCEx);
add_handler(NtUserGetDC);
add_handler(NtUserGetWindowDC);
add_handler(NtUserGetDpiForCurrentProcess);
add_handler(NtReleaseSemaphore);
add_handler(NtEnumerateKey);