#pragma once #include "memory_permission.hpp" #include #include #include struct emulator_hook; using memory_operation = memory_permission; enum class instruction_hook_continuation : bool { run_instruction = false, skip_instruction = true, }; enum class memory_violation_continuation : bool { stop = false, resume = true, }; enum class memory_violation_type : uint8_t { unmapped, protection, }; struct basic_block { uint64_t address; size_t instruction_count; size_t size; }; using edge_generation_hook_callback = std::function; using basic_block_hook_callback = std::function; 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; class hook_interface { public: virtual ~hook_interface() = default; virtual emulator_hook* hook_memory_violation(uint64_t address, size_t size, memory_violation_hook_callback callback) = 0; virtual emulator_hook* hook_memory_access(uint64_t address, size_t size, memory_operation filter, complex_memory_hook_callback callback) = 0; virtual emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) = 0; virtual emulator_hook* hook_interrupt(interrupt_hook_callback callback) = 0; virtual emulator_hook* hook_edge_generation(edge_generation_hook_callback callback) = 0; virtual emulator_hook* hook_basic_block(basic_block_hook_callback callback) = 0; virtual void delete_hook(emulator_hook* hook) = 0; emulator_hook* hook_memory_violation(memory_violation_hook_callback callback) { return this->hook_memory_violation(0, std::numeric_limits::max(), std::move(callback)); } emulator_hook* hook_memory_read(const uint64_t address, const size_t size, simple_memory_hook_callback callback) { return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::read); } emulator_hook* hook_memory_write(const uint64_t address, const size_t size, simple_memory_hook_callback callback) { return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::write); } emulator_hook* hook_memory_execution(const uint64_t address, const size_t size, simple_memory_hook_callback callback) { return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::exec); } private: emulator_hook* hook_simple_memory_access(const uint64_t address, const size_t size, simple_memory_hook_callback callback, const memory_operation operation) { assert((static_cast(operation) & (static_cast(operation) - 1)) == 0); return this->hook_memory_access(address, size, operation, [c = std::move(callback)](const uint64_t a, const size_t s, const uint64_t value, memory_operation) { c(a, s, value); }); } };