1
0
mirror of synced 2025-01-11 05:42:15 +01:00

impr: Added image load and image base address to disassembler

#1994
This commit is contained in:
WerWolv 2024-12-10 20:33:28 +01:00
parent c70cc3a6f1
commit 21b315b97e
12 changed files with 56 additions and 55 deletions

View File

@ -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);

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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": "逆アセンブル",

View File

@ -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": "디스어셈블",

View File

@ -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",

View File

@ -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": "传统 BPFcBPF",
"hex.disassembler.view.disassembler.bpf.extended": "扩展 BPFeBPF",
"hex.disassembler.view.disassembler.disassemble": "反汇编",

View File

@ -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": "解譯",

View File

@ -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();