#pragma once #include #include #include #include "helpers.hpp" namespace Common { class CapstoneDisassembler { csh handle; // Handle to our disassembler object cs_insn* instructions = nullptr; // Pointer to instruction object bool initialized = false; public: bool isInitialized() { return initialized; } void init(cs_arch arch, cs_mode mode) { initialized = (cs_open(arch, mode, &handle) == CS_ERR_OK); } CapstoneDisassembler() {} CapstoneDisassembler(cs_arch arch, cs_mode mode) { init(arch, mode); } // Returns the number of instructions successfully disassembled // pc: program counter of the instruction to disassemble // bytes: Byte representation of instruction // buffer: text buffer to output the disassembly too usize disassemble(std::string& buffer, u32 pc, std::span bytes, u64 offset = 0) { if (!initialized) { buffer = "Capstone was not properly initialized"; return 0; } usize count = cs_disasm(handle, bytes.data(), bytes.size(), pc, offset, &instructions); if (count == 0) { // Error in disassembly, quit early and return empty string buffer = "Error disassembling instructions with Capstone"; return 0; } buffer = ""; for (usize i = 0; i < count; i++) { buffer += std::string(instructions[i].mnemonic) + " " + std::string(instructions[i].op_str); if (i < count - 1) { // Append newlines between instructions, sans the final instruction buffer += "\n"; } } cs_free(instructions, count); return count; } }; } // namespace Common