feat: Added initial support for custom disassemblers
This commit is contained in:
parent
a76c6c653d
commit
bf44a1cce6
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -44,3 +44,6 @@
|
|||||||
[submodule "lib/third_party/HashLibPlus"]
|
[submodule "lib/third_party/HashLibPlus"]
|
||||||
path = lib/third_party/HashLibPlus
|
path = lib/third_party/HashLibPlus
|
||||||
url = https://github.com/WerWolv/HashLibPlus
|
url = https://github.com/WerWolv/HashLibPlus
|
||||||
|
[submodule "lib/external/disassembler"]
|
||||||
|
path = lib/external/disassembler
|
||||||
|
url = https://github.com/WerWolv/Disassembler
|
||||||
|
@ -728,6 +728,7 @@ macro(addBundledLibraries)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/pattern_language EXCLUDE_FROM_ALL)
|
||||||
|
add_subdirectory(${EXTERNAL_LIBS_FOLDER}/disassembler EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
if (LIBPL_SHARED_LIBRARY)
|
if (LIBPL_SHARED_LIBRARY)
|
||||||
install(
|
install(
|
||||||
|
1
lib/external/disassembler
vendored
Submodule
1
lib/external/disassembler
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 2209885ee77456fd922999e183f7feb33bed8794
|
@ -1461,8 +1461,8 @@ namespace hex {
|
|||||||
|
|
||||||
template<std::derived_from<Architecture> T>
|
template<std::derived_from<Architecture> T>
|
||||||
void add(auto && ...args) {
|
void add(auto && ...args) {
|
||||||
impl::addArchitectureCreator([args...] {
|
impl::addArchitectureCreator([...args = std::move(args)] {
|
||||||
return std::make_unique<T>(std::forward<decltype(args)>(args)...);
|
return std::make_unique<T>(args...);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,8 +82,9 @@ namespace hex::paths {
|
|||||||
const static inline impl::DataPath Nodes("scripts/nodes");
|
const static inline impl::DataPath Nodes("scripts/nodes");
|
||||||
const static inline impl::DataPath Layouts("layouts");
|
const static inline impl::DataPath Layouts("layouts");
|
||||||
const static inline impl::DataPath Workspaces("workspaces");
|
const static inline impl::DataPath Workspaces("workspaces");
|
||||||
|
const static inline impl::DataPath Disassemblers("disassemblers");
|
||||||
|
|
||||||
constexpr static inline std::array<const impl::DefaultPath*, 20> All = {
|
constexpr static inline std::array<const impl::DefaultPath*, 21> All = {
|
||||||
&Config,
|
&Config,
|
||||||
&Recent,
|
&Recent,
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ namespace hex::paths {
|
|||||||
&Nodes,
|
&Nodes,
|
||||||
&Layouts,
|
&Layouts,
|
||||||
&Workspaces,
|
&Workspaces,
|
||||||
|
&Disassemblers
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -151,7 +151,7 @@ namespace hex::crash {
|
|||||||
try {
|
try {
|
||||||
std::rethrow_exception(std::current_exception());
|
std::rethrow_exception(std::current_exception());
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
std::string exceptionStr = hex::format("{}()::what() -> {}", llvm::itaniumDemangle(typeid(ex).name()), ex.what());
|
std::string exceptionStr = hex::format("{}()::what() -> {}", llvm::demangle(typeid(ex).name()), ex.what());
|
||||||
|
|
||||||
handleCrash(exceptionStr);
|
handleCrash(exceptionStr);
|
||||||
log::fatal("Program terminated with uncaught exception: {}", exceptionStr);
|
log::fatal("Program terminated with uncaught exception: {}", exceptionStr);
|
||||||
|
@ -476,6 +476,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "Custom data processor nodes", &paths::Nodes },
|
{ "Custom data processor nodes", &paths::Nodes },
|
||||||
{ "Layouts", &paths::Layouts },
|
{ "Layouts", &paths::Layouts },
|
||||||
{ "Workspaces", &paths::Workspaces },
|
{ "Workspaces", &paths::Workspaces },
|
||||||
|
{ "Disassemblers", &paths::Disassemblers },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(PathTypes.back().first != nullptr, "All path items need to be populated!");
|
static_assert(PathTypes.back().first != nullptr, "All path items need to be populated!");
|
||||||
|
@ -27,6 +27,7 @@ add_imhex_plugin(
|
|||||||
source/content/pl_builtin_types.cpp
|
source/content/pl_builtin_types.cpp
|
||||||
|
|
||||||
source/content/disassemblers/capstone_architectures.cpp
|
source/content/disassemblers/capstone_architectures.cpp
|
||||||
|
source/content/disassemblers/custom_architectures.cpp
|
||||||
INCLUDES
|
INCLUDES
|
||||||
include
|
include
|
||||||
${CAPSTONE_INCLUDE_DIR}
|
${CAPSTONE_INCLUDE_DIR}
|
||||||
@ -34,4 +35,5 @@ add_imhex_plugin(
|
|||||||
ui
|
ui
|
||||||
fonts
|
fonts
|
||||||
${CAPSTONE_LIBRARY}
|
${CAPSTONE_LIBRARY}
|
||||||
|
libdisassembler
|
||||||
)
|
)
|
||||||
|
@ -30,7 +30,7 @@ namespace hex::plugin::disasm {
|
|||||||
RISCV = CS_ARCH_RISCV,
|
RISCV = CS_ARCH_RISCV,
|
||||||
MOS65XX = CS_ARCH_MOS65XX,
|
MOS65XX = CS_ARCH_MOS65XX,
|
||||||
BPF = CS_ARCH_BPF,
|
BPF = CS_ARCH_BPF,
|
||||||
SH = CS_ARCH_SH,
|
SUPERH = CS_ARCH_SH,
|
||||||
TRICORE = CS_ARCH_TRICORE,
|
TRICORE = CS_ARCH_TRICORE,
|
||||||
MAX = TRICORE,
|
MAX = TRICORE,
|
||||||
# else
|
# else
|
||||||
@ -163,7 +163,7 @@ namespace hex::plugin::disasm {
|
|||||||
arch = CS_ARCH_MOS65XX;
|
arch = CS_ARCH_MOS65XX;
|
||||||
else if (equalsIgnoreCase(archName, "bpf"))
|
else if (equalsIgnoreCase(archName, "bpf"))
|
||||||
arch = CS_ARCH_BPF;
|
arch = CS_ARCH_BPF;
|
||||||
else if (equalsIgnoreCase(archName, "sh"))
|
else if (equalsIgnoreCase(archName, "sh") || equalsIgnoreCase(archName, "superh"))
|
||||||
arch = CS_ARCH_SH;
|
arch = CS_ARCH_SH;
|
||||||
else if (equalsIgnoreCase(archName, "tricore"))
|
else if (equalsIgnoreCase(archName, "tricore"))
|
||||||
arch = CS_ARCH_TRICORE;
|
arch = CS_ARCH_TRICORE;
|
||||||
|
@ -9,11 +9,15 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class CapstoneArchitecture : public ContentRegistry::Disassembler::Architecture {
|
class CapstoneArchitecture : public ContentRegistry::Disassembler::Architecture {
|
||||||
public:
|
public:
|
||||||
explicit CapstoneArchitecture(BuiltinArchitecture architecture)
|
explicit CapstoneArchitecture(BuiltinArchitecture architecture, cs_mode mode = cs_mode(0))
|
||||||
: Architecture(CapstoneDisassembler::ArchitectureNames[u32(architecture)]),
|
: Architecture(CapstoneDisassembler::ArchitectureNames[u32(architecture)]),
|
||||||
m_architecture(architecture) { }
|
m_architecture(architecture),
|
||||||
|
m_mode(mode) { }
|
||||||
|
|
||||||
bool start() override {
|
bool start() override {
|
||||||
|
if (m_initialized) return false;
|
||||||
|
|
||||||
|
m_instruction = nullptr;
|
||||||
auto mode = m_mode;
|
auto mode = m_mode;
|
||||||
if (m_endian == true) {
|
if (m_endian == true) {
|
||||||
mode = cs_mode(u32(mode) | CS_MODE_LITTLE_ENDIAN);
|
mode = cs_mode(u32(mode) | CS_MODE_LITTLE_ENDIAN);
|
||||||
@ -27,39 +31,43 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
cs_option(m_handle, CS_OPT_SKIPDATA, CS_OPT_ON);
|
cs_option(m_handle, CS_OPT_SKIPDATA, CS_OPT_ON);
|
||||||
|
|
||||||
|
m_instruction = cs_malloc(m_handle);
|
||||||
|
|
||||||
|
m_initialized = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void end() override {
|
void end() override {
|
||||||
|
cs_free(m_instruction, 1);
|
||||||
cs_close(&m_handle);
|
cs_close(&m_handle);
|
||||||
|
|
||||||
|
m_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
ImGui::RadioButton("hex.ui.common.little_endian"_lang, &m_endian, true);
|
ImGui::RadioButton("hex.ui.common.little_endian"_lang, &m_endian, true);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton("hex.ui.common.big_endian"_lang, &m_endian, false);
|
ImGui::RadioButton("hex.ui.common.big_endian"_lang, &m_endian, false);
|
||||||
|
ImGui::NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ContentRegistry::Disassembler::Instruction> disassemble(u64 imageBaseAddress, u64 instructionLoadAddress, u64 instructionDataAddress, std::span<const u8> code) override {
|
std::optional<ContentRegistry::Disassembler::Instruction> disassemble(u64 imageBaseAddress, u64 instructionLoadAddress, u64 instructionDataAddress, std::span<const u8> code) override {
|
||||||
auto *instruction = cs_malloc(m_handle);
|
|
||||||
ON_SCOPE_EXIT { cs_free(instruction, 1); };
|
|
||||||
|
|
||||||
auto ptr = code.data();
|
auto ptr = code.data();
|
||||||
auto size = code.size_bytes();
|
auto size = code.size_bytes();
|
||||||
|
|
||||||
if (!cs_disasm_iter(m_handle, &ptr, &size, &instructionLoadAddress, instruction)) {
|
if (!cs_disasm_iter(m_handle, &ptr, &size, &instructionLoadAddress, m_instruction)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentRegistry::Disassembler::Instruction disassembly = { };
|
ContentRegistry::Disassembler::Instruction disassembly = { };
|
||||||
disassembly.address = instruction->address;
|
disassembly.address = m_instruction->address;
|
||||||
disassembly.offset = instructionDataAddress - imageBaseAddress;
|
disassembly.offset = instructionDataAddress - imageBaseAddress;
|
||||||
disassembly.size = instruction->size;
|
disassembly.size = m_instruction->size;
|
||||||
disassembly.mnemonic = instruction->mnemonic;
|
disassembly.mnemonic = m_instruction->mnemonic;
|
||||||
disassembly.operators = instruction->op_str;
|
disassembly.operators = m_instruction->op_str;
|
||||||
|
|
||||||
for (u16 j = 0; j < instruction->size; j++)
|
for (u16 j = 0; j < m_instruction->size; j++)
|
||||||
disassembly.bytes += hex::format("{0:02X} ", instruction->bytes[j]);
|
disassembly.bytes += hex::format("{0:02X} ", m_instruction->bytes[j]);
|
||||||
disassembly.bytes.pop_back();
|
disassembly.bytes.pop_back();
|
||||||
|
|
||||||
return disassembly;
|
return disassembly;
|
||||||
@ -68,17 +76,21 @@ namespace hex::plugin::disasm {
|
|||||||
private:
|
private:
|
||||||
BuiltinArchitecture m_architecture;
|
BuiltinArchitecture m_architecture;
|
||||||
csh m_handle = 0;
|
csh m_handle = 0;
|
||||||
|
cs_insn *m_instruction = nullptr;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cs_mode m_mode = cs_mode(0);
|
cs_mode m_mode = cs_mode(0);
|
||||||
int m_endian = false;
|
int m_endian = false;
|
||||||
|
bool m_initialized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArchitectureARM : public CapstoneArchitecture {
|
class ArchitectureARM : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureARM() : CapstoneArchitecture(BuiltinArchitecture::ARM) {}
|
ArchitectureARM(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::ARM, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.arm.arm"_lang, &m_armMode, CS_MODE_ARM);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.arm.arm"_lang, &m_armMode, CS_MODE_ARM);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.arm.thumb"_lang, &m_armMode, CS_MODE_THUMB);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.arm.thumb"_lang, &m_armMode, CS_MODE_THUMB);
|
||||||
@ -98,16 +110,18 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureARM64 : public CapstoneArchitecture {
|
class ArchitectureARM64 : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureARM64() : CapstoneArchitecture(BuiltinArchitecture::ARM64) {}
|
ArchitectureARM64(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::ARM64, mode) {}
|
||||||
|
|
||||||
void drawSettings() override { }
|
void drawSettings() override { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArchitectureMIPS : public CapstoneArchitecture {
|
class ArchitectureMIPS : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureMIPS() : CapstoneArchitecture(BuiltinArchitecture::MIPS) {}
|
ArchitectureMIPS(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::MIPS, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.mips.mips32"_lang, &m_mipsMode, CS_MODE_MIPS32);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.mips.mips32"_lang, &m_mipsMode, CS_MODE_MIPS32);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.mips.mips64"_lang, &m_mipsMode, CS_MODE_MIPS64);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.mips.mips64"_lang, &m_mipsMode, CS_MODE_MIPS64);
|
||||||
@ -130,9 +144,11 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureX86 : public CapstoneArchitecture {
|
class ArchitectureX86 : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureX86() : CapstoneArchitecture(BuiltinArchitecture::X86) {}
|
ArchitectureX86(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::X86, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.16bit"_lang, &m_x86Mode, CS_MODE_16);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.16bit"_lang, &m_x86Mode, CS_MODE_16);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.32bit"_lang, &m_x86Mode, CS_MODE_32);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.32bit"_lang, &m_x86Mode, CS_MODE_32);
|
||||||
@ -148,9 +164,11 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitecturePowerPC : public CapstoneArchitecture {
|
class ArchitecturePowerPC : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitecturePowerPC() : CapstoneArchitecture(BuiltinArchitecture::PPC) {}
|
ArchitecturePowerPC(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::PPC, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.32bit"_lang, &m_ppcMode, CS_MODE_32);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.32bit"_lang, &m_ppcMode, CS_MODE_32);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.64bit"_lang, &m_ppcMode, CS_MODE_64);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.64bit"_lang, &m_ppcMode, CS_MODE_64);
|
||||||
@ -176,9 +194,11 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureSPARC : public CapstoneArchitecture {
|
class ArchitectureSPARC : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureSPARC() : CapstoneArchitecture(BuiltinArchitecture::SPARC) {}
|
ArchitectureSPARC(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::SPARC, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
ImGui::Checkbox("hex.disassembler.view.disassembler.sparc.v9"_lang, &m_v9Mode);
|
ImGui::Checkbox("hex.disassembler.view.disassembler.sparc.v9"_lang, &m_v9Mode);
|
||||||
|
|
||||||
m_mode = cs_mode(m_v9Mode ? CS_MODE_V9 : cs_mode(0));
|
m_mode = cs_mode(m_v9Mode ? CS_MODE_V9 : cs_mode(0));
|
||||||
@ -190,23 +210,29 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureSystemZ : public CapstoneArchitecture {
|
class ArchitectureSystemZ : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureSystemZ() : CapstoneArchitecture(BuiltinArchitecture::SYSZ) {}
|
ArchitectureSystemZ(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::SYSZ, mode) {}
|
||||||
|
|
||||||
void drawSettings() override { }
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArchitectureXCore : public CapstoneArchitecture {
|
class ArchitectureXCore : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureXCore() : CapstoneArchitecture(BuiltinArchitecture::XCORE) {}
|
ArchitectureXCore(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::XCORE, mode) {}
|
||||||
|
|
||||||
void drawSettings() override { }
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArchitectureM68K : public CapstoneArchitecture {
|
class ArchitectureM68K : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureM68K() : CapstoneArchitecture(BuiltinArchitecture::M68K) {}
|
ArchitectureM68K(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::M68K, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
std::pair<const char *, cs_mode> modes[] = {
|
std::pair<const char *, cs_mode> modes[] = {
|
||||||
{"hex.disassembler.view.disassembler.m68k.000"_lang, CS_MODE_M68K_000},
|
{"hex.disassembler.view.disassembler.m68k.000"_lang, CS_MODE_M68K_000},
|
||||||
{ "hex.disassembler.view.disassembler.m68k.010"_lang, CS_MODE_M68K_010},
|
{ "hex.disassembler.view.disassembler.m68k.010"_lang, CS_MODE_M68K_010},
|
||||||
@ -233,15 +259,19 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureTMS320C64X : public CapstoneArchitecture {
|
class ArchitectureTMS320C64X : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureTMS320C64X() : CapstoneArchitecture(BuiltinArchitecture::TMS320C64X) {}
|
ArchitectureTMS320C64X(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::TMS320C64X, mode) {}
|
||||||
|
|
||||||
void drawSettings() override { }
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
class ArchitectureM680X : public CapstoneArchitecture {
|
class ArchitectureM680X : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureM680X() : CapstoneArchitecture(BuiltinArchitecture::M680X) {}
|
ArchitectureM680X(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::M680X, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
std::pair<const char *, cs_mode> modes[] = {
|
std::pair<const char *, cs_mode> modes[] = {
|
||||||
{"hex.disassembler.view.disassembler.m680x.6301"_lang, CS_MODE_M680X_6301 },
|
{"hex.disassembler.view.disassembler.m680x.6301"_lang, CS_MODE_M680X_6301 },
|
||||||
{ "hex.disassembler.view.disassembler.m680x.6309"_lang, CS_MODE_M680X_6309 },
|
{ "hex.disassembler.view.disassembler.m680x.6309"_lang, CS_MODE_M680X_6309 },
|
||||||
@ -272,25 +302,31 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureEVM : public CapstoneArchitecture {
|
class ArchitectureEVM : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureEVM() : CapstoneArchitecture(BuiltinArchitecture::EVM) {}
|
ArchitectureEVM(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::EVM, mode) {}
|
||||||
|
|
||||||
void drawSettings() override { }
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CS_API_MAJOR >= 5
|
#if CS_API_MAJOR >= 5
|
||||||
|
|
||||||
class ArchitectureWASM : public CapstoneArchitecture {
|
class ArchitectureWASM : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureWASM() : CapstoneArchitecture(BuiltinArchitecture::WASM) {}
|
ArchitectureWASM(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::WASM, mode) {}
|
||||||
|
|
||||||
void drawSettings() override { }
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArchitectureRISCV : public CapstoneArchitecture {
|
class ArchitectureRISCV : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureRISCV() : CapstoneArchitecture(BuiltinArchitecture::RISCV) {}
|
ArchitectureRISCV(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::RISCV, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.32bit"_lang, &m_riscvMode, CS_MODE_RISCV32);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.32bit"_lang, &m_riscvMode, CS_MODE_RISCV32);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.64bit"_lang, &m_riscvMode, CS_MODE_RISCV64);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.64bit"_lang, &m_riscvMode, CS_MODE_RISCV64);
|
||||||
@ -307,9 +343,11 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureMOS65XX : public CapstoneArchitecture {
|
class ArchitectureMOS65XX : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureMOS65XX() : CapstoneArchitecture(BuiltinArchitecture::MOS65XX) {}
|
ArchitectureMOS65XX(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::MOS65XX, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
std::pair<const char *, cs_mode> modes[] = {
|
std::pair<const char *, cs_mode> modes[] = {
|
||||||
{"hex.disassembler.view.disassembler.mos65xx.6502"_lang, CS_MODE_MOS65XX_6502 },
|
{"hex.disassembler.view.disassembler.mos65xx.6502"_lang, CS_MODE_MOS65XX_6502 },
|
||||||
{ "hex.disassembler.view.disassembler.mos65xx.65c02"_lang, CS_MODE_MOS65XX_65C02 },
|
{ "hex.disassembler.view.disassembler.mos65xx.65c02"_lang, CS_MODE_MOS65XX_65C02 },
|
||||||
@ -337,9 +375,11 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureBPF : public CapstoneArchitecture {
|
class ArchitectureBPF : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureBPF() : CapstoneArchitecture(BuiltinArchitecture::BPF) {}
|
ArchitectureBPF(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::BPF, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.bpf.classic"_lang, &m_bpfMode, CS_MODE_BPF_CLASSIC);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.bpf.classic"_lang, &m_bpfMode, CS_MODE_BPF_CLASSIC);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::RadioButton("hex.disassembler.view.disassembler.bpf.extended"_lang, &m_bpfMode, CS_MODE_BPF_EXTENDED);
|
ImGui::RadioButton("hex.disassembler.view.disassembler.bpf.extended"_lang, &m_bpfMode, CS_MODE_BPF_EXTENDED);
|
||||||
@ -353,9 +393,11 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureSuperH : public CapstoneArchitecture {
|
class ArchitectureSuperH : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureSuperH() : CapstoneArchitecture(BuiltinArchitecture::SH) {}
|
ArchitectureSuperH(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::SUPERH, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
std::pair<const char*, cs_mode> modes[] = {
|
std::pair<const char*, cs_mode> modes[] = {
|
||||||
{ "hex.disassembler.view.disassembler.sh.sh2"_lang, CS_MODE_SH2 },
|
{ "hex.disassembler.view.disassembler.sh.sh2"_lang, CS_MODE_SH2 },
|
||||||
{ "hex.disassembler.view.disassembler.sh.sh2a"_lang, CS_MODE_SH2A },
|
{ "hex.disassembler.view.disassembler.sh.sh2a"_lang, CS_MODE_SH2A },
|
||||||
@ -387,9 +429,11 @@ namespace hex::plugin::disasm {
|
|||||||
|
|
||||||
class ArchitectureTricore : public CapstoneArchitecture {
|
class ArchitectureTricore : public CapstoneArchitecture {
|
||||||
public:
|
public:
|
||||||
ArchitectureTricore() : CapstoneArchitecture(BuiltinArchitecture::TRICORE) {}
|
ArchitectureTricore(cs_mode mode = cs_mode(0)) : CapstoneArchitecture(BuiltinArchitecture::TRICORE, mode) {}
|
||||||
|
|
||||||
void drawSettings() override {
|
void drawSettings() override {
|
||||||
|
CapstoneArchitecture::drawSettings();
|
||||||
|
|
||||||
std::pair<const char*, cs_mode> modes[] = {
|
std::pair<const char*, cs_mode> modes[] = {
|
||||||
{ "hex.disassembler.view.disassembler.tricore.110"_lang, CS_MODE_TRICORE_110 },
|
{ "hex.disassembler.view.disassembler.tricore.110"_lang, CS_MODE_TRICORE_110 },
|
||||||
{ "hex.disassembler.view.disassembler.tricore.120"_lang, CS_MODE_TRICORE_120 },
|
{ "hex.disassembler.view.disassembler.tricore.120"_lang, CS_MODE_TRICORE_120 },
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
#include <hex/api/content_registry.hpp>
|
||||||
|
#include <hex/helpers/default_paths.hpp>
|
||||||
|
|
||||||
|
#include <disasm/disasm.hpp>
|
||||||
|
#include <hex/helpers/fmt.hpp>
|
||||||
|
#include <hex/helpers/logger.hpp>
|
||||||
|
#include <wolv/utils/string.hpp>
|
||||||
|
|
||||||
|
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<ContentRegistry::Disassembler::Instruction> disassemble(u64 imageBaseAddress, u64 instructionLoadAddress, u64 instructionDataAddress, std::span<const u8> 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()) {
|
||||||
|
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<CustomArchitecture>(std::move(spec));
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
log::error("Failed to load disassembler config '{}': {}", wolv::util::toUTF8String(entry.path()), e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,6 +18,7 @@ namespace hex::plugin::disasm {
|
|||||||
void registerPatternLanguageTypes();
|
void registerPatternLanguageTypes();
|
||||||
|
|
||||||
void registerCapstoneArchitectures();
|
void registerCapstoneArchitectures();
|
||||||
|
void registerCustomArchitectures();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,4 +47,5 @@ IMHEX_PLUGIN_SETUP("Disassembler", "WerWolv", "Disassembler support") {
|
|||||||
registerPatternLanguageTypes();
|
registerPatternLanguageTypes();
|
||||||
|
|
||||||
registerCapstoneArchitectures();
|
registerCapstoneArchitectures();
|
||||||
|
registerCustomArchitectures();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user