#pragma once #include #include #include #include "common/segment_utils.hpp" class emulator; class instructions { public: instructions() = default; ~instructions() { this->release(); } instructions(instructions&& obj) noexcept : instructions() { this->operator=(std::move(obj)); } instructions& operator=(instructions&& obj) noexcept { if (this != &obj) { this->release(); this->instructions_ = obj.instructions_; obj.instructions_ = {}; } return *this; } instructions(const instructions&) = delete; instructions& operator=(const instructions&) = delete; operator std::span() const { return this->instructions_; } bool empty() const noexcept { return this->instructions_.empty(); } size_t size() const noexcept { return this->instructions_.size(); } const cs_insn* data() const noexcept { return this->instructions_.data(); } const cs_insn& operator[](const size_t index) const { return this->instructions_[index]; } auto begin() const { return this->instructions_.begin(); } auto end() const { return this->instructions_.end(); } private: friend class disassembler; std::span instructions_{}; explicit instructions(const std::span insts) : instructions_(insts) { } void release(); }; class disassembler { public: disassembler(); ~disassembler(); disassembler(disassembler&& obj) noexcept; disassembler& operator=(disassembler&& obj) noexcept; disassembler(const disassembler& obj) = delete; disassembler& operator=(const disassembler& obj) = delete; using segment_bitness = segment_utils::segment_bitness; instructions disassemble(emulator& cpu, uint16_t cs_selector, std::span data, size_t count) const; static std::optional get_segment_bitness(emulator& cpu, uint16_t cs_selector); csh resolve_handle(emulator& cpu, uint16_t cs_selector) const; csh get_handle_64() const { return this->handle_64_; } csh get_handle_32() const { return this->handle_32_; } csh get_handle_16() const { return this->handle_16_; } private: csh handle_64_{}; csh handle_32_{}; csh handle_16_{}; void release(); };