From cb9ecc4b432d25c3b11dc5fc88a4e77d940c33c8 Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Wed, 8 Jul 2015 23:05:48 +0200 Subject: [PATCH] NE_alpha6 - solved a bug in offset calculation for Intel images inside a capsule - fitParser code cleanup - hopefully the last commit to this tree, time to start another branch and rewrite the whole thing once again --- UEFITool/uefitool.cpp | 62 +++++---------------------------- common/ffsparser.cpp | 79 ++++--------------------------------------- common/ffsparser.h | 2 +- common/fitparser.cpp | 49 +++++++++++++++++++++------ common/fitparser.h | 5 +-- 5 files changed, 57 insertions(+), 140 deletions(-) diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp index 37b96df..564dfff 100644 --- a/UEFITool/uefitool.cpp +++ b/UEFITool/uefitool.cpp @@ -17,7 +17,7 @@ UEFITool::UEFITool(QWidget *parent) : QMainWindow(parent), ui(new Ui::UEFITool), -version(tr("0.30.0_alpha5")) +version(tr("0.30.0_alpha6")) { clipboard = QApplication::clipboard(); @@ -806,13 +806,13 @@ void UEFITool::writeSettings() void UEFITool::showFitTable() { - QVector > fitEntries = fitParser->getFitEntries(); - if (fitEntries.isEmpty()) + QVector > fitTable = fitParser->getFitTable(); + if (fitTable.isEmpty()) return; // Set up the FIT table ui->fitTableWidget->clear(); - ui->fitTableWidget->setRowCount(fitEntries.length()); + ui->fitTableWidget->setRowCount(fitTable.length()); ui->fitTableWidget->setColumnCount(6); //ui->fitTableWidget->verticalHeader()->setVisible(false); ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Type") << tr("Checksum") << tr("Remark")); @@ -822,59 +822,13 @@ void UEFITool::showFitTable() ui->fitTableWidget->horizontalHeader()->setStretchLastSection(true); // Add all data to the table widget - for (INT32 i = 0; i < fitEntries.length(); i++) { - FIT_ENTRY* entry = &(fitEntries[i].first); - if (i) - ui->fitTableWidget->setItem(i, 0, new QTableWidgetItem(tr("%1h").hexarg2(entry->Address, 16))); - else - ui->fitTableWidget->setItem(i, 0, new QTableWidgetItem(tr("_FIT_ "))); - - ui->fitTableWidget->setItem(i, 1, new QTableWidgetItem(tr("%1h (%2)").hexarg2(entry->Size * 16, 8).arg(entry->Size * 16))); - ui->fitTableWidget->setItem(i, 2, new QTableWidgetItem(tr("%1h").hexarg2(entry->Version, 4))); - - QString typeString; - switch (entry->Type & 0x7F) { - case FIT_TYPE_HEADER: - typeString.append(tr("Header")); - break; - case FIT_TYPE_MICROCODE: - typeString.append(tr("Microcode")); - break; - case FIT_TYPE_BIOS_AC_MODULE: - typeString.append(tr("BIOS ACM")); - break; - case FIT_TYPE_BIOS_INIT_MODULE: - typeString.append(tr("BIOS Init")); - break; - case FIT_TYPE_TPM_POLICY: - typeString.append(tr("TPM Policy")); - break; - case FIT_TYPE_BIOS_POLICY_DATA: - typeString.append(tr("BIOS Policy Data")); - break; - case FIT_TYPE_TXT_CONF_POLICY: - typeString.append(tr("TXT Configuration Policy")); - break; - case FIT_TYPE_AC_KEY_MANIFEST: - typeString.append(tr("BootGuard Key Manifest")); - break; - case FIT_TYPE_AC_BOOT_POLICY: - typeString.append(tr("BootGuard Boot Policy")); - break; - case FIT_TYPE_EMPTY: - typeString.append(tr("Empty")); - break; - default: - typeString.append(tr("Unknown")); + for (INT32 i = 0; i < fitTable.length(); i++) { + for (UINT8 j = 0; j < 6; j++) { + ui->fitTableWidget->setItem(i, j, new QTableWidgetItem(fitTable[i][j])); } - - ui->fitTableWidget->setItem(i, 3, new QTableWidgetItem(typeString)); - ui->fitTableWidget->setItem(i, 4, new QTableWidgetItem(tr("%1h").hexarg2(entry->Checksum, 2))); - ui->fitTableWidget->setItem(i, 5, new QTableWidgetItem(fitEntries[i].second)); } ui->fitTableWidget->resizeColumnsToContents(); ui->fitTableWidget->resizeRowsToContents(); ui->messagesTabWidget->setCurrentIndex(2); - -} \ No newline at end of file +} diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index 465c865..2a8c7a8 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -135,7 +135,7 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex & if (descriptorHeader->Signature == FLASH_DESCRIPTOR_SIGNATURE) { // Parse as Intel image QModelIndex imageIndex; - result = parseIntelImage(flashImage, index, imageIndex); + result = parseIntelImage(flashImage, capsuleHeaderSize, index, imageIndex); if (result != ERR_INVALID_FLASH_DESCRIPTOR) return result; } @@ -169,7 +169,7 @@ STATUS FfsParser::parseImageFile(const QByteArray & buffer, const QModelIndex & return ERR_SUCCESS; } -STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const QModelIndex & parent, QModelIndex & index) +STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index) { // Sanity check if (intelImage.isEmpty()) @@ -307,6 +307,7 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const QModelInd // Construct parsing data pdata.fixed = TRUE; + pdata.offset = parentOffset; if (pdata.isOnFlash) info.prepend(tr("Offset: %1h\n").hexarg(pdata.offset)); // Add Intel image tree item @@ -323,19 +324,19 @@ STATUS FfsParser::parseIntelImage(const QByteArray & intelImage, const QModelInd QVector offsets; if (regionSection->GbeLimit) { offsets.append(gbeBegin); - info += tr("\nGbE region offset: %1h").hexarg(gbeBegin); + info += tr("\nGbE region offset: %1h").hexarg(gbeBegin + parentOffset); } if (regionSection->MeLimit) { offsets.append(meBegin); - info += tr("\nME region offset: %1h").hexarg(meBegin); + info += tr("\nME region offset: %1h").hexarg(meBegin + parentOffset); } if (regionSection->BiosLimit) { offsets.append(biosBegin); - info += tr("\nBIOS region offset: %1h").hexarg(biosBegin); + info += tr("\nBIOS region offset: %1h").hexarg(biosBegin + parentOffset); } if (regionSection->PdrLimit) { offsets.append(pdrBegin); - info += tr("\nPDR region offset: %1h").hexarg(pdrBegin); + info += tr("\nPDR region offset: %1h").hexarg(pdrBegin + parentOffset); } // Region access settings @@ -2327,69 +2328,3 @@ STATUS FfsParser::addMemoryAddressesRecursive(const QModelIndex & index, const U return ERR_SUCCESS; } -/*STATUS FfsParser::parseFit(const QModelIndex & index) -{ - // Check sanity - if (!lastVtf.isValid()) - return EFI_INVALID_PARAMETER; - - // Search for FIT - QModelIndex fitIndex; - STATUS result = findFitRecursive(index, fitIndex); - if (result) - return result; - - // FIT not found - if (!fitIndex.isValid()) - return ERR_SUCCESS; - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromQModelIndex(fitIndex); - - // Explicitly set the item as fixed - pdata.fixed = TRUE; - - // Set modified parsing data - model->setParsingData(fitIndex, parsingDataToQByteArray(pdata)); - - return ERR_SUCCESS; -} - -STATUS FfsParser::findFitRecursive(const QModelIndex & index, QModelIndex & found) -{ - // Sanity check - if (!index.isValid()) - return EFI_SUCCESS; - - // Process child items - for (int i = 0; i < model->rowCount(index); i++) { - findFitRecursive(index.child(i, 0), found); - if (found.isValid()) - return EFI_SUCCESS; - } - - // Get parsing data for the current item - PARSING_DATA pdata = parsingDataFromQModelIndex(index); - - // Check item's address to be in required range - INT32 offset = model->body(index).indexOf(FIT_SIGNATURE); - // Check for FIT signature in item's body - if (offset >= 0) { - // FIT candidate found, calculate it's offset and physical address - UINT32 fitOffset = pdata.offset + model->header(index).size() + (UINT32)offset; - UINT32 fitAddress = pdata.address + model->header(index).size() + (UINT32)offset; - - // Check FIT address to be in the last VTF - QByteArray lastVtfBody = model->body(lastVtf); - if (*(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET) == fitAddress) { - msg(tr("findFitRecursive: FIT table found at offset %1h, physical address %2h") - .hexarg2(fitOffset, 8) - .hexarg2(fitAddress, 8), - index); - found = index; - return ERR_SUCCESS; - } - } - - return ERR_SUCCESS; -}*/ \ No newline at end of file diff --git a/common/ffsparser.h b/common/ffsparser.h index c24980e..ca7e385 100644 --- a/common/ffsparser.h +++ b/common/ffsparser.h @@ -61,7 +61,7 @@ private: QVector > messagesVector; QModelIndex lastVtf; - STATUS parseIntelImage(const QByteArray & intelImage, const QModelIndex & parent, QModelIndex & root); + STATUS parseIntelImage(const QByteArray & intelImage, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & root); STATUS parseGbeRegion(const QByteArray & gbe, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parseMeRegion(const QByteArray & me, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parseBiosRegion(const QByteArray & bios, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); diff --git a/common/fitparser.cpp b/common/fitparser.cpp index c034f33..04476ce 100644 --- a/common/fitparser.cpp +++ b/common/fitparser.cpp @@ -52,26 +52,21 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn // Set modified parsing data model->setParsingData(fitIndex, parsingDataToQByteArray(pdata)); - // Add all FIT entries into QVector - const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(model->body(fitIndex).constData() + fitOffset); - // Special case of FIT header QString remark; + const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(model->body(fitIndex).constData() + fitOffset); // Check FIT checksum, if present + UINT32 fitSize = (fitHeader->Size & 0xFFFFFF) << 4; if (fitHeader->Type & 0x80) { // Calculate FIT entry checksum - UINT32 fitSize = (fitHeader->Size & 0xFFFFFF) << 4; UINT8 calculated = calculateChecksum8((const UINT8*)fitHeader, fitSize); if (calculated) { remark.append(tr("Invalid FIT table checksum, ").hexarg2(calculated, 2)); } } - // Check fit header version and type - if (fitHeader->Version != FIT_HEADER_VERSION) { - remark.append(tr("Invalid FIT header version, ")); - } + // Check fit header type if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) { remark.append(tr("Invalid FIT header type, ")); } @@ -80,11 +75,19 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn if (!remark.isEmpty()) remark = remark.left(remark.length() - 2); - // Add FIT header to fitEntries vector - fitEntries.append(QPair(*fitHeader, remark)); + // Add FIT header to fitTable + QVector currentStrings; + currentStrings += tr("_FIT_ "); + currentStrings += tr("%1").hexarg2(fitSize, 8); + currentStrings += tr("%1").hexarg2(fitHeader->Version, 4); + currentStrings += fitEntryTypeToQString(fitHeader->Type); + currentStrings += tr("%1").hexarg2(fitHeader->Checksum, 2); + currentStrings += remark; + fitTable.append(currentStrings); // Process all other entries for (UINT32 i = 1; i < fitHeader->Size; i++) { + currentStrings.clear(); remark.clear(); const FIT_ENTRY* currentEntry = fitHeader + i; @@ -110,12 +113,36 @@ STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIn break; } - fitEntries.append(QPair(*currentEntry, remark)); + // Add entry to fitTable + currentStrings += tr("%1").hexarg2(currentEntry->Address, 16); + currentStrings += tr("%1").hexarg2(currentEntry->Size, 8); + currentStrings += tr("%1").hexarg2(currentEntry->Version, 4); + currentStrings += fitEntryTypeToQString(currentEntry->Type); + currentStrings += tr("%1").hexarg2(currentEntry->Checksum, 2); + currentStrings += remark; + fitTable.append(currentStrings); } return ERR_SUCCESS; } +QString FitParser::fitEntryTypeToQString(UINT8 type) +{ + switch (type & 0x7F) { + case FIT_TYPE_HEADER: return tr("Header"); + case FIT_TYPE_MICROCODE: return tr("Microcode"); + case FIT_TYPE_BIOS_AC_MODULE: return tr("BIOS ACM"); + case FIT_TYPE_BIOS_INIT_MODULE: return tr("BIOS Init"); + case FIT_TYPE_TPM_POLICY: return tr("TPM Policy"); + case FIT_TYPE_BIOS_POLICY_DATA: return tr("BIOS Policy Data"); + case FIT_TYPE_TXT_CONF_POLICY: return tr("TXT Configuration Policy"); + case FIT_TYPE_AC_KEY_MANIFEST: return tr("BootGuard Key Manifest"); + case FIT_TYPE_AC_BOOT_POLICY: return tr("BootGuard Boot Policy"); + case FIT_TYPE_EMPTY: return tr("Empty"); + default: return tr("Unknown"); + } +} + STATUS FitParser::findFitRecursive(const QModelIndex & index, QModelIndex & found, UINT32 & fitOffset) { // Sanity check diff --git a/common/fitparser.h b/common/fitparser.h index ab296b8..419e3f2 100644 --- a/common/fitparser.h +++ b/common/fitparser.h @@ -37,14 +37,15 @@ public: ~FitParser(); STATUS parse(const QModelIndex & index, const QModelIndex & lastVtf); - QVector > getFitEntries() const { return fitEntries; } + QVector > getFitTable() const { return fitTable; } private: TreeModel *model; QModelIndex lastVtf; - QVector > fitEntries; + QVector > fitTable; STATUS findFitRecursive(const QModelIndex & index, QModelIndex & found, UINT32 & fitOffset); + QString fitEntryTypeToQString(UINT8 type); }; #endif