parent
c70cc3a6f1
commit
21b315b97e
@ -31,9 +31,10 @@ namespace hex::plugin::disasm {
|
||||
private:
|
||||
TaskHolder m_disassemblerTask;
|
||||
|
||||
u64 m_baseAddress = 0;
|
||||
u64 m_imageLoadAddress = 0;
|
||||
u64 m_imageBaseAddress = 0;
|
||||
ui::RegionType m_range = ui::RegionType::EntireData;
|
||||
Region m_codeRegion = { 0, 0 };
|
||||
Region m_regionToDisassemble = { };
|
||||
|
||||
Architecture m_architecture = Architecture::ARM;
|
||||
cs_mode m_mode = cs_mode(0);
|
||||
|
@ -13,17 +13,18 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "Standard",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "Basisadresse",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "Classic",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "Extended",
|
||||
"hex.disassembler.view.disassembler.disassemble": "Disassemble",
|
||||
"hex.disassembler.view.disassembler.export": "Exportieren",
|
||||
"hex.disassembler.view.disassembler.export.popup.error": "Der Export zur ASM-Datei ist fehlgeschlagen.",
|
||||
"hex.disassembler.view.disassembler.disassembling": "Disassemblen...",
|
||||
"hex.disassembler.view.disassembler.disassembly.address": "Adresse",
|
||||
"hex.disassembler.view.disassembler.disassembly.bytes": "Byte",
|
||||
"hex.disassembler.view.disassembler.disassembly.offset": "Offset",
|
||||
"hex.disassembler.view.disassembler.disassembly.title": "Disassembly",
|
||||
"hex.disassembler.view.disassembler.export": "Exportieren",
|
||||
"hex.disassembler.view.disassembler.export.popup.error": "Der Export zur ASM-Datei ist fehlgeschlagen.",
|
||||
"hex.disassembler.view.disassembler.image_load_address": "Load Adresse",
|
||||
"hex.disassembler.view.disassembler.image_base_address": "Image Basisadresse",
|
||||
"hex.disassembler.view.disassembler.m680x.6301": "6301",
|
||||
"hex.disassembler.view.disassembler.m680x.6309": "6309",
|
||||
"hex.disassembler.view.disassembler.m680x.6800": "6800",
|
||||
|
@ -13,17 +13,18 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "Default",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "Base address",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "Classic",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "Extended",
|
||||
"hex.disassembler.view.disassembler.image_base_address": "Image Base Address",
|
||||
"hex.disassembler.view.disassembler.disassemble": "Disassemble",
|
||||
"hex.disassembler.view.disassembler.export": "Export instructions as...",
|
||||
"hex.disassembler.view.disassembler.export.popup.error": "Failed to export to ASM file!",
|
||||
"hex.disassembler.view.disassembler.disassembling": "Disassembling...",
|
||||
"hex.disassembler.view.disassembler.disassembly.address": "Address",
|
||||
"hex.disassembler.view.disassembler.disassembly.bytes": "Byte",
|
||||
"hex.disassembler.view.disassembler.disassembly.offset": "Offset",
|
||||
"hex.disassembler.view.disassembler.disassembly.title": "Disassembly",
|
||||
"hex.disassembler.view.disassembler.export": "Export instructions as...",
|
||||
"hex.disassembler.view.disassembler.export.popup.error": "Failed to export to ASM file!",
|
||||
"hex.disassembler.view.disassembler.image_load_address": "Image Load Address",
|
||||
"hex.disassembler.view.disassembler.m680x.6301": "6301",
|
||||
"hex.disassembler.view.disassembler.m680x.6309": "6309",
|
||||
"hex.disassembler.view.disassembler.m680x.6800": "6800",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "",
|
||||
"hex.disassembler.view.disassembler.arm.default": "Estándar",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "",
|
||||
"hex.disassembler.view.disassembler.base": "Dirección base",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "Clásica",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "Extendida",
|
||||
"hex.disassembler.view.disassembler.disassemble": "Desensamblar",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "Alapértelmezett",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "Alapcím",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "Klasszikus",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "Bővített",
|
||||
"hex.disassembler.view.disassembler.disassemble": "Disassemble",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "Default",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "Indirizzo di base",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "Classico",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "Esteso",
|
||||
"hex.disassembler.view.disassembler.disassemble": "Disassembla",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "デフォルト",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "ベースアドレス",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "クラシック",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "拡張",
|
||||
"hex.disassembler.view.disassembler.disassemble": "逆アセンブル",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "기본",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "베이스 주소",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "클래식",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "확장",
|
||||
"hex.disassembler.view.disassembler.disassemble": "디스어셈블",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "Default",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "Endereço base",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "Classico",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "Extendido",
|
||||
"hex.disassembler.view.disassembler.disassemble": "Desmontar",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "默认",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "基地址",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "传统 BPF(cBPF)",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "扩展 BPF(eBPF)",
|
||||
"hex.disassembler.view.disassembler.disassemble": "反汇编",
|
||||
|
@ -13,7 +13,6 @@
|
||||
"hex.disassembler.view.disassembler.arm.cortex_m": "Cortex-M",
|
||||
"hex.disassembler.view.disassembler.arm.default": "預設",
|
||||
"hex.disassembler.view.disassembler.arm.thumb": "Thumb",
|
||||
"hex.disassembler.view.disassembler.base": "基址",
|
||||
"hex.disassembler.view.disassembler.bpf.classic": "經典",
|
||||
"hex.disassembler.view.disassembler.bpf.extended": "擴充",
|
||||
"hex.disassembler.view.disassembler.disassemble": "解譯",
|
||||
|
@ -9,7 +9,10 @@
|
||||
#include <cstring>
|
||||
#include <toasts/toast_notification.hpp>
|
||||
|
||||
#include <wolv/literals.hpp>
|
||||
|
||||
using namespace std::literals::string_literals;
|
||||
using namespace wolv::literals;
|
||||
|
||||
namespace hex::plugin::disasm {
|
||||
|
||||
@ -23,7 +26,7 @@ namespace hex::plugin::disasm {
|
||||
this->getWindowOpenState() = true;
|
||||
|
||||
m_range = ui::RegionType::Region;
|
||||
m_codeRegion = ImHexApi::HexEditor::getSelection()->getRegion();
|
||||
m_regionToDisassemble = ImHexApi::HexEditor::getSelection()->getRegion();
|
||||
|
||||
this->disassemble();
|
||||
}, [this]{
|
||||
@ -40,9 +43,12 @@ namespace hex::plugin::disasm {
|
||||
void ViewDisassembler::disassemble() {
|
||||
m_disassembly.clear();
|
||||
|
||||
m_disassemblerTask = TaskManager::createTask("hex.disassembler.view.disassembler.disassembling"_lang, m_codeRegion.getSize(), [this](auto &task) {
|
||||
if (m_regionToDisassemble.getStartAddress() < m_imageBaseAddress)
|
||||
return;
|
||||
|
||||
m_disassemblerTask = TaskManager::createTask("hex.disassembler.view.disassembler.disassembling"_lang, m_regionToDisassemble.getSize(), [this](auto &task) {
|
||||
csh capstoneHandle;
|
||||
cs_insn *instructions = nullptr;
|
||||
cs_insn instruction;
|
||||
|
||||
cs_mode mode = m_mode;
|
||||
|
||||
@ -53,52 +59,45 @@ namespace hex::plugin::disasm {
|
||||
cs_option(capstoneHandle, CS_OPT_SKIPDATA, CS_OPT_ON);
|
||||
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
std::vector<u8> buffer(2048, 0x00);
|
||||
size_t size = m_codeRegion.getSize();
|
||||
std::vector<u8> buffer(1_MiB, 0x00);
|
||||
|
||||
const u64 codeOffset = m_regionToDisassemble.getStartAddress() - m_imageBaseAddress;
|
||||
|
||||
// Read the data in chunks and disassemble it
|
||||
for (u64 address = 0; address < size; address += 2048) {
|
||||
task.update(address);
|
||||
u64 instructionLoadAddress = m_imageLoadAddress + codeOffset;
|
||||
u64 instructionDataAddress = m_regionToDisassemble.getStartAddress();
|
||||
|
||||
bool hadError = false;
|
||||
while (instructionDataAddress < m_regionToDisassemble.getEndAddress()) {
|
||||
// Read a chunk of data
|
||||
size_t bufferSize = std::min(u64(2048), (size - address));
|
||||
provider->read(m_codeRegion.getStartAddress() + address, buffer.data(), bufferSize);
|
||||
size_t bufferSize = std::min<u64>(buffer.size(), (m_regionToDisassemble.getEndAddress() - instructionDataAddress));
|
||||
provider->read(instructionDataAddress, buffer.data(), bufferSize);
|
||||
|
||||
// Ask capstone to disassemble the data
|
||||
size_t instructionCount = cs_disasm(capstoneHandle, buffer.data(), bufferSize, m_baseAddress + address, 0, &instructions);
|
||||
if (instructionCount == 0)
|
||||
break;
|
||||
const u8 *code = buffer.data();
|
||||
while (cs_disasm_iter(capstoneHandle, &code, &bufferSize, &instructionLoadAddress, &instruction)) {
|
||||
task.update(instructionDataAddress);
|
||||
|
||||
// Reserve enough space for the disassembly
|
||||
m_disassembly.reserve(m_disassembly.size() + instructionCount);
|
||||
|
||||
// Convert the capstone instructions to our disassembly format
|
||||
u64 usedBytes = 0;
|
||||
for (u32 i = 0; i < instructionCount; i++) {
|
||||
const auto &instr = instructions[i];
|
||||
// Convert the capstone instructions to our disassembly format
|
||||
Disassembly disassembly = { };
|
||||
disassembly.address = instr.address;
|
||||
disassembly.offset = m_codeRegion.getStartAddress() + address + usedBytes;
|
||||
disassembly.size = instr.size;
|
||||
disassembly.mnemonic = instr.mnemonic;
|
||||
disassembly.operators = instr.op_str;
|
||||
disassembly.address = instruction.address;
|
||||
disassembly.offset = instructionDataAddress - m_imageBaseAddress;
|
||||
disassembly.size = instruction.size;
|
||||
disassembly.mnemonic = instruction.mnemonic;
|
||||
disassembly.operators = instruction.op_str;
|
||||
|
||||
for (u16 j = 0; j < instr.size; j++)
|
||||
disassembly.bytes += hex::format("{0:02X} ", instr.bytes[j]);
|
||||
for (u16 j = 0; j < instruction.size; j++)
|
||||
disassembly.bytes += hex::format("{0:02X} ", instruction.bytes[j]);
|
||||
disassembly.bytes.pop_back();
|
||||
|
||||
m_disassembly.push_back(disassembly);
|
||||
|
||||
usedBytes += instr.size;
|
||||
instructionDataAddress += instruction.size;
|
||||
hadError = false;
|
||||
}
|
||||
|
||||
// If capstone couldn't disassemble all bytes in the buffer, we might have cut off an instruction
|
||||
// Adjust the address,so it's being disassembled when we read the next chunk
|
||||
if (instructionCount < bufferSize)
|
||||
address -= (bufferSize - usedBytes);
|
||||
|
||||
// Clean up the capstone instructions
|
||||
cs_free(instructions, instructionCount);
|
||||
if (hadError) break;
|
||||
hadError = true;
|
||||
}
|
||||
|
||||
cs_close(&capstoneHandle);
|
||||
@ -141,11 +140,18 @@ namespace hex::plugin::disasm {
|
||||
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
|
||||
ImGuiExt::Header("hex.disassembler.view.disassembler.position"_lang, true);
|
||||
|
||||
// Draw base address input
|
||||
ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.base"_lang, &m_baseAddress, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
// Draw region selection picker
|
||||
ui::regionSelectionPicker(&m_codeRegion, provider, &m_range);
|
||||
ui::regionSelectionPicker(&m_regionToDisassemble, provider, &m_range);
|
||||
|
||||
// Draw base address input
|
||||
ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_load_address"_lang, &m_imageLoadAddress, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
// Draw code region start address input
|
||||
ImGui::BeginDisabled(m_range == ui::RegionType::EntireData);
|
||||
{
|
||||
ImGuiExt::InputHexadecimal("hex.disassembler.view.disassembler.image_base_address"_lang, &m_imageBaseAddress, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
// Draw settings
|
||||
{
|
||||
@ -427,7 +433,7 @@ namespace hex::plugin::disasm {
|
||||
}
|
||||
|
||||
// Draw disassemble button
|
||||
ImGui::BeginDisabled(m_disassemblerTask.isRunning());
|
||||
ImGui::BeginDisabled(m_disassemblerTask.isRunning() || m_regionToDisassemble.getStartAddress() < m_imageBaseAddress);
|
||||
{
|
||||
if (ImGui::Button("hex.disassembler.view.disassembler.disassemble"_lang))
|
||||
this->disassemble();
|
||||
|
Loading…
x
Reference in New Issue
Block a user