From 701717c554ce287fbf3abb77758dccfbfd996d49 Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Fri, 15 Aug 2014 13:24:03 +0200 Subject: [PATCH] UEFIExtract 0.3.0 - added filtering by FFS file GUID, only specified files can now be unpacked --- UEFIExtract/uefiextract.cpp | 38 ++++++++++-------- UEFIExtract/uefiextract.h | 5 ++- UEFIExtract/uefiextract_main.cpp | 50 ++++++++++++++++------- ffsengine.cpp | 68 +++++++++++++++++--------------- ffsengine.h | 2 +- 5 files changed, 99 insertions(+), 64 deletions(-) diff --git a/UEFIExtract/uefiextract.cpp b/UEFIExtract/uefiextract.cpp index 7f7614a..3570764 100644 --- a/UEFIExtract/uefiextract.cpp +++ b/UEFIExtract/uefiextract.cpp @@ -24,30 +24,36 @@ UEFIExtract::~UEFIExtract() delete ffsEngine; } -UINT8 UEFIExtract::extractAll(QString path) +UINT8 UEFIExtract::init(const QString & path) { - QFileInfo fileInfo = QFileInfo(path); + fileInfo = QFileInfo(path); - if (!fileInfo.exists()) - return ERR_FILE_OPEN; + if (!fileInfo.exists()) + return ERR_FILE_OPEN; - QFile inputFile; - inputFile.setFileName(path); + QFile inputFile; + inputFile.setFileName(path); - if (!inputFile.open(QFile::ReadOnly)) - return ERR_FILE_OPEN; + if (!inputFile.open(QFile::ReadOnly)) + return ERR_FILE_OPEN; - QByteArray buffer = inputFile.readAll(); - inputFile.close(); + QByteArray buffer = inputFile.readAll(); + inputFile.close(); - UINT8 result = ffsEngine->parseImageFile(buffer); - if (result) - return result; + UINT8 result = ffsEngine->parseImageFile(buffer); + if (result) + return result; + return ERR_SUCCESS; +} + +UINT8 UEFIExtract::extract(QString guid) +{ QModelIndex rootIndex = ffsEngine->treeModel()->index(0, 0); - result = ffsEngine->dump(rootIndex, fileInfo.fileName().append(".dump")); - if (result) - return result; + UINT8 result = ffsEngine->dump(rootIndex, fileInfo.fileName().append(".dump"), guid); + if (result) + return result; + return ERR_SUCCESS; } \ No newline at end of file diff --git a/UEFIExtract/uefiextract.h b/UEFIExtract/uefiextract.h index a3aede0..9cf9c40 100644 --- a/UEFIExtract/uefiextract.h +++ b/UEFIExtract/uefiextract.h @@ -31,10 +31,13 @@ public: explicit UEFIExtract(QObject *parent = 0); ~UEFIExtract(); - UINT8 extractAll(QString path); + UINT8 init(const QString & path); + UINT8 extract(QString guid = QString()); private: FfsEngine* ffsEngine; + QFileInfo fileInfo; + }; #endif diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index 0e6a10d..b08b055 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -25,24 +25,44 @@ int main(int argc, char *argv[]) UEFIExtract w; UINT8 result = ERR_SUCCESS; - if (a.arguments().length() > 1) { - result = w.extractAll(a.arguments().at(1)); - switch (result) { - case ERR_DIR_ALREADY_EXIST: - std::cout << "Dump directory already exist, please remove it" << std::endl; - break; - case ERR_DIR_CREATE: - std::cout << "Can't create directory" << std::endl; - break; - case ERR_FILE_OPEN: - std::cout << "Can't create file" << std::endl; - break; - } + if (a.arguments().length() > 1 ) { + w.init(a.arguments().at(1)); + + if (a.arguments().length() == 2) { + result = w.extract(); + switch (result) { + case ERR_DIR_ALREADY_EXIST: + std::cout << "Dump directory already exist, please remove it" << std::endl; + break; + case ERR_DIR_CREATE: + std::cout << "Can't create directory" << std::endl; + break; + case ERR_FILE_OPEN: + std::cout << "Can't create file" << std::endl; + break; + } + } + else { + for (int i = 2; i < a.arguments().length(); i++) { + result = w.extract(a.arguments().at(i)); + switch (result) { + case ERR_DIR_ALREADY_EXIST: + std::cout << "Dump directory already exist, please remove it" << std::endl; + break; + case ERR_DIR_CREATE: + std::cout << "Can't create directory" << std::endl; + break; + case ERR_FILE_OPEN: + std::cout << "Can't create file" << std::endl; + break; + } + } + } } else { result = ERR_INVALID_PARAMETER; - std::cout << "UEFIExtract 0.2.2" << std::endl << std::endl << - "Usage: uefiextract imagefile\n" << std::endl; + std::cout << "UEFIExtract 0.3.0" << std::endl << std::endl << + "Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ...]\n" << std::endl; } return result; diff --git a/ffsengine.cpp b/ffsengine.cpp index 5b5d196..68241a3 100644 --- a/ffsengine.cpp +++ b/ffsengine.cpp @@ -3432,51 +3432,57 @@ UINT32 FfsEngine::crc32(UINT32 initial, const UINT8* buffer, UINT32 length) return(crc32 ^ 0xFFFFFFFF); } -UINT8 FfsEngine::dump(const QModelIndex & index, const QString path) +UINT8 FfsEngine::dump(const QModelIndex & index, const QString & path, const QString & guid) { if (!index.isValid()) return ERR_INVALID_PARAMETER; QDir dir; - if (dir.cd(path)) - return ERR_DIR_ALREADY_EXIST; + + if (guid.isEmpty() || + guidToQString(*(EFI_GUID*)model->header(index).constData()) == guid || + guidToQString(*(EFI_GUID*)model->header(model->findParentOfType(index, Types::File)).constData()) == guid) { + + if (dir.cd(path)) + return ERR_DIR_ALREADY_EXIST; - if (!dir.mkpath(path)) - return ERR_DIR_CREATE; + if (!dir.mkpath(path)) + return ERR_DIR_CREATE; - QFile file; - if (!model->header(index).isEmpty()) { - file.setFileName(tr("%1/header.bin").arg(path)); - if (!file.open(QFile::WriteOnly)) - return ERR_FILE_OPEN; - file.write(model->header(index)); - file.close(); - } + QFile file; + if (!model->header(index).isEmpty()) { + file.setFileName(tr("%1/header.bin").arg(path)); + if (!file.open(QFile::WriteOnly)) + return ERR_FILE_OPEN; + file.write(model->header(index)); + file.close(); + } - if (!model->body(index).isEmpty()) { - file.setFileName(tr("%1/body.bin").arg(path)); - if (!file.open(QFile::WriteOnly)) - return ERR_FILE_OPEN; - file.write(model->body(index)); - file.close(); - } + if (!model->body(index).isEmpty()) { + file.setFileName(tr("%1/body.bin").arg(path)); + if (!file.open(QFile::WriteOnly)) + return ERR_FILE_OPEN; + file.write(model->body(index)); + file.close(); + } - QString info = tr("Type: %1\nSubtype: %2\n%3%4") - .arg(model->typeString(index)) - .arg(model->subtypeString(index)) - .arg(model->textString(index).isEmpty() ? "" : tr("Text: %1\n").arg(model->textString(index))) - .arg(model->info(index)); - file.setFileName(tr("%1/info.txt").arg(path)); - if (!file.open(QFile::Text | QFile::WriteOnly)) - return ERR_FILE_OPEN; - file.write(info.toLatin1()); - file.close(); + QString info = tr("Type: %1\nSubtype: %2\n%3%4") + .arg(model->typeString(index)) + .arg(model->subtypeString(index)) + .arg(model->textString(index).isEmpty() ? "" : tr("Text: %1\n").arg(model->textString(index))) + .arg(model->info(index)); + file.setFileName(tr("%1/info.txt").arg(path)); + if (!file.open(QFile::Text | QFile::WriteOnly)) + return ERR_FILE_OPEN; + file.write(info.toLatin1()); + file.close(); + } UINT8 result; for (int i = 0; i < model->rowCount(index); i++) { QModelIndex childIndex = index.child(i, 0); QString childPath = tr("%1/%2 %3").arg(path).arg(i).arg(model->textString(childIndex).isEmpty() ? model->nameString(childIndex) : model->textString(childIndex)); - result = dump(childIndex, childPath); + result = dump(childIndex, childPath, guid); if (result) return result; } diff --git a/ffsengine.h b/ffsengine.h index a5c1516..8d4a3c8 100644 --- a/ffsengine.h +++ b/ffsengine.h @@ -94,7 +94,7 @@ public: UINT8 replace(const QModelIndex & index, const QByteArray & object, const UINT8 mode); UINT8 remove(const QModelIndex & index); UINT8 rebuild(const QModelIndex & index); - UINT8 dump(const QModelIndex & index, const QString path); + UINT8 dump(const QModelIndex & index, const QString & path, const QString & filter = QString()); UINT8 patch(const QModelIndex & index, const QVector & patches); // Search routines