From eb7d9544e0940619f98e05e9596b99c59261db23 Mon Sep 17 00:00:00 2001 From: Takahiro Haruyama Date: Wed, 11 Sep 2024 23:46:38 +0900 Subject: [PATCH 1/5] Dump EFI module name and type in json --- efiXloader/uefitool.cpp | 8 ++++++++ efiXloader/uefitool.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/efiXloader/uefitool.cpp b/efiXloader/uefitool.cpp index 5c8a8244..a89d61c6 100644 --- a/efiXloader/uefitool.cpp +++ b/efiXloader/uefitool.cpp @@ -272,6 +272,8 @@ void efiloader::Uefitool::dump(const UModelIndex &index, uint8_t el_type, .is_null()) { // check if GUID already exists get_unique_name(module_name); images_guids[guid.c_str()] = module_name.c_str(); + mod_types[module_name.c_str()] = + fileTypeToUString(model.subtype(index.parent())).toLocal8Bit(); file->qname.swap(module_name); file->write(); files.push_back(file); @@ -307,6 +309,8 @@ void efiloader::Uefitool::dump(const UModelIndex &index, uint8_t el_type, if (module_name.size()) { // save image to the images_guids images_guids[module_name.c_str()] = module_name.c_str(); + mod_types[module_name.c_str()] = + fileTypeToUString(model.subtype(index.parent())).toLocal8Bit(); } } break; @@ -370,4 +374,8 @@ void efiloader::Uefitool::dump_jsons() { out.replace_extension("").replace_extension(".images.json"); std::ofstream out_guids(out); out_guids << std::setw(4) << images_guids << std::endl; + // Dump module types + out.replace_extension("").replace_extension(".mod_types.json"); + std::ofstream out_mod_types(out); + out_mod_types << std::setw(4) << mod_types << std::endl; } diff --git a/efiXloader/uefitool.h b/efiXloader/uefitool.h index 3e69b618..f29e5322 100644 --- a/efiXloader/uefitool.h +++ b/efiXloader/uefitool.h @@ -112,7 +112,7 @@ class Uefitool { } messages = ffs.getMessages(); } - ~Uefitool(){}; + ~Uefitool() {}; void show_messages(); bool messages_occurs() { return !messages.empty(); }; void dump(); @@ -133,6 +133,7 @@ class Uefitool { void dump_jsons(); // dump JSON with DEPEX and GUIDs information for each image json all_deps; // DEPEX information for each image json images_guids; // matching the modules to the parent's GUIDs + json mod_types; // EFI module name and its type TreeModel model; const char *buffer; uint32_t buffer_size; From b9072b1830754d2ec79c0f6b21546d2a9e294738 Mon Sep 17 00:00:00 2001 From: Takahiro Haruyama Date: Thu, 3 Oct 2024 23:28:57 +0900 Subject: [PATCH 2/5] Remove the left cpp file --- efiXloader/uefitool.cpp | 381 ---------------------------------------- 1 file changed, 381 deletions(-) delete mode 100644 efiXloader/uefitool.cpp diff --git a/efiXloader/uefitool.cpp b/efiXloader/uefitool.cpp deleted file mode 100644 index a89d61c6..00000000 --- a/efiXloader/uefitool.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* - * efiXloader - * Copyright (C) 2020-2023 Binarly - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * uefitool.cpp - */ - -#include "uefitool.h" -#include -#include -#include - -void efiloader::File::print() { - msg("[UEFITOOL PARSER] file ( %s ) \n", qname.c_str()); - for (int i = 0; i < 0x10; i++) { - msg("%02X ", ubytes[i]); - }; - msg("\n"); -} - -void efiloader::Uefitool::show_messages() { - for (size_t i = 0; i < messages.size(); i++) { - msg("[UEFITOOL PARSER] %s\n", messages[i].first.toLocal8Bit()); - } -} - -void efiloader::Uefitool::get_unique_name(qstring &name) { - // If the given name is already in use, create a new one - qstring new_name = name; - std::string suf; - int index = 0; - while (!(unique_names.insert(new_name).second)) { - suf = "_" + std::to_string(++index); - new_name = name + static_cast(suf.c_str()); - } - name = new_name; -} - -void efiloader::Uefitool::get_image_guid(qstring &image_guid, UModelIndex index) { - UString guid; - UModelIndex guid_index; - switch (model.subtype(model.parent(index))) { - case EFI_SECTION_COMPRESSION: - case EFI_SECTION_GUID_DEFINED: - guid_index = model.parent(model.parent(index)); - break; - default: - guid_index = model.parent(index); - } - // get parent header and read GUID - guid = guidToUString( - readUnaligned((const EFI_GUID *)(model.header(guid_index).constData()))); - image_guid = reinterpret_cast(guid.data); -} - -std::vector -efiloader::Uefitool::parseDepexSectionBody(const UModelIndex &index, UString &parsed) { - // Adopted from FfsParser::parseDepexSectionBody - std::vector res; - - if (!index.isValid()) - return res; - - UByteArray body = model.body(index); - - // Check data to be present - if (body.size() < 2) { // 2 is a minimal sane value, i.e TRUE + END - return res; - } - - const EFI_GUID *guid; - const UINT8 *current = (const UINT8 *)body.constData(); - - // Special cases of first opcode - switch (*current) { - case EFI_DEP_BEFORE: - if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { - return res; - } - guid = (const EFI_GUID *)(current + EFI_DEP_OPCODE_SIZE); - parsed += UString("\nBEFORE ") + guidToUString(readUnaligned(guid)); - current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); - if (*current != EFI_DEP_END) { - return res; - } - return res; - case EFI_DEP_AFTER: - if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { - return res; - } - guid = (const EFI_GUID *)(current + EFI_DEP_OPCODE_SIZE); - parsed += UString("\nAFTER ") + guidToUString(readUnaligned(guid)); - current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); - if (*current != EFI_DEP_END) { - return res; - } - return res; - case EFI_DEP_SOR: - if (body.size() <= 2 * EFI_DEP_OPCODE_SIZE) { - return res; - } - parsed += UString("\nSOR"); - current += EFI_DEP_OPCODE_SIZE; - break; - } - - // Parse the rest of depex - while (current - (const UINT8 *)body.constData() < body.size()) { - switch (*current) { - case EFI_DEP_BEFORE: { - return res; - } - case EFI_DEP_AFTER: { - return res; - } - case EFI_DEP_SOR: { - return res; - } - case EFI_DEP_PUSH: - // Check that the rest of depex has correct size - if ((UINT32)body.size() - - (UINT32)(current - (const UINT8 *)body.constData()) <= - EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { - parsed.clear(); - return res; - } - guid = (const EFI_GUID *)(current + EFI_DEP_OPCODE_SIZE); - parsed += UString("\nPUSH ") + guidToUString(readUnaligned(guid)); - // Add protocol GUID to result vector - res.push_back( - reinterpret_cast(guidToUString(readUnaligned(guid)).data)); - current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); - break; - case EFI_DEP_AND: - parsed += UString("\nAND"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_OR: - parsed += UString("\nOR"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_NOT: - parsed += UString("\nNOT"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_TRUE: - parsed += UString("\nTRUE"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_FALSE: - parsed += UString("\nFALSE"); - current += EFI_DEP_OPCODE_SIZE; - break; - case EFI_DEP_END: - parsed += UString("\nEND"); - current += EFI_DEP_OPCODE_SIZE; - // Check that END is the last opcode - if (current - (const UINT8 *)body.constData() < body.size()) { - parsed.clear(); - } - break; - default: - return res; - break; - } - } - - return res; -} - -std::vector -efiloader::Uefitool::parseAprioriRawSection(const UModelIndex &index) { - // Adopted from FfsParser::parseDepexSectionBody - std::vector res; - - if (!index.isValid()) - return res; - - UByteArray body = model.body(index); - - // Sanity check - if (body.size() % sizeof(EFI_GUID)) { - return res; - } - - UINT32 count = (UINT32)(body.size() / sizeof(EFI_GUID)); - if (count > 0) { - for (UINT32 i = 0; i < count; i++) { - const EFI_GUID *guid = (const EFI_GUID *)body.constData() + i; - res.push_back( - reinterpret_cast(guidToUString(readUnaligned(guid)).data)); - } - } - - return res; -} - -void efiloader::Uefitool::set_machine_type(UByteArray pe_body) { - const char *data = pe_body.constData(); - if (pe_body.size() < 64) { - return; - } - uint32_t _pe_header_off = *(uint32_t *)(data + 0x3c); - if (pe_body.size() < _pe_header_off + 6) { - return; - } - if (*(uint32_t *)(data + _pe_header_off) == 0x4550) { - machine_type = *(uint16_t *)(data + _pe_header_off + 4); - machine_type_detected = true; - } -} - -void efiloader::Uefitool::handle_raw_section(const UModelIndex &index) { - UModelIndex parent_file = model.findParentOfType(index, Types::File); - if (!parent_file.isValid()) { - return; - } - UByteArray parent_file_guid(model.header(parent_file).constData(), sizeof(EFI_GUID)); - if (parent_file_guid == EFI_PEI_APRIORI_FILE_GUID) { - msg("[efiXloader] PEI Apriori file found\n"); - get_apriori(index, "PEI_APRIORI_FILE"); - } - if (parent_file_guid == EFI_DXE_APRIORI_FILE_GUID) { - msg("[efiXloader] DXE Apriori file found\n"); - get_apriori(index, "DXE_APRIORI_FILE"); - } -} - -void efiloader::Uefitool::dump(const UModelIndex &index, uint8_t el_type, - efiloader::File *file) { - qstring module_name(""); - qstring guid(""); - - switch (model.subtype(index)) { - case EFI_SECTION_RAW: - handle_raw_section(index); - break; - case EFI_SECTION_TE: - file->is_te = true; - file->ubytes = model.body(index); - break; - case EFI_SECTION_PE32: - file->is_pe = true; - file->ubytes = model.body(index); - if (!machine_type_detected) { - set_machine_type(model.body(index)); - } - break; - case EFI_SECTION_USER_INTERFACE: - file->has_ui = true; - if (file->is_pe || file->is_te) { - file->uname = model.body(index); - utf16_utf8(&module_name, - reinterpret_cast(file->uname.data())); - if (module_name.size()) { - // save image to the images_guids - get_image_guid(guid, index); - if (images_guids[guid.c_str()] - .is_null()) { // check if GUID already exists - get_unique_name(module_name); - images_guids[guid.c_str()] = module_name.c_str(); - mod_types[module_name.c_str()] = - fileTypeToUString(model.subtype(index.parent())).toLocal8Bit(); - file->qname.swap(module_name); - file->write(); - files.push_back(file); - } - } - } - break; - case EFI_SECTION_COMPRESSION: - case EFI_SECTION_GUID_DEFINED: - for (int i = 0; i < model.rowCount(index); i++) { - dump(index.child(i, 0), i, file); - } - break; - // Get DEPEX information - case EFI_SECTION_DXE_DEPEX: - get_deps(index, "EFI_SECTION_DXE_DEPEX"); - break; - case EFI_SECTION_MM_DEPEX: - get_deps(index, "EFI_SECTION_MM_DEPEX"); - break; - case EFI_SECTION_PEI_DEPEX: - get_deps(index, "EFI_SECTION_PEI_DEPEX"); - break; - case EFI_SECTION_VERSION: - break; - default: - // if there is no UI section, then the image name is GUID - if ((file->is_pe || file->is_te) && !file->has_ui) { - get_image_guid(module_name, index); - file->qname.swap(module_name); - file->write(); - files.push_back(file); - if (module_name.size()) { - // save image to the images_guids - images_guids[module_name.c_str()] = module_name.c_str(); - mod_types[module_name.c_str()] = - fileTypeToUString(model.subtype(index.parent())).toLocal8Bit(); - } - } - break; - } - - return dump(index); -} - -void efiloader::Uefitool::dump(const UModelIndex &index) { - USTATUS err; - msg("[UEFITOOL PARSER] file (%s, %s)\n", itemTypeToUString(model.type(index)).data, - itemSubtypeToUString(model.type(index), model.subtype(index)).data); - msg("[UEFITOOL PARSER] number of items: %#x\n", model.rowCount(index)); - if (is_file_index(index)) { - efiloader::File *file = new File; - for (int i = 0; i < model.rowCount(index); i++) { - dump(index.child(i, 0), i, file); - } - } else { - for (int i = 0; i < model.rowCount(index); i++) { - dump(index.child(i, 0)); - } - } -} - -void efiloader::Uefitool::dump() { return dump(model.index(0, 0)); } - -void efiloader::Uefitool::get_deps(UModelIndex index, std::string key) { - UString parsed; - std::vector deps; - qstring image_guid(""); - - get_image_guid(image_guid, index); - deps = parseDepexSectionBody(index, parsed); - if (deps.size()) { - msg("[efiXloader] dependency section for image with GUID %s: %s\n", - image_guid.c_str(), parsed.data); - all_deps[key][image_guid.c_str()] = deps; - } -} - -void efiloader::Uefitool::get_apriori(UModelIndex index, std::string key) { - if (all_deps.contains(key)) { - return; - } - std::vector deps = parseAprioriRawSection(index); - if (deps.empty()) { - return; - } - all_deps[key] = deps; -} - -void efiloader::Uefitool::dump_jsons() { - // Dump deps - std::filesystem::path out; - out /= get_path(PATH_TYPE_IDB); - out.replace_extension(".deps.json"); - std::ofstream out_deps(out); - out_deps << std::setw(4) << all_deps << std::endl; - // Dump images - out.replace_extension("").replace_extension(".images.json"); - std::ofstream out_guids(out); - out_guids << std::setw(4) << images_guids << std::endl; - // Dump module types - out.replace_extension("").replace_extension(".mod_types.json"); - std::ofstream out_mod_types(out); - out_mod_types << std::setw(4) << mod_types << std::endl; -} From 0573da0e53dd4ac21739a5866cdf68ef7207bfb4 Mon Sep 17 00:00:00 2001 From: Takahiro Haruyama Date: Fri, 4 Oct 2024 17:11:52 +0900 Subject: [PATCH 3/5] Add UEFI module type to *.images.json --- efiXloader/uefitool.cc | 8 ++++++-- efiXloader/uefitool.h | 1 - efiXplorer/efi_deps.cc | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/efiXloader/uefitool.cc b/efiXloader/uefitool.cc index 9da705ac..035286db 100644 --- a/efiXloader/uefitool.cc +++ b/efiXloader/uefitool.cc @@ -270,7 +270,9 @@ void efiloader::Uefitool::dump(const UModelIndex &index, uint8_t el_type, if (images_guids[guid.c_str()] .is_null()) { // check if GUID already exists get_unique_name(module_name); - images_guids[guid.c_str()] = module_name.c_str(); + images_guids[guid.c_str()] = { + module_name.c_str(), + fileTypeToUString(model.subtype(index.parent())).toLocal8Bit()}; file->qname.swap(module_name); file->write(); files.push_back(file); @@ -305,7 +307,9 @@ void efiloader::Uefitool::dump(const UModelIndex &index, uint8_t el_type, files.push_back(file); if (module_name.size()) { // save image to the images_guids - images_guids[module_name.c_str()] = module_name.c_str(); + images_guids[module_name.c_str()] = { + module_name.c_str(), + fileTypeToUString(model.subtype(index.parent())).toLocal8Bit()}; } } break; diff --git a/efiXloader/uefitool.h b/efiXloader/uefitool.h index 33f6169d..ab04a208 100644 --- a/efiXloader/uefitool.h +++ b/efiXloader/uefitool.h @@ -139,7 +139,6 @@ class Uefitool { dump_jsons(); // dump JSON with DEPEX and GUIDs information for each image json all_deps; // DEPEX information for each image json images_guids; // matching the modules to the parent's GUIDs - json mod_types; // EFI module name and its type TreeModel model; const char *buffer; uint32_t buffer_size; diff --git a/efiXplorer/efi_deps.cc b/efiXplorer/efi_deps.cc index e3ebf8ad..50c074b2 100644 --- a/efiXplorer/efi_deps.cc +++ b/efiXplorer/efi_deps.cc @@ -244,7 +244,7 @@ json efi_deps_t::get_module_info(std::string module) { // can not get name for module continue; } - std::string dmodule_name = m_modules_guids[dmodule_guid]; + std::string dmodule_name = m_modules_guids[dmodule_guid][0]; if (dmodule_name == module) { deps_protocols = element.value(); found = true; @@ -268,7 +268,7 @@ string_set_t efi_deps_t::get_apriori_modules() { for (auto file : files) { auto modules = m_uefitool_deps[file]; for (auto &mguid : modules) { - std::string module = m_modules_guids[mguid]; + std::string module = m_modules_guids[mguid][0]; apriori_modules.insert(module); efi_utils::log("module from %s: %s\n", file.c_str(), module.c_str()); } From 3b5acc5b59d20c22e86ec479f438665069e5567c Mon Sep 17 00:00:00 2001 From: yeggor Date: Sat, 5 Oct 2024 02:55:12 +0100 Subject: [PATCH 4/5] dump modules in readable format --- efiXloader/uefitool.cc | 29 ++++++++++++++--------------- efiXloader/uefitool.h | 21 ++++++++++++++------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/efiXloader/uefitool.cc b/efiXloader/uefitool.cc index 035286db..63884280 100644 --- a/efiXloader/uefitool.cc +++ b/efiXloader/uefitool.cc @@ -64,8 +64,8 @@ void efiloader::Uefitool::get_image_guid(qstring &image_guid, } std::vector -efiloader::Uefitool::parseDepexSectionBody(const UModelIndex &index, - UString &parsed) { +efiloader::Uefitool::parse_depex_section_body(const UModelIndex &index, + UString &parsed) { // Adopted from FfsParser::parseDepexSectionBody std::vector res; @@ -180,7 +180,7 @@ efiloader::Uefitool::parseDepexSectionBody(const UModelIndex &index, } std::vector -efiloader::Uefitool::parseAprioriRawSection(const UModelIndex &index) { +efiloader::Uefitool::parse_apriori_raw_section(const UModelIndex &index) { // Adopted from FfsParser::parseDepexSectionBody std::vector res; @@ -270,9 +270,8 @@ void efiloader::Uefitool::dump(const UModelIndex &index, uint8_t el_type, if (images_guids[guid.c_str()] .is_null()) { // check if GUID already exists get_unique_name(module_name); - images_guids[guid.c_str()] = { - module_name.c_str(), - fileTypeToUString(model.subtype(index.parent())).toLocal8Bit()}; + images_guids[guid.c_str()] = {{"name", module_name.c_str()}, + {"kind", get_kind(index)}}; file->qname.swap(module_name); file->write(); files.push_back(file); @@ -307,9 +306,8 @@ void efiloader::Uefitool::dump(const UModelIndex &index, uint8_t el_type, files.push_back(file); if (module_name.size()) { // save image to the images_guids - images_guids[module_name.c_str()] = { - module_name.c_str(), - fileTypeToUString(model.subtype(index.parent())).toLocal8Bit()}; + images_guids[module_name.c_str()] = {{"name", module_name.c_str()}, + {"kind", get_kind(index)}}; } } break; @@ -344,7 +342,7 @@ void efiloader::Uefitool::get_deps(UModelIndex index, std::string key) { qstring image_guid(""); get_image_guid(image_guid, index); - deps = parseDepexSectionBody(index, parsed); + deps = parse_depex_section_body(index, parsed); if (deps.size()) { msg("[efiXloader] dependency section for image with GUID %s: %s\n", image_guid.c_str(), parsed.data); @@ -356,7 +354,7 @@ void efiloader::Uefitool::get_apriori(UModelIndex index, std::string key) { if (all_deps.contains(key)) { return; } - std::vector deps = parseAprioriRawSection(index); + auto deps = parse_apriori_raw_section(index); if (deps.empty()) { return; } @@ -364,14 +362,15 @@ void efiloader::Uefitool::get_apriori(UModelIndex index, std::string key) { } void efiloader::Uefitool::dump_jsons() { - // Dump deps + // dump JSON with DEPEX and GUIDs information for each image + std::filesystem::path out; out /= get_path(PATH_TYPE_IDB); out.replace_extension(".deps.json"); std::ofstream out_deps(out); - out_deps << std::setw(4) << all_deps << std::endl; - // Dump images + out_deps << std::setw(2) << all_deps << std::endl; + out.replace_extension("").replace_extension(".images.json"); std::ofstream out_guids(out); - out_guids << std::setw(4) << images_guids << std::endl; + out_guids << std::setw(2) << images_guids << std::endl; } diff --git a/efiXloader/uefitool.h b/efiXloader/uefitool.h index ab04a208..825a895e 100644 --- a/efiXloader/uefitool.h +++ b/efiXloader/uefitool.h @@ -130,15 +130,17 @@ class Uefitool { } void get_unique_name(qstring &image_name); void get_image_guid(qstring &image_guid, UModelIndex index); - std::vector parseDepexSectionBody(const UModelIndex &index, - UString &parsed); - std::vector parseAprioriRawSection(const UModelIndex &index); + std::vector parse_depex_section_body(const UModelIndex &index, + UString &parsed); + std::vector parse_apriori_raw_section(const UModelIndex &index); void get_deps(UModelIndex index, std::string key); void get_apriori(UModelIndex index, std::string key); - void - dump_jsons(); // dump JSON with DEPEX and GUIDs information for each image - json all_deps; // DEPEX information for each image - json images_guids; // matching the modules to the parent's GUIDs + void dump_jsons(); + + // DEPEX information for each image + json all_deps; + + json images_guids; TreeModel model; const char *buffer; uint32_t buffer_size; @@ -149,5 +151,10 @@ class Uefitool { void set_machine_type(UByteArray pe_body); uint16_t machine_type = 0xffff; bool machine_type_detected = false; + +private: + std::string get_kind(const UModelIndex &index) { + return fileTypeToUString(model.subtype(index.parent())).toLocal8Bit(); + } }; } // namespace efiloader From 6fe16b14f292d1af5fe6ef4f65c5c306d69305ec Mon Sep 17 00:00:00 2001 From: yeggor Date: Sat, 5 Oct 2024 02:56:08 +0100 Subject: [PATCH 5/5] get module name by key instead of index, handle exceptions for build_modules_sequence --- efiXplorer/efi_deps.cc | 4 ++-- efiXplorer/efi_ui.cc | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/efiXplorer/efi_deps.cc b/efiXplorer/efi_deps.cc index 50c074b2..e586e63c 100644 --- a/efiXplorer/efi_deps.cc +++ b/efiXplorer/efi_deps.cc @@ -244,7 +244,7 @@ json efi_deps_t::get_module_info(std::string module) { // can not get name for module continue; } - std::string dmodule_name = m_modules_guids[dmodule_guid][0]; + std::string dmodule_name = m_modules_guids[dmodule_guid]["name"]; if (dmodule_name == module) { deps_protocols = element.value(); found = true; @@ -268,7 +268,7 @@ string_set_t efi_deps_t::get_apriori_modules() { for (auto file : files) { auto modules = m_uefitool_deps[file]; for (auto &mguid : modules) { - std::string module = m_modules_guids[mguid][0]; + std::string module = m_modules_guids[mguid]["name"]; apriori_modules.insert(module); efi_utils::log("module from %s: %s\n", file.c_str(), module.c_str()); } diff --git a/efiXplorer/efi_ui.cc b/efiXplorer/efi_ui.cc index 24884068..f4778887 100644 --- a/efiXplorer/efi_ui.cc +++ b/efiXplorer/efi_ui.cc @@ -316,7 +316,13 @@ void attach_action_protocols_deps() { // action handler for showing the sequence of modules execution struct modules_seq_handler_t : public action_handler_t { virtual int idaapi activate(action_activation_ctx_t *ctx) { - g_deps.build_modules_sequence(); + try { + g_deps.build_modules_sequence(); + } catch (std::exception &e) { + efi_utils::log("failed to build modules sequence: %s\n", e.what()); + return -1; + } + std::string s = g_deps.m_modules_sequence.dump(2); efi_utils::log("sequence of modules execution: %s\n", s.c_str());