Implement serialization as a concept

This commit is contained in:
momo5502
2024-09-13 10:03:23 +02:00
parent bdf179b0c2
commit 68cffae5c4
6 changed files with 39 additions and 30 deletions

View File

@@ -46,7 +46,7 @@ using memory_violation_hook_callback = std::function<memory_violation_continuati
uint64_t address, size_t size, memory_operation operation,
memory_violation_type type)>;
class emulator : public memory_manager, public utils::serializable
class emulator : public memory_manager
{
public:
emulator() = default;
@@ -97,12 +97,12 @@ public:
return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::exec);
}
void serialize(utils::buffer_serializer& buffer) const final
void serialize(utils::buffer_serializer& buffer) const
{
this->perform_serialization(buffer, false);
}
void deserialize(utils::buffer_deserializer& buffer) final
void deserialize(utils::buffer_deserializer& buffer)
{
this->perform_deserialization(buffer, false);
}

View File

@@ -11,12 +11,21 @@ namespace utils
class buffer_serializer;
class buffer_deserializer;
template <typename T>
concept Serializable = requires(T a, const T ac, buffer_serializer & serializer, buffer_deserializer & deserializer)
{
{ ac.serialize(serializer) } -> std::same_as<void>;
{ a.deserialize(deserializer) } -> std::same_as<void>;
};
/* Use concept instead, to prevent overhead of virtual function calls
struct serializable
{
virtual ~serializable() = default;
virtual void serialize(buffer_serializer& buffer) const = 0;
virtual void deserialize(buffer_deserializer& buffer) = 0;
};
*/
namespace detail
{
@@ -104,7 +113,7 @@ namespace utils
template <typename T>
void read(T& object)
{
if constexpr (std::is_base_of_v<serializable, T>)
if constexpr (Serializable<T>)
{
object.deserialize(*this);
}
@@ -258,7 +267,7 @@ namespace utils
template <typename T>
void write(const T& object)
{
if constexpr (std::is_base_of_v<serializable, T>)
if constexpr (Serializable<T>)
{
object.serialize(*this);
}

View File

@@ -2,7 +2,7 @@
#include "memory_utils.hpp"
template <typename T>
class emulator_object : utils::serializable
class emulator_object
{
public:
using value_type = T;
@@ -68,12 +68,12 @@ public:
this->write(obj, index);
}
void serialize(utils::buffer_serializer& buffer) const override
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->address_);
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->address_);
}
@@ -83,7 +83,7 @@ private:
uint64_t address_{};
};
class emulator_allocator : utils::serializable
class emulator_allocator
{
public:
emulator_allocator(emulator& emu)
@@ -159,14 +159,14 @@ public:
return this->size_;
}
void serialize(utils::buffer_serializer& buffer) const override
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->address_);
buffer.write(this->size_);
buffer.write(this->active_address_);
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->address_);
buffer.read(this->size_);

View File

@@ -68,8 +68,8 @@ constexpr handle make_pseudo_handle(const uint32_t id, const handle_types::type
}
template <handle_types::type Type, typename T>
requires(std::is_base_of_v<utils::serializable, T>)
class handle_store : utils::serializable
requires(utils::Serializable<T>)
class handle_store
{
public:
handle store(T value)
@@ -135,12 +135,12 @@ public:
return this->erase(hh);
}
void serialize(utils::buffer_serializer& buffer) const override
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write_map(this->store_);
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read_map(this->store_);
}

View File

@@ -2,7 +2,7 @@
#include "mapped_module.hpp"
#include <emulator.hpp>
class module_manager : public utils::serializable
class module_manager
{
public:
module_manager(emulator& emu);
@@ -20,8 +20,8 @@ public:
return nullptr;
}
void serialize(utils::buffer_serializer& buffer) const override;
void deserialize(utils::buffer_deserializer& buffer) override;
void serialize(utils::buffer_serializer& buffer) const;
void deserialize(utils::buffer_deserializer& buffer);
private:
emulator* emu_{};

View File

@@ -7,7 +7,7 @@
#include <x64_emulator.hpp>
struct event : utils::serializable
struct event
{
bool signaled{};
EVENT_TYPE type{};
@@ -24,51 +24,51 @@ struct event : utils::serializable
return res;
}
void serialize(utils::buffer_serializer& buffer) const override
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->signaled);
buffer.write(this->type);
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->signaled);
buffer.read(this->type);
}
};
struct file : utils::serializable
struct file
{
utils::nt::handle<INVALID_HANDLE_VALUE> handle{};
std::wstring name{};
void serialize(utils::buffer_serializer& buffer) const override
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->name);
// TODO: Serialize handle
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->name);
this->handle = INVALID_HANDLE_VALUE;
}
};
struct semaphore : utils::serializable
struct semaphore
{
std::wstring name{};
volatile uint32_t current_count{};
uint32_t max_count{};
void serialize(utils::buffer_serializer& buffer) const override
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->name);
buffer.write(this->current_count);
buffer.write(this->max_count);
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->name);
buffer.read(this->current_count);
@@ -76,7 +76,7 @@ struct semaphore : utils::serializable
}
};
struct process_context : utils::serializable
struct process_context
{
process_context(x64_emulator& emu)
: emu(&emu)
@@ -112,7 +112,7 @@ struct process_context : utils::serializable
bool verbose{false};
void serialize(utils::buffer_serializer& buffer) const override
void serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->executed_instructions);
buffer.write(this->teb);
@@ -133,7 +133,7 @@ struct process_context : utils::serializable
buffer.write(this->gs_segment);
}
void deserialize(utils::buffer_deserializer& buffer) override
void deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->executed_instructions);
buffer.read(this->teb);