#define ICICLE_EMULATOR_IMPL #include "icicle_x64_emulator.hpp" using icicle_emulator = struct icicle_emulator_; extern "C" { icicle_emulator* icicle_create_emulator(); int32_t icicle_protect_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions); int32_t icicle_map_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions); int32_t icicle_unmap_memory(icicle_emulator*, uint64_t address, uint64_t length); int32_t icicle_read_memory(icicle_emulator*, uint64_t address, void* data, size_t length); int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length); size_t icicle_read_register(icicle_emulator*, int reg, void* data, size_t length); size_t icicle_write_register(icicle_emulator*, int reg, const void* data, size_t length); void icicle_destroy_emulator(icicle_emulator*); } namespace icicle { namespace { void ice(const bool result, const std::string_view error) { if (!result) { throw std::runtime_error(std::string(error)); } } } class icicle_x64_emulator : public x64_emulator { public: icicle_x64_emulator() : emu_(icicle_create_emulator()) { if (!this->emu_) { throw std::runtime_error("Failed to create icicle emulator instance"); } } ~icicle_x64_emulator() override { if (this->emu_) { icicle_destroy_emulator(this->emu_); this->emu_ = nullptr; } } void start(const uint64_t start, const uint64_t end, std::chrono::nanoseconds timeout, const size_t count) override { if (timeout.count() < 0) { timeout = {}; } } void stop() override { } size_t write_raw_register(const int reg, const void* value, const size_t size) override { return icicle_write_register(this->emu_, reg, value, size); } size_t read_raw_register(const int reg, void* value, const size_t size) override { return icicle_read_register(this->emu_, reg, value, size); } void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb, mmio_write_callback write_cb) override { return; // throw std::runtime_error("Not implemented"); } void map_memory(const uint64_t address, const size_t size, memory_permission permissions) override { const auto res = icicle_map_memory(this->emu_, address, size, static_cast(permissions)); ice(res, "Failed to map memory"); } void unmap_memory(const uint64_t address, const size_t size) override { const auto res = icicle_unmap_memory(this->emu_, address, size); ice(res, "Failed to unmap memory"); } bool try_read_memory(const uint64_t address, void* data, const size_t size) const override { return icicle_read_memory(this->emu_, address, data, size); } void read_memory(const uint64_t address, void* data, const size_t size) const override { const auto res = this->try_read_memory(address, data, size); ice(res, "Failed to read memory"); } void write_memory(const uint64_t address, const void* data, const size_t size) override { const auto res = icicle_write_memory(this->emu_, address, data, size); ice(res, "Failed to write memory"); } void apply_memory_protection(const uint64_t address, const size_t size, memory_permission permissions) override { const auto res = icicle_protect_memory(this->emu_, address, size, static_cast(permissions)); ice(res, "Failed to apply permissions"); } emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override { return nullptr; // throw std::runtime_error("Not implemented"); } emulator_hook* hook_basic_block(basic_block_hook_callback callback) override { return nullptr; // throw std::runtime_error("Not implemented"); } emulator_hook* hook_edge_generation(edge_generation_hook_callback callback) override { return nullptr; // throw std::runtime_error("Not implemented"); } emulator_hook* hook_interrupt(interrupt_hook_callback callback) override { return nullptr; // throw std::runtime_error("Not implemented"); } emulator_hook* hook_memory_violation(uint64_t address, size_t size, memory_violation_hook_callback callback) override { return nullptr; // throw std::runtime_error("Not implemented"); } emulator_hook* hook_memory_access(const uint64_t address, const size_t size, const memory_operation filter, complex_memory_hook_callback callback) override { if (filter == memory_permission::none) { return nullptr; } return nullptr; // throw std::runtime_error("Not implemented"); } void delete_hook(emulator_hook* hook) override { // throw std::runtime_error("Not implemented"); } void serialize_state(utils::buffer_serializer& buffer, const bool is_snapshot) const override { // throw std::runtime_error("Not implemented"); } void deserialize_state(utils::buffer_deserializer& buffer, const bool is_snapshot) override { // throw std::runtime_error("Not implemented"); } std::vector save_registers() override { // throw std::runtime_error("Not implemented"); return {}; } void restore_registers(const std::vector& register_data) override { // throw std::runtime_error("Not implemented"); } bool has_violation() const override { return false; } private: icicle_emulator* emu_{}; }; std::unique_ptr create_x64_emulator() { return std::make_unique(); } }