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, uint64_t address, size_t size, memory_operation operation,
memory_violation_type type)>; memory_violation_type type)>;
class emulator : public memory_manager, public utils::serializable class emulator : public memory_manager
{ {
public: public:
emulator() = default; emulator() = default;
@@ -97,12 +97,12 @@ public:
return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::exec); 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); this->perform_serialization(buffer, false);
} }
void deserialize(utils::buffer_deserializer& buffer) final void deserialize(utils::buffer_deserializer& buffer)
{ {
this->perform_deserialization(buffer, false); this->perform_deserialization(buffer, false);
} }

View File

@@ -11,12 +11,21 @@ namespace utils
class buffer_serializer; class buffer_serializer;
class buffer_deserializer; 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 struct serializable
{ {
virtual ~serializable() = default; virtual ~serializable() = default;
virtual void serialize(buffer_serializer& buffer) const = 0; virtual void serialize(buffer_serializer& buffer) const = 0;
virtual void deserialize(buffer_deserializer& buffer) = 0; virtual void deserialize(buffer_deserializer& buffer) = 0;
}; };
*/
namespace detail namespace detail
{ {
@@ -104,7 +113,7 @@ namespace utils
template <typename T> template <typename T>
void read(T& object) void read(T& object)
{ {
if constexpr (std::is_base_of_v<serializable, T>) if constexpr (Serializable<T>)
{ {
object.deserialize(*this); object.deserialize(*this);
} }
@@ -258,7 +267,7 @@ namespace utils
template <typename T> template <typename T>
void write(const T& object) void write(const T& object)
{ {
if constexpr (std::is_base_of_v<serializable, T>) if constexpr (Serializable<T>)
{ {
object.serialize(*this); object.serialize(*this);
} }

View File

@@ -2,7 +2,7 @@
#include "memory_utils.hpp" #include "memory_utils.hpp"
template <typename T> template <typename T>
class emulator_object : utils::serializable class emulator_object
{ {
public: public:
using value_type = T; using value_type = T;
@@ -68,12 +68,12 @@ public:
this->write(obj, index); this->write(obj, index);
} }
void serialize(utils::buffer_serializer& buffer) const override void serialize(utils::buffer_serializer& buffer) const
{ {
buffer.write(this->address_); buffer.write(this->address_);
} }
void deserialize(utils::buffer_deserializer& buffer) override void deserialize(utils::buffer_deserializer& buffer)
{ {
buffer.read(this->address_); buffer.read(this->address_);
} }
@@ -83,7 +83,7 @@ private:
uint64_t address_{}; uint64_t address_{};
}; };
class emulator_allocator : utils::serializable class emulator_allocator
{ {
public: public:
emulator_allocator(emulator& emu) emulator_allocator(emulator& emu)
@@ -159,14 +159,14 @@ public:
return this->size_; 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->address_);
buffer.write(this->size_); buffer.write(this->size_);
buffer.write(this->active_address_); 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->address_);
buffer.read(this->size_); 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> template <handle_types::type Type, typename T>
requires(std::is_base_of_v<utils::serializable, T>) requires(utils::Serializable<T>)
class handle_store : utils::serializable class handle_store
{ {
public: public:
handle store(T value) handle store(T value)
@@ -135,12 +135,12 @@ public:
return this->erase(hh); return this->erase(hh);
} }
void serialize(utils::buffer_serializer& buffer) const override void serialize(utils::buffer_serializer& buffer) const
{ {
buffer.write_map(this->store_); buffer.write_map(this->store_);
} }
void deserialize(utils::buffer_deserializer& buffer) override void deserialize(utils::buffer_deserializer& buffer)
{ {
buffer.read_map(this->store_); buffer.read_map(this->store_);
} }

View File

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

View File

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