From 0454a369e53418f0c1b115eab57e3e0112c8e250 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Wed, 25 Dec 2024 16:36:53 +0100 Subject: [PATCH] fix: Crashes when disassembling data Fixes #2025 --- .../source/content/pl_builtin_types.cpp | 16 ++++++++------- .../content/views/view_disassembler.cpp | 20 ++++++++++--------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/plugins/disassembler/source/content/pl_builtin_types.cpp b/plugins/disassembler/source/content/pl_builtin_types.cpp index 5f37f3b26785e..dbbacdc29f68b 100644 --- a/plugins/disassembler/source/content/pl_builtin_types.cpp +++ b/plugins/disassembler/source/content/pl_builtin_types.cpp @@ -104,21 +104,23 @@ namespace hex::plugin::disasm { std::vector data(std::min(32, evaluator->getSectionSize(sectionId) - address)); evaluator->readData(address, data.data(), data.size(), sectionId); - cs_insn instruction; + auto *instruction = cs_malloc(capstone); + ON_SCOPE_EXIT { cs_free(instruction, 1); }; + const u8 *code = data.data(); size_t dataSize = data.size(); - if (!cs_disasm_iter(capstone, &code, &dataSize, &instructionLoadAddress, &instruction)) { + if (!cs_disasm_iter(capstone, &code, &dataSize, &instructionLoadAddress, instruction)) { err::E0012.throwError("Failed to disassemble instruction"); } - auto result = std::make_unique(evaluator, address, instruction.size, 0); + auto result = std::make_unique(evaluator, address, instruction->size, 0); std::string instructionString; - if (instruction.mnemonic[0] != '\x00') - instructionString += instruction.mnemonic; - if (instruction.op_str[0] != '\x00') { + if (instruction->mnemonic[0] != '\x00') + instructionString += instruction->mnemonic; + if (instruction->op_str[0] != '\x00') { instructionString += ' '; - instructionString += instruction.op_str; + instructionString += instruction->op_str; } result->setInstructionString(instructionString); diff --git a/plugins/disassembler/source/content/views/view_disassembler.cpp b/plugins/disassembler/source/content/views/view_disassembler.cpp index 1afad4c634224..ae81c42ad9dc8 100644 --- a/plugins/disassembler/source/content/views/view_disassembler.cpp +++ b/plugins/disassembler/source/content/views/view_disassembler.cpp @@ -48,12 +48,14 @@ namespace hex::plugin::disasm { m_disassemblerTask = TaskManager::createTask("hex.disassembler.view.disassembler.disassembling"_lang, m_regionToDisassemble.getSize(), [this](auto &task) { csh capstoneHandle; - cs_insn instruction; cs_mode mode = m_mode; // Create a capstone disassembler instance if (cs_open(Disassembler::toCapstoneArchitecture(m_architecture), mode, &capstoneHandle) == CS_ERR_OK) { + auto *instruction = cs_malloc(capstoneHandle); + ON_SCOPE_EXIT { cs_free(instruction, 1); }; + // Tell capstone to skip data bytes cs_option(capstoneHandle, CS_OPT_SKIPDATA, CS_OPT_ON); @@ -75,24 +77,24 @@ namespace hex::plugin::disasm { // Ask capstone to disassemble the data const u8 *code = buffer.data(); - while (cs_disasm_iter(capstoneHandle, &code, &bufferSize, &instructionLoadAddress, &instruction)) { + while (cs_disasm_iter(capstoneHandle, &code, &bufferSize, &instructionLoadAddress, instruction)) { task.update(instructionDataAddress); // Convert the capstone instructions to our disassembly format Disassembly disassembly = { }; - disassembly.address = instruction.address; + disassembly.address = instruction->address; disassembly.offset = instructionDataAddress - m_imageBaseAddress; - disassembly.size = instruction.size; - disassembly.mnemonic = instruction.mnemonic; - disassembly.operators = instruction.op_str; + disassembly.size = instruction->size; + disassembly.mnemonic = instruction->mnemonic; + disassembly.operators = instruction->op_str; - for (u16 j = 0; j < instruction.size; j++) - disassembly.bytes += hex::format("{0:02X} ", instruction.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); - instructionDataAddress += instruction.size; + instructionDataAddress += instruction->size; hadError = false; }