More serialization support

This commit is contained in:
momo5502
2024-09-12 13:21:52 +02:00
parent cef85295af
commit d94a92df45
2 changed files with 72 additions and 3 deletions

View File

@@ -32,10 +32,11 @@ using instruction_hook_callback = std::function<instruction_hook_continuation()>
using interrupt_hook_callback = std::function<void(int interrupt)>;
using simple_memory_hook_callback = std::function<void(uint64_t address, size_t size)>;
using complex_memory_hook_callback = std::function<void(uint64_t address, size_t size, memory_operation operation)>;
using memory_violation_hook_callback = std::function<memory_violation_continuation(uint64_t address, size_t size, memory_operation operation,
memory_violation_type type)>;
using memory_violation_hook_callback = std::function<memory_violation_continuation(
uint64_t address, size_t size, memory_operation operation,
memory_violation_type type)>;
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;
};

View File

@@ -106,6 +106,47 @@ namespace unicorn
std::vector<hook_entry> 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<complex_memory_hook_callback>& 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};