From e3ace324ee7e543974e567126b61bcbf338609e1 Mon Sep 17 00:00:00 2001 From: Alex Matrosov Date: Sun, 29 Apr 2018 22:33:19 -0700 Subject: [PATCH] bugfix --- UEFIDump/uefidump_main.cpp | 4 +- UEFIExtract/uefiextract_main.cpp | 4 +- UEFIFind/uefifind_main.cpp | 4 +- UEFITool/qhexedit2/qhexedit.cpp | 4 +- UEFITool/uefitool.cpp | 206 +++-- UEFITool/uefitool.h | 7 + UEFITool/uefitool.pro | 2 + UEFITool/uefitool.ui | 44 +- UEFITool/uefitool_main.cpp | 2 +- common/LZMA/LzmaCompress.c | 103 +-- common/LZMA/LzmaCompress.h | 16 +- common/LZMA/LzmaDecompress.c | 14 +- common/Tiano/EfiTianoCompress.c | 42 +- common/descriptor.cpp | 4 +- common/ffsparser.cpp | 1228 ++++++++++++++++-------------- common/ffsparser.h | 9 +- common/ffsreport.cpp | 2 +- common/guiddatabase.cpp | 2 +- common/nvramparser.cpp | 119 +-- common/treeitem.cpp | 4 +- common/utility.cpp | 15 +- 21 files changed, 1007 insertions(+), 828 deletions(-) diff --git a/UEFIDump/uefidump_main.cpp b/UEFIDump/uefidump_main.cpp index b280a3d..d3f16ca 100644 --- a/UEFIDump/uefidump_main.cpp +++ b/UEFIDump/uefidump_main.cpp @@ -1,6 +1,6 @@ /* uefidump_main.cpp -Copyright (c) 2017, LongSoft. All rights reserved. +Copyright (c) 2018, LongSoft. 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 @@ -29,7 +29,7 @@ int main(int argc, char *argv[]) return (uefidumper.dump(buffer, UString(argv[1])) != U_SUCCESS); } - std::cout << "UEFIDump 0.1.6" << std::endl << std::endl + std::cout << "UEFIDump 0.1.7" << std::endl << std::endl << "Usage: UEFIDump imagefile" << std::endl; return 0; } diff --git a/UEFIExtract/uefiextract_main.cpp b/UEFIExtract/uefiextract_main.cpp index d8a9cb5..f014beb 100644 --- a/UEFIExtract/uefiextract_main.cpp +++ b/UEFIExtract/uefiextract_main.cpp @@ -1,5 +1,5 @@ /* uefiextract_main.cpp -Copyright (c) 2017, LongSoft. All rights reserved. +Copyright (c) 2018, LongSoft. 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 @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) } } // If parameters are different, show version and usage information - std::cout << "UEFIExtract 0.13.5" << std::endl << std::endl + std::cout << "UEFIExtract 0.13.6" << 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 dump - only generate dump, no report needed." << std::endl diff --git a/UEFIFind/uefifind_main.cpp b/UEFIFind/uefifind_main.cpp index 09c64ec..59c5a6e 100644 --- a/UEFIFind/uefifind_main.cpp +++ b/UEFIFind/uefifind_main.cpp @@ -1,6 +1,6 @@ /* uefifind_main.cpp -Copyright (c) 2017, LongSoft. All rights reserved. +Copyright (c) 2018, LongSoft. 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 @@ -148,7 +148,7 @@ int main(int argc, char *argv[]) return U_SUCCESS; } else { - std::cout << "UEFIFind 0.10.10" << std::endl << std::endl << + std::cout << "UEFIFind 0.10.11" << std::endl << std::endl << "Usage: UEFIFind {header | body | all} {list | count} pattern imagefile" << std::endl << " or UEFIFind file patternsfile imagefile" << std::endl; return U_INVALID_PARAMETER; diff --git a/UEFITool/qhexedit2/qhexedit.cpp b/UEFITool/qhexedit2/qhexedit.cpp index 25e3151..6ecfc8b 100644 --- a/UEFITool/qhexedit2/qhexedit.cpp +++ b/UEFITool/qhexedit2/qhexedit.cpp @@ -165,7 +165,7 @@ void QHexEdit::setCursorPosition(qint64 position) // 3. Calc new position of cursor _bPosCurrent = position / 2; - _pxCursorY = ((position / 2 - _bPosFirst) / _bytesPerLine + 1) * _pxCharHeight; + _pxCursorY = (int)((position / 2 - _bPosFirst) / _bytesPerLine + 1) * _pxCharHeight; int x = (position % (2 * _bytesPerLine)); if (_editAreaIsAscii) { @@ -341,7 +341,7 @@ void QHexEdit::insert(qint64 pos, const QByteArray &ba) void QHexEdit::replace(qint64 pos, qint64 len, const QByteArray &ba) { - _undoStack->overwrite(pos, len, ba); + _undoStack->overwrite(pos, (int)len, ba); refresh(); } diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp index f6a2ba7..ca34d32 100644 --- a/UEFITool/uefitool.cpp +++ b/UEFITool/uefitool.cpp @@ -17,7 +17,11 @@ UEFITool::UEFITool(QWidget *parent) : QMainWindow(parent), ui(new Ui::UEFITool), +<<<<<<< HEAD +version(tr("NE alpha 48")) +======= version(tr("NE alpha 47")) +>>>>>>> 775ad7d25b97e266928f437af14b47d38578af63 { clipboard = QApplication::clipboard(); @@ -32,6 +36,7 @@ version(tr("NE alpha 47")) ffsFinder = NULL; ffsOps = NULL; ffsBuilder = NULL; + ffsReport = NULL; // Connect signals to slots connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile())); @@ -60,35 +65,21 @@ version(tr("NE alpha 47")) connect(ui->actionGoToOffset, SIGNAL(triggered()), this, SLOT(goToOffset())); connect(ui->actionGoToAddress, SIGNAL(triggered()), this, SLOT(goToAddress())); connect(ui->actionLoadGuidDatabase, SIGNAL(triggered()), this, SLOT(loadGuidDatabase())); + connect(ui->actionUnloadGuidDatabase, SIGNAL(triggered()), this, SLOT(unloadGuidDatabase())); + connect(ui->actionLoadDefaultGuidDatabase, SIGNAL(triggered()), this, SLOT(loadDefaultGuidDatabase())); + connect(ui->actionGenerateReport, SIGNAL(triggered()), this, SLOT(generateReport())); connect(ui->actionToggleBootGuardMarking, SIGNAL(toggled(bool)), this, SLOT(toggleBootGuardMarking(bool))); connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings())); // Enable Drag-and-Drop actions setAcceptDrops(true); + // Disable Builder tab, doesn't work right now + ui->messagesTabWidget->setTabEnabled(4, false); + // Set current directory currentDir = "."; - // Set monospace font for some controls - QFont font("Courier New", 10); -#if defined Q_OS_OSX - font = QFont("Menlo", 10); -#elif defined Q_OS_WIN - font = QFont("Consolas", 9); -#endif - ui->infoEdit->setFont(font); - ui->parserMessagesListWidget->setFont(font); - ui->finderMessagesListWidget->setFont(font); - ui->builderMessagesListWidget->setFont(font); - ui->fitTableWidget->setFont(font); - ui->bootGuardEdit->setFont(font); - ui->structureTreeView->setFont(font); - searchDialog->ui->guidEdit->setFont(font); - searchDialog->ui->hexEdit->setFont(font); - hexViewDialog->setFont(font); - goToOffsetDialog->ui->hexSpinBox->setFont(font); - goToAddressDialog->ui->hexSpinBox->setFont(font); - // Load built-in GUID database initGuidDatabase(":/guids.csv"); @@ -105,6 +96,7 @@ UEFITool::~UEFITool() delete ffsOps; delete ffsFinder; delete ffsParser; + delete ffsReport; delete model; delete hexViewDialog; delete searchDialog; @@ -171,8 +163,9 @@ void UEFITool::init() void UEFITool::populateUi(const QItemSelection &selected) { - if (selected.isEmpty()) + if (selected.isEmpty()) { return; + } populateUi(selected.indexes().at(0)); } @@ -180,8 +173,9 @@ void UEFITool::populateUi(const QItemSelection &selected) void UEFITool::populateUi(const QModelIndex ¤t) { // Check sanity - if (!current.isValid()) + if (!current.isValid()) { return; + } UINT8 type = model->type(current); UINT8 subtype = model->subtype(current); @@ -364,7 +358,7 @@ void UEFITool::goToAddress() return; UINT32 address = (UINT32)goToAddressDialog->ui->hexSpinBox->value(); - QModelIndex index = model->findByOffset(address - ffsParser->getAddressDiff()); + QModelIndex index = model->findByOffset(address - (UINT32)ffsParser->getAddressDiff()); if (index.isValid()) { ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter); ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear); @@ -622,75 +616,75 @@ void UEFITool::extract(const UINT8 mode) QString path; if (mode == EXTRACT_MODE_AS_IS) { switch (type) { - case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", "Capsule files (*.cap *.bin);;All files (*)"); break; - case Types::Image: path = QFileDialog::getSaveFileName(this, tr("Save image to file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)"); break; - case Types::Region: path = QFileDialog::getSaveFileName(this, tr("Save region to file"), name + ".rgn", "Region files (*.rgn *.bin);;All files (*)"); break; - case Types::Padding: path = QFileDialog::getSaveFileName(this, tr("Save padding to file"), name + ".pad", "Padding files (*.pad *.bin);;All files (*)"); break; - case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume to file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)"); break; - case Types::File: path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"), name + ".ffs", "FFS files (*.ffs *.bin);;All files (*)"); break; - case Types::Section: path = QFileDialog::getSaveFileName(this, tr("Save section to file"), name + ".sct", "Section files (*.sct *.bin);;All files (*)"); break; - case Types::NvarEntry: path = QFileDialog::getSaveFileName(this, tr("Save NVAR entry to file"), name + ".nvar", "NVAR entry files (*.nvar *.bin);;All files (*)"); break; - case Types::VssEntry: path = QFileDialog::getSaveFileName(this, tr("Save VSS entry to file"), name + ".vss", "VSS entry files (*.vss *.bin);;All files (*)"); break; - case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save Fsys entry to file"), name + ".fse", "Fsys entry files (*.fse *.bin);;All files (*)"); break; - case Types::EvsaEntry: path = QFileDialog::getSaveFileName(this, tr("Save EVSA entry to file"), name + ".evse", "EVSA entry files (*.evse *.bin);;All files (*)"); break; - case Types::FlashMapEntry: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap entry to file"), name + ".fme", "FlashMap entry files (*.fme *.bin);;All files (*)"); break; - case Types::VssStore: path = QFileDialog::getSaveFileName(this, tr("Save VSS store to file"), name + ".vss", "VSS store files (*.vss *.bin);;All files (*)"); break; - case Types::Vss2Store: path = QFileDialog::getSaveFileName(this, tr("Save VSS2 store to file"), name + ".vss2", "VSS2 store files (*.vss2 *.bin);;All files (*)"); break; - case Types::FdcStore: path = QFileDialog::getSaveFileName(this, tr("Save FDC store to file"), name + ".fdc", "FDC store files (*.fdc *.bin);;All files (*)"); break; - case Types::FsysStore: path = QFileDialog::getSaveFileName(this, tr("Save Fsys store to file"), name + ".fsys", "Fsys store files (*.fsys *.bin);;All files (*)"); break; - case Types::EvsaStore: path = QFileDialog::getSaveFileName(this, tr("Save EVSA store to file"), name + ".evsa", "EVSA store files (*.evsa *.bin);;All files (*)"); break; - case Types::FtwStore: path = QFileDialog::getSaveFileName(this, tr("Save FTW store to file"), name + ".ftw", "FTW store files (*.ftw *.bin);;All files (*)"); break; - case Types::FlashMapStore: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store to file"), name + ".fmap", "FlashMap store files (*.fmap *.bin);;All files (*)"); break; - case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save CMDB store to file"), name + ".cmdb", "CMDB store files (*.cmdb *.bin);;All files (*)"); break; - case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode binary to file"), name + ".ucd", "Microcode binary files (*.ucd *.bin);;All files (*)"); break; + case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", tr("Capsule files (*.cap *.bin);;All files (*)")); break; + case Types::Image: path = QFileDialog::getSaveFileName(this, tr("Save image to file"), name + ".rom", tr("Image files (*.rom *.bin);;All files (*)")); break; + case Types::Region: path = QFileDialog::getSaveFileName(this, tr("Save region to file"), name + ".rgn", tr("Region files (*.rgn *.bin);;All files (*)")); break; + case Types::Padding: path = QFileDialog::getSaveFileName(this, tr("Save padding to file"), name + ".pad", tr("Padding files (*.pad *.bin);;All files (*)")); break; + case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume to file"), name + ".vol", tr("Volume files (*.vol *.bin);;All files (*)")); break; + case Types::File: path = QFileDialog::getSaveFileName(this, tr("Save FFS file to file"), name + ".ffs", tr("FFS files (*.ffs *.bin);;All files (*)")); break; + case Types::Section: path = QFileDialog::getSaveFileName(this, tr("Save section to file"), name + ".sct", tr("Section files (*.sct *.bin);;All files (*)")); break; + case Types::NvarEntry: path = QFileDialog::getSaveFileName(this, tr("Save NVAR entry to file"), name + ".nvar", tr("NVAR entry files (*.nvar *.bin);;All files (*)")); break; + case Types::VssEntry: path = QFileDialog::getSaveFileName(this, tr("Save VSS entry to file"), name + ".vss", tr("VSS entry files (*.vss *.bin);;All files (*)")); break; + case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save Fsys entry to file"), name + ".fse", tr("Fsys entry files (*.fse *.bin);;All files (*)")); break; + case Types::EvsaEntry: path = QFileDialog::getSaveFileName(this, tr("Save EVSA entry to file"), name + ".evse", tr("EVSA entry files (*.evse *.bin);;All files (*)")); break; + case Types::FlashMapEntry: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap entry to file"), name + ".fme", tr("FlashMap entry files (*.fme *.bin);;All files (*)")); break; + case Types::VssStore: path = QFileDialog::getSaveFileName(this, tr("Save VSS store to file"), name + ".vss", tr("VSS store files (*.vss *.bin);;All files (*)")); break; + case Types::Vss2Store: path = QFileDialog::getSaveFileName(this, tr("Save VSS2 store to file"), name + ".vss2", tr("VSS2 store files (*.vss2 *.bin);;All files (*)")); break; + case Types::FdcStore: path = QFileDialog::getSaveFileName(this, tr("Save FDC store to file"), name + ".fdc", tr("FDC store files (*.fdc *.bin);;All files (*)")); break; + case Types::FsysStore: path = QFileDialog::getSaveFileName(this, tr("Save Fsys store to file"), name + ".fsys", tr("Fsys store files (*.fsys *.bin);;All files (*)")); break; + case Types::EvsaStore: path = QFileDialog::getSaveFileName(this, tr("Save EVSA store to file"), name + ".evsa", tr("EVSA store files (*.evsa *.bin);;All files (*)")); break; + case Types::FtwStore: path = QFileDialog::getSaveFileName(this, tr("Save FTW store to file"), name + ".ftw", tr("FTW store files (*.ftw *.bin);;All files (*)")); break; + case Types::FlashMapStore: path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store to file"), name + ".fmap", tr("FlashMap store files (*.fmap *.bin);;All files (*)")); break; + case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save CMDB store to file"), name + ".cmdb", tr("CMDB store files (*.cmdb *.bin);;All files (*)")); break; + case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode binary to file"), name + ".ucd", tr("Microcode binary files (*.ucd *.bin);;All files (*)")); break; case Types::SlicData: - if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey to file"), name + ".spk", "SLIC pubkey files (*.spk *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker to file"), name + ".smk", "SLIC marker files (*.smk *.bin);;All files (*)"); + if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey to file"), name + ".spk", tr("SLIC pubkey files (*.spk *.bin);;All files (*)")); + else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker to file"), name + ".smk", tr("SLIC marker files (*.smk *.bin);;All files (*)")); break; - default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); + default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); } } else if (mode == EXTRACT_MODE_BODY || mode == EXTRACT_MODE_BODY_UNCOMPRESSED) { switch (type) { - case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), name + ".rom", "Image files (*.rom *.bin);;All files (*)"); break; - case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", "Volume body files (*.vbd *.bin);;All files (*)"); break; + case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule body to image file"), name + ".rom", tr("Image files (*.rom *.bin);;All files (*)")); break; + case Types::Volume: path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", tr("Volume body files (*.vbd *.bin);;All files (*)")); break; case Types::File: if (subtype == EFI_FV_FILETYPE_ALL - || subtype == EFI_FV_FILETYPE_RAW) path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)"); + || subtype == EFI_FV_FILETYPE_RAW) path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to raw file"), name + ".raw", tr("Raw files (*.raw *.bin);;All files (*)")); + else path = QFileDialog::getSaveFileName(this, tr("Save FFS file body to file"), name + ".fbd", tr("FFS file body files (*.fbd *.bin);;All files (*)")); break; case Types::Section: if (subtype == EFI_SECTION_COMPRESSION || subtype == EFI_SECTION_GUID_DEFINED - || subtype == EFI_SECTION_DISPOSABLE) path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), name + ".fbd", "FFS file body files (*.fbd *.bin);;All files (*)"); - else if (subtype == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), name + ".vol", "Volume files (*.vol *.bin);;All files (*)"); - else if (subtype == EFI_SECTION_RAW) path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)"); + || subtype == EFI_SECTION_DISPOSABLE) path = QFileDialog::getSaveFileName(this, tr("Save encapsulation section body to FFS body file"), name + ".fbd", tr("FFS file body files (*.fbd *.bin);;All files (*)")); + else if (subtype == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) path = QFileDialog::getSaveFileName(this, tr("Save section body to volume file"), name + ".vol", tr("Volume files (*.vol *.bin);;All files (*)")); + else if (subtype == EFI_SECTION_RAW) path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), name + ".raw", tr("Raw files (*.raw *.bin);;All files (*)")); else if (subtype == EFI_SECTION_PE32 || subtype == EFI_SECTION_TE - || subtype == EFI_SECTION_PIC) path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", "EFI executable files (*.efi *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); + || subtype == EFI_SECTION_PIC) path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", tr("EFI executable files (*.efi *.bin);;All files (*)")); + else path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); break; case Types::NvarEntry: case Types::VssEntry: case Types::EvsaEntry: case Types::FlashMapEntry: - case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save entry body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); break; + case Types::FsysEntry: path = QFileDialog::getSaveFileName(this, tr("Save entry body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); break; case Types::VssStore: case Types::Vss2Store: case Types::FtwStore: case Types::FdcStore: case Types::FsysStore: case Types::FlashMapStore: - case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save store body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); break; - case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode body to file"), name + ".ucb", "Microcode body files (*.ucb *.bin);;All files (*)"); break; + case Types::CmdbStore: path = QFileDialog::getSaveFileName(this, tr("Save store body to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); break; + case Types::Microcode: path = QFileDialog::getSaveFileName(this, tr("Save microcode body to file"), name + ".ucb", tr("Microcode body files (*.ucb *.bin);;All files (*)")); break; case Types::SlicData: - if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey body to file"), name + ".spb", "SLIC pubkey body files (*.spb *.bin);;All files (*)"); - else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker body to file"), name + ".smb", "SLIC marker body files (*.smb *.bin);;All files (*)"); + if (subtype == Subtypes::PubkeySlicData) path = QFileDialog::getSaveFileName(this, tr("Save SLIC pubkey body to file"), name + ".spb", tr("SLIC pubkey body files (*.spb *.bin);;All files (*)")); + else path = QFileDialog::getSaveFileName(this, tr("Save SLIC marker body to file"), name + ".smb", tr("SLIC marker body files (*.smb *.bin);;All files (*)")); break; - default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); + default: path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); } } - else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); + else path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", tr("Binary files (*.bin);;All files (*)")); if (path.trimmed().isEmpty()) return; @@ -733,7 +727,7 @@ void UEFITool::remove() void UEFITool::about() { QMessageBox::about(this, tr("About UEFITool"), tr( - "Copyright (c) 2016, Nikolaj Schlej aka CodeRush.
" + "Copyright (c) 2018, LongSoft" "Program icon made by Alexander Zhidkov.
" "The program uses QHexEdit2 library made by Simsys.
" "Qt-less engine is using Bstrlib made by Paul Hsieh.

" @@ -757,7 +751,7 @@ void UEFITool::exit() void UEFITool::saveImageFile() { - /*QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *.scap *.bio *.fd *.wph *.dec);;All files (*)"); + /*QString path = QFileDialog::getSaveFileName(this, tr("Save BIOS image file"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *.scap *.bio *.fd *.wph *.dec);;All files (*)")); if (path.isEmpty()) return; @@ -790,13 +784,13 @@ void UEFITool::saveImageFile() void UEFITool::openImageFile() { - QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, "BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"); + QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)")); openImageFile(path); } void UEFITool::openImageFileInNewWindow() { - QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file in new window"), currentDir, "BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)"); + QString path = QFileDialog::getOpenFileName(this, tr("Open BIOS image file in new window"), currentDir, tr("BIOS image files (*.rom *.bin *.cap *scap *.bio *.fd *.wph *.dec);;All files (*)")); if (path.trimmed().isEmpty()) return; QProcess::startDetached(currentProgramPath, QStringList(path)); @@ -848,12 +842,18 @@ void UEFITool::openImageFile(QString path) // ... and other operations delete ffsOps; ffsOps = new FfsOperations(model); + // ... and reports + delete ffsReport; + ffsReport = new FfsReport(model); // Enable goToOffset and goToAddress ui->actionGoToOffset->setEnabled(true); if (ffsParser->getAddressDiff() < 0xFFFFFFFFUL) ui->actionGoToAddress->setEnabled(true); + // Enable generateReport + ui->actionGenerateReport->setEnabled(true); + // Set current directory currentDir = fileInfo.absolutePath(); @@ -1023,13 +1023,15 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event) return; } - if (!ui->structureTreeView->underMouse()) + if (!ui->structureTreeView->underMouse()) { return; + } QPoint pt = event->pos(); QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt)); - if (!index.isValid()) + if (!index.isValid()) { return; + } switch (model->type(index)) { @@ -1075,6 +1077,34 @@ void UEFITool::readSettings() ui->structureTreeView->setColumnWidth(2, settings.value("tree/columnWidth2", ui->structureTreeView->columnWidth(2)).toInt()); ui->structureTreeView->setColumnWidth(3, settings.value("tree/columnWidth3", ui->structureTreeView->columnWidth(3)).toInt()); markingEnabled = settings.value("tree/markingEnabled", true).toBool(); + ui->actionToggleBootGuardMarking->setChecked(markingEnabled); + + // Set monospace font for some controls + QString fontName; + int fontSize; +#if defined Q_OS_OSX + fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString(); + fontSize = settings.value("mainWindow/fontSize", 10).toInt(); +#elif defined Q_OS_WIN + fontName = settings.value("mainWindow/fontName", QString("Consolas")).toString(); + fontSize = settings.value("mainWindow/fontSize", 9).toInt(); +#else + fontName = settings.value("mainWindow/fontName", QString("Courier New")).toString(); + fontSize = settings.value("mainWindow/fontSize", 10).toInt(); +#endif + currentFont = QFont(fontName, fontSize); + ui->infoEdit->setFont(currentFont); + ui->parserMessagesListWidget->setFont(currentFont); + ui->finderMessagesListWidget->setFont(currentFont); + ui->builderMessagesListWidget->setFont(currentFont); + ui->fitTableWidget->setFont(currentFont); + ui->bootGuardEdit->setFont(currentFont); + ui->structureTreeView->setFont(currentFont); + searchDialog->ui->guidEdit->setFont(currentFont); + searchDialog->ui->hexEdit->setFont(currentFont); + hexViewDialog->setFont(currentFont); + goToOffsetDialog->ui->hexSpinBox->setFont(currentFont); + goToAddressDialog->ui->hexSpinBox->setFont(currentFont); } void UEFITool::writeSettings() @@ -1091,6 +1121,8 @@ void UEFITool::writeSettings() settings.setValue("tree/columnWidth2", ui->structureTreeView->columnWidth(2)); settings.setValue("tree/columnWidth3", ui->structureTreeView->columnWidth(3)); settings.setValue("tree/markingEnabled", markingEnabled); + settings.setValue("mainWindow/fontName", currentFont.family()); + settings.setValue("mainWindow/fontSize", currentFont.pointSize()); } void UEFITool::showFitTable() @@ -1155,10 +1187,44 @@ void UEFITool::currentTabChanged(int index) void UEFITool::loadGuidDatabase() { - QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, "GUID database files (*.gdb);;All files (*)"); + QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, tr("Comma-separated values files (*.csv);;All files (*)")); if (!path.isEmpty()) { initGuidDatabase(path); if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("New GUID database loaded"), tr("Apply new GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) openImageFile(currentPath); } } + +void UEFITool::unloadGuidDatabase() +{ + initGuidDatabase(); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("GUID database unloaded"), tr("Apply changes on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); +} + +void UEFITool::loadDefaultGuidDatabase() +{ + initGuidDatabase(":/guids.csv"); + if (!currentPath.isEmpty() && QMessageBox::Yes == QMessageBox::information(this, tr("Default GUID database loaded"), tr("Apply default GUID database on the opened file?\nUnsaved changes and tree position will be lost."), QMessageBox::Yes, QMessageBox::No)) + openImageFile(currentPath); +} + + + +void UEFITool::generateReport() +{ + QString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)")); + if (!path.isEmpty()) { + std::vector report = ffsReport->generate(); + if (report.size()) { + QFile file; + file.setFileName(path); + 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(); + } + } + } +} diff --git a/UEFITool/uefitool.h b/UEFITool/uefitool.h index dbc243e..ced3065 100644 --- a/UEFITool/uefitool.h +++ b/UEFITool/uefitool.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include "../common/ffsparser.h" #include "../common/ffsops.h" #include "../common/ffsbuilder.h" +#include "../common/ffsreport.h" #include "../common/guiddatabase.h" #include "searchdialog.h" @@ -115,6 +117,9 @@ private slots: void writeSettings(); void loadGuidDatabase(); + void unloadGuidDatabase(); + void loadDefaultGuidDatabase(); + void generateReport(); void currentTabChanged(int index); @@ -123,6 +128,7 @@ private: TreeModel* model; FfsParser* ffsParser; FfsFinder* ffsFinder; + FfsReport* ffsReport; FfsOperations* ffsOps; FfsBuilder* ffsBuilder; SearchDialog* searchDialog; @@ -133,6 +139,7 @@ private: QString currentDir; QString currentPath; QString currentProgramPath; + QFont currentFont; const QString version; bool markingEnabled; diff --git a/UEFITool/uefitool.pro b/UEFITool/uefitool.pro index 2acb10a..468aefa 100644 --- a/UEFITool/uefitool.pro +++ b/UEFITool/uefitool.pro @@ -32,6 +32,7 @@ HEADERS += uefitool.h \ ../common/parsingdata.h \ ../common/ffsbuilder.h \ ../common/ffsparser.h \ + ../common/ffsreport.h \ ../common/treeitem.h \ ../common/treemodel.h \ ../common/LZMA/LzmaCompress.h \ @@ -64,6 +65,7 @@ SOURCES += uefitool_main.cpp \ ../common/utility.cpp \ ../common/ffsbuilder.cpp \ ../common/ffsparser.cpp \ + ../common/ffsreport.cpp \ ../common/treeitem.cpp \ ../common/treemodel.cpp \ ../common/LZMA/LzmaCompress.c \ diff --git a/UEFITool/uefitool.ui b/UEFITool/uefitool.ui index 98142e5..6950a81 100644 --- a/UEFITool/uefitool.ui +++ b/UEFITool/uefitool.ui @@ -322,7 +322,11 @@ + + + + @@ -473,7 +477,7 @@ false - Entry + &Entry @@ -532,7 +536,7 @@ - + &View @@ -540,7 +544,7 @@ - + @@ -718,7 +722,7 @@ false - Sear&ch... + Searc&h... Ctrl+F @@ -867,12 +871,42 @@ true - &BootGuard marking + BootGuard &markings Ctrl+Shift+B + + + false + + + Generate &report... + + + Generate report + + + Ctrl+Alt+R + + + + + &Unload GUID database + + + Ctrl+Alt+U + + + + + Load &default GUID database + + + Ctrl+Alt+D + + diff --git a/UEFITool/uefitool_main.cpp b/UEFITool/uefitool_main.cpp index ca81d24..1b2df2a 100644 --- a/UEFITool/uefitool_main.cpp +++ b/UEFITool/uefitool_main.cpp @@ -1,6 +1,6 @@ /* uefitool_main.cpp - Copyright (c) 2014, Nikolaj Schlej. All rights reserved. + Copyright (c) 2018, LongSoft. 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 diff --git a/common/LZMA/LzmaCompress.c b/common/LZMA/LzmaCompress.c index f796cfd..c4411f3 100644 --- a/common/LZMA/LzmaCompress.c +++ b/common/LZMA/LzmaCompress.c @@ -25,8 +25,8 @@ static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma }; SRes OnProgress(void *p, UInt64 inSize, UInt64 outSize) { - (void)p; (void) inSize; (void) outSize; - return SZ_OK; + (void)p; (void)inSize; (void)outSize; + return SZ_OK; } static ICompressProgress g_ProgressCallback = { &OnProgress }; @@ -35,75 +35,76 @@ STATIC UINT64 EFIAPI RShiftU64( -UINT64 Operand, -UINT32 Count + UINT64 Operand, + UINT32 Count ) { - return Operand >> Count; + return Operand >> Count; } VOID SetEncodedSizeOfBuf( -UINT64 EncodedSize, -UINT8 *EncodedData + UINT64 EncodedSize, + UINT8* EncodedData ) { - INT32 Index; + INT32 Index; - EncodedData[LZMA_PROPS_SIZE] = EncodedSize & 0xFF; - for (Index = LZMA_PROPS_SIZE + 1; Index <= LZMA_PROPS_SIZE + 7; Index++) - { - EncodedSize = RShiftU64(EncodedSize, 8); - EncodedData[Index] = EncodedSize & 0xFF; - } + EncodedData[LZMA_PROPS_SIZE] = EncodedSize & 0xFF; + for (Index = LZMA_PROPS_SIZE + 1; Index <= LZMA_PROPS_SIZE + 7; Index++) + { + EncodedSize = RShiftU64(EncodedSize, 8); + EncodedData[Index] = EncodedSize & 0xFF; + } } INT32 EFIAPI LzmaCompress( -CONST UINT8 *Source, -UINT32 SourceSize, -UINT8 *Destination, -UINT32 *DestinationSize + CONST UINT8 *Source, + UINTN SourceSize, + UINT8 *Destination, + UINTN *DestinationSize ) { - SRes LzmaResult; - CLzmaEncProps props; - SizeT propsSize = LZMA_PROPS_SIZE; - SizeT destLen = SourceSize + SourceSize / 3 + 128; + SRes LzmaResult; + CLzmaEncProps props; + SizeT propsSize = LZMA_PROPS_SIZE; + SizeT destLen = SourceSize + SourceSize / 3 + 128; - if (*DestinationSize < destLen) - { - *DestinationSize = (UINT32)destLen; - return EFI_BUFFER_TOO_SMALL; - } + if (*DestinationSize < destLen) + { + *DestinationSize = destLen; + return EFI_BUFFER_TOO_SMALL; + } - LzmaEncProps_Init(&props); - props.dictSize = LZMA_DICTIONARY_SIZE; - props.level = 9; - props.fb = 273; + LzmaEncProps_Init(&props); + // TOOD: need to detect this instead of hardcoding + props.dictSize = LZMA_DICTIONARY_SIZE; + props.level = 9; + props.fb = 273; - LzmaResult = LzmaEncode( - (Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE), - &destLen, - Source, - SourceSize, - &props, - (UINT8*)Destination, - &propsSize, - props.writeEndMark, - &g_ProgressCallback, - &SzAllocForLzma, - &SzAllocForLzma); + LzmaResult = LzmaEncode( + (Byte*)((UINT8*)Destination + LZMA_HEADER_SIZE), + &destLen, + Source, + SourceSize, + &props, + (UINT8*)Destination, + &propsSize, + props.writeEndMark, + &g_ProgressCallback, + &SzAllocForLzma, + &SzAllocForLzma); - *DestinationSize = (UINT32)(destLen + LZMA_HEADER_SIZE); + *DestinationSize = destLen + LZMA_HEADER_SIZE; - SetEncodedSizeOfBuf((UINT64)SourceSize, Destination); + SetEncodedSizeOfBuf(SourceSize, Destination); - if (LzmaResult == SZ_OK) { - return EFI_SUCCESS; - } - else { - return EFI_INVALID_PARAMETER; - } + if (LzmaResult == SZ_OK) { + return EFI_SUCCESS; + } + else { + return EFI_INVALID_PARAMETER; + } } diff --git a/common/LZMA/LzmaCompress.h b/common/LZMA/LzmaCompress.h index eeadb5c..afed363 100644 --- a/common/LZMA/LzmaCompress.h +++ b/common/LZMA/LzmaCompress.h @@ -24,14 +24,14 @@ extern "C" { #define LZMA_DICTIONARY_SIZE 0x800000 #define _LZMA_SIZE_OPT - INT32 - EFIAPI - LzmaCompress( - const UINT8 *Source, - UINT32 SourceSize, - UINT8 *Destination, - UINT32 *DestinationSize - ); + INT32 + EFIAPI + LzmaCompress( + const UINT8 *Source, + UINTN SourceSize, + UINT8 *Destination, + UINTN *DestinationSize + ); #ifdef __cplusplus } diff --git a/common/LZMA/LzmaDecompress.c b/common/LZMA/LzmaDecompress.c index 1bac9d7..03a3799 100644 --- a/common/LZMA/LzmaDecompress.c +++ b/common/LZMA/LzmaDecompress.c @@ -89,17 +89,13 @@ INT32 EFIAPI LzmaGetInfo( CONST VOID *Source, -UINT32 SourceSize, -UINT32 *DestinationSize +UINTN SourceSize, +UINTN *DestinationSize ) { - UInt64 DecodedSize; - ASSERT(SourceSize >= LZMA_HEADER_SIZE); (void)SourceSize; - - DecodedSize = GetDecodedSizeOfBuf((UINT8*)Source); - *DestinationSize = (UINT32)DecodedSize; + *DestinationSize = (UINTN)GetDecodedSizeOfBuf((UINT8*)Source); return U_SUCCESS; } @@ -126,8 +122,8 @@ INT32 EFIAPI LzmaDecompress( CONST VOID *Source, -UINT32 SourceSize, -VOID *Destination +UINTN SourceSize, +VOID *Destination ) { SRes LzmaResult; diff --git a/common/Tiano/EfiTianoCompress.c b/common/Tiano/EfiTianoCompress.c index a2fe4bf..afd2ec2 100644 --- a/common/Tiano/EfiTianoCompress.c +++ b/common/Tiano/EfiTianoCompress.c @@ -69,18 +69,15 @@ PutDword( STATIC EFI_STATUS -AllocateMemory ( - ); +AllocateMemory (VOID); STATIC VOID -FreeMemory ( - ); +FreeMemory (VOID); STATIC VOID -InitSlide ( - ); +InitSlide (VOID); STATIC NODE @@ -105,28 +102,23 @@ Split ( STATIC VOID -InsertNode ( - ); +InsertNode (VOID); STATIC VOID -DeleteNode ( - ); +DeleteNode (VOID); STATIC VOID -GetNextMatch ( - ); +GetNextMatch (VOID); STATIC EFI_STATUS -Encode ( - ); +Encode (VOID); STATIC VOID -CountTFreq ( - ); +CountTFreq (VOID); STATIC VOID @@ -138,8 +130,7 @@ WritePTLen ( STATIC VOID -WriteCLen ( - ); +WriteCLen (VOID); STATIC VOID @@ -155,8 +146,7 @@ EncodeP ( STATIC VOID -SendBlock ( - ); +SendBlock (VOID); STATIC VOID @@ -167,18 +157,15 @@ Output ( STATIC VOID -HufEncodeStart ( - ); +HufEncodeStart (VOID); STATIC VOID -HufEncodeEnd ( - ); +HufEncodeEnd (VOID); STATIC VOID -MakeCrcTable ( - ); +MakeCrcTable (VOID); STATIC VOID @@ -196,8 +183,7 @@ FreadCrc ( STATIC VOID -InitPutBits ( - ); +InitPutBits (VOID); STATIC VOID diff --git a/common/descriptor.cpp b/common/descriptor.cpp index 93afabe..7f072b7 100644 --- a/common/descriptor.cpp +++ b/common/descriptor.cpp @@ -25,13 +25,13 @@ const UINT8* calculateAddress16(const UINT8* baseAddress, const UINT16 baseOrLim return baseAddress + baseOrLimit * 0x1000; } -// Calculate offset of region using it's base +// Calculate offset of region using its base UINT32 calculateRegionOffset(const UINT16 base) { return base * 0x1000; } -//Calculate size of region using it's base and limit +//Calculate size of region using its base and limit UINT32 calculateRegionSize(const UINT16 base, const UINT16 limit) { if (limit) diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index 9210183..c548156 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -1,6 +1,6 @@ /* ffsparser.cpp -Copyright (c) 2016, Nikolaj Schlej. All rights reserved. +Copyright (c) 2018, 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 @@ -51,7 +51,7 @@ struct REGION_INFO { // Constructor FfsParser::FfsParser(TreeModel* treeModel) : model(treeModel), -capsuleOffsetFixup(0), addressDiff(0x100000000ULL), +imageBase(0), addressDiff(0x100000000ULL), bgAcmFound(false), bgKeyManifestFound(false), bgBootPolicyFound(false), bgFirstVolumeOffset(0x100000000ULL) { nvramParser = new NvramParser(treeModel, this); meParser = new MeParser(treeModel); @@ -81,222 +81,241 @@ USTATUS FfsParser::parse(const UByteArray & buffer) openedImage = buffer; USTATUS result = performFirstPass(buffer, root); addOffsetsRecursive(root); - if (result) + if (result) { return result; + } - if (lastVtf.isValid()) + if (lastVtf.isValid()) { result = performSecondPass(root); - else - msg(UString("parse: not a single Volume Top File is found, the image may be corrupted")); - + } + else { + msg(usprintf("%s: not a single Volume Top File is found, the image may be corrupted", __FUNCTION__)); + } + return result; } USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & index) { - // Reset capsule offset fixup value - capsuleOffsetFixup = 0; + // Sanity check + if (buffer.isEmpty()) { + return EFI_INVALID_PARAMETER; + } + // Try parsing as UEFI Capsule + USTATUS result = parseCapsule(buffer, index); + if (result != U_ITEM_NOT_FOUND) { + return result; + } + + // Try parsing as Intel image + result = parseIntelImage(buffer, 0, UModelIndex(), index); + if (result != U_ITEM_NOT_FOUND) { + return result; + } + + // Parse as generic image + return parseGenericImage(buffer, 0, UModelIndex(), index); +} + +USTATUS FfsParser::parseGenericImage(const UByteArray & buffer, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) +{ + // Parse as generic UEFI image + UString name("UEFI image"); + UString info = usprintf("Full size: %Xh (%u)", buffer.size(), buffer.size()); + + // Add tree item + index = model->addItem(model->offset(parent) + localOffset, Types::Image, Subtypes::UefiImage, name, UString(), info, UByteArray(), buffer, UByteArray(), Fixed, parent); + + // Parse the image as raw area + return parseRawArea(index); +} + +USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index) +{ // Check buffer size to be more than or equal to size of EFI_CAPSULE_HEADER - if ((UINT32)buffer.size() <= sizeof(EFI_CAPSULE_HEADER)) { - msg(UString("performFirstPass: image file is smaller than minimum size of 1Ch (28) bytes")); - return U_INVALID_PARAMETER; + if ((UINT32)capsule.size() < sizeof(EFI_CAPSULE_HEADER)) { + return U_ITEM_NOT_FOUND; } UINT32 capsuleHeaderSize = 0; // Check buffer for being normal EFI capsule header - if (buffer.startsWith(EFI_CAPSULE_GUID) - || buffer.startsWith(INTEL_CAPSULE_GUID) - || buffer.startsWith(LENOVO_CAPSULE_GUID) - || buffer.startsWith(LENOVO2_CAPSULE_GUID)) { + if (capsule.startsWith(EFI_CAPSULE_GUID) + || capsule.startsWith(INTEL_CAPSULE_GUID) + || capsule.startsWith(LENOVO_CAPSULE_GUID) + || capsule.startsWith(LENOVO2_CAPSULE_GUID)) { // Get info - const EFI_CAPSULE_HEADER* capsuleHeader = (const EFI_CAPSULE_HEADER*)buffer.constData(); + const EFI_CAPSULE_HEADER* capsuleHeader = (const EFI_CAPSULE_HEADER*)capsule.constData(); // Check sanity of HeaderSize and CapsuleImageSize values - if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)buffer.size() || capsuleHeader->HeaderSize > capsuleHeader->CapsuleImageSize) { - msg(usprintf("performFirstPass: UEFI capsule header size of %Xh (%u) bytes is invalid", - capsuleHeader->HeaderSize, - capsuleHeader->HeaderSize)); + if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)capsule.size() + || capsuleHeader->HeaderSize > capsuleHeader->CapsuleImageSize) { + msg(usprintf("%s: UEFI capsule header size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->HeaderSize, + capsuleHeader->HeaderSize)); return U_INVALID_CAPSULE; } - if (capsuleHeader->CapsuleImageSize == 0 || capsuleHeader->CapsuleImageSize > (UINT32)buffer.size()) { - msg(usprintf("performFirstPass: UEFI capsule image size of %Xh (%u) bytes is invalid", - capsuleHeader->CapsuleImageSize, - capsuleHeader->CapsuleImageSize)); + if (capsuleHeader->CapsuleImageSize == 0 || capsuleHeader->CapsuleImageSize > (UINT32)capsule.size()) { + msg(usprintf("%s: UEFI capsule image size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->CapsuleImageSize, + capsuleHeader->CapsuleImageSize)); return U_INVALID_CAPSULE; } capsuleHeaderSize = capsuleHeader->HeaderSize; - UByteArray header = buffer.left(capsuleHeaderSize); - UByteArray body = buffer.mid(capsuleHeaderSize); + UByteArray header = capsule.left(capsuleHeaderSize); + UByteArray body = capsule.mid(capsuleHeaderSize); UString name("UEFI capsule"); - UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", - buffer.size(), buffer.size(), - capsuleHeaderSize, capsuleHeaderSize, - capsuleHeader->CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleImageSize - capsuleHeaderSize, - capsuleHeader->Flags); - - // Set capsule offset fixup for correct volume allignment warnings - capsuleOffsetFixup = capsuleHeaderSize; + UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", + capsule.size(), capsule.size(), + capsuleHeaderSize, capsuleHeaderSize, + capsuleHeader->CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleImageSize - capsuleHeaderSize, + capsuleHeader->Flags); // Add tree item index = model->addItem(0, Types::Capsule, Subtypes::UefiCapsule, name, UString(), info, header, body, UByteArray(), Fixed); } // Check buffer for being Toshiba capsule header - else if (buffer.startsWith(TOSHIBA_CAPSULE_GUID)) { + else if (capsule.startsWith(TOSHIBA_CAPSULE_GUID)) { // Get info - const TOSHIBA_CAPSULE_HEADER* capsuleHeader = (const TOSHIBA_CAPSULE_HEADER*)buffer.constData(); + const TOSHIBA_CAPSULE_HEADER* capsuleHeader = (const TOSHIBA_CAPSULE_HEADER*)capsule.constData(); // Check sanity of HeaderSize and FullSize values - if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)buffer.size() || capsuleHeader->HeaderSize > capsuleHeader->FullSize) { - msg(usprintf("performFirstPass: Toshiba capsule header size of %Xh (%u) bytes is invalid", - capsuleHeader->HeaderSize, capsuleHeader->HeaderSize)); + if (capsuleHeader->HeaderSize == 0 || capsuleHeader->HeaderSize > (UINT32)capsule.size() + || capsuleHeader->HeaderSize > capsuleHeader->FullSize) { + msg(usprintf("%s: Toshiba capsule header size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->HeaderSize, capsuleHeader->HeaderSize)); return U_INVALID_CAPSULE; } - if (capsuleHeader->FullSize == 0 || capsuleHeader->FullSize > (UINT32)buffer.size()) { - msg(usprintf("performFirstPass: Toshiba capsule full size of %Xh (%u) bytes is invalid", - capsuleHeader->FullSize, capsuleHeader->FullSize)); + if (capsuleHeader->FullSize == 0 || capsuleHeader->FullSize > (UINT32)capsule.size()) { + msg(usprintf("%s: Toshiba capsule full size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->FullSize, capsuleHeader->FullSize)); return U_INVALID_CAPSULE; } capsuleHeaderSize = capsuleHeader->HeaderSize; - UByteArray header = buffer.left(capsuleHeaderSize); - UByteArray body = buffer.mid(capsuleHeaderSize); + UByteArray header = capsule.left(capsuleHeaderSize); + UByteArray body = capsule.mid(capsuleHeaderSize); UString name("Toshiba capsule"); - UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", - buffer.size(), buffer.size(), - capsuleHeaderSize, capsuleHeaderSize, - capsuleHeader->FullSize - capsuleHeaderSize, capsuleHeader->FullSize - capsuleHeaderSize, - capsuleHeader->Flags); - - // Set capsule offset fixup for correct volume allignment warnings - capsuleOffsetFixup = capsuleHeaderSize; + UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleGuid, false) + + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", + capsule.size(), capsule.size(), + capsuleHeaderSize, capsuleHeaderSize, + capsuleHeader->FullSize - capsuleHeaderSize, capsuleHeader->FullSize - capsuleHeaderSize, + capsuleHeader->Flags); // Add tree item index = model->addItem(0, Types::Capsule, Subtypes::ToshibaCapsule, name, UString(), info, header, body, UByteArray(), Fixed); } // Check buffer for being extended Aptio capsule header - else if (buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID) || buffer.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) { - bool signedCapsule = buffer.startsWith(APTIO_SIGNED_CAPSULE_GUID); + else if (capsule.startsWith(APTIO_SIGNED_CAPSULE_GUID) + || capsule.startsWith(APTIO_UNSIGNED_CAPSULE_GUID)) { + bool signedCapsule = capsule.startsWith(APTIO_SIGNED_CAPSULE_GUID); - if ((UINT32)buffer.size() <= sizeof(APTIO_CAPSULE_HEADER)) { - msg(UString("performFirstPass: AMI capsule image file is smaller than minimum size of 20h (32) bytes")); - return U_INVALID_PARAMETER; + if ((UINT32)capsule.size() <= sizeof(APTIO_CAPSULE_HEADER)) { + msg(usprintf("%s: AMI capsule image file is smaller than minimum size of 20h (32) bytes", __FUNCTION__)); + return U_INVALID_CAPSULE; } // Get info - const APTIO_CAPSULE_HEADER* capsuleHeader = (const APTIO_CAPSULE_HEADER*)buffer.constData(); + const APTIO_CAPSULE_HEADER* capsuleHeader = (const APTIO_CAPSULE_HEADER*)capsule.constData(); // Check sanity of RomImageOffset and CapsuleImageSize values - if (capsuleHeader->RomImageOffset == 0 || capsuleHeader->RomImageOffset > (UINT32)buffer.size() || capsuleHeader->RomImageOffset > capsuleHeader->CapsuleHeader.CapsuleImageSize) { - msg(usprintf("performFirstPass: AMI capsule image offset of %Xh (%u) bytes is invalid", - capsuleHeader->RomImageOffset, capsuleHeader->RomImageOffset)); + if (capsuleHeader->RomImageOffset == 0 || capsuleHeader->RomImageOffset > (UINT32)capsule.size() + || capsuleHeader->RomImageOffset > capsuleHeader->CapsuleHeader.CapsuleImageSize) { + msg(usprintf("%s: AMI capsule image offset of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->RomImageOffset, capsuleHeader->RomImageOffset)); return U_INVALID_CAPSULE; } - if (capsuleHeader->CapsuleHeader.CapsuleImageSize == 0 || capsuleHeader->CapsuleHeader.CapsuleImageSize > (UINT32)buffer.size()) { - msg(usprintf("performFirstPass: AMI capsule image size of %Xh (%u) bytes is invalid", - capsuleHeader->CapsuleHeader.CapsuleImageSize, - capsuleHeader->CapsuleHeader.CapsuleImageSize)); + if (capsuleHeader->CapsuleHeader.CapsuleImageSize == 0 + || capsuleHeader->CapsuleHeader.CapsuleImageSize > (UINT32)capsule.size()) { + msg(usprintf("%s: AMI capsule image size of %Xh (%u) bytes is invalid", __FUNCTION__, + capsuleHeader->CapsuleHeader.CapsuleImageSize, + capsuleHeader->CapsuleHeader.CapsuleImageSize)); return U_INVALID_CAPSULE; } capsuleHeaderSize = capsuleHeader->RomImageOffset; - UByteArray header = buffer.left(capsuleHeaderSize); - UByteArray body = buffer.mid(capsuleHeaderSize); + UByteArray header = capsule.left(capsuleHeaderSize); + UByteArray body = capsule.mid(capsuleHeaderSize); UString name("AMI Aptio capsule"); UString info = UString("Capsule GUID: ") + guidToUString(capsuleHeader->CapsuleHeader.CapsuleGuid, false) + - usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", - buffer.size(), buffer.size(), - capsuleHeaderSize, capsuleHeaderSize, - capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, - capsuleHeader->CapsuleHeader.Flags); - - // Set capsule offset fixup for correct volume allignment warnings - capsuleOffsetFixup = capsuleHeaderSize; + usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nImage size: %Xh (%u)\nFlags: %08Xh", + capsule.size(), capsule.size(), + capsuleHeaderSize, capsuleHeaderSize, + capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, capsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, + capsuleHeader->CapsuleHeader.Flags); // Add tree item index = model->addItem(0, Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, UString(), info, header, body, UByteArray(), Fixed); // Show message about possible Aptio signature break if (signedCapsule) { - msg(UString("performFirstPass: Aptio capsule signature may become invalid after image modifications"), index); + msg(usprintf("%s: Aptio capsule signature may become invalid after image modifications", __FUNCTION__), index); } } - // Skip capsule header to have flash chip image - UByteArray flashImage = buffer.mid(capsuleHeaderSize); + // Capsule present + if (capsuleHeaderSize > 0) { + // Set imageBase for proper alignment calculation + imageBase = capsuleHeaderSize; - // Check for Intel flash descriptor presence - const FLASH_DESCRIPTOR_HEADER* descriptorHeader = (const FLASH_DESCRIPTOR_HEADER*)flashImage.constData(); - - // Check descriptor signature - USTATUS result; - if (descriptorHeader->Signature == FLASH_DESCRIPTOR_SIGNATURE) { - // Parse as Intel image + UByteArray image = capsule.mid(capsuleHeaderSize); UModelIndex imageIndex; - result = parseIntelImage(flashImage, capsuleOffsetFixup, index, imageIndex); - if (result != U_INVALID_FLASH_DESCRIPTOR) { - if (!index.isValid()) { - index = imageIndex; - } + + // Try parsing as Intel image + USTATUS result = parseIntelImage(image, capsuleHeaderSize, index, imageIndex); + if (result != U_ITEM_NOT_FOUND) { return result; } + + // Parse as generic image + return parseGenericImage(image, capsuleHeaderSize, index, imageIndex); } - // Get info - UString name("UEFI image"); - UString info = usprintf("Full size: %Xh (%u)", flashImage.size(), flashImage.size()); - - // Add tree item - UModelIndex biosIndex = model->addItem(capsuleOffsetFixup, Types::Image, Subtypes::UefiImage, name, UString(), info, UByteArray(), flashImage, UByteArray(), Fixed, index); - - // Parse the image - result = parseRawArea(biosIndex); - if (!index.isValid()) - index = biosIndex; - return result; + return U_ITEM_NOT_FOUND; } USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { - // Sanity check - if (intelImage.isEmpty()) - return EFI_INVALID_PARAMETER; - - // Store the beginning of descriptor as descriptor base address - const UINT8* descriptor = (const UINT8*)intelImage.constData(); - // Check for buffer size to be greater or equal to descriptor region size if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) { - msg(usprintf("parseIntelImage: input file is smaller than minimum descriptor size of %Xh (%u) bytes", FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE)); - return U_INVALID_FLASH_DESCRIPTOR; + msg(usprintf("%s: input file is smaller than minimum descriptor size of %Xh (%u) bytes", __FUNCTION__, FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE)); + return U_ITEM_NOT_FOUND; + } + + // Store the beginning of descriptor as descriptor base address + const FLASH_DESCRIPTOR_HEADER* descriptor = (const FLASH_DESCRIPTOR_HEADER*)intelImage.constData(); + + // Check descriptor signature + if (descriptor->Signature != FLASH_DESCRIPTOR_SIGNATURE) { + return U_ITEM_NOT_FOUND; } // Parse descriptor map - const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); - const FLASH_DESCRIPTOR_UPPER_MAP* upperMap = (const FLASH_DESCRIPTOR_UPPER_MAP*)(descriptor + FLASH_DESCRIPTOR_UPPER_MAP_BASE); + const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)((UINT8*)descriptor + sizeof(FLASH_DESCRIPTOR_HEADER)); + const FLASH_DESCRIPTOR_UPPER_MAP* upperMap = (const FLASH_DESCRIPTOR_UPPER_MAP*)((UINT8*)descriptor + FLASH_DESCRIPTOR_UPPER_MAP_BASE); // Check sanity of base values if (descriptorMap->MasterBase > FLASH_DESCRIPTOR_MAX_BASE || descriptorMap->MasterBase == descriptorMap->RegionBase || descriptorMap->MasterBase == descriptorMap->ComponentBase) { - msg(usprintf("parseIntelImage: invalid descriptor master base %02Xh", descriptorMap->MasterBase)); + msg(usprintf("%s: invalid descriptor master base %02Xh", __FUNCTION__, descriptorMap->MasterBase)); return U_INVALID_FLASH_DESCRIPTOR; } if (descriptorMap->RegionBase > FLASH_DESCRIPTOR_MAX_BASE || descriptorMap->RegionBase == descriptorMap->ComponentBase) { - msg(usprintf("parseIntelImage: invalid descriptor region base %02Xh", descriptorMap->RegionBase)); + msg(usprintf("%s: invalid descriptor region base %02Xh", __FUNCTION__, descriptorMap->RegionBase)); return U_INVALID_FLASH_DESCRIPTOR; } if (descriptorMap->ComponentBase > FLASH_DESCRIPTOR_MAX_BASE) { - msg(usprintf("parseIntelImage: invalid descriptor component base %02Xh", descriptorMap->ComponentBase)); + msg(usprintf("%s: invalid descriptor component base %02Xh", __FUNCTION__, descriptorMap->ComponentBase)); return U_INVALID_FLASH_DESCRIPTOR; } - const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8(descriptor, descriptorMap->RegionBase); - const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8(descriptor, descriptorMap->ComponentBase); + const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8((UINT8*)descriptor, descriptorMap->RegionBase); + const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8((UINT8*)descriptor, descriptorMap->ComponentBase); // Check descriptor version by getting hardcoded value of FlashParameters.ReadClockFrequency UINT8 descriptorVersion = 0; @@ -330,7 +349,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l // Check for Gigabyte specific descriptor map if (bios.length == (UINT32)intelImage.size()) { if (!me.offset) { - msg(UString("parseIntelImage: can't determine BIOS region start from Gigabyte-specific descriptor")); + msg(usprintf("%s: can't determine BIOS region start from Gigabyte-specific descriptor", __FUNCTION__)); return U_INVALID_FLASH_DESCRIPTOR; } // Use ME region end as BIOS region offset @@ -346,7 +365,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l regions.push_back(bios); } else { - msg(UString("parseIntelImage: descriptor parsing failed, BIOS region not found in descriptor")); + msg(usprintf("%s: descriptor parsing failed, BIOS region not found in descriptor", __FUNCTION__)); return U_INVALID_FLASH_DESCRIPTOR; } @@ -376,7 +395,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l REGION_INFO region; // Check intersection with the descriptor if (regions.front().offset < FLASH_DESCRIPTOR_SIZE) { - msg(UString("parseIntelImage: ") + itemSubtypeToUString(Types::Region, regions.front().type) + msg(usprintf("%s: ", __FUNCTION__) + itemSubtypeToUString(Types::Region, regions.front().type) + UString(" region has intersection with flash descriptor"), index); return U_INVALID_FLASH_DESCRIPTOR; @@ -394,7 +413,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l UINT32 previousRegionEnd = regions[i-1].offset + regions[i-1].length; // Check that current region is fully present in the image if ((UINT64)regions[i].offset + (UINT64)regions[i].length > (UINT64)intelImage.size()) { - msg(UString("parseIntelImage: ") + itemSubtypeToUString(Types::Region, regions[i].type) + msg(usprintf("%s: ", __FUNCTION__) + itemSubtypeToUString(Types::Region, regions[i].type) + UString(" region is located outside of the opened image. If your system uses dual-chip storage, please append another part to the opened image"), index); return U_TRUNCATED_IMAGE; @@ -402,7 +421,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l // Check for intersection with previous region if (regions[i].offset < previousRegionEnd) { - msg(UString("parseIntelImage: ") + itemSubtypeToUString(Types::Region, regions[i].type) + msg(usprintf("%s: ", __FUNCTION__) + itemSubtypeToUString(Types::Region, regions[i].type) + UString(" region has intersection with ") + itemSubtypeToUString(Types::Region, regions[i - 1].type) +UString(" region"), index); return U_INVALID_FLASH_DESCRIPTOR; @@ -440,13 +459,19 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l descriptorMap->NumberOfProcStraps); // Add Intel image tree item - index = model->addItem(localOffset, Types::Image, Subtypes::IntelImage, name, UString(), info, UByteArray(), intelImage, UByteArray(), Fixed, parent); + index = model->addItem(model->offset(parent) + localOffset, Types::Image, Subtypes::IntelImage, name, UString(), info, UByteArray(), intelImage, UByteArray(), Fixed, parent); // Descriptor // Get descriptor info UByteArray body = intelImage.left(FLASH_DESCRIPTOR_SIZE); name = UString("Descriptor region"); - info = usprintf("Full size: %Xh (%u)", FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE); + info = usprintf("ReservedVector:\n%02X %02X %02X %02X %02X %02X %02X %02X\n" + "%02X %02X %02X %02X %02X %02X %02X %02X\nFull size: %Xh (%u)", + descriptor->ReservedVector[0], descriptor->ReservedVector[1], descriptor->ReservedVector[2], descriptor->ReservedVector[3], + descriptor->ReservedVector[4], descriptor->ReservedVector[5], descriptor->ReservedVector[6], descriptor->ReservedVector[7], + descriptor->ReservedVector[8], descriptor->ReservedVector[9], descriptor->ReservedVector[10], descriptor->ReservedVector[11], + descriptor->ReservedVector[12], descriptor->ReservedVector[13], descriptor->ReservedVector[14], descriptor->ReservedVector[15], + FLASH_DESCRIPTOR_SIZE, FLASH_DESCRIPTOR_SIZE); // Add offsets of actual regions for (size_t i = 0; i < regions.size(); i++) { @@ -457,7 +482,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l // Region access settings if (descriptorVersion == 1) { - const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8(descriptor, descriptorMap->MasterBase); + const FLASH_DESCRIPTOR_MASTER_SECTION* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION*)calculateAddress8((UINT8*)descriptor, descriptorMap->MasterBase); info += UString("\nRegion access settings:"); info += usprintf("\nBIOS: %02Xh %02Xh ME: %02Xh %02Xh\nGbE: %02Xh %02Xh", masterSection->BiosRead, @@ -481,7 +506,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l masterSection->BiosWrite & FLASH_DESCRIPTOR_REGION_ACCESS_PDR ? "Yes " : "No "); } else if (descriptorVersion == 2) { - const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8(descriptor, descriptorMap->MasterBase); + const FLASH_DESCRIPTOR_MASTER_SECTION_V2* masterSection = (const FLASH_DESCRIPTOR_MASTER_SECTION_V2*)calculateAddress8((UINT8*)descriptor, descriptorMap->MasterBase); info += UString("\nRegion access settings:"); info += usprintf("\nBIOS: %03Xh %03Xh ME: %03Xh %03Xh\nGbE: %03Xh %03Xh EC: %03Xh %03Xh", masterSection->BiosRead, @@ -515,7 +540,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l } // VSCC table - const VSCC_TABLE_ENTRY* vsccTableEntry = (const VSCC_TABLE_ENTRY*)(descriptor + ((UINT16)upperMap->VsccTableBase << 4)); + const VSCC_TABLE_ENTRY* vsccTableEntry = (const VSCC_TABLE_ENTRY*)((UINT8*)descriptor + ((UINT16)upperMap->VsccTableBase << 4)); info += UString("\nFlash chips in VSCC table:"); UINT8 vsscTableSize = upperMap->VsccTableSize * sizeof(UINT32) / sizeof(VSCC_TABLE_ENTRY); for (UINT8 i = 0; i < vsscTableSize; i++) { @@ -524,13 +549,14 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l + jedecId + UString(")"); if (jedecId == UString("Unknown")) { - msg(usprintf("SPI flash with unknown JEDEC ID %02X%02X%02X found in VSCC table", vsccTableEntry->VendorId, vsccTableEntry->DeviceId0, vsccTableEntry->DeviceId1), index); + msg(usprintf("%s: SPI flash with unknown JEDEC ID %02X%02X%02X found in VSCC table", __FUNCTION__, + vsccTableEntry->VendorId, vsccTableEntry->DeviceId0, vsccTableEntry->DeviceId1), index); } vsccTableEntry++; } // Add descriptor tree item - UModelIndex regionIndex = model->addItem(localOffset, Types::Region, Subtypes::DescriptorRegion, name, UString(), info, UByteArray(), body, UByteArray(), Fixed, index); + UModelIndex regionIndex = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::DescriptorRegion, name, UString(), info, UByteArray(), body, UByteArray(), Fixed, index); // Parse regions UINT8 result = U_SUCCESS; @@ -575,11 +601,11 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l padding.size(), padding.size()); // Add tree item - regionIndex = model->addItem(localOffset + region.offset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); + regionIndex = model->addItem(model->offset(parent) + region.offset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); result = U_SUCCESS; } break; default: - msg(UString("parseIntelImage: region of unknown type found"), index); + msg(usprintf("%s: region of unknown type found", __FUNCTION__), index); result = U_INVALID_FLASH_DESCRIPTOR; } // Store the first failed result as a final result @@ -667,10 +693,10 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset // Show messages if (emptyRegion) { - msg(UString("parseMeRegion: ME region is empty"), index); + msg(usprintf("%s: ME region is empty", __FUNCTION__), index); } else if (!versionFound) { - msg(UString("parseMeRegion: ME version is unknown, it can be damaged"), index); + msg(usprintf("%s: ME version is unknown, it can be damaged", __FUNCTION__), index); } else { meParser->parseMeRegionBody(index); @@ -794,7 +820,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index) UINT32 bmVolumeSize = 0; result = getVolumeSize(data, volumeOffset, volumeSize, bmVolumeSize); if (result) { - msg(UString("parseRawArea: getVolumeSize failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: getVolumeSize failed with error ", __FUNCTION__) + errorCodeToUString(result), index); return result; } @@ -809,7 +835,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index) // Add tree item UModelIndex paddingIndex = model->addItem(offset + volumeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); - msg(UString("parseRawArea: one of volumes inside overlaps the end of data"), paddingIndex); + msg(usprintf("%s: one of volumes inside overlaps the end of data", __FUNCTION__), paddingIndex); // Update variables prevVolumeOffset = volumeOffset; @@ -821,12 +847,12 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index) UModelIndex volumeIndex; UByteArray volume = data.mid(volumeOffset, volumeSize); result = parseVolumeHeader(volume, headerSize + volumeOffset, index, volumeIndex); - if (result) - msg(UString("parseRawArea: volume header parsing failed with error ") + errorCodeToUString(result), index); - else { + if (result) { + msg(usprintf("%s: volume header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + } else { // Show messages if (volumeSize != bmVolumeSize) - msg(usprintf("parseRawArea: volume size stored in header %Xh differs from calculated using block map %Xh", + msg(usprintf("%s: volume size stored in header %Xh differs from calculated using block map %Xh", __FUNCTION__, volumeSize, bmVolumeSize), volumeIndex); } @@ -876,7 +902,7 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc // Check that there is space for the volume header if ((UINT32)volume.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) { - msg(usprintf("parseVolumeHeader: input volume size %Xh (%u) is smaller than volume header size 40h (64)", volume.size(), volume.size())); + msg(usprintf("%s: input volume size %Xh (%u) is smaller than volume header size 40h (64)", __FUNCTION__, volume.size(), volume.size())); return U_INVALID_VOLUME; } @@ -885,13 +911,13 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc // Check sanity of HeaderLength value if ((UINT32)ALIGN8(volumeHeader->HeaderLength) > (UINT32)volume.size()) { - msg(UString("parseVolumeHeader: volume header overlaps the end of data")); + msg(usprintf("%s: volume header overlaps the end of data", __FUNCTION__)); return U_INVALID_VOLUME; } // Check sanity of ExtHeaderOffset value if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset && (UINT32)ALIGN8(volumeHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER)) > (UINT32)volume.size()) { - msg(UString("parseVolumeHeader: extended volume header overlaps the end of data")); + msg(usprintf("%s: extended volume header overlaps the end of data", __FUNCTION__)); return U_INVALID_VOLUME; } @@ -939,7 +965,7 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc bool msgAlignmentBitsSet = false; bool msgUnaligned = false; bool msgUnknownRevision = false; - UINT32 alignment = 65536; // Default volume alignment is 64K + UINT32 alignment = 0x10000; // Default volume alignment is 64K if (volumeHeader->Revision == 1) { // Acquire alignment capability bit bool alignmentCap = (volumeHeader->Attributes & EFI_FVB_ALIGNMENT_CAP) != 0; @@ -954,11 +980,12 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc // Acquire alignment alignment = (UINT32)(1UL << ((volumeHeader->Attributes & EFI_FVB2_ALIGNMENT) >> 16)); // Check alignment - if (!isUnknown && !model->compressed(parent) && ((model->offset(parent) + localOffset - capsuleOffsetFixup) % alignment)) + if (!isUnknown && !model->compressed(parent) && ((model->offset(parent) + localOffset - imageBase) % alignment)) msgUnaligned = true; } - else + else { msgUnknownRevision = true; + } // Check attributes // Determine value of empty byte @@ -1047,20 +1074,20 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc // Show messages if (isUnknown) - msg(UString("parseVolumeHeader: unknown file system ") + guidToUString(volumeHeader->FileSystemGuid), index); + msg(usprintf("%s: unknown file system ", __FUNCTION__) + guidToUString(volumeHeader->FileSystemGuid), index); if (msgInvalidChecksum) - msg(UString("parseVolumeHeader: volume header checksum is invalid"), index); + msg(usprintf("%s: volume header checksum is invalid", __FUNCTION__), index); if (msgAlignmentBitsSet) - msg(UString("parseVolumeHeader: alignment bits set on volume without alignment capability"), index); + msg(usprintf("%s: alignment bits set on volume without alignment capability", __FUNCTION__), index); if (msgUnaligned) - msg(UString("parseVolumeHeader: unaligned volume"), index); + msg(usprintf("%s: unaligned volume", __FUNCTION__), index); if (msgUnknownRevision) - msg(usprintf("parseVolumeHeader: unknown volume revision %u", volumeHeader->Revision), index); + msg(usprintf("%s: unknown volume revision %u", __FUNCTION__, volumeHeader->Revision), index); return U_SUCCESS; } -USTATUS FfsParser::findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 localOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset) +USTATUS FfsParser::findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset) { int nextIndex = bios.indexOf(EFI_FV_SIGNATURE, volumeOffset); if (nextIndex < EFI_FV_SIGNATURE_OFFSET) @@ -1070,14 +1097,14 @@ USTATUS FfsParser::findNextVolume(const UModelIndex & index, const UByteArray & for (; nextIndex > 0; nextIndex = bios.indexOf(EFI_FV_SIGNATURE, nextIndex + 1)) { const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + nextIndex - EFI_FV_SIGNATURE_OFFSET); if (volumeHeader->FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY) || volumeHeader->FvLength >= 0xFFFFFFFFUL) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid FvLength %" PRIX64 "h", - localOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), + msg(usprintf("%s: volume candidate at offset %Xh skipped, has invalid FvLength %" PRIX64 "h", __FUNCTION__, + globalOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), volumeHeader->FvLength), index); continue; } if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) { - msg(usprintf("findNextVolume: volume candidate at offset %Xh skipped, has invalid Revision byte value %02Xh", - localOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), + msg(usprintf("%s: volume candidate at offset %Xh skipped, has invalid Revision byte value %02Xh", __FUNCTION__, + globalOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET), volumeHeader->Revision), index); continue; } @@ -1136,7 +1163,7 @@ USTATUS FfsParser::parseVolumeNonUefiData(const UByteArray & data, const UINT32 // Add padding tree item UModelIndex paddingIndex = model->addItem(model->offset(index) + localOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), data, UByteArray(), Fixed, index); - msg(UString("parseVolumeNonUefiData: non-UEFI data found in volume's free space"), paddingIndex); + msg(usprintf("%s: non-UEFI data found in volume's free space", __FUNCTION__), paddingIndex); // Parse contents as RAW area return parseRawArea(paddingIndex); @@ -1250,11 +1277,12 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index) header = file.left(sizeof(EFI_FFS_FILE_HEADER2)); } - //Parse current file's header + // Parse current file's header UModelIndex fileIndex; USTATUS result = parseFileHeader(file, volumeHeaderSize + fileOffset, index, fileIndex); - if (result) - msg(UString("parseVolumeBody: file header parsing failed with error ") + errorCodeToUString(result), index); + if (result) { + msg(usprintf("%s: file header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); + } // Move to next file fileOffset += fileSize; @@ -1284,7 +1312,7 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index) // Check GUIDs for being equal if (currentGuid == anotherGuid) { - msg(UString("parseVolumeBody: file with duplicate GUID ") + guidToUString(*(EFI_GUID*)(anotherGuid.data())), another); + msg(usprintf("%s: file with duplicate GUID ", __FUNCTION__) + guidToUString(*(EFI_GUID*)(anotherGuid.data())), another); } } } @@ -1310,33 +1338,41 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index) UINT32 FfsParser::getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion) { + if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER)) { + return 0; + } + + const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)(volume.constData() + fileOffset); + if (ffsVersion == 2) { - if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER)) - return 0; - const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)(volume.constData() + fileOffset); return uint24ToUint32(fileHeader->Size); } else if (ffsVersion == 3) { - if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER2)) - return 0; - const EFI_FFS_FILE_HEADER2* fileHeader = (const EFI_FFS_FILE_HEADER2*)(volume.constData() + fileOffset); - if (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE) - return (UINT32) fileHeader->ExtendedSize; - else - return uint24ToUint32(fileHeader->Size); + if (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE) { + if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER2)) { + return 0; + } + + const EFI_FFS_FILE_HEADER2* fileHeader2 = (const EFI_FFS_FILE_HEADER2*)(volume.constData() + fileOffset); + return (UINT32) fileHeader2->ExtendedSize; + } + + return uint24ToUint32(fileHeader->Size); } - else - return 0; + + return 0; } USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index) { // Sanity check - if (file.isEmpty()) + if (file.isEmpty()) { return U_INVALID_PARAMETER; + } - if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER)) + if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER)) { return U_INVALID_FILE; + } // Obtain required information from parent volume UINT8 ffsVersion = 2; @@ -1354,13 +1390,11 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf // Get file header UByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER)); - bool largeFile = false; EFI_FFS_FILE_HEADER* tempFileHeader = (EFI_FFS_FILE_HEADER*)header.data(); if (ffsVersion == 3 && (tempFileHeader->Attributes & FFS_ATTRIB_LARGE_FILE)) { if ((UINT32)file.size() < sizeof(EFI_FFS_FILE_HEADER2)) return U_INVALID_FILE; header = file.left(sizeof(EFI_FFS_FILE_HEADER2)); - largeFile = true; } const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)header.constData(); @@ -1430,10 +1464,11 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf // Get info UString name; UString info; - if (fileHeader->Type != EFI_FV_FILETYPE_PAD) + if (fileHeader->Type != EFI_FV_FILETYPE_PAD) { name = guidToUString(fileHeader->Name); - else + } else { name = UString("Pad-file"); + } info = UString("File GUID: ") + guidToUString(fileHeader->Name, false) + usprintf("\nType: %02Xh\nAttributes: %02Xh\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nTail size: %Xh (%u)\nState: %02Xh", @@ -1490,41 +1525,53 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf // Show messages if (msgUnalignedFile) - msg(UString("parseFileHeader: unaligned file"), index); + msg(usprintf("%s: unaligned file", __FUNCTION__), index); if (msgFileAlignmentIsGreaterThanVolumeAlignment) - msg(usprintf("parseFileHeader: file alignment %Xh is greater than parent volume alignment %Xh", alignment, volumeAlignment), index); + msg(usprintf("%s: file alignment %Xh is greater than parent volume alignment %Xh", __FUNCTION__, alignment, volumeAlignment), index); if (msgInvalidHeaderChecksum) +<<<<<<< HEAD + msg(usprintf("%s: invalid header checksum %02Xh, should be %02Xh", __FUNCTION__, fileHeader->IntegrityCheck.Checksum.Header, calculatedHeader), index); + if (msgInvalidDataChecksum) + msg(usprintf("%s: invalid data checksum %02Xh, should be %02Xh", __FUNCTION__, fileHeader->IntegrityCheck.Checksum.File, calculatedData), index); + if (msgInvalidTailValue) + msg(usprintf("%s: invalid tail value %04Xh", __FUNCTION__, *(const UINT16*)tail.constData()), index); +======= msg(usprintf("parseFileHeader: invalid header checksum %02Xh, should be %02Xh", fileHeader->IntegrityCheck.Checksum.Header, calculatedHeader), index); if (msgInvalidDataChecksum) msg(usprintf("parseFileHeader: invalid data checksum %02Xh, should be %02Xh", fileHeader->IntegrityCheck.Checksum.File, calculatedData), index); if (msgInvalidTailValue) msg(usprintf("parseFileHeader: invalid tail value %04Xh", *(const UINT16*)tail.constData()), index); +>>>>>>> 775ad7d25b97e266928f437af14b47d38578af63 if (msgUnknownType) - msg(usprintf("parseFileHeader: unknown file type %02Xh", fileHeader->Type), index); + msg(usprintf("%s: unknown file type %02Xh", __FUNCTION__, fileHeader->Type), index); return U_SUCCESS; } UINT32 FfsParser::getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion) { + if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER)) { + return 0; + } + const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(file.constData() + sectionOffset); + if (ffsVersion == 2) { - if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER)) - return 0; - const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(file.constData() + sectionOffset); return uint24ToUint32(sectionHeader->Size); } else if (ffsVersion == 3) { - if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER2)) - return 0; - const EFI_COMMON_SECTION_HEADER2* sectionHeader = (const EFI_COMMON_SECTION_HEADER2*)(file.constData() + sectionOffset); UINT32 size = uint24ToUint32(sectionHeader->Size); - if (size == EFI_SECTION2_IS_USED) - return sectionHeader->ExtendedSize; - else - return size; + if (size == EFI_SECTION2_IS_USED) { + if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER2)) { + return 0; + } + const EFI_COMMON_SECTION_HEADER2* sectionHeader2 = (const EFI_COMMON_SECTION_HEADER2*)(file.constData() + sectionOffset); + return sectionHeader2->ExtendedSize; + } + + return size; } - else - return 0; + + return 0; } USTATUS FfsParser::parseFileBody(const UModelIndex & index) @@ -1619,7 +1666,7 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index) UModelIndex dataIndex = model->addItem(model->offset(index) + model->header(index).size() + nonEmptyByteOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); // Show message - msg(UString("parsePadFileBody: non-UEFI data found in pad-file"), dataIndex); + msg(usprintf("%s: non-UEFI data found in pad-file", __FUNCTION__), dataIndex); // Rename the file model->setName(index, UString("Non-empty pad-file")); @@ -1666,7 +1713,7 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex UModelIndex dataIndex = model->addItem(model->offset(index) + headerSize + sectionOffset, Types::Padding, Subtypes::DataPadding, UString("Non-UEFI data"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); // Show message - msg(UString("parseSections: non-UEFI data found in sections area"), dataIndex); + msg(usprintf("%s: non-UEFI data found in sections area", __FUNCTION__), dataIndex); // Exit from parsing loop break; @@ -1713,8 +1760,9 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity - if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) + if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) { return U_INVALID_SECTION; + } const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); switch (sectionHeader->Type) { @@ -1740,7 +1788,7 @@ USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 l // Unknown default: USTATUS result = parseCommonSectionHeader(section, localOffset, parent, index, insertIntoTree); - msg(usprintf("parseSectionHeader: section with unknown type %02Xh", sectionHeader->Type), index); + msg(usprintf("%s: section with unknown type %02Xh", __FUNCTION__, sectionHeader->Type), index); return result; } } @@ -1748,9 +1796,10 @@ USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 l USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree) { // Check sanity - if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) + if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) { return U_INVALID_SECTION; - + } + // Obtain required information from parent volume UINT8 ffsVersion = 2; UModelIndex parentVolumeIndex = model->findParentOfType(parent, Types::Volume); @@ -1777,8 +1826,9 @@ USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UI } // Check sanity again - if ((UINT32)section.size() < headerSize) + if ((UINT32)section.size() < headerSize) { return U_INVALID_SECTION; + } UByteArray header = section.left(headerSize); UByteArray body = section.mid(headerSize); @@ -1794,7 +1844,8 @@ USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UI // Add tree item if (insertIntoTree) { index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent); - } + } + return U_SUCCESS; } @@ -1843,9 +1894,10 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons } // Check sanity again - if ((UINT32)section.size() < headerSize) + if ((UINT32)section.size() < headerSize) { return U_INVALID_SECTION; - + } + UByteArray header = section.left(headerSize); UByteArray body = section.mid(headerSize); @@ -1869,6 +1921,7 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons pdata.uncompressedSize = uncompressedLength; model->setParsingData(index, UByteArray((const char*)&pdata, sizeof(pdata))); } + return U_SUCCESS; } @@ -2018,7 +2071,6 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI } msgSignedSectionFound = true; } - UByteArray header = section.left(dataOffset); UByteArray body = section.mid(dataOffset); @@ -2048,19 +2100,19 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI // Show messages if (msgSignedSectionFound) - msg(UString("parseGuidedSectionHeader: section signature may become invalid after any modification"), index); + msg(usprintf("%s: section signature may become invalid after any modification", __FUNCTION__), index); if (msgNoAuthStatusAttribute) - msg(UString("parseGuidedSectionHeader: CRC32 GUIDed section without AuthStatusValid attribute"), index); + msg(usprintf("%s: CRC32 GUIDed section without AuthStatusValid attribute", __FUNCTION__), index); if (msgNoProcessingRequiredAttributeCompressed) - msg(UString("parseGuidedSectionHeader: compressed GUIDed section without ProcessingRequired attribute"), index); + msg(usprintf("%s: compressed GUIDed section without ProcessingRequired attribute", __FUNCTION__), index); if (msgNoProcessingRequiredAttributeSigned) - msg(UString("parseGuidedSectionHeader: signed GUIDed section without ProcessingRequired attribute"), index); + msg(usprintf("%s: signed GUIDed section without ProcessingRequired attribute", __FUNCTION__), index); if (msgInvalidCrc) - msg(UString("parseGuidedSectionHeader: GUID defined section with invalid CRC32"), index); + msg(usprintf("%s: GUID defined section with invalid CRC32", __FUNCTION__), index); if (msgUnknownCertType) - msg(UString("parseGuidedSectionHeader: signed GUIDed section with unknown type"), index); + msg(usprintf("%s: signed GUIDed section with unknown type", __FUNCTION__), index); if (msgUnknownCertSubtype) - msg(UString("parseGuidedSectionHeader: signed GUIDed section with unknown subtype"), index); + msg(usprintf("%s: signed GUIDed section with unknown subtype", __FUNCTION__), index); } return U_SUCCESS; @@ -2138,6 +2190,7 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section, // Rename section model->setName(index, guidToUString(guid)); } + return U_SUCCESS; } @@ -2203,6 +2256,7 @@ USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const U if (insertIntoTree) { index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent); } + return U_SUCCESS; } @@ -2268,6 +2322,7 @@ USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const if (insertIntoTree) { index = model->addItem(model->offset(parent) + localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent); } + return U_SUCCESS; } @@ -2401,7 +2456,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index) if (baGuid == EFI_GUIDED_SECTION_TIANO) { USTATUS result = decompress(model->body(index), EFI_STANDARD_COMPRESSION, algorithm, processed, efiDecompressed); if (result) { - msg(UString("parseGuidedSectionBody: decompression failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); return U_SUCCESS; } @@ -2417,7 +2472,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index) processed = efiDecompressed; } else { - msg(UString("parseGuidedSectionBody: can't guess the correct decompression algorithm, both preparse steps are failed"), index); + msg(usprintf("%s: can't guess the correct decompression algorithm, both preparse steps are failed", __FUNCTION__), index); parseCurrentSection = false; } } @@ -2429,7 +2484,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index) else if (baGuid == EFI_GUIDED_SECTION_LZMA || baGuid == EFI_GUIDED_SECTION_LZMAF86) { USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, processed, efiDecompressed); if (result) { - msg(UString("parseGuidedSectionBody: decompression failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); return U_SUCCESS; } @@ -2451,7 +2506,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index) model->setCompressed(index, true); if (!parseCurrentSection) { - msg(UString("parseGuidedSectionBody: GUID defined section can not be processed"), index); + msg(usprintf("%s: GUID defined section can not be processed", __FUNCTION__), index); return U_SUCCESS; } @@ -2481,7 +2536,7 @@ USTATUS FfsParser::parseDepexSectionBody(const UModelIndex & index) // Check data to be present if (body.size() < 2) { // 2 is a minimal sane value, i.e TRUE + END - msg(UString("parseDepexSectionBody: DEPEX section too short"), index); + msg(usprintf("%s: DEPEX section too short", __FUNCTION__), index); return U_DEPEX_PARSE_FAILED; } @@ -2492,33 +2547,33 @@ USTATUS FfsParser::parseDepexSectionBody(const UModelIndex & index) switch (*current) { case EFI_DEP_BEFORE: if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)) { - msg(UString("parseDepexSectionBody: DEPEX section too long for a section starting with BEFORE opcode"), index); + msg(usprintf("%s: DEPEX section too long for a section starting with BEFORE opcode", __FUNCTION__), index); return U_SUCCESS; } guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); parsed += UString("\nBEFORE ") + guidToUString(*guid); current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); if (*current != EFI_DEP_END){ - msg(UString("parseDepexSectionBody: DEPEX section ends with non-END opcode"), index); + msg(usprintf("%s: DEPEX section ends with non-END opcode", __FUNCTION__), index); return U_SUCCESS; } return U_SUCCESS; case EFI_DEP_AFTER: if (body.size() != 2 * EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID)){ - msg(UString("parseDepexSectionBody: DEPEX section too long for a section starting with AFTER opcode"), index); + msg(usprintf("%s: DEPEX section too long for a section starting with AFTER opcode", __FUNCTION__), index); return U_SUCCESS; } guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); parsed += UString("\nAFTER ") + guidToUString(*guid); current += EFI_DEP_OPCODE_SIZE + sizeof(EFI_GUID); if (*current != EFI_DEP_END) { - msg(UString("parseDepexSectionBody: DEPEX section ends with non-END opcode"), index); + msg(usprintf("%s: DEPEX section ends with non-END opcode", __FUNCTION__), index); return U_SUCCESS; } return U_SUCCESS; case EFI_DEP_SOR: if (body.size() <= 2 * EFI_DEP_OPCODE_SIZE) { - msg(UString("parseDepexSectionBody: DEPEX section too short for a section starting with SOR opcode"), index); + msg(usprintf("%s: DEPEX section too short for a section starting with SOR opcode", __FUNCTION__), index); return U_SUCCESS; } parsed += UString("\nSOR"); @@ -2530,22 +2585,22 @@ USTATUS FfsParser::parseDepexSectionBody(const UModelIndex & index) while (current - (const UINT8*)body.constData() < body.size()) { switch (*current) { case EFI_DEP_BEFORE: { - msg(UString("parseDepexSectionBody: misplaced BEFORE opcode"), index); + msg(usprintf("%s: misplaced BEFORE opcode", __FUNCTION__), index); return U_SUCCESS; } case EFI_DEP_AFTER: { - msg(UString("parseDepexSectionBody: misplaced AFTER opcode"), index); + msg(usprintf("%s: misplaced AFTER opcode", __FUNCTION__), index); return U_SUCCESS; } case EFI_DEP_SOR: { - msg(UString("parseDepexSectionBody: misplaced SOR opcode"), index); + msg(usprintf("%s: misplaced SOR opcode", __FUNCTION__), index); return U_SUCCESS; } 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(); - msg(UString("parseDepexSectionBody: remains of DEPEX section too short for PUSH opcode"), index); + msg(usprintf("%s: remains of DEPEX section too short for PUSH opcode", __FUNCTION__), index); return U_SUCCESS; } guid = (const EFI_GUID*)(current + EFI_DEP_OPCODE_SIZE); @@ -2578,11 +2633,11 @@ USTATUS FfsParser::parseDepexSectionBody(const UModelIndex & index) // Check that END is the last opcode if (current - (const UINT8*)body.constData() < body.size()) { parsed.clear(); - msg(UString("parseDepexSectionBody: DEPEX section ends with non-END opcode"), index); + msg(usprintf("%s: DEPEX section ends with non-END opcode", __FUNCTION__), index); } break; default: - msg(UString("parseDepexSectionBody: unknown opcode"), index); + msg(usprintf("%s: unknown opcode %02Xh", __FUNCTION__, *current), index); return U_SUCCESS; break; } @@ -2615,7 +2670,7 @@ USTATUS FfsParser::parseAprioriRawSection(const UByteArray & body, UString & par { // Sanity check if (body.size() % sizeof(EFI_GUID)) { - msg(UString("parseAprioriRawSection: apriori file has size is not a multiple of 16")); + msg(usprintf("%s: apriori file has size is not a multiple of 16", __FUNCTION__)); } parsed.clear(); UINT32 count = body.size() / sizeof(EFI_GUID); @@ -2692,7 +2747,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) // Get section body UByteArray body = model->body(index); if ((UINT32)body.size() < sizeof(EFI_IMAGE_DOS_HEADER)) { - msg(UString("parsePeImageSectionBody: section body size is smaller than DOS header size"), index); + msg(usprintf("%s: section body size is smaller than DOS header size", __FUNCTION__), index); return U_SUCCESS; } @@ -2700,7 +2755,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)body.constData(); if (dosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { info += usprintf("\nDOS signature: %04Xh, invalid", dosHeader->e_magic); - msg(UString("parsePeImageSectionBody: PE32 image with invalid DOS signature"), index); + msg(usprintf("%s: PE32 image with invalid DOS signature", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } @@ -2708,14 +2763,14 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) const EFI_IMAGE_PE_HEADER* peHeader = (EFI_IMAGE_PE_HEADER*)(body.constData() + dosHeader->e_lfanew); if (body.size() < (UINT8*)peHeader - (UINT8*)dosHeader) { info += UString("\nDOS header: invalid"); - msg(UString("parsePeImageSectionBody: PE32 image with invalid DOS header"), index); + msg(usprintf("%s: PE32 image with invalid DOS header", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE) { info += usprintf("\nPE signature: %08Xh, invalid", peHeader->Signature); - msg(UString("parsePeImageSectionBody: PE32 image with invalid PE signature"), index); + msg(usprintf("%s: PE32 image with invalid PE signature", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } @@ -2723,7 +2778,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) const EFI_IMAGE_FILE_HEADER* imageFileHeader = (const EFI_IMAGE_FILE_HEADER*)(peHeader + 1); if (body.size() < (UINT8*)imageFileHeader - (UINT8*)dosHeader) { info += UString("\nPE header: invalid"); - msg(UString("parsePeImageSectionBody: PE32 image with invalid PE header"), index); + msg(usprintf("%s: PE32 image with invalid PE header", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } @@ -2740,7 +2795,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) optionalHeader.H32 = (const EFI_IMAGE_OPTIONAL_HEADER32*)(imageFileHeader + 1); if (body.size() < (UINT8*)optionalHeader.H32 - (UINT8*)dosHeader) { info += UString("\nPE optional header: invalid"); - msg(UString("parsePeImageSectionBody: PE32 image with invalid PE optional header"), index); + msg(usprintf("%s: PE32 image with invalid PE optional header", __FUNCTION__), index); model->addInfo(index, info); return U_SUCCESS; } @@ -2763,7 +2818,7 @@ USTATUS FfsParser::parsePeImageSectionBody(const UModelIndex & index) } else { info += usprintf("\nOptional header signature: %04Xh, unknown", optionalHeader.H32->Magic); - msg(UString("parsePeImageSectionBody: PE32 image with invalid optional PE header signature"), index); + msg(usprintf("%s: PE32 image with invalid optional PE header signature", __FUNCTION__), index); } model->addInfo(index, info); @@ -2780,7 +2835,7 @@ USTATUS FfsParser::parseTeImageSectionBody(const UModelIndex & index) // Get section body UByteArray body = model->body(index); if ((UINT32)body.size() < sizeof(EFI_IMAGE_TE_HEADER)) { - msg(UString("parsePeImageSectionBody: section body size is smaller than TE header size"), index); + msg(usprintf("%s: section body size is smaller than TE header size", __FUNCTION__), index); return U_SUCCESS; } @@ -2788,7 +2843,7 @@ USTATUS FfsParser::parseTeImageSectionBody(const UModelIndex & index) const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)body.constData(); if (teHeader->Signature != EFI_IMAGE_TE_SIGNATURE) { info += usprintf("\nSignature: %04Xh, invalid", teHeader->Signature); - msg(UString("parseTeImageSectionBody: TE image with invalid TE signature"), index); + msg(usprintf("%s: TE image with invalid TE signature", __FUNCTION__), index); } else { info += usprintf("\nSignature: %04Xh", teHeader->Signature) + @@ -2826,7 +2881,7 @@ USTATUS FfsParser::performSecondPass(const UModelIndex & index) // Check for compressed lastVtf if (model->compressed(lastVtf)) { - msg(UString("performSecondPass: the last VTF appears inside compressed item, the image may be damaged"), lastVtf); + msg(usprintf("%s: the last VTF appears inside compressed item, the image may be damaged", __FUNCTION__), lastVtf); return U_SUCCESS; } @@ -2909,7 +2964,7 @@ USTATUS FfsParser::addMemoryAddressesRecursive(const UModelIndex & index) // Show message if imageBaseType is still unknown if (imageBaseType == EFI_IMAGE_TE_BASE_OTHER) - msg(UString("addMemoryAddressesRecursive: TE image base is neither zero, nor original, nor adjusted, nor top-swapped"), index); + msg(usprintf("%s: TE image base is neither zero, nor original, nor adjusted, nor top-swapped", __FUNCTION__), index); // Update parsing data TE_IMAGE_SECTION_PARSING_DATA pdata; @@ -2990,11 +3045,11 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) sha256(protectedParts.constData(), protectedParts.size(), digest.data()); if (digest != bgBpDigest) { - msg(UString("checkProtectedRanges: BG-protected ranges hash mismatch, opened image may refuse to boot"), index); + msg(usprintf("%s: BG-protected ranges hash mismatch, opened image may refuse to boot", __FUNCTION__), index); } } else if (bgBootPolicyFound) { - msg(usprintf("checkProtectedRanges: BootPolicy doesn't define any BG-protected ranges"), index); + msg(usprintf("%s: BootPolicy doesn't define any BG-protected ranges", __FUNCTION__), index); } // Calculate digests for vendor-protected ranges @@ -3002,13 +3057,13 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) if (bgProtectedRanges[i].Type == BG_PROTECTED_RANGE_VENDOR_HASH_AMI_OLD && bgProtectedRanges[i].Size != 0 && bgProtectedRanges[i].Size != 0xFFFFFFFF) { if (!bgDxeCoreIndex.isValid()) { - msg(UString("checkProtectedRanges: can't determine DXE volume offset, old AMI protected range hash can't be checked"), index); + msg(usprintf("%s: can't determine DXE volume offset, old AMI protected range hash can't be checked", __FUNCTION__), index); } else { // Offset will be determined as the offset of root volume with first DXE core UModelIndex dxeRootVolumeIndex = model->findLastParentOfType(bgDxeCoreIndex, Types::Volume); if (!dxeRootVolumeIndex.isValid()) { - msg(UString("checkProtectedRanges: can't determine DXE volume offset, old AMI protected range hash can't be checked"), index); + msg(usprintf("%s: can't determine DXE volume offset, old AMI protected range hash can't be checked", __FUNCTION__), index); } else { bgProtectedRanges[i].Offset = model->offset(dxeRootVolumeIndex); @@ -3018,7 +3073,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) sha256(protectedParts.constData(), protectedParts.size(), digest.data()); if (digest != bgProtectedRanges[i].Hash) { - msg(usprintf("checkProtectedRanges: old AMI protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", + msg(usprintf("%s: old AMI protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, bgProtectedRanges[i].Offset, bgProtectedRanges[i].Offset + bgProtectedRanges[i].Size), model->findByOffset(bgProtectedRanges[i].Offset)); } @@ -3029,13 +3084,13 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) } else if (bgProtectedRanges[i].Type == BG_PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB) { if (!bgDxeCoreIndex.isValid()) { - msg(UString("checkProtectedRanges: can't determine DXE volume offset, post-IBB protected range hash can't be checked"), index); + msg(usprintf("%s: can't determine DXE volume offset, post-IBB protected range hash can't be checked", __FUNCTION__), index); } else { // Offset will be determined as the offset of root volume with first DXE core UModelIndex dxeRootVolumeIndex = model->findLastParentOfType(bgDxeCoreIndex, Types::Volume); if (!dxeRootVolumeIndex.isValid()) { - msg(UString("checkProtectedRanges: can't determine DXE volume offset, post-IBB protected range hash can't be checked"), index); + msg(usprintf("%s: can't determine DXE volume offset, post-IBB protected range hash can't be checked", __FUNCTION__), index); } else { @@ -3047,7 +3102,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) sha256(protectedParts.constData(), protectedParts.size(), digest.data()); if (digest != bgProtectedRanges[i].Hash) { - msg(usprintf("checkProtectedRanges: post-IBB protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", + msg(usprintf("%s: post-IBB protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, bgProtectedRanges[i].Offset, bgProtectedRanges[i].Offset + bgProtectedRanges[i].Size), model->findByOffset(bgProtectedRanges[i].Offset)); } @@ -3067,7 +3122,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) sha256(protectedParts.constData(), protectedParts.size(), digest.data()); if (digest != bgProtectedRanges[i].Hash) { - msg(usprintf("checkProtectedRanges: AMI protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", + msg(usprintf("%s: AMI protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, bgProtectedRanges[i].Offset, bgProtectedRanges[i].Offset + bgProtectedRanges[i].Size), model->findByOffset(bgProtectedRanges[i].Offset)); } @@ -3084,7 +3139,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) sha256(protectedParts.constData(), protectedParts.size(), digest.data()); if (digest != bgProtectedRanges[i].Hash) { - msg(usprintf("checkProtectedRanges: Phoenix protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", + msg(usprintf("%s: Phoenix protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, bgProtectedRanges[i].Offset, bgProtectedRanges[i].Offset + bgProtectedRanges[i].Size), model->findByOffset(bgProtectedRanges[i].Offset)); } @@ -3101,7 +3156,7 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index) sha256(protectedParts.constData(), protectedParts.size(), digest.data()); if (digest != bgProtectedRanges[i].Hash) { - msg(usprintf("checkProtectedRanges: Microsoft protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", + msg(usprintf("%s: Microsoft protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__, bgProtectedRanges[i].Offset, bgProtectedRanges[i].Offset + bgProtectedRanges[i].Size), model->findByOffset(bgProtectedRanges[i].Offset)); } @@ -3152,8 +3207,8 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel if (fileGuid == BG_VENDOR_HASH_FILE_GUID_PHOENIX) { // File too small to have even a signature - if (model->body(index).size() < sizeof(BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX)) { - msg(UString("parseVendorHashFile: unknown or corrupted Phoenix hash file found"), index); + if ((UINT32)model->body(index).size() < sizeof(BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX)) { + msg(usprintf("%s: unknown or corrupted Phoenix hash file found", __FUNCTION__), index); model->setText(index, UString("Phoenix hash file")); return U_INVALID_FILE; } @@ -3162,7 +3217,7 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel if (header->Signature == BG_VENDOR_HASH_FILE_SIGNATURE_PHOENIX) { if ((UINT32)model->body(index).size() < sizeof(BG_VENDOR_HASH_FILE_HEADER_PHOENIX) || (UINT32)model->body(index).size() < sizeof(BG_VENDOR_HASH_FILE_HEADER_PHOENIX) + header->NumEntries * sizeof(BG_VENDOR_HASH_FILE_ENTRY)) { - msg(UString("parseVendorHashFile: unknown or corrupted Phoenix hash file found"), index); + msg(usprintf("%s: unknown or corrupted Phoenix hash file found", __FUNCTION__), index); model->setText(index, UString("Phoenix hash file")); return U_INVALID_FILE; } @@ -3172,6 +3227,7 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel for (UINT32 i = 0; i < header->NumEntries; i++) { protectedRangesFound = true; const BG_VENDOR_HASH_FILE_ENTRY* entry = (const BG_VENDOR_HASH_FILE_ENTRY*)(header + 1) + i; + BG_PROTECTED_RANGE range; range.Offset = entry->Offset; range.Size = entry->Size; @@ -3192,10 +3248,10 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); } - msg(UString("parseVendorHashFile: Phoenix hash file found"), index); + msg(usprintf("%s: Phoenix hash file found", __FUNCTION__), index); } else { - msg(UString("parseVendorHashFile: empty Phoenix hash file found"), index); + msg(usprintf("%s: empty Phoenix hash file found", __FUNCTION__), index); } model->setText(index, UString("Phoenix hash file")); @@ -3204,7 +3260,7 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel else if (fileGuid == BG_VENDOR_HASH_FILE_GUID_AMI) { UModelIndex fileIndex = model->parent(index); UINT32 size = model->body(index).size(); - if (size != model->body(index).count('\xFF')) { + if (size != (UINT32)model->body(index).count('\xFF')) { if (size == sizeof(BG_VENDOR_HASH_FILE_HEADER_AMI_NEW)) { bool protectedRangesFound = false; UINT32 NumEntries = (UINT32)model->body(index).size() / sizeof(BG_VENDOR_HASH_FILE_ENTRY); @@ -3231,7 +3287,7 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); } - msg(UString("parseVendorHashFile: new AMI hash file found"), fileIndex); + msg(usprintf("%s: new AMI hash file found", __FUNCTION__), fileIndex); } else if (size == sizeof(BG_VENDOR_HASH_FILE_HEADER_AMI_OLD)) { bootGuardInfo += usprintf("Old AMI hash file found at offset %Xh\nProtected range:", model->offset(fileIndex)); @@ -3249,14 +3305,14 @@ USTATUS FfsParser::parseVendorHashFile(const UByteArray & fileGuid, const UModel range.Type = BG_PROTECTED_RANGE_VENDOR_HASH_AMI_OLD; bgProtectedRanges.push_back(range); - msg(UString("parseVendorHashFile: old AMI hash file found"), fileIndex); + msg(usprintf("%s: old AMI hash file found", __FUNCTION__), fileIndex); } else { - msg(UString("parseVendorHashFile: unknown or corrupted AMI hash file found"), index); + msg(usprintf("%s: unknown or corrupted AMI hash file found", __FUNCTION__), index); } } else { - msg(UString("parseVendorHashFile: empty AMI hash file found"), fileIndex); + msg(usprintf("%s: empty AMI hash file found", __FUNCTION__), fileIndex); } model->setText(fileIndex, UString("AMI hash file")); @@ -3307,7 +3363,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index) tempFitHeader->Checksum = 0; UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize); if (calculated != fitHeader->Checksum) { - msg(usprintf("parseFit: invalid FIT table checksum %02Xh, should be %02Xh", fitHeader->Checksum, calculated), fitIndex); + msg(usprintf("%s: invalid FIT table checksum %02Xh, should be %02Xh", __FUNCTION__, fitHeader->Checksum, calculated), fitIndex); } } @@ -3341,7 +3397,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index) // Check sanity if (currentEntry->Type == FIT_TYPE_HEADER) { - msg(UString("parseFit: second FIT header found, the table is damaged"), fitIndex); + msg(usprintf("%s: second FIT header found, the table is damaged", __FUNCTION__), fitIndex); return U_INVALID_FIT; } @@ -3383,8 +3439,9 @@ USTATUS FfsParser::parseFit(const UModelIndex & index) if (status != U_SUCCESS) itemIndex = UModelIndex(); } - else - msg(usprintf("parseFit: FIT entry #%d not found in the image", i), fitIndex); + else { + msg(usprintf("%s: FIT entry #%d not found in the image", __FUNCTION__, i), fitIndex); + } } // Add entry to fitTable @@ -3400,15 +3457,15 @@ USTATUS FfsParser::parseFit(const UModelIndex & index) // Perform validation of BootGuard stuff if (bgAcmFound) { if (!bgKeyManifestFound) { - msg(usprintf("parseBootGuardData: ACM found, but KeyManifest isn't"), acmIndex); + msg(usprintf("%s: ACM found, but KeyManifest isn't", __FUNCTION__), acmIndex); } else if (!bgBootPolicyFound) { - msg(usprintf("parseBootGuardData: ACM and KeyManifest found, BootPolicy isn't"), kmIndex); + msg(usprintf("%s: ACM and KeyManifest found, BootPolicy isn't", __FUNCTION__), kmIndex); } else { // Check key hashes if (!bgKmHash.isEmpty() && bgBpHash.isEmpty() && bgKmHash != bgBpHash) { - msg(usprintf("parseBootGuardData: BootPolicy key hash stored in KeyManifest differs from the hash of public key stored in BootPolicy"), bpIndex); + msg(usprintf("%s: BootPolicy key hash stored in KeyManifest differs from the hash of public key stored in BootPolicy", __FUNCTION__), bpIndex); return U_SUCCESS; } } @@ -3420,8 +3477,9 @@ USTATUS FfsParser::parseFit(const UModelIndex & index) USTATUS FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset) { // Sanity check - if (!index.isValid()) + if (!index.isValid()) { return U_SUCCESS; + } // Process child items for (int i = 0; i < model->rowCount(index); i++) { @@ -3437,17 +3495,17 @@ USTATUS FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & fou offset >= 0; offset = model->body(index).indexOf(FIT_SIGNATURE, offset + 1)) { // FIT candidate found, calculate it's physical address - UINT32 fitAddress = model->offset(index) + addressDiff + model->header(index).size() + (UINT32)offset; + UINT32 fitAddress = model->offset(index) + (UINT32)addressDiff + model->header(index).size() + (UINT32)offset; // Check FIT address to be stored in the last VTF if (fitAddress == storedFitAddress) { found = index; fitOffset = offset; - msg(usprintf("findFitRecursive: real FIT table found at physical address %08Xh", fitAddress), found); + msg(usprintf("%s: real FIT table found at physical address %08Xh", __FUNCTION__, fitAddress), found); return U_SUCCESS; } else if (model->rowCount(index) == 0) // Show messages only to leaf items - msg(UString("findFitRecursive: FIT table candidate found, but not referenced from the last VTF"), index); + msg(usprintf("%s: FIT table candidate found, but not referenced from the last VTF", __FUNCTION__), index); } return U_SUCCESS; @@ -3456,46 +3514,61 @@ USTATUS FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & fou USTATUS FfsParser::parseIntelMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) { U_UNUSED_PARAMETER(parent); - if (localOffset + sizeof(INTEL_MICROCODE_HEADER) <= (UINT32)microcode.size()) { - const INTEL_MICROCODE_HEADER* header = (const INTEL_MICROCODE_HEADER*)(microcode.constData() + localOffset); - if (header->Version == INTEL_MICROCODE_HEADER_VERSION) { - bool reservedBytesValid = true; - for (UINT8 i = 0; i < sizeof(header->Reserved); i++) - if (header->Reserved[i] != INTEL_MICROCODE_HEADER_RESERVED_BYTE) { - reservedBytesValid = false; - break; - } - if (reservedBytesValid) { - UINT32 mcSize = header->TotalSize; - if (localOffset + mcSize <= (UINT32)microcode.size()) { - // Valid microcode found - info = usprintf("LocalOffset %08Xh, CPUID %08Xh, Revision %08Xh, Date %02X.%02X.%04X", - localOffset, - header->CpuSignature, - header->Revision, - header->DateDay, - header->DateMonth, - header->DateYear - ); - realSize = mcSize; - return U_SUCCESS; - } - } - } + if ((UINT32)microcode.size() < localOffset + sizeof(INTEL_MICROCODE_HEADER)) { + return U_INVALID_MICROCODE; } - return U_INVALID_MICROCODE; + const INTEL_MICROCODE_HEADER* header = (const INTEL_MICROCODE_HEADER*)(microcode.constData() + localOffset); + if (header->Version != INTEL_MICROCODE_HEADER_VERSION) { + return U_INVALID_MICROCODE; + } + + bool reservedBytesValid = true; + for (UINT8 i = 0; i < sizeof(header->Reserved); i++) + if (header->Reserved[i] != INTEL_MICROCODE_HEADER_RESERVED_BYTE) { + reservedBytesValid = false; + break; + } + if (!reservedBytesValid) { + return U_INVALID_MICROCODE; + } + + UINT32 mcSize = header->TotalSize; + if ((UINT32)microcode.size() < localOffset + mcSize) { + return U_INVALID_MICROCODE; + } + + // Valid microcode found + info = usprintf("LocalOffset %08Xh, CPUID %08Xh, Revision %08Xh, Date %02X.%02X.%04X", + localOffset, + header->CpuSignature, + header->Revision, + header->DateDay, + header->DateMonth, + header->DateYear + ); + realSize = mcSize; + return U_SUCCESS; } USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) { - if (localOffset + sizeof(INTEL_ACM_HEADER) <= (UINT32)acm.size()) { - const INTEL_ACM_HEADER* header = (const INTEL_ACM_HEADER*)(acm.constData() + localOffset); - if (header->ModuleType == INTEL_ACM_MODULE_TYPE && header->ModuleVendor == INTEL_ACM_MODULE_VENDOR) { - UINT32 acmSize = header->ModuleSize * sizeof(UINT32); - if (localOffset + acmSize <= (UINT32)acm.size()) { - // Valid ACM found - info = usprintf("LocalOffset %08Xh, EntryPoint %08Xh, ACM SVN %04Xh, Date %02X.%02X.%04X", + if ((UINT32)acm.size() < localOffset + sizeof(INTEL_ACM_HEADER)) { + return U_INVALID_ACM; + } + + const INTEL_ACM_HEADER* header = (const INTEL_ACM_HEADER*)(acm.constData() + localOffset); + if (header->ModuleType != INTEL_ACM_MODULE_TYPE || header->ModuleVendor != INTEL_ACM_MODULE_VENDOR) { + return U_INVALID_ACM; + } + + UINT32 acmSize = header->ModuleSize * sizeof(UINT32); + if ((UINT32)acm.size() < localOffset + acmSize) { + return U_INVALID_ACM; + } + + // Valid ACM found + info = usprintf("LocalOffset %08Xh, EntryPoint %08Xh, ACM SVN %04Xh, Date %02X.%02X.%04X", localOffset, header->EntryPoint, header->AcmSvn, @@ -3503,134 +3576,127 @@ USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffse header->DateMonth, header->DateYear ); - realSize = acmSize; + realSize = acmSize; - // Add ACM header info - bootGuardInfo += usprintf( - "Intel ACM found at offset %Xh\n" - "ModuleType: %08Xh HeaderLength: %08Xh HeaderVersion: %08Xh\n" - "ChipsetId: %04Xh Flags: %04Xh ModuleVendor: %04Xh\n" - "Date: %02X.%02X.%04X ModuleSize: %08Xh EntryPoint: %08Xh\n" - "AcmSvn: %04Xh Unknown1: %08Xh Unknown2: %08Xh\n" - "GdtBase: %08Xh GdtMax: %08Xh SegSel: %08Xh\n" - "KeySize: %08Xh Unknown3: %08Xh", - model->offset(parent) + localOffset, - header->ModuleType, - header->ModuleSize * sizeof(UINT32), - header->HeaderVersion, - header->ChipsetId, - header->Flags, - header->ModuleVendor, - header->DateDay, header->DateMonth, header->DateYear, - header->ModuleSize * sizeof(UINT32), - header->EntryPoint, - header->AcmSvn, - header->Unknown1, - header->Unknown2, - header->GdtBase, - header->GdtMax, - header->SegmentSel, - header->KeySize * sizeof(UINT32), - header->Unknown4 * sizeof(UINT32) - ); - // Add PubKey - bootGuardInfo += usprintf("\n\nACM RSA Public Key (Exponent: %Xh):", header->RsaPubExp); - for (UINT16 i = 0; i < sizeof(header->RsaPubKey); i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", header->RsaPubKey[i]); - } - // Add RsaSig - bootGuardInfo += UString("\n\nACM RSA Signature:"); - for (UINT16 i = 0; i < sizeof(header->RsaSig); i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", header->RsaSig[i]); - } - bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); - bgAcmFound = true; - return U_SUCCESS; - } - } + // Add ACM header info + bootGuardInfo += usprintf( + "Intel ACM found at offset %Xh\n" + "ModuleType: %08Xh HeaderLength: %08Xh HeaderVersion: %08Xh\n" + "ChipsetId: %04Xh Flags: %04Xh ModuleVendor: %04Xh\n" + "Date: %02X.%02X.%04X ModuleSize: %08Xh EntryPoint: %08Xh\n" + "AcmSvn: %04Xh Unknown1: %08Xh Unknown2: %08Xh\n" + "GdtBase: %08Xh GdtMax: %08Xh SegSel: %08Xh\n" + "KeySize: %08Xh Unknown3: %08Xh", + model->offset(parent) + localOffset, + header->ModuleType, + header->ModuleSize * sizeof(UINT32), + header->HeaderVersion, + header->ChipsetId, + header->Flags, + header->ModuleVendor, + header->DateDay, header->DateMonth, header->DateYear, + header->ModuleSize * sizeof(UINT32), + header->EntryPoint, + header->AcmSvn, + header->Unknown1, + header->Unknown2, + header->GdtBase, + header->GdtMax, + header->SegmentSel, + header->KeySize * sizeof(UINT32), + header->Unknown4 * sizeof(UINT32) + ); + // Add PubKey + bootGuardInfo += usprintf("\n\nACM RSA Public Key (Exponent: %Xh):", header->RsaPubExp); + for (UINT16 i = 0; i < sizeof(header->RsaPubKey); i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", header->RsaPubKey[i]); } - - return U_INVALID_ACM; + // Add RsaSig + bootGuardInfo += UString("\n\nACM RSA Signature:"); + for (UINT16 i = 0; i < sizeof(header->RsaSig); i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", header->RsaSig[i]); + } + bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); + bgAcmFound = true; + return U_SUCCESS; } USTATUS FfsParser::parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) { - U_UNUSED_PARAMETER(parent); U_UNUSED_PARAMETER(realSize); - if (localOffset + sizeof(BG_KEY_MANIFEST) <= (UINT32)keyManifest.size()) { - const BG_KEY_MANIFEST* header = (const BG_KEY_MANIFEST*)(keyManifest.constData() + localOffset); - if (header->Tag == BG_KEY_MANIFEST_TAG) { - UINT32 kmSize = sizeof(BG_KEY_MANIFEST); - if (localOffset + kmSize <= (UINT32)keyManifest.size()) { - // Valid KM found - info = usprintf("LocalOffset %08Xh, KM Version %02Xh, KM SVN: %02Xh, KM ID %02Xh", + if ((UINT32)keyManifest.size() < localOffset + sizeof(BG_KEY_MANIFEST)) { + return U_INVALID_BG_KEY_MANIFEST; + } + + const BG_KEY_MANIFEST* header = (const BG_KEY_MANIFEST*)(keyManifest.constData() + localOffset); + if (header->Tag != BG_KEY_MANIFEST_TAG) { + return U_INVALID_BG_KEY_MANIFEST; + } + + // Valid KM found + info = usprintf("LocalOffset %08Xh, KM Version %02Xh, KM SVN: %02Xh, KM ID %02Xh", localOffset, header->KmVersion, header->KmSvn, header->KmId ); - // Add KM header info - bootGuardInfo += usprintf( - "Intel BootGuard Key manifest found at offset %Xh\n" - "Tag: __KEYM__ Version: %02Xh KmVersion: %02Xh KmSvn: %02Xh KmId: %02Xh", - model->offset(parent) + localOffset, - header->Version, - header->KmVersion, - header->KmSvn, - header->KmId - ); + // Add KM header info + bootGuardInfo += usprintf( + "Intel BootGuard Key manifest found at offset %Xh\n" + "Tag: __KEYM__ Version: %02Xh KmVersion: %02Xh KmSvn: %02Xh KmId: %02Xh", + model->offset(parent) + localOffset, + header->Version, + header->KmVersion, + header->KmSvn, + header->KmId + ); - // Add hash of Key Manifest PubKey, this hash will be written to FPFs - UINT8 hash[SHA256_DIGEST_SIZE]; - sha256(&header->KeyManifestSignature.PubKey.Modulus, sizeof(header->KeyManifestSignature.PubKey.Modulus), hash); - bootGuardInfo += UString("\n\nKey Manifest RSA Public Key Hash:\n"); - for (UINT8 i = 0; i < sizeof(hash); i++) { - bootGuardInfo += usprintf("%02X", hash[i]); - } - - // Add BpKeyHash - bootGuardInfo += UString("\n\nBoot Policy RSA Public Key Hash:\n"); - for (UINT8 i = 0; i < sizeof(header->BpKeyHash.HashBuffer); i++) { - bootGuardInfo += usprintf("%02X", header->BpKeyHash.HashBuffer[i]); - } - bgKmHash = UByteArray((const char*)header->BpKeyHash.HashBuffer, sizeof(header->BpKeyHash.HashBuffer)); - - // Add Key Manifest PubKey - bootGuardInfo += usprintf("\n\nKey Manifest RSA Public Key (Exponent: %Xh):", - header->KeyManifestSignature.PubKey.Exponent); - for (UINT16 i = 0; i < sizeof(header->KeyManifestSignature.PubKey.Modulus); i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", header->KeyManifestSignature.PubKey.Modulus[i]); - } - // Add Key Manifest Signature - bootGuardInfo += UString("\n\nKey Manifest RSA Signature:"); - for (UINT16 i = 0; i < sizeof(header->KeyManifestSignature.Signature.Signature); i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", header->KeyManifestSignature.Signature.Signature[i]); - } - bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); - bgKeyManifestFound = true; - return U_SUCCESS; - } - } + // Add hash of Key Manifest PubKey, this hash will be written to FPFs + UINT8 hash[SHA256_DIGEST_SIZE]; + sha256(&header->KeyManifestSignature.PubKey.Modulus, sizeof(header->KeyManifestSignature.PubKey.Modulus), hash); + bootGuardInfo += UString("\n\nKey Manifest RSA Public Key Hash:\n"); + for (UINT8 i = 0; i < sizeof(hash); i++) { + bootGuardInfo += usprintf("%02X", hash[i]); } - return U_INVALID_BG_KEY_MANIFEST; + // Add BpKeyHash + bootGuardInfo += UString("\n\nBoot Policy RSA Public Key Hash:\n"); + for (UINT8 i = 0; i < sizeof(header->BpKeyHash.HashBuffer); i++) { + bootGuardInfo += usprintf("%02X", header->BpKeyHash.HashBuffer[i]); + } + bgKmHash = UByteArray((const char*)header->BpKeyHash.HashBuffer, sizeof(header->BpKeyHash.HashBuffer)); + + // Add Key Manifest PubKey + bootGuardInfo += usprintf("\n\nKey Manifest RSA Public Key (Exponent: %Xh):", + header->KeyManifestSignature.PubKey.Exponent); + for (UINT16 i = 0; i < sizeof(header->KeyManifestSignature.PubKey.Modulus); i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", header->KeyManifestSignature.PubKey.Modulus[i]); + } + // Add Key Manifest Signature + bootGuardInfo += UString("\n\nKey Manifest RSA Signature:"); + for (UINT16 i = 0; i < sizeof(header->KeyManifestSignature.Signature.Signature); i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", header->KeyManifestSignature.Signature.Signature[i]); + } + bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); + bgKeyManifestFound = true; + return U_SUCCESS; } USTATUS FfsParser::findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize) { UINT32 dataSize = bootPolicy.size(); - - if (dataSize < sizeof(UINT64)) + if (dataSize < sizeof(UINT64)) { return U_ELEMENTS_NOT_FOUND; + } UINT32 offset = elementOffset; for (; offset < dataSize - sizeof(UINT64); offset++) { @@ -3666,184 +3732,190 @@ USTATUS FfsParser::findNextElement(const UByteArray & bootPolicy, const UINT32 e USTATUS FfsParser::parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize) { U_UNUSED_PARAMETER(realSize); - if (localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER) <= (UINT32)bootPolicy.size()) { - const BG_BOOT_POLICY_MANIFEST_HEADER* header = (const BG_BOOT_POLICY_MANIFEST_HEADER*)(bootPolicy.constData() + localOffset); - if (header->Tag == BG_BOOT_POLICY_MANIFEST_HEADER_TAG) { - UINT32 bmSize = sizeof(BG_BOOT_POLICY_MANIFEST_HEADER); - if (localOffset + bmSize <= (UINT32)bootPolicy.size()) { - // Valid BPM found - info = usprintf("LocalOffset %08Xh, BP SVN %02Xh, ACM SVN %02Xh", + if ((UINT32)bootPolicy.size() < localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER)) { + return U_INVALID_BG_BOOT_POLICY; + } + + const BG_BOOT_POLICY_MANIFEST_HEADER* header = (const BG_BOOT_POLICY_MANIFEST_HEADER*)(bootPolicy.constData() + localOffset); + if (header->Tag != BG_BOOT_POLICY_MANIFEST_HEADER_TAG) { + return U_INVALID_BG_BOOT_POLICY; + } + + UINT32 bmSize = sizeof(BG_BOOT_POLICY_MANIFEST_HEADER); + if ((UINT32)bootPolicy.size() < localOffset + bmSize) { + return U_INVALID_BG_BOOT_POLICY; + } + + // Valid BPM found + info = usprintf("LocalOffset %08Xh, BP SVN %02Xh, ACM SVN %02Xh", localOffset, header->BPSVN, header->ACMSVN ); - // Add BP header info - bootGuardInfo += usprintf( - "Intel BootGuard Boot Policy Manifest found at offset %Xh\n" - "Tag: __ACBP__ Version: %02Xh HeaderVersion: %02Xh\n" - "PMBPMVersion: %02Xh PBSVN: %02Xh ACMSVN: %02Xh NEMDataStack: %04Xh\n", - model->offset(parent) + localOffset, - header->Version, - header->HeaderVersion, - header->PMBPMVersion, - header->BPSVN, - header->ACMSVN, - header->NEMDataSize - ); + // Add BP header info + bootGuardInfo += usprintf( + "Intel BootGuard Boot Policy Manifest found at offset %Xh\n" + "Tag: __ACBP__ Version: %02Xh HeaderVersion: %02Xh\n" + "PMBPMVersion: %02Xh PBSVN: %02Xh ACMSVN: %02Xh NEMDataStack: %04Xh\n", + model->offset(parent) + localOffset, + header->Version, + header->HeaderVersion, + header->PMBPMVersion, + header->BPSVN, + header->ACMSVN, + header->NEMDataSize + ); - // Iterate over elements to get them all - UINT32 elementOffset = 0; - UINT32 elementSize = 0; - USTATUS status = findNextElement(bootPolicy, localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER), elementOffset, elementSize); - while (status == U_SUCCESS) { - const UINT64* currentPos = (const UINT64*)(bootPolicy.constData() + elementOffset); - if (*currentPos == BG_BOOT_POLICY_MANIFEST_IBB_ELEMENT_TAG) { - const BG_IBB_ELEMENT* elementHeader = (const BG_IBB_ELEMENT*)currentPos; - // Valid IBB element found - bootGuardInfo += usprintf( - "\nInitial Boot Block Element found at offset %Xh\n" - "Tag: __IBBS__ Version: %02Xh Unknown: %02Xh\n" - "Flags: %08Xh IbbMchBar: %08Xh VtdBar: %08Xh\n" - "PmrlBase: %08Xh PmrlLimit: %08Xh EntryPoint: %08Xh", - model->offset(parent) + localOffset + elementOffset, - elementHeader->Version, - elementHeader->Unknown, - elementHeader->Flags, - elementHeader->IbbMchBar, - elementHeader->VtdBar, - elementHeader->PmrlBase, - elementHeader->PmrlLimit, - elementHeader->EntryPoint - ); + // Iterate over elements to get them all + UINT32 elementOffset = 0; + UINT32 elementSize = 0; + USTATUS status = findNextElement(bootPolicy, localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER), elementOffset, elementSize); + while (status == U_SUCCESS) { + const UINT64* currentPos = (const UINT64*)(bootPolicy.constData() + elementOffset); + if (*currentPos == BG_BOOT_POLICY_MANIFEST_IBB_ELEMENT_TAG) { + const BG_IBB_ELEMENT* elementHeader = (const BG_IBB_ELEMENT*)currentPos; + // Valid IBB element found + bootGuardInfo += usprintf( + "\nInitial Boot Block Element found at offset %Xh\n" + "Tag: __IBBS__ Version: %02Xh Unknown: %02Xh\n" + "Flags: %08Xh IbbMchBar: %08Xh VtdBar: %08Xh\n" + "PmrlBase: %08Xh PmrlLimit: %08Xh EntryPoint: %08Xh", + model->offset(parent) + localOffset + elementOffset, + elementHeader->Version, + elementHeader->Unknown, + elementHeader->Flags, + elementHeader->IbbMchBar, + elementHeader->VtdBar, + elementHeader->PmrlBase, + elementHeader->PmrlLimit, + elementHeader->EntryPoint + ); - // Add PostIbbHash - bootGuardInfo += UString("\n\nPost IBB Hash:\n"); - for (UINT8 i = 0; i < sizeof(elementHeader->IbbHash.HashBuffer); i++) { - bootGuardInfo += usprintf("%02X", elementHeader->IbbHash.HashBuffer[i]); - } + // Add PostIbbHash + bootGuardInfo += UString("\n\nPost IBB Hash:\n"); + for (UINT8 i = 0; i < sizeof(elementHeader->IbbHash.HashBuffer); i++) { + bootGuardInfo += usprintf("%02X", elementHeader->IbbHash.HashBuffer[i]); + } - // Check for non-empry PostIbbHash - UByteArray postIbbHash((const char*)elementHeader->IbbHash.HashBuffer, sizeof(elementHeader->IbbHash.HashBuffer)); - if (postIbbHash.count('\x00') != postIbbHash.size() && postIbbHash.count('\xFF') != postIbbHash.size()) { - BG_PROTECTED_RANGE range; - range.Type = BG_PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB; - range.Hash = postIbbHash; - bgProtectedRanges.push_back(range); - } + // Check for non-empry PostIbbHash + UByteArray postIbbHash((const char*)elementHeader->IbbHash.HashBuffer, sizeof(elementHeader->IbbHash.HashBuffer)); + if (postIbbHash.count('\x00') != postIbbHash.size() && postIbbHash.count('\xFF') != postIbbHash.size()) { + BG_PROTECTED_RANGE range; + range.Type = BG_PROTECTED_RANGE_INTEL_BOOT_GUARD_POST_IBB; + range.Hash = postIbbHash; + bgProtectedRanges.push_back(range); + } - // Add Digest - bgBpDigest = UByteArray((const char*)elementHeader->Digest.HashBuffer, sizeof(elementHeader->Digest.HashBuffer)); - bootGuardInfo += UString("\n\nIBB Digest:\n"); - for (UINT8 i = 0; i < (UINT8)bgBpDigest.size(); i++) { - bootGuardInfo += usprintf("%02X", (UINT8)bgBpDigest.at(i)); - } + // Add Digest + bgBpDigest = UByteArray((const char*)elementHeader->Digest.HashBuffer, sizeof(elementHeader->Digest.HashBuffer)); + bootGuardInfo += UString("\n\nIBB Digest:\n"); + for (UINT8 i = 0; i < (UINT8)bgBpDigest.size(); i++) { + bootGuardInfo += usprintf("%02X", (UINT8)bgBpDigest.at(i)); + } - // Add all IBB segments - bootGuardInfo += UString("\n\nIBB Segments:\n"); - const BG_IBB_SEGMENT_ELEMENT* segments = (const BG_IBB_SEGMENT_ELEMENT*)(elementHeader + 1); - for (UINT8 i = 0; i < elementHeader->IbbSegCount; i++) { - bootGuardInfo += usprintf("Flags: %04Xh Address: %08Xh Size: %08Xh\n", - segments[i].Flags, segments[i].Base, segments[i].Size); - if (segments[i].Flags == BG_IBB_SEGMENT_FLAG_IBB) { - BG_PROTECTED_RANGE range; - range.Offset = segments[i].Base; - range.Size = segments[i].Size; - range.Type = BG_PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB; - bgProtectedRanges.push_back(range); - } - } - } - else if (*currentPos == BG_BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_TAG) { - const BG_PLATFORM_MANUFACTURER_ELEMENT* elementHeader = (const BG_PLATFORM_MANUFACTURER_ELEMENT*)currentPos; - bootGuardInfo += usprintf( - "\nPlatform Manufacturer Data Element found at offset %Xh\n" - "Tag: __PMDA__ Version: %02Xh DataSize: %02Xh", - model->offset(parent) + localOffset + elementOffset, - elementHeader->Version, - elementHeader->DataSize - ); - // Check for Microsoft PMDA hash data - const BG_MICROSOFT_PMDA_HEADER* header = (const BG_MICROSOFT_PMDA_HEADER*)(elementHeader + 1); - if (header->Version == BG_MICROSOFT_PMDA_VERSION - && elementHeader->DataSize == sizeof(BG_MICROSOFT_PMDA_HEADER) + sizeof(BG_MICROSOFT_PMDA_ENTRY)*header->NumEntries) { - // Add entries - bootGuardInfo += UString("\nMicrosoft PMDA-based protected ranges:\n"); - const BG_MICROSOFT_PMDA_ENTRY* entries = (const BG_MICROSOFT_PMDA_ENTRY*)(header + 1); - for (UINT32 i = 0; i < header->NumEntries; i++) { - - bootGuardInfo += usprintf("Address: %08Xh Size: %08Xh\n", entries[i].Address, entries[i].Size); - bootGuardInfo += UString("Hash: "); - for (UINT8 j = 0; j < sizeof(entries[i].Hash); j++) { - bootGuardInfo += usprintf("%02X", entries[i].Hash[j]); - } - bootGuardInfo += UString("\n"); - - BG_PROTECTED_RANGE range; - range.Offset = entries[i].Address; - range.Size = entries[i].Size; - range.Hash = UByteArray((const char*)entries[i].Hash, sizeof(entries[i].Hash)); - range.Type = BG_PROTECTED_RANGE_VENDOR_HASH_MICROSOFT; - bgProtectedRanges.push_back(range); - } - } - else { - // Add raw data - const UINT8* data = (const UINT8*)(elementHeader + 1); - for (UINT16 i = 0; i < elementHeader->DataSize; i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", data[i]); - } - bootGuardInfo += UString("\n"); - } - } - else if (*currentPos == BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_TAG) { - const BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT* elementHeader = (const BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT*)currentPos; - bootGuardInfo += usprintf( - "\nBoot Policy Signature Element found at offset %Xh\n" - "Tag: __PMSG__ Version: %02Xh", - model->offset(parent) + localOffset + elementOffset, - elementHeader->Version - ); - // Add PubKey - bootGuardInfo += usprintf("\n\nBoot Policy RSA Public Key (Exponent: %Xh):", elementHeader->KeySignature.PubKey.Exponent); - for (UINT16 i = 0; i < sizeof(elementHeader->KeySignature.PubKey.Modulus); i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", elementHeader->KeySignature.PubKey.Modulus[i]); - } - - // Calculate and add PubKey hash - UINT8 hash[SHA256_DIGEST_SIZE]; - sha256(&elementHeader->KeySignature.PubKey.Modulus, sizeof(elementHeader->KeySignature.PubKey.Modulus), hash); - bootGuardInfo += UString("\n\nBoot Policy RSA Public Key Hash:"); - for (UINT8 i = 0; i < sizeof(hash); i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", hash[i]); - } - bgBpHash = UByteArray((const char*)hash, sizeof(hash)); - - // Add Signature - bootGuardInfo += UString("\n\nBoot Policy RSA Signature:"); - for (UINT16 i = 0; i < sizeof(elementHeader->KeySignature.Signature.Signature); i++) { - if (i % 32 == 0) - bootGuardInfo += UString("\n"); - bootGuardInfo += usprintf("%02X", elementHeader->KeySignature.Signature.Signature[i]); - } - } - status = findNextElement(bootPolicy, elementOffset + elementSize, elementOffset, elementSize); + // Add all IBB segments + bootGuardInfo += UString("\n\nIBB Segments:\n"); + const BG_IBB_SEGMENT_ELEMENT* segments = (const BG_IBB_SEGMENT_ELEMENT*)(elementHeader + 1); + for (UINT8 i = 0; i < elementHeader->IbbSegCount; i++) { + bootGuardInfo += usprintf("Flags: %04Xh Address: %08Xh Size: %08Xh\n", + segments[i].Flags, segments[i].Base, segments[i].Size); + if (segments[i].Flags == BG_IBB_SEGMENT_FLAG_IBB) { + BG_PROTECTED_RANGE range; + range.Offset = segments[i].Base; + range.Size = segments[i].Size; + range.Type = BG_PROTECTED_RANGE_INTEL_BOOT_GUARD_IBB; + bgProtectedRanges.push_back(range); } - - bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); - bgBootPolicyFound = true; - return U_SUCCESS; } } + else if (*currentPos == BG_BOOT_POLICY_MANIFEST_PLATFORM_MANUFACTURER_ELEMENT_TAG) { + const BG_PLATFORM_MANUFACTURER_ELEMENT* elementHeader = (const BG_PLATFORM_MANUFACTURER_ELEMENT*)currentPos; + bootGuardInfo += usprintf( + "\nPlatform Manufacturer Data Element found at offset %Xh\n" + "Tag: __PMDA__ Version: %02Xh DataSize: %02Xh", + model->offset(parent) + localOffset + elementOffset, + elementHeader->Version, + elementHeader->DataSize + ); + // Check for Microsoft PMDA hash data + const BG_MICROSOFT_PMDA_HEADER* header = (const BG_MICROSOFT_PMDA_HEADER*)(elementHeader + 1); + if (header->Version == BG_MICROSOFT_PMDA_VERSION + && elementHeader->DataSize == sizeof(BG_MICROSOFT_PMDA_HEADER) + sizeof(BG_MICROSOFT_PMDA_ENTRY)*header->NumEntries) { + // Add entries + bootGuardInfo += UString("\nMicrosoft PMDA-based protected ranges:\n"); + const BG_MICROSOFT_PMDA_ENTRY* entries = (const BG_MICROSOFT_PMDA_ENTRY*)(header + 1); + for (UINT32 i = 0; i < header->NumEntries; i++) { + + bootGuardInfo += usprintf("Address: %08Xh Size: %08Xh\n", entries[i].Address, entries[i].Size); + bootGuardInfo += UString("Hash: "); + for (UINT8 j = 0; j < sizeof(entries[i].Hash); j++) { + bootGuardInfo += usprintf("%02X", entries[i].Hash[j]); + } + bootGuardInfo += UString("\n"); + + BG_PROTECTED_RANGE range; + range.Offset = entries[i].Address; + range.Size = entries[i].Size; + range.Hash = UByteArray((const char*)entries[i].Hash, sizeof(entries[i].Hash)); + range.Type = BG_PROTECTED_RANGE_VENDOR_HASH_MICROSOFT; + bgProtectedRanges.push_back(range); + } + } + else { + // Add raw data + const UINT8* data = (const UINT8*)(elementHeader + 1); + for (UINT16 i = 0; i < elementHeader->DataSize; i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", data[i]); + } + bootGuardInfo += UString("\n"); + } + } + else if (*currentPos == BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT_TAG) { + const BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT* elementHeader = (const BG_BOOT_POLICY_MANIFEST_SIGNATURE_ELEMENT*)currentPos; + bootGuardInfo += usprintf( + "\nBoot Policy Signature Element found at offset %Xh\n" + "Tag: __PMSG__ Version: %02Xh", + model->offset(parent) + localOffset + elementOffset, + elementHeader->Version + ); + + // Add PubKey + bootGuardInfo += usprintf("\n\nBoot Policy RSA Public Key (Exponent: %Xh):", elementHeader->KeySignature.PubKey.Exponent); + for (UINT16 i = 0; i < sizeof(elementHeader->KeySignature.PubKey.Modulus); i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", elementHeader->KeySignature.PubKey.Modulus[i]); + } + + // Calculate and add PubKey hash + UINT8 hash[SHA256_DIGEST_SIZE]; + sha256(&elementHeader->KeySignature.PubKey.Modulus, sizeof(elementHeader->KeySignature.PubKey.Modulus), hash); + bootGuardInfo += UString("\n\nBoot Policy RSA Public Key Hash:"); + for (UINT8 i = 0; i < sizeof(hash); i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", hash[i]); + } + bgBpHash = UByteArray((const char*)hash, sizeof(hash)); + + // Add Signature + bootGuardInfo += UString("\n\nBoot Policy RSA Signature:"); + for (UINT16 i = 0; i < sizeof(elementHeader->KeySignature.Signature.Signature); i++) { + if (i % 32 == 0) + bootGuardInfo += UString("\n"); + bootGuardInfo += usprintf("%02X", elementHeader->KeySignature.Signature.Signature[i]); + } + } + status = findNextElement(bootPolicy, elementOffset + elementSize, elementOffset, elementSize); } - return U_INVALID_BG_BOOT_POLICY; + bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n"); + bgBootPolicyFound = true; + return U_SUCCESS; } #endif + diff --git a/common/ffsparser.h b/common/ffsparser.h index 496bcb0..ca17ab0 100644 --- a/common/ffsparser.h +++ b/common/ffsparser.h @@ -75,7 +75,7 @@ private: UByteArray openedImage; UModelIndex lastVtf; - UINT32 capsuleOffsetFixup; + UINT32 imageBase; UINT64 addressDiff; std::vector, UModelIndex> > fitTable; @@ -93,6 +93,10 @@ private: // First pass USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index); + USTATUS parseCapsule(const UByteArray & capsule, UModelIndex & index); + USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseGenericImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); + USTATUS parseRawArea(const UModelIndex & index); USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseVolumeBody(const UModelIndex & index); @@ -101,7 +105,6 @@ private: USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree); USTATUS parseSectionBody(const UModelIndex & index); - USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & root); USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index); @@ -129,7 +132,7 @@ private: USTATUS parseTeImageSectionBody(const UModelIndex & index); USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed); - USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 localOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset); + USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset); USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize); UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion); UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion); diff --git a/common/ffsreport.cpp b/common/ffsreport.cpp index f3628e3..edaa8ee 100644 --- a/common/ffsreport.cpp +++ b/common/ffsreport.cpp @@ -45,7 +45,7 @@ std::vector FfsReport::generate() USTATUS FfsReport::generateRecursive(std::vector & report, UModelIndex index, UINT32 level) { if (!index.isValid()) - return U_SUCCESS; //Nothing to report for invalid index + return U_SUCCESS; // Nothing to report for invalid index // Calculate item CRC32 UByteArray data = model->header(index) + model->body(index) + model->tail(index); diff --git a/common/guiddatabase.cpp b/common/guiddatabase.cpp index ddfe5be..3a0050b 100644 --- a/common/guiddatabase.cpp +++ b/common/guiddatabase.cpp @@ -56,7 +56,7 @@ void initGuidDatabase(const UString & path, UINT32* numEntries) } if (numEntries) - *numEntries = gGuidToUStringMap.size(); + *numEntries = (UINT32)gGuidToUStringMap.size(); } UString guidDatabaseLookup(const EFI_GUID & guid) diff --git a/common/nvramparser.cpp b/common/nvramparser.cpp index ed2eebc..aafd160 100644 --- a/common/nvramparser.cpp +++ b/common/nvramparser.cpp @@ -102,7 +102,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index) else { // Nothing is parsed yet, but the file is not empty if (!offset) { - msg(UString("parseNvarStore: file can't be parsed as NVAR variables store"), index); + msg(usprintf("%s: file can't be parsed as NVAR variables store", __FUNCTION__), index); return U_SUCCESS; } @@ -225,7 +225,8 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index) isInvalidLink = true; UModelIndex nvarIndex; // Search prevously added entries for a link to this variable - for (int i = 0; i < model->rowCount(index); i++) { + // WARNING: O(n^2), may be very slow + for (int i = model->rowCount(index) - 1; i >= 0; i--) { nvarIndex = index.child(i, 0); if (model->hasEmptyParsingData(nvarIndex) == false) { UByteArray nvarData = model->parsingData(nvarIndex); @@ -352,10 +353,10 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index) model->setParsingData(varIndex, UByteArray((const char*)&pdata, sizeof(pdata))); // Show messages - if (msgUnknownExtDataFormat) msg(UString("parseNvarStore: unknown extended data format"), varIndex); - if (msgExtHeaderTooLong) msg(usprintf("parseNvarStore: extended header size (%Xh) is greater than body size (%Xh)", + if (msgUnknownExtDataFormat) msg(usprintf("%s: unknown extended data format", __FUNCTION__), varIndex); + if (msgExtHeaderTooLong) msg(usprintf("%s: extended header size (%Xh) is greater than body size (%Xh)", __FUNCTION__, extendedHeaderSize, body.size()), varIndex); - if (msgExtDataTooShort) msg(usprintf("parseNvarStore: extended header size (%Xh) is too small for timestamp and hash", + if (msgExtDataTooShort) msg(usprintf("%s: extended header size (%Xh) is too small for timestamp and hash", __FUNCTION__, tail.size()), varIndex); // Try parsing the entry data as NVAR storage if it begins with NVAR signature @@ -433,7 +434,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index) UINT32 storeSize = 0; result = getStoreSize(data, storeOffset, storeSize); if (result) { - msg(UString("parseNvramVolumeBody: getStoreSize failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: getStoreSize failed with error ", __FUNCTION__) + errorCodeToUString(result), index); return result; } @@ -448,7 +449,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index) // Add tree item UModelIndex paddingIndex = model->addItem(localOffset + storeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); - msg(UString("parseNvramVolumeBody: one of stores inside overlaps the end of data"), paddingIndex); + msg(usprintf("%s: one of stores inside overlaps the end of data", __FUNCTION__), paddingIndex); // Update variables prevStoreOffset = storeOffset; @@ -461,7 +462,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index) UByteArray store = data.mid(storeOffset, storeSize); result = parseStoreHeader(store, localOffset + storeOffset, index, storeIndex); if (result) - msg(UString("parseNvramVolumeBody: store header parsing failed with error ") + errorCodeToUString(result), index); + msg(usprintf("%s: store header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); // Go to next store prevStoreOffset = storeOffset; @@ -483,7 +484,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index) else { // Nothing is parsed yet, but the file is not empty if (!storeOffset) { - msg(UString("parseNvramVolumeBody: can't be parsed as NVRAM volume"), index); + msg(usprintf("%s: can't be parsed as NVRAM volume", __FUNCTION__), index); return U_SUCCESS; } @@ -521,11 +522,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & if (*currentPos == NVRAM_VSS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_SVS_STORE_SIGNATURE) { //$VSS or $SVS signatures found, perform checks const VSS_VARIABLE_STORE_HEADER* vssHeader = (const VSS_VARIABLE_STORE_HEADER*)currentPos; if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { - msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", localOffset + offset, vssHeader->Format), index); + msg(usprintf("%s: VSS store candidate at offset %Xh skipped, has invalid format %02Xh", __FUNCTION__, localOffset + offset, vssHeader->Format), index); continue; } if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) { - msg(usprintf("findNextStore: VSS store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, vssHeader->Size), index); + msg(usprintf("%s: VSS store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, vssHeader->Size), index); continue; } // All checks passed, store found @@ -538,11 +539,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & const VSS2_VARIABLE_STORE_HEADER* vssHeader = (const VSS2_VARIABLE_STORE_HEADER*)currentPos; if (vssHeader->Format != NVRAM_VSS_VARIABLE_STORE_FORMATTED) { - msg(usprintf("findNextStore: VSS2 store candidate at offset %Xh skipped, has invalid format %02Xh", localOffset + offset, vssHeader->Format), index); + msg(usprintf("%s: VSS2 store candidate at offset %Xh skipped, has invalid format %02Xh", __FUNCTION__, localOffset + offset, vssHeader->Format), index); continue; } if (vssHeader->Size == 0 || vssHeader->Size == 0xFFFFFFFF) { - msg(usprintf("findNextStore: VSS2 store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, vssHeader->Size), index); + msg(usprintf("%s: VSS2 store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, vssHeader->Size), index); continue; } // All checks passed, store found @@ -551,7 +552,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & else if (*currentPos == NVRAM_FDC_VOLUME_SIGNATURE) { //FDC signature found const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)currentPos; if (fdcHeader->Size == 0 || fdcHeader->Size == 0xFFFFFFFF) { - msg(usprintf("findNextStore: FDC store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, fdcHeader->Size), index); + msg(usprintf("%s: FDC store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fdcHeader->Size), index); continue; } // All checks passed, store found @@ -560,7 +561,7 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { //Fsys or Gaid signature found const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos; if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) { - msg(usprintf("findNextStore: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, fsysHeader->Size), index); + msg(usprintf("%s: Fsys store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, fsysHeader->Size), index); continue; } // All checks passed, store found @@ -572,11 +573,11 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)(currentPos - 1); if (evsaHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE) { - msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid type %02Xh", localOffset + offset - 4, evsaHeader->Header.Type), index); + msg(usprintf("%s: EVSA store candidate at offset %Xh skipped, has invalid type %02Xh", __FUNCTION__, localOffset + offset - 4, evsaHeader->Header.Type), index); continue; } if (evsaHeader->StoreSize == 0 || evsaHeader->StoreSize == 0xFFFFFFFF) { - msg(usprintf("findNextStore: EVSA store candidate at offset %Xh skipped, has invalid size %Xh", localOffset + offset, evsaHeader->StoreSize), index); + msg(usprintf("%s: EVSA store candidate at offset %Xh skipped, has invalid size %Xh", __FUNCTION__, localOffset + offset, evsaHeader->StoreSize), index); continue; } // All checks passed, store found @@ -592,14 +593,14 @@ USTATUS NvramParser::findNextStore(const UModelIndex & index, const UByteArray & const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)currentPos; if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize if (ftwHeader->WriteQueueSize == 0 || ftwHeader->WriteQueueSize == 0xFFFFFFFF) { - msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", localOffset + offset, ftwHeader->WriteQueueSize), index); + msg(usprintf("%s: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", __FUNCTION__, localOffset + offset, ftwHeader->WriteQueueSize), index); continue; } } else if (ftwHeader->WriteQueueSize % 0x10 == 0x00) { // Header with 64 bit WriteQueueSize const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64* ftw64Header = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64*)currentPos; if (ftw64Header->WriteQueueSize == 0 || ftw64Header->WriteQueueSize >= 0xFFFFFFFF) { - msg(usprintf("findNextStore: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", localOffset + offset, ftw64Header->WriteQueueSize), index); + msg(usprintf("%s: FTW block candidate at offset %Xh skipped, has invalid body size %Xh", __FUNCTION__, localOffset + offset, ftw64Header->WriteQueueSize), index); continue; } } @@ -750,7 +751,7 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < sizeof(VSS_VARIABLE_STORE_HEADER)) { - msg(UString("parseVssStoreHeader: volume body is too small even for VSS store header"), parent); + msg(usprintf("%s: volume body is too small even for VSS store header", __FUNCTION__), parent); return U_SUCCESS; } @@ -765,7 +766,7 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < storeSize) { - msg(usprintf("parseVssStoreHeader: VSS store size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: VSS store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, storeSize, storeSize, dataSize, dataSize), parent); return U_SUCCESS; @@ -799,7 +800,7 @@ USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < sizeof(VSS2_VARIABLE_STORE_HEADER)) { - msg(UString("parseVss2StoreHeader: volume body is too small even for VSS2 store header"), parent); + msg(usprintf("%s: volume body is too small even for VSS2 store header", __FUNCTION__), parent); return U_SUCCESS; } @@ -814,7 +815,7 @@ USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < storeSize) { - msg(usprintf("parseVssStoreHeader: VSS2 store size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: VSS2 store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, storeSize, storeSize, dataSize, dataSize), parent); return U_SUCCESS; @@ -847,7 +848,7 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64)) { - msg(UString("parseFtwStoreHeader: volume body is too small even for FTW store header"), parent); + msg(usprintf("%s: volume body is too small even for FTW store header", __FUNCTION__), parent); return U_SUCCESS; } @@ -876,7 +877,7 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 has32bitHeader = false; } if (dataSize < ftwBlockSize) { - msg(usprintf("parseFtwStoreHeader: FTW store size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: FTW store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, ftwBlockSize, ftwBlockSize, dataSize, dataSize), parent); return U_SUCCESS; @@ -917,7 +918,7 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < sizeof(FDC_VOLUME_HEADER)) { - msg(UString("parseFdcStoreHeader: volume body is too small even for FDC store header"), parent); + msg(usprintf("%s: volume body is too small even for FDC store header", __FUNCTION__), parent); return U_SUCCESS; } @@ -926,7 +927,7 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < fdcStoreHeader->Size) { - msg(usprintf("parseFdcStoreHeader: FDC store size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: FDC store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, fdcStoreHeader->Size, fdcStoreHeader->Size, dataSize, dataSize), parent); return U_SUCCESS; @@ -935,7 +936,7 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 // Check header size UINT32 headerSize = sizeof(FDC_VOLUME_HEADER); if (dataSize < headerSize) { - msg(usprintf("parseFdcStoreHeader: FDC store header size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: FDC store header size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, fdcStoreHeader->Size, fdcStoreHeader->Size, dataSize, dataSize), parent); return U_SUCCESS; @@ -964,7 +965,7 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < sizeof(APPLE_FSYS_STORE_HEADER)) { - msg(UString("parseFsysStoreHeader: volume body is too small even for Fsys store header"), parent); + msg(usprintf("%s: volume body is too small even for Fsys store header", __FUNCTION__), parent); return U_SUCCESS; } @@ -973,7 +974,7 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < fsysStoreHeader->Size) { - msg(usprintf("parseFsysStoreHeader: Fsys store size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: Fsys store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, fsysStoreHeader->Size, fsysStoreHeader->Size, dataSize, dataSize), parent); return U_SUCCESS; @@ -1011,7 +1012,7 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 // Check dataSize if (dataSize < sizeof(EVSA_STORE_ENTRY)) { - msg(UString("parseEvsaStoreHeader: volume body is too small even for EVSA store header"), parent); + msg(usprintf("%s: volume body is too small even for EVSA store header", __FUNCTION__), parent); return U_SUCCESS; } @@ -1020,7 +1021,7 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < evsaStoreHeader->StoreSize) { - msg(usprintf("parseEvsaStoreHeader: EVSA store size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: EVSA store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, evsaStoreHeader->StoreSize, evsaStoreHeader->StoreSize, dataSize, dataSize), parent); return U_SUCCESS; @@ -1056,7 +1057,7 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI // Check data size if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) { - msg(UString("parseFlashMapStoreHeader: volume body is too small even for FlashMap block header"), parent); + msg(usprintf("%s: volume body is too small even for FlashMap block header", __FUNCTION__), parent); return U_SUCCESS; } @@ -1066,7 +1067,7 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI // Check store size UINT32 flashMapSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + flashMapHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY); if (dataSize < flashMapSize) { - msg(usprintf("parseFlashMapStoreHeader: FlashMap block size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: FlashMap block size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, flashMapSize, flashMapSize, dataSize, dataSize), parent); return U_SUCCESS; @@ -1096,13 +1097,13 @@ USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32 // Check store size if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) { - msg(UString("parseCmdbStoreHeader: volume body is too small even for CMDB store header"), parent); + msg(usprintf("%s: volume body is too small even for CMDB store header", __FUNCTION__), parent); return U_SUCCESS; } UINT32 cmdbSize = NVRAM_PHOENIX_CMDB_SIZE; if (dataSize < cmdbSize) { - msg(usprintf("parseCmdbStoreHeader: CMDB store size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: CMDB store size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, cmdbSize, cmdbSize, dataSize, dataSize), parent); return U_SUCCESS; @@ -1134,7 +1135,7 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3 // Check data size if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) { - msg(UString("parseSlicPubkeyHeader: volume body is too small even for SLIC pubkey header"), parent); + msg(usprintf("%s: volume body is too small even for SLIC pubkey header", __FUNCTION__), parent); return U_SUCCESS; } @@ -1143,7 +1144,7 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3 // Check store size if (dataSize < pubkeyHeader->Size) { - msg(usprintf("parseSlicPubkeyHeader: SLIC pubkey size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: SLIC pubkey size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, pubkeyHeader->Size, pubkeyHeader->Size, dataSize, dataSize), parent); return U_SUCCESS; @@ -1176,7 +1177,7 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3 // Check data size if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) { - msg(UString("parseSlicMarkerHeader: volume body is too small even for SLIC marker header"), parent); + msg(usprintf("%s: volume body is too small even for SLIC marker header", __FUNCTION__), parent); return U_SUCCESS; } @@ -1185,7 +1186,7 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3 // Check store size if (dataSize < markerHeader->Size) { - msg(usprintf("parseSlicMarkerHeader: SLIC marker size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: SLIC marker size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, markerHeader->Size, markerHeader->Size, dataSize, dataSize), parent); return U_SUCCESS; @@ -1218,7 +1219,7 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U // Check data size if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) { - msg(UString("parseIntelMicrocodeHeader: volume body is too small even for Intel microcode header"), parent); + msg(usprintf("%s: volume body is too small even for Intel microcode header", __FUNCTION__), parent); return U_SUCCESS; } @@ -1227,7 +1228,7 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U // Check store size if (dataSize < ucodeHeader->TotalSize) { - msg(usprintf("parseIntelMicrocodeHeader: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", + msg(usprintf("%s: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__, ucodeHeader->TotalSize, ucodeHeader->TotalSize, dataSize, dataSize), parent); return U_SUCCESS; @@ -1267,7 +1268,7 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc const UINT32* signature = (const UINT32*)store.constData(); // Check store size if (dataSize < sizeof(UINT32)) { - msg(UString("parseStoreHeader: volume body is too small even for store signature"), parent); + msg(usprintf("%s: volume body is too small even for a store signature", __FUNCTION__), parent); return U_SUCCESS; } @@ -1288,7 +1289,7 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) return parseFsysStoreHeader(store, localOffset, parent, index); // EVSA store - else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) + else if (dataSize >= 2 * sizeof(UINT32) && *(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) return parseEvsaStoreHeader(store, localOffset, parent, index); // Phoenix SCT flash map else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) @@ -1297,10 +1298,10 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) return parseCmdbStoreHeader(store, localOffset, parent, index); // SLIC pubkey - else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) + else if (dataSize >= 5 * sizeof(UINT32) && *(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) return parseSlicPubkeyHeader(store, localOffset, parent, index); // SLIC marker - else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) + else if (dataSize >= 34 && *(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) return parseSlicMarkerHeader(store, localOffset, parent, index); // Intel microcode // Must be checked after SLIC marker because of the same *signature values @@ -1327,20 +1328,20 @@ USTATUS NvramParser::parseFdcStoreBody(const UModelIndex & index) UModelIndex volumeIndex; USTATUS status = ffsParser->parseVolumeHeader(data, localOffset, index, volumeIndex); if (status || !volumeIndex.isValid()) { - msg(UString("parseFdcStoreBody: store can't be parsed as FDC store"), index); + msg(usprintf("%s: store can't be parsed as FDC store", __FUNCTION__), index); return U_SUCCESS; } // Determine if it's a VSS or VSS2 store inside UByteArray store = model->body(volumeIndex); - if (store.size() >= sizeof(UINT32) && *(const UINT32*)store.constData() == NVRAM_VSS_STORE_SIGNATURE) { + if ((UINT32)store.size() >= sizeof(UINT32) && *(const UINT32*)store.constData() == NVRAM_VSS_STORE_SIGNATURE) { UModelIndex vssIndex; status = parseVssStoreHeader(store, localOffset + model->header(volumeIndex).size(), true, volumeIndex, vssIndex); if (status) return status; return parseVssStoreBody(vssIndex, 0); } - else if (store.size() >= sizeof(EFI_GUID) && store.left(sizeof(EFI_GUID)) == NVRAM_FDC_STORE_GUID) { + else if ((UINT32)store.size() >= sizeof(EFI_GUID) && store.left(sizeof(EFI_GUID)) == NVRAM_FDC_STORE_GUID) { UModelIndex vss2Index; status = parseVss2StoreHeader(store, localOffset + model->header(volumeIndex).size(), true, volumeIndex, vss2Index); if (status) @@ -1348,7 +1349,7 @@ USTATUS NvramParser::parseFdcStoreBody(const UModelIndex & index) return parseVssStoreBody(vss2Index, 0); } else { - msg(UString("parseFdcStoreBody: internal volume can't be parsed as VSS/VSS2 store"), index); + msg(usprintf("%s: internal volume can't be parsed as VSS/VSS2 store", __FUNCTION__), index); return U_SUCCESS; } @@ -1378,7 +1379,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen // Check that the is enough space for variable header const UINT32 dataSize = (UINT32)data.size(); if (dataSize < sizeof(VSS_VARIABLE_HEADER)) { - msg(UString("parseVssStoreBody: store body is too small even for VSS variable header"), index); + msg(usprintf("%s: store body is too small even for VSS variable header", __FUNCTION__), index); return U_SUCCESS; } @@ -1512,7 +1513,7 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen else { // Padding // Nothing is parsed yet, but the store is not empty if (!offset) { - msg(UString("parseVssStoreBody: store can't be parsed as VSS store"), index); + msg(usprintf("%s: store can't be parsed as VSS store", __FUNCTION__), index); return U_SUCCESS; } @@ -1647,7 +1648,7 @@ USTATUS NvramParser::parseFsysStoreBody(const UModelIndex & index) model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index); // Show message - msg(UString("parseFsysStoreBody: next variable appears too big, added as padding"), index); + msg(usprintf("%s: next variable appears too big, added as padding", __FUNCTION__), index); return U_SUCCESS; } @@ -1728,7 +1729,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index) UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index); // Show message - msg(UString("parseEvsaStoreBody: variable parsing failed, the rest of unparsed store added as padding"), itemIndex); + msg(usprintf("%s: variable parsing failed, the rest of unparsed store added as padding", __FUNCTION__), itemIndex); } break; } @@ -1820,7 +1821,7 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index) UModelIndex itemIndex = model->addItem(localOffset + offset, Types::Padding, getPaddingType(body), UString("Padding"), UString(), info, UByteArray(), body, UByteArray(), Fixed, index); // Show message - msg(usprintf("parseEvsaStoreBody: unknown variable of type %02Xh found at offset %Xh, the rest of unparsed store added as padding", entryHeader->Type, offset), itemIndex); + msg(usprintf("%s: unknown variable of type %02Xh found at offset %Xh, the rest of unparsed store added as padding", __FUNCTION__, entryHeader->Type, offset), itemIndex); } break; } @@ -1850,17 +1851,17 @@ USTATUS NvramParser::parseEvsaStoreBody(const UModelIndex & index) if (guid.isEmpty() && name.isEmpty()) { // Both name and guid aren't found model->setSubtype(current, Subtypes::InvalidEvsaEntry); model->setName(current, UString("Invalid")); - msg(UString("parseEvsaStoreBody: data variable with invalid GuidId and invalid VarId"), current); + msg(usprintf("%s: data variable with invalid GuidId and invalid VarId", __FUNCTION__), current); } else if (guid.isEmpty()) { // Guid not found model->setSubtype(current, Subtypes::InvalidEvsaEntry); model->setName(current, UString("Invalid")); - msg(UString("parseEvsaStoreBody: data variable with invalid GuidId"), current); + msg(usprintf("%s: data variable with invalid GuidId", __FUNCTION__), current); } else if (name.isEmpty()) { // Name not found model->setSubtype(current, Subtypes::InvalidEvsaEntry); model->setName(current, UString("Invalid")); - msg(UString("parseEvsaStoreBody: data variable with invalid VarId"), current); + msg(usprintf("%s: data variable with invalid VarId", __FUNCTION__), current); } else { // Variable is OK, rename it if (dataHeader->Header.Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) { @@ -1909,7 +1910,7 @@ USTATUS NvramParser::parseFlashMapBody(const UModelIndex & index) // Show message if (unparsedSize < entryHeader->Size) - msg(UString("parseFlashMapBody: next entry appears too big, added as padding"), index); + msg(usprintf("%s: next entry appears too big, added as padding", __FUNCTION__), index); break; } diff --git a/common/treeitem.cpp b/common/treeitem.cpp index 939a6f9..38d103a 100644 --- a/common/treeitem.cpp +++ b/common/treeitem.cpp @@ -20,9 +20,10 @@ TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype, const bool fixed, const bool compressed, TreeItem *parent) : itemOffset(offset), - itemAction(Actions::NoAction), + itemAction(Actions::NoAction), itemType(type), itemSubtype(subtype), + itemMarking(0), itemName(name), itemText(text), itemInfo(info), @@ -31,7 +32,6 @@ TreeItem::TreeItem(const UINT32 offset, const UINT8 type, const UINT8 subtype, itemTail(tail), itemFixed(fixed), itemCompressed(compressed), - itemMarking(0), parentItem(parent) { } diff --git a/common/utility.cpp b/common/utility.cpp index 31491e2..c517e05 100644 --- a/common/utility.cpp +++ b/common/utility.cpp @@ -34,6 +34,7 @@ UString uniqueItemName(const UModelIndex & index) UString itemText = model->text(index); // Default name + UString name = itemName; switch (model->type(index)) { case Types::NvarEntry: @@ -49,17 +50,26 @@ UString uniqueItemName(const UModelIndex & index) UModelIndex fileIndex = model->findParentOfType(index, Types::File); UString fileText = model->text(fileIndex); name = fileText.isEmpty() ? model->name(fileIndex) : model->name(fileIndex) + '_' + fileText; - } break; + + // Special case of GUIDed sections + if (model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) { + name = model->name(index) +'_' + name; + } + } break; } + // Populate subtypeString UString subtypeString = itemSubtypeToUString(model->type(index), model->subtype(index)); + + // Create final name name = itemTypeToUString(model->type(index)) + (subtypeString.length() ? ('_' + subtypeString) : UString()) + '_' + name; + // Replace some symbols with underscopes for better readability name.findreplace(' ', '_'); name.findreplace('/', '_'); - name.findreplace('-', '_'); + name.findreplace('\\', '_'); return name; } @@ -341,6 +351,7 @@ UINT16 calculateChecksum16(const UINT16* buffer, UINT32 bufferSize) return (UINT16)(0x10000 - counter); } +// Get padding type for a given padding UINT8 getPaddingType(const UByteArray & padding) { if (padding.count('\x00') == padding.size())