#pragma once #include #include #include #include struct Disassembler { struct DisassemblyResult { bool success = false; std::string full; u64 address; std::string mnemonic; struct Operand { u32 color; std::string str; }; std::array ops{}; }; ~Disassembler() { cs_close(&handle); } static Disassembler &GetInstance(bool rsp = false) { static Disassembler ret(rsp); return ret; } [[nodiscard]] DisassemblyResult Disassemble(const u32 address) const; [[nodiscard]] DisassemblyResult DisassembleDetailed(u32 address, u32 instruction) const; [[nodiscard]] DisassemblyResult DisassembleSimple(u32 address, u32 instruction) const; private: explicit Disassembler(const bool rsp) : rsp(rsp) { if (cs_open(CS_ARCH_MIPS, static_cast((rsp ? CS_MODE_32 : CS_MODE_64) | CS_MODE_BIG_ENDIAN), &handle) != CS_ERR_OK) { panic("Could not initialize {} disassembler!", rsp ? "RSP" : "CPU"); } if (cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON) != CS_ERR_OK) { Util::Error::GetInstance().Throw({Util::Error::Severity::WARN}, {Util::Error::Type::CAPSTONE_ERROR}, {}, {}, "Could not enable disassembler's details!"); details = false; } } bool rsp = false; bool details = true; csh handle{}; };