#include #include #include #include #include #include namespace hex::plugin::disasm { class CustomArchitecture : public ContentRegistry::Disassembler::Architecture { public: CustomArchitecture(::disasm::spec::Spec spec) : Architecture(spec.getName()), m_spec(std::move(spec)) {} bool start() override { return true; } void end() override { } void drawSettings() override { } std::optional disassemble(u64 imageBaseAddress, u64 instructionLoadAddress, u64 instructionDataAddress, std::span code) override { std::ignore = imageBaseAddress; std::ignore = instructionDataAddress; std::ignore = instructionLoadAddress; std::ignore = code; auto instructions = m_spec.disassemble(code, 1); if (instructions.empty()) { return std::nullopt; } const auto &instruction = instructions.front(); ContentRegistry::Disassembler::Instruction disassembly = { }; disassembly.address = instructionDataAddress; disassembly.offset = instructionDataAddress - imageBaseAddress; disassembly.size = instruction.bytes.size(); disassembly.mnemonic = instruction.mnemonic; disassembly.operators = instruction.operands; for (u8 byte : instruction.bytes) disassembly.bytes += hex::format("{0:02X} ", byte); disassembly.bytes.pop_back(); return disassembly; } private: ::disasm::spec::Spec m_spec; }; void registerCustomArchitectures() { for (const auto &folder : hex::paths::Disassemblers.all()) { if (!wolv::io::fs::exists(folder)) continue; for (const auto &entry : std::fs::directory_iterator(folder)) { try { auto spec = ::disasm::spec::Loader::load(entry.path(), { entry.path().parent_path() }); ContentRegistry::Disassembler::add(std::move(spec)); } catch (const std::exception &e) { log::error("Failed to load disassembler config '{}': {}", wolv::util::toUTF8String(entry.path()), e.what()); } } } } }