From f529fdd20dd6d6bab497d7186f9676acf8b3e4d4 Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Wed, 9 Jul 2014 09:20:13 +0200 Subject: [PATCH] UEFITool 0.18.1 - descriptor parsing enabled for Gigabyte boards - search dialog UI reworked (GUID search to be added in next release) - added MAN$ signature check for old ME firmware versions --- UEFIExtract/uefiextract_main.cpp | 2 +- UEFIPatch/uefipatch_main.cpp | 2 +- ffsengine.cpp | 75 +++++++------ ffsengine.h | 6 +- me.h | 3 +- searchdialog.ui | 178 +++++++++++++------------------ uefitool.cpp | 21 ++-- 7 files changed, 132 insertions(+), 155 deletions(-) diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index b63182f..73155f8 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -41,7 +41,7 @@ int main(int argc, char *argv[]) } else { result = ERR_INVALID_PARAMETER; - std::cout << "UEFIExtract 0.2" << std::endl << std::endl << + std::cout << "UEFIExtract 0.2.1" << std::endl << std::endl << "Usage: uefiextract imagefile\n" << std::endl; } diff --git a/UEFIPatch/uefipatch_main.cpp b/UEFIPatch/uefipatch_main.cpp index 050eb0b..15f465f 100644 --- a/UEFIPatch/uefipatch_main.cpp +++ b/UEFIPatch/uefipatch_main.cpp @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) result = w.patchFromFile(a.arguments().at(1)); } else { - std::cout << "UEFIPatch 0.2.0 - UEFI image file patching utility" << std::endl << std::endl << + std::cout << "UEFIPatch 0.2.1 - UEFI image file patching utility" << std::endl << std::endl << "Usage: UEFIPatch image_file" << std::endl << std::endl << "Patches will be read from patches.txt file\n"; return ERR_SUCCESS; diff --git a/ffsengine.cpp b/ffsengine.cpp index 5c99281..d601c03 100644 --- a/ffsengine.cpp +++ b/ffsengine.cpp @@ -169,7 +169,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in // Check for buffer size to be greater or equal to descriptor region size if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) { - msg(tr("parseInputFile: Input file is smaller then minimum descriptor size of %1 bytes").arg(FLASH_DESCRIPTOR_SIZE)); + msg(tr("parseIntelImage: Input file is smaller then minimum descriptor size of %1 bytes").arg(FLASH_DESCRIPTOR_SIZE)); return ERR_INVALID_FLASH_DESCRIPTOR; } @@ -215,56 +215,66 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in if (regionSection->BiosLimit) { biosBegin = calculateRegionOffset(regionSection->BiosBase); biosEnd = calculateRegionSize(regionSection->BiosBase, regionSection->BiosLimit); + + // Check for Gigabyte specific descriptor map + if (biosEnd - biosBegin == intelImage.size()) { + if (!meEnd) { + msg(tr("parseIntelImage: can determine BIOS region start on Gigabyte-specific descriptor")); + return ERR_INVALID_FLASH_DESCRIPTOR; + } + biosBegin = meEnd; + } + bios = intelImage.mid(biosBegin, biosEnd); biosEnd += biosBegin; } else { - msg(tr("parseInputFile: descriptor parsing failed, BIOS region not found in descriptor")); + msg(tr("parseIntelImage: descriptor parsing failed, BIOS region not found in descriptor")); return ERR_INVALID_FLASH_DESCRIPTOR; } // Check for intersections between regions if (hasIntersection(descriptorBegin, descriptorEnd, gbeBegin, gbeEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with GbE region")); + msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with GbE region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(descriptorBegin, descriptorEnd, meBegin, meEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with ME region")); + msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with ME region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(descriptorBegin, descriptorEnd, biosBegin, biosEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with BIOS region")); + msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with BIOS region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(descriptorBegin, descriptorEnd, pdrBegin, pdrEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, descriptor region has intersection with PDR region")); + msg(tr("parseIntelImage: descriptor parsing failed, descriptor region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(gbeBegin, gbeEnd, meBegin, meEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, GbE region has intersection with ME region")); + msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with ME region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(gbeBegin, gbeEnd, biosBegin, biosEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, GbE region has intersection with BIOS region")); + msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with BIOS region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(gbeBegin, gbeEnd, pdrBegin, pdrEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, GbE region has intersection with PDR region")); + msg(tr("parseIntelImage: descriptor parsing failed, GbE region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(meBegin, meEnd, biosBegin, biosEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, ME region has intersection with BIOS region")); + msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with BIOS region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(meBegin, meEnd, pdrBegin, pdrEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, ME region has intersection with PDR region")); + msg(tr("parseIntelImage: descriptor parsing failed, ME region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } if (hasIntersection(biosBegin, biosEnd, pdrBegin, pdrEnd)) { - msg(tr("parseInputFile: descriptor parsing failed, BIOS region has intersection with PDR region")); + msg(tr("parseIntelImage: descriptor parsing failed, BIOS region has intersection with PDR region")); return ERR_INVALID_FLASH_DESCRIPTOR; } - + // Region map is consistent QByteArray body; QString name; @@ -409,12 +419,21 @@ UINT8 FfsEngine::parseMeRegion(const QByteArray & me, QModelIndex & index, const QString info = tr("Size: %1"). arg(me.size(), 8, 16, QChar('0')); - INT32 versionOffset = me.indexOf(ME_VERSION_SIGNATURE); - if (versionOffset < 0){ - info += tr("\nVersion: unknown"); - msg(tr("parseRegion: ME region version is unknown, it can be damaged"), parent); + // Search for new signature + INT32 versionOffset = me.indexOf(ME_VERSION_SIGNATURE2); + bool versionFound = true; + if (versionOffset < 0){ // New signature not found + // Search for old signature + versionOffset = me.indexOf(ME_VERSION_SIGNATURE); + if (versionOffset < 0){ + info += tr("\nVersion: unknown"); + msg(tr("parseRegion: ME region version is unknown, it can be damaged"), parent); + versionFound = false; + } } - else { + + // Add version information + if (versionFound) { ME_VERSION* version = (ME_VERSION*)(me.constData() + versionOffset); info += tr("\nVersion: %1.%2.%3.%4") .arg(version->major) @@ -2772,12 +2791,7 @@ UINT8 FfsEngine::reconstructImageFile(QByteArray & reconstructed) } // Search routines -UINT8 FfsEngine::findHexPattern(const QByteArray & pattern, const UINT8 mode) -{ - return findHexPatternIn(model->index(0, 0), pattern, mode); -} - -UINT8 FfsEngine::findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode) +UINT8 FfsEngine::findHexPattern(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode) { if (pattern.isEmpty()) return ERR_INVALID_PARAMETER; @@ -2787,7 +2801,7 @@ UINT8 FfsEngine::findHexPatternIn(const QModelIndex & index, const QByteArray & bool hasChildren = (model->rowCount(index) > 0); for (int i = 0; i < model->rowCount(index); i++) { - findHexPatternIn(index.child(i, index.column()), pattern, mode); + findHexPattern(index.child(i, index.column()), pattern, mode); } QByteArray data; @@ -2816,12 +2830,7 @@ UINT8 FfsEngine::findHexPatternIn(const QModelIndex & index, const QByteArray & return ERR_SUCCESS; } -UINT8 FfsEngine::findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive) -{ - return findTextPatternIn(model->index(0, 0), pattern, unicode, caseSensitive); -} - -UINT8 FfsEngine::findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive) +UINT8 FfsEngine::findTextPattern(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive) { if (pattern.isEmpty()) return ERR_INVALID_PARAMETER; @@ -2831,7 +2840,7 @@ UINT8 FfsEngine::findTextPatternIn(const QModelIndex & index, const QString & pa bool hasChildren = (model->rowCount(index) > 0); for (int i = 0; i < model->rowCount(index); i++) { - findTextPatternIn(index.child(i, index.column()), pattern, unicode, caseSensitive); + findTextPattern(index.child(i, index.column()), pattern, unicode, caseSensitive); } if (hasChildren) @@ -2845,7 +2854,7 @@ UINT8 FfsEngine::findTextPatternIn(const QModelIndex & index, const QString & pa int offset = -1; while ((offset = data.indexOf(pattern, offset + 1, caseSensitive)) >= 0) { - msg(tr("%1 text pattern \"%2\" found in %3 at offset %4") + msg(tr("%1 text \"%2\" found in %3 at offset %4") .arg(unicode ? "Unicode" : "ASCII") .arg(pattern) .arg(model->nameString(index)) diff --git a/ffsengine.h b/ffsengine.h index a44cb38..c466a9a 100644 --- a/ffsengine.h +++ b/ffsengine.h @@ -96,10 +96,8 @@ public: UINT8 patch(const QModelIndex & index, const QVector & patches); // Search routines - UINT8 findHexPattern(const QByteArray & pattern, const UINT8 mode); - UINT8 findHexPatternIn(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode); - UINT8 findTextPattern(const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive); - UINT8 findTextPatternIn(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive); + UINT8 findHexPattern(const QModelIndex & index, const QByteArray & pattern, const UINT8 mode); + UINT8 findTextPattern(const QModelIndex & index, const QString & pattern, const bool unicode, const Qt::CaseSensitivity caseSensitive); private: TreeModel *model; diff --git a/me.h b/me.h index f4a1472..305f284 100644 --- a/me.h +++ b/me.h @@ -18,7 +18,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. // Make sure we use right packing rules #pragma pack(push,1) -const QByteArray ME_VERSION_SIGNATURE("\x24\x4D\x4E\x32", 4); +const QByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN +const QByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2 typedef struct { UINT32 signature; diff --git a/searchdialog.ui b/searchdialog.ui index 1ddfb47..2e9bd0f 100644 --- a/searchdialog.ui +++ b/searchdialog.ui @@ -6,96 +6,71 @@ 0 0 - 290 - 195 + 340 + 214 Search - - - - - Search for: - - - - - - - Data type: - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - Hex pattern - - - - - Text string - - - - - - + + false + + + + 0 - - - - 0 - - - 0 - - + + + Hex pattern + + + + + + Hex pattern: + + + + + + + - Hex pattern search scope + Search scope - + + + 6 + + + 9 + - + Header and body + + true + - + Header only - + Body only - - true - @@ -103,22 +78,29 @@ - - - - 0 - - - 0 - - + + + Text + + + + + + Text: + + + + + + + - Text string options + Text search options - + - + Unicode @@ -128,7 +110,7 @@ - + Case sensitive @@ -141,15 +123,19 @@ + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + - searchEdit - dataTypeComboBox - allRadioButton - bodyOnlyRadioButton - unicodeCheckBox - caseSensitiveCheckBox buttonBox @@ -161,12 +147,12 @@ accept() - 173 - 162 + 182 + 185 157 - 216 + 194 @@ -177,28 +163,12 @@ reject() - 173 - 162 + 182 + 185 286 - 216 - - - - - dataTypeComboBox - activated(int) - stackedWidget - setCurrentIndex(int) - - - 151 - 42 - - - 88 - 68 + 194 diff --git a/uefitool.cpp b/uefitool.cpp index 9ebaceb..316ea63 100644 --- a/uefitool.cpp +++ b/uefitool.cpp @@ -123,33 +123,32 @@ void UEFITool::populateUi(const QModelIndex ¤t) void UEFITool::search() { - // Set focus to edit box - searchDialog->ui->searchEdit->setFocus(); - if (searchDialog->exec() != QDialog::Accepted) return; - int index = searchDialog->ui->dataTypeComboBox->currentIndex(); + QModelIndex rootIndex = ffsEngine->treeModel()->index(0, 0); + + int index = searchDialog->ui->tabWidget->currentIndex(); if (index == 0) { // Hex pattern - QByteArray pattern = QByteArray::fromHex(searchDialog->ui->searchEdit->text().toLatin1()); + QByteArray pattern = QByteArray::fromHex(searchDialog->ui->hexEdit->text().toLatin1()); if (pattern.isEmpty()) return; UINT8 mode; - if (searchDialog->ui->headerOnlyRadioButton->isChecked()) + if (searchDialog->ui->hexScopeHeaderRadioButton->isChecked()) mode = SEARCH_MODE_HEADER; - else if (searchDialog->ui->bodyOnlyRadioButton->isChecked()) + else if (searchDialog->ui->hexScopeBodyRadioButton->isChecked()) mode = SEARCH_MODE_BODY; else mode = SEARCH_MODE_ALL; - ffsEngine->findHexPattern(pattern, mode); + ffsEngine->findHexPattern(rootIndex, pattern, mode); showMessages(); } else if (index == 1) { // Text string - QString pattern = searchDialog->ui->searchEdit->text(); + QString pattern = searchDialog->ui->textEdit->text(); if (pattern.isEmpty()) return; - ffsEngine->findTextPattern(pattern, searchDialog->ui->unicodeCheckBox->isChecked(), - (Qt::CaseSensitivity) searchDialog->ui->caseSensitiveCheckBox->isChecked()); + ffsEngine->findTextPattern(rootIndex, pattern, searchDialog->ui->textUnicodeCheckBox->isChecked(), + (Qt::CaseSensitivity) searchDialog->ui->textCaseSensitiveCheckBox->isChecked()); showMessages(); } }