From d94a92df45d05425654948a42b3445a28c3b30cd Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 12 Sep 2024 13:21:52 +0200 Subject: [PATCH] More serialization support --- src/emulator/emulator.hpp | 22 ++++++-- src/unicorn_emulator/unicorn_x64_emulator.cpp | 53 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/emulator/emulator.hpp b/src/emulator/emulator.hpp index 94c57e54..1c9b6d06 100644 --- a/src/emulator/emulator.hpp +++ b/src/emulator/emulator.hpp @@ -32,10 +32,11 @@ using instruction_hook_callback = std::function using interrupt_hook_callback = std::function; using simple_memory_hook_callback = std::function; using complex_memory_hook_callback = std::function; -using memory_violation_hook_callback = std::function; +using memory_violation_hook_callback = std::function; -class emulator : public memory_manager +class emulator : public memory_manager, public utils::serializable { public: emulator() = default; @@ -84,6 +85,18 @@ public: return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::exec); } + void serialize(utils::buffer_serializer& buffer) const final + { + this->serialize_memory_state(buffer); + this->serialize_state(buffer); + } + + void deserialize(utils::buffer_deserializer& buffer) final + { + this->deserialize_memory_state(buffer); + this->deserialize_state(buffer); + } + private: emulator_hook* hook_simple_memory_access(const uint64_t address, const size_t size, simple_memory_hook_callback callback, const memory_operation operation) @@ -96,4 +109,7 @@ private: c(a, s); }); } + + virtual void serialize_state(utils::buffer_serializer& buffer) const = 0; + virtual void deserialize_state(utils::buffer_deserializer& buffer) = 0; }; diff --git a/src/unicorn_emulator/unicorn_x64_emulator.cpp b/src/unicorn_emulator/unicorn_x64_emulator.cpp index b2eb2933..55a91f51 100644 --- a/src/unicorn_emulator/unicorn_x64_emulator.cpp +++ b/src/unicorn_emulator/unicorn_x64_emulator.cpp @@ -106,6 +106,47 @@ namespace unicorn std::vector hooks_; }; + class uc_context_serializer + { + public: + uc_context_serializer(uc_engine* uc) + : uc_(uc) + , size_(uc_context_size(uc)) + { + uce(uc_context_alloc(uc, &this->context_)); + } + + ~uc_context_serializer() + { + if (this->context_) + { + (void)uc_context_free(this->context_); + } + } + + void serialize(utils::buffer_serializer& buffer) const + { + uce(uc_context_save(this->uc_, this->context_)); + buffer.write(this->context_, this->size_); + } + + void deserialize(utils::buffer_deserializer& buffer) const + { + buffer.read(this->context_, this->size_); + uce(uc_context_restore(this->uc_, this->context_)); + } + + uc_context_serializer(uc_context_serializer&&) = delete; + uc_context_serializer(const uc_context_serializer&) = delete; + uc_context_serializer& operator=(uc_context_serializer&&) = delete; + uc_context_serializer& operator=(const uc_context_serializer&) = delete; + + private: + uc_engine* uc_{}; + uc_context* context_{}; + size_t size_{}; + }; + void add_read_hook(uc_engine* uc, const uint64_t address, const size_t size, hook_container& container, const std::shared_ptr& callback) { @@ -455,6 +496,18 @@ namespace unicorn return this->uc_; } + void serialize_state(utils::buffer_serializer& buffer) const override + { + const uc_context_serializer serializer(this->uc_); + serializer.serialize(buffer); + } + + void deserialize_state(utils::buffer_deserializer& buffer) override + { + const uc_context_serializer serializer(this->uc_); + serializer.deserialize(buffer); + } + private: uc_engine* uc_{}; bool retry_after_violation_{false};