diff --git a/UEFIExtract/uefiextract.pro b/UEFIExtract/uefiextract.pro index 16fbf52..4cc84a8 100644 --- a/UEFIExtract/uefiextract.pro +++ b/UEFIExtract/uefiextract.pro @@ -13,6 +13,7 @@ SOURCES += uefiextract_main.cpp \ ../common/ffs.cpp \ ../common/nvram.cpp \ ../common/ffsparser.cpp \ + ../common/ffsreport.cpp \ ../common/fitparser.cpp \ ../common/peimage.cpp \ ../common/treeitem.cpp \ @@ -30,6 +31,7 @@ HEADERS += ffsdumper.h \ ../common/ffs.h \ ../common/nvram.h \ ../common/ffsparser.h \ + ../common/ffsreport.h \ ../common/fitparser.h \ ../common/peimage.h \ ../common/types.h \ diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index 8e8c55d..6cbf3ec 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include "../common/ffsparser.h" +#include "../common/ffsreport.h" #include "../common/fitparser.h" #include "ffsdumper.h" @@ -94,6 +95,20 @@ int main(int argc, char *argv[]) } } + // Create ffsReport + FfsReport ffsReport(&model); + std::vector report = ffsReport.generate(); + if (report.size()) { + QFile file; + file.setFileName(fileInfo.fileName().append(".report.txt")); + if (file.open(QFile::Text | QFile::WriteOnly)) { + for (size_t i = 0; i < report.size(); i++) { + file.write(report[i].toLatin1().append('\n')); + } + file.close(); + } + } + // Create ffsDumper FfsDumper ffsDumper(&model); @@ -104,6 +119,9 @@ int main(int argc, char *argv[]) else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("all")) { // Dump everything return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true) != ERR_SUCCESS); } + else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("none")) { // Skip dumping + return 0; + } else { // Dump specific files UINT32 returned = 0; for (int i = 2; i < a.arguments().length(); i++) { @@ -113,12 +131,15 @@ int main(int argc, char *argv[]) } return returned; } + + return 0; } else { // Show version and usage information - std::cout << "UEFIExtract 0.11.0" << std::endl << std::endl - << "Usage: UEFIExtract imagefile - dumps only leaf tree items into .dump folder" << std::endl - << " UEFIExtract imagefile all - dumps all tree items" - << " UIFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dumps an FFS file(s) with specific GUID(s)" + std::cout << "UEFIExtract 0.12.0" << std::endl << std::endl + << "Usage: UEFIExtract imagefile - generate report and dump only leaf tree items into .dump folder" << std::endl + << " UEFIExtract imagefile all - generate report and dump all tree items" << std::endl + << " UEFIExtract imagefile none - only generate report, no dump needed" << std::endl + << " UIFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dump only FFS file(s) with specific GUID(s)" << std::endl << "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl; return 1; } diff --git a/common/ffsreport.cpp b/common/ffsreport.cpp new file mode 100644 index 0000000..b1ca61c --- /dev/null +++ b/common/ffsreport.cpp @@ -0,0 +1,71 @@ +/* fssreport.cpp + +Copyright (c) 2016, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#include "ffsreport.h" + +std::vector FfsReport::generate() +{ + std::vector report; + + // Check model pointer + if (!model) { + report.push_back(QObject::tr("ERROR: Invalid model pointer provided.")); + return report; + } + + // Check root index to be valid + QModelIndex root = model->index(0,0); + if (!root.isValid()) { + report.push_back(QObject::tr("ERROR: Model root index is invalid.")); + return report; + } + + // Generate report recursive + report.push_back(QObject::tr(" Type | Subtype | Size | CRC32 | Name ")); + STATUS result = generateRecursive(report, root); + if (result) { + report.push_back(QObject::tr("ERROR: generateRecursive returned %1.") + .arg(errorCodeToQString(result))); + } + + return report; +} + +STATUS FfsReport::generateRecursive(std::vector & report, QModelIndex index, UINT32 level) +{ + if (!index.isValid()) + return ERR_SUCCESS; //Nothing to report for invalid index + + // Calculate item CRC32 + QByteArray data = model->header(index) + model->body(index) + model->tail(index); + UINT32 crc = crc32(0, (const UINT8*)data.constData(), data.size()); + + // Information on current item + QString text = model->text(index); + report.push_back(QObject::tr("%1 | %2 | %3 | %4 | %5 %6 %7") + .arg(itemTypeToQString(model->type(index)), 16, QChar(' ')) + .arg(itemSubtypeToQString(model->type(index), model->subtype(index)), 24, QChar(' ')) + .hexarg2(data.size(), 8) + .hexarg2(crc, 8) + .arg(' ', level, QChar('-')) + .arg(model->name(index)) + .arg(text.isEmpty() ? "" : text.prepend("| ")) + ); + + // Information on child items + for (int i = 0; i < model->rowCount(index); i++) { + generateRecursive(report, index.child(i,0), level + 1); + } + + return ERR_SUCCESS; +} diff --git a/common/ffsreport.h b/common/ffsreport.h new file mode 100644 index 0000000..9432fda --- /dev/null +++ b/common/ffsreport.h @@ -0,0 +1,45 @@ +/* fssreport.h + +Copyright (c) 2016, Nikolaj Schlej. All rights reserved. +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +*/ + +#ifndef FFSREPORT_H +#define FFSREPORT_H + +#include + +#include +#include +#include +#include + +#include "basetypes.h" +#include "treemodel.h" +#include "ffs.h" +#include "utility.h" + +class FfsReport +{ +public: + + FfsReport(TreeModel * treeModel) : model(treeModel) {} + ~FfsReport() {}; + + std::vector generate(); + +private: + TreeModel* model; + + STATUS generateRecursive(std::vector & report, QModelIndex index, UINT32 level = 0); + +}; + +#endif // FFSREPORT_H