From cda0018a295c4848fe80fd0513f50ee9d13e1322 Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Sun, 17 Apr 2016 01:25:44 +0200 Subject: [PATCH] A bit of refactoring here and there - more refactoring to go, because new NVRAM code was written in a hurry and needs to be cleaned up --- UEFITool/uefitool.cpp | 282 +++++++++++++++++------------------------- UEFITool/uefitool.h | 2 +- common/basetypes.h | 3 + common/ffsops.cpp | 50 ++------ common/ffsops.h | 13 +- common/ffsparser.cpp | 254 ++++++++++++++++++------------------- common/ffsparser.h | 20 ++- common/nvram.cpp | 62 ++++------ common/nvram.h | 39 +++--- common/parsingdata.h | 2 +- common/types.cpp | 282 ++++++++++++++---------------------------- common/types.h | 58 +++++---- 12 files changed, 438 insertions(+), 629 deletions(-) diff --git a/UEFITool/uefitool.cpp b/UEFITool/uefitool.cpp index d9c56d1..66da0e3 100644 --- a/UEFITool/uefitool.cpp +++ b/UEFITool/uefitool.cpp @@ -17,7 +17,7 @@ UEFITool::UEFITool(QWidget *parent) : QMainWindow(parent), ui(new Ui::UEFITool), -version(tr("0.30.0_alpha25")) +version(tr("0.30.0_alpha26")) { clipboard = QApplication::clipboard(); @@ -31,9 +31,6 @@ version(tr("0.30.0_alpha25")) ffsOps = NULL; ffsBuilder = NULL; - // Set window title - this->setWindowTitle(tr("UEFITool %1").arg(version)); - // Connect signals to slots connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile())); connect(ui->actionOpenImageFileInNewWindow, SIGNAL(triggered()), this, SLOT(openImageFileInNewWindow())); @@ -59,7 +56,7 @@ version(tr("0.30.0_alpha25")) connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(writeSettings())); // Enable Drag-and-Drop actions - this->setAcceptDrops(true); + setAcceptDrops(true); // Set current directory currentDir = "."; @@ -73,8 +70,9 @@ version(tr("0.30.0_alpha25")) #endif ui->infoEdit->setFont(font); ui->parserMessagesListWidget->setFont(font); - ui->finderMessagesListWidget->setFont(font); ui->fitMessagesListWidget->setFont(font); + ui->finderMessagesListWidget->setFont(font); + ui->builderMessagesListWidget->setFont(font); ui->fitTableWidget->setFont(font); ui->structureTreeView->setFont(font); searchDialog->ui->guidEdit->setFont(font); @@ -89,21 +87,16 @@ version(tr("0.30.0_alpha25")) UEFITool::~UEFITool() { + delete ffsBuilder; delete ffsOps; delete ffsFinder; delete fitParser; delete ffsParser; - delete ffsBuilder; delete model; delete searchDialog; delete ui; } -void UEFITool::setProgramPath(QString path) -{ - currentProgramPath = path; -}; - void UEFITool::init() { // Clear components @@ -116,7 +109,7 @@ void UEFITool::init() ui->messagesTabWidget->setTabEnabled(1, false); // Set window title - this->setWindowTitle(tr("UEFITool %1").arg(version)); + setWindowTitle(tr("UEFITool %1").arg(version)); // Disable menus ui->menuCapsuleActions->setDisabled(true); @@ -126,6 +119,9 @@ void UEFITool::init() ui->menuVolumeActions->setDisabled(true); ui->menuFileActions->setDisabled(true); ui->menuSectionActions->setDisabled(true); + ui->menuStoreActions->setDisabled(true); + ui->menuVariableActions->setDisabled(true); + ui->actionMessagesCopy->setDisabled(true); ui->actionMessagesCopyAll->setDisabled(true); @@ -143,18 +139,19 @@ void UEFITool::init() // Connect connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(populateUi(const QModelIndex &))); - connect(ui->parserMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); - connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); - connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); - connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); - connect(ui->fitMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); - connect(ui->fitMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); + connect(ui->parserMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); + connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); + connect(ui->fitMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); + connect(ui->fitMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); + connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); + connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); connect(ui->builderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*))); - connect(ui->builderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); + connect(ui->builderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*))); } void UEFITool::populateUi(const QModelIndex ¤t) { + // Check sanity if (!current.isValid()) return; @@ -172,15 +169,24 @@ void UEFITool::populateUi(const QModelIndex ¤t) ui->menuVolumeActions->setEnabled(type == Types::Volume); ui->menuFileActions->setEnabled(type == Types::File); ui->menuSectionActions->setEnabled(type == Types::Section); - ui->menuVariableActions->setEnabled(type == Types::NvramVariableNvar || type == Types::NvramVariableVss || type == Types::NvramEntryFsys - || type == Types::NvramEntryEvsa || type == Types::NvramEntryFlashMap); - ui->menuStoreActions->setEnabled(type == Types::NvramStoreVss || type == Types::NvramStoreFdc || type == Types::NvramStoreFsys - || type == Types::NvramStoreEvsa || type == Types::NvramStoreFtw || type == Types::NvramStoreFlashMap || type == Types::NvramStoreCmdb - || type == Types::Microcode || type == Types::SlicPubkey || type == Types::SlicMarker); + ui->menuVariableActions->setEnabled(type == Types::NvarEntry + || type == Types::VssEntry + || type == Types::FsysEntry + || type == Types::EvsaEntry + || type == Types::FlashMapEntry); + ui->menuStoreActions->setEnabled(type == Types::VssStore + || type == Types::FdcStore + || type == Types::FsysStore + || type == Types::EvsaStore + || type == Types::FtwStore + || type == Types::FlashMapStore + || type == Types::CmdbStore + || type == Types::Microcode + || type == Types::SlicData); // Enable actions ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current)); - ui->actionGoToData->setEnabled(type == Types::NvramVariableNvar && subtype == Subtypes::LinkNvarVariable); + ui->actionGoToData->setEnabled(type == Types::NvarEntry && subtype == Subtypes::LinkNvarEntry); // Disable rebuild for now //ui->actionRebuild->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion); @@ -284,7 +290,7 @@ void UEFITool::search() void UEFITool::goToData() { QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex(); - if (!index.isValid() || model->type(index) != Types::NvramVariableNvar || model->subtype(index) != Subtypes::LinkNvarVariable) + if (!index.isValid() || model->type(index) != Types::NvarEntry || model->subtype(index) != Subtypes::LinkNvarEntry) return; // Get parent @@ -515,122 +521,77 @@ void UEFITool::extract(const UINT8 mode) //ui->statusBar->showMessage(name); UINT8 type = model->type(index); + UINT8 subtype = model->subtype(index); 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 (*)"); + 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::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::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 (*)"); 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::NvramVariableNvar: - path = QFileDialog::getSaveFileName(this, tr("Save NVAR variable to file"), name + ".nvar", "NVAR variable files (*.nvar *.bin);;All files (*)"); - break; - case Types::NvramVariableVss: - path = QFileDialog::getSaveFileName(this, tr("Save VSS variable to file"), name + ".var", "VSS variable files (*.var *.bin);;All files (*)"); - break; - case Types::NvramEntryFsys: - path = QFileDialog::getSaveFileName(this, tr("Save Fsys entry to file"), name + ".fse", "Fsys entry files (*.fse *.bin);;All files (*)"); - break; - case Types::NvramEntryEvsa: - path = QFileDialog::getSaveFileName(this, tr("Save EVSA entry to file"), name + ".evse", "EVSA entry files (*.evse *.bin);;All files (*)"); - break; - case Types::NvramEntryFlashMap: - path = QFileDialog::getSaveFileName(this, tr("Save FlashMap entry to file"), name + ".fme", "FlashMap entry files (*.fme *.bin);;All files (*)"); - break; - case Types::NvramStoreVss: - path = QFileDialog::getSaveFileName(this, tr("Save VSS store to file"), name + ".vss", "VSS store files (*.vss *.bin);;All files (*)"); - break; - case Types::NvramStoreFdc: - path = QFileDialog::getSaveFileName(this, tr("Save FDC store to file"), name + ".fdc", "FDC store files (*.fdc *.bin);;All files (*)"); - break; - case Types::NvramStoreFsys: - path = QFileDialog::getSaveFileName(this, tr("Save Fsys store to file"), name + ".fsys", "Fsys store files (*.fsys *.bin);;All files (*)"); - break; - case Types::NvramStoreEvsa: - path = QFileDialog::getSaveFileName(this, tr("Save EVSA store to file"), name + ".evsa", "EVSA store files (*.evsa *.bin);;All files (*)"); - break; - case Types::NvramStoreFtw: - path = QFileDialog::getSaveFileName(this, tr("Save FTW store to file"), name + ".ftw", "FTW store files (*.ftw *.bin);;All files (*)"); - break; - case Types::NvramStoreFlashMap: - path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store to file"), name + ".fmap", "FlashMap store files (*.fmap *.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", "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 (*)"); + 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::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 (*)"); break; - case Types::Volume: - path = QFileDialog::getSaveFileName(this, tr("Save volume body to file"), name + ".vbd", "Volume body files (*.vbd *.bin);;All files (*)"); + 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 (*)"); + 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 (*)"); + 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::VssStore: + 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::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 (*)"); break; - case Types::File: { - if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == 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 (*)"); - } - break; - case Types::Section: { - if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == 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 (model->subtype(index) == 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 (model->subtype(index) == EFI_SECTION_RAW) - path = QFileDialog::getSaveFileName(this, tr("Save section body to raw file"), name + ".raw", "Raw files (*.raw *.bin);;All files (*)"); - else if (model->subtype(index) == EFI_SECTION_PE32 || model->subtype(index) == EFI_SECTION_TE || model->subtype(index) == EFI_SECTION_PIC) - path = QFileDialog::getSaveFileName(this, tr("Save section body to EFI executable file"), name + ".efi", "EFI executable files (*.efi *.dxe *.pei *.bin);;All files (*)"); - else - path = QFileDialog::getSaveFileName(this, tr("Save section body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); - } - break; - case Types::NvramVariableNvar: - case Types::NvramVariableVss: - case Types::NvramEntryEvsa: - path = QFileDialog::getSaveFileName(this, tr("Save variable body to file"), name + ".bin", "Binary files (*.bin);;All files (*)"); - break; - case Types::NvramStoreVss: - case Types::NvramStoreFdc: - path = QFileDialog::getSaveFileName(this, tr("Save VSS variable store body to file"), name + ".vsb", "VSS variable store body files (*.vsb *.bin);;All files (*)"); - break; - case Types::NvramStoreFsys: - path = QFileDialog::getSaveFileName(this, tr("Save Fsys store body to file"), name + ".fsb", "Fsys store body files (*.fsb *.bin);;All files (*)"); - break; - case Types::NvramStoreEvsa: - path = QFileDialog::getSaveFileName(this, tr("Save EVSA store body to file"), name + ".esb", "EVSA store body files (*.esb *.bin);;All files (*)"); - break; - case Types::NvramStoreFtw: - path = QFileDialog::getSaveFileName(this, tr("Save FTW store body to file"), name + ".ftb", "FTW store body files (*.ftb *.bin);;All files (*)"); - break; - case Types::NvramStoreFlashMap: - path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store body to file"), name + ".fmb", "FlashMap store body files (*.fmb *.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", "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", "Binary files (*.bin);;All files (*)"); if (path.trimmed().isEmpty()) return; @@ -962,46 +923,27 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event) switch (model->type(index)) { - case Types::Capsule: - ui->menuCapsuleActions->exec(event->globalPos()); - break; - case Types::Image: - ui->menuImageActions->exec(event->globalPos()); - break; - case Types::Region: - ui->menuRegionActions->exec(event->globalPos()); - break; - case Types::Padding: - ui->menuPaddingActions->exec(event->globalPos()); - break; - case Types::Volume: - ui->menuVolumeActions->exec(event->globalPos()); - break; - case Types::File: - ui->menuFileActions->exec(event->globalPos()); - break; - case Types::Section: - ui->menuSectionActions->exec(event->globalPos()); - break; - case Types::NvramVariableNvar: - case Types::NvramVariableVss: - case Types::NvramEntryFsys: - case Types::NvramEntryEvsa: - case Types::NvramEntryFlashMap: - ui->menuVariableActions->exec(event->globalPos()); - break; - case Types::NvramStoreVss: - case Types::NvramStoreFdc: - case Types::NvramStoreFsys: - case Types::NvramStoreEvsa: - case Types::NvramStoreFtw: - case Types::NvramStoreFlashMap: - case Types::NvramStoreCmdb: + case Types::Capsule: ui->menuCapsuleActions->exec(event->globalPos()); break; + case Types::Image: ui->menuImageActions->exec(event->globalPos()); break; + case Types::Region: ui->menuRegionActions->exec(event->globalPos()); break; + case Types::Padding: ui->menuPaddingActions->exec(event->globalPos()); break; + case Types::Volume: ui->menuVolumeActions->exec(event->globalPos()); break; + case Types::File: ui->menuFileActions->exec(event->globalPos()); break; + case Types::Section: ui->menuSectionActions->exec(event->globalPos()); break; + case Types::NvarEntry: + case Types::VssEntry: + case Types::FsysEntry: + case Types::EvsaEntry: + case Types::FlashMapEntry: ui->menuVariableActions->exec(event->globalPos()); break; + case Types::VssStore: + case Types::FdcStore: + case Types::FsysStore: + case Types::EvsaStore: + case Types::FtwStore: + case Types::FlashMapStore: + case Types::CmdbStore: case Types::Microcode: - case Types::SlicPubkey: - case Types::SlicMarker: - ui->menuStoreActions->exec(event->globalPos()); - break; + case Types::SlicData: ui->menuStoreActions->exec(event->globalPos()); break; } } diff --git a/UEFITool/uefitool.h b/UEFITool/uefitool.h index 517cac2..0dcf0c0 100644 --- a/UEFITool/uefitool.h +++ b/UEFITool/uefitool.h @@ -59,7 +59,7 @@ public: ~UEFITool(); void openImageFile(QString path); - void setProgramPath(QString path); + void setProgramPath(QString path) { currentProgramPath = path; } private slots: void init(); diff --git a/common/basetypes.h b/common/basetypes.h index bd386fa..a2faed1 100644 --- a/common/basetypes.h +++ b/common/basetypes.h @@ -166,4 +166,7 @@ UINT8: 8; #define hexarg(X) arg(QString("%1").arg((X),0,16).toUpper()) #define hexarg2(X, Y) arg(QString("%1").arg((X),(Y),16,QLatin1Char('0')).toUpper()) +// SHA256 hash size in bytes +#define SHA256_HASH_SIZE 0x20 + #endif // BASETYPES_H diff --git a/common/ffsops.cpp b/common/ffsops.cpp index 7454374..ba0d8d1 100644 --- a/common/ffsops.cpp +++ b/common/ffsops.cpp @@ -13,30 +13,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "ffsops.h" -FfsOperations::FfsOperations(TreeModel* treeModel) - : model(treeModel) -{ -} - -FfsOperations::~FfsOperations() -{ -} - -void FfsOperations::msg(const QString & message, const QModelIndex & index) -{ - messagesVector.push_back(std::pair(message, index)); -} - -std::vector > FfsOperations::getMessages() const -{ - return messagesVector; -} - -void FfsOperations::clearMessages() -{ - messagesVector.clear(); -} - STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode) { // Sanity check @@ -49,18 +25,18 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr // Construct a name for extracted data QString itemName = model->name(index); QString itemText = model->text(index); + + // Default name + name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_'); + switch (model->type(index)) { - case Types::Volume: { - if (pdata.volume.hasExtendedHeader) - name = guidToQString(pdata.volume.extendedHeaderGuid).replace('-', '_'); - else - name = itemName.replace('-', '_'); - } break; - case Types::NvramVariableNvar: - case Types::NvramVariableVss: - case Types::File: { - name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_'); - } break; + case Types::Volume: if (pdata.volume.hasExtendedHeader) name = guidToQString(pdata.volume.extendedHeaderGuid).replace('-', '_'); break; + case Types::NvarEntry: + case Types::VssEntry: + case Types::FsysEntry: + case Types::EvsaEntry: + case Types::FlashMapEntry: + case Types::File: name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_'); break; case Types::Section: { // Get parent file name QModelIndex fileIndex = model->findParentOfType(index, Types::File); @@ -68,9 +44,7 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_'); // Append section subtype name name += QChar('_') + itemName.replace(' ', '_'); - } break; - default: - name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_'); + } break; } // Get extracted data diff --git a/common/ffsops.h b/common/ffsops.h index 56f2e82..4876411 100644 --- a/common/ffsops.h +++ b/common/ffsops.h @@ -29,11 +29,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. class FfsOperations { public: - explicit FfsOperations(TreeModel * treeModel); - ~FfsOperations(); - std::vector > getMessages() const; - void clearMessages(); + FfsOperations(TreeModel * treeModel) : model(treeModel) {} + ~FfsOperations() {}; + + std::vector > getMessages() const { return messagesVector; } + void clearMessages() { messagesVector.clear(); } STATUS extract(const QModelIndex & index, QString & name, QByteArray & extracted, const UINT8 mode); STATUS replace(const QModelIndex & index, const QString & data, const UINT8 mode); @@ -45,7 +46,9 @@ private: TreeModel* model; std::vector > messagesVector; - void msg(const QString & message, const QModelIndex &index = QModelIndex()); + void msg(const QString & message, const QModelIndex &index = QModelIndex()) { + messagesVector.push_back(std::pair(message, index)); + } }; #endif // FFSOPS_H diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index 999e090..a06e878 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -33,12 +33,10 @@ STATUS FfsParser::parse(const QByteArray & buffer) if (result) return result; - if (lastVtf.isValid()) { + if (lastVtf.isValid()) result = performSecondPass(root); - } - else { + else msg(QObject::tr("parse: not a single Volume Top File is found, the image may be corrupted")); - } return result; } @@ -202,7 +200,7 @@ STATUS FfsParser::performFirstPass(const QByteArray & buffer, QModelIndex & inde QModelIndex biosIndex = model->addItem(Types::Image, Subtypes::UefiImage, name, QString(), info, QByteArray(), flashImage, TRUE, parsingDataToQByteArray(pdata), index); // Parse the image - result = parseRawArea(flashImage, biosIndex); + result = parseRawArea(biosIndex); if (!index.isValid()) index = biosIndex; return result; @@ -742,7 +740,7 @@ STATUS FfsParser::parsePdrRegion(const QByteArray & pdr, const UINT32 parentOffs index = model->addItem(Types::Region, Subtypes::PdrRegion, name, QString(), info, QByteArray(), pdr, TRUE, parsingDataToQByteArray(pdata), parent); // Parse PDR region as BIOS space - UINT8 result = parseRawArea(pdr, index); + UINT8 result = parseRawArea(index); if (result && result != ERR_VOLUMES_NOT_FOUND && result != ERR_INVALID_VOLUME) return result; @@ -792,7 +790,7 @@ STATUS FfsParser::parseBiosRegion(const QByteArray & bios, const UINT32 parentOf // Add tree item index = model->addItem(Types::Region, Subtypes::BiosRegion, name, QString(), info, QByteArray(), bios, TRUE, parsingDataToQByteArray(pdata), parent); - return parseRawArea(bios, index); + return parseRawArea(index); } UINT8 FfsParser::getPaddingType(const QByteArray & padding) @@ -804,7 +802,7 @@ UINT8 FfsParser::getPaddingType(const QByteArray & padding) return Subtypes::DataPadding; } -STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & index) +STATUS FfsParser::parseRawArea(const QModelIndex & index) { // Sanity check if (!index.isValid()) @@ -815,6 +813,9 @@ STATUS FfsParser::parseRawArea(const QByteArray & data, const QModelIndex & inde UINT32 headerSize = model->header(index).size(); UINT32 offset = pdata.offset + headerSize; + // Get item data + QByteArray data = model->body(index); + // Search for first volume STATUS result; UINT32 prevVolumeOffset; @@ -1322,7 +1323,7 @@ STATUS FfsParser::parseVolumeBody(const QModelIndex & index) // Parse VSS NVRAM volumes with a dedicated function if (model->subtype(index) == Subtypes::NvramVolume) - return parseStoreArea(volumeBody, index); + return parseNvramVolumeBody(index); if (pdata.ffsVersion != 2 && pdata.ffsVersion != 3) // Don't parse unknown volumes return ERR_SUCCESS; @@ -1680,7 +1681,7 @@ STATUS FfsParser::parseFileBody(const QModelIndex & index) if (pdata.file.format == RAW_FILE_FORMAT_NVAR_STORE) return parseNvarStore(model->body(index), index); - return parseRawArea(model->body(index), index); + return parseRawArea(index); } // Parse sections @@ -2252,7 +2253,7 @@ STATUS FfsParser::parseSectionBody(const QModelIndex & index) case EFI_SECTION_GUID_DEFINED: return parseGuidedSectionBody(index); case EFI_SECTION_DISPOSABLE: return parseSections(model->body(index), index); // Leaf - case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseRawArea(model->body(index), index); + case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseRawArea(index); case EFI_SECTION_VERSION: return parseVersionSectionBody(index); case EFI_SECTION_DXE_DEPEX: case EFI_SECTION_PEI_DEPEX: @@ -2261,7 +2262,7 @@ STATUS FfsParser::parseSectionBody(const QModelIndex & index) case EFI_SECTION_PE32: case EFI_SECTION_PIC: return parsePeImageSectionBody(index); case EFI_SECTION_USER_INTERFACE: return parseUiSectionBody(index); - case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return parseRawArea(model->body(index), index); + case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return parseRawArea(index); case EFI_SECTION_RAW: return parseRawSectionBody(index); // No parsing needed case EFI_SECTION_COMPATIBILITY16: @@ -2615,7 +2616,7 @@ STATUS FfsParser::parseRawSectionBody(const QModelIndex & index) } // Parse as raw area - return parseRawArea(model->body(index), index); + return parseRawArea(index); } @@ -2873,7 +2874,7 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in UINT32 offset = 0; UINT32 guidsInStore = 0; - // Parse all variables + // Parse all entries while (1) { bool msgUnknownExtDataFormat = false; bool msgExtHeaderTooLong = false; @@ -2894,7 +2895,7 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in UINT64 timestamp = 0; QByteArray hash; - UINT8 subtype = Subtypes::FullNvarVariable; + UINT8 subtype = Subtypes::FullNvarEntry; QString name; QString text; QByteArray header; @@ -2904,13 +2905,12 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in UINT32 guidAreaSize = guidsInStore * sizeof(EFI_GUID); UINT32 unparsedSize = (UINT32)data.size() - offset - guidAreaSize; - // Get variable header - const NVAR_VARIABLE_HEADER* variableHeader = (const NVAR_VARIABLE_HEADER*)(data.constData() + offset); + // Get entry header + const NVAR_ENTRY_HEADER* entryHeader = (const NVAR_ENTRY_HEADER*)(data.constData() + offset); - // Check variable header - if (unparsedSize < sizeof(NVAR_VARIABLE_HEADER) || - variableHeader->Signature != NVRAM_NVAR_VARIABLE_SIGNATURE || - unparsedSize < variableHeader->Size) { + // Check header size + if (unparsedSize < sizeof(NVAR_ENTRY_HEADER) || + unparsedSize < entryHeader->Size) { // Check if the data left is a free space or a padding QByteArray padding = data.mid(offset, unparsedSize); @@ -2958,29 +2958,29 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in } // Contruct generic header and body - header = data.mid(offset, sizeof(NVAR_VARIABLE_HEADER)); - body = data.mid(offset + sizeof(NVAR_VARIABLE_HEADER), variableHeader->Size - sizeof(NVAR_VARIABLE_HEADER)); + header = data.mid(offset, sizeof(NVAR_ENTRY_HEADER)); + body = data.mid(offset + sizeof(NVAR_ENTRY_HEADER), entryHeader->Size - sizeof(NVAR_ENTRY_HEADER)); UINT32 lastVariableFlag = pdata.emptyByte ? 0xFFFFFF : 0; // Set default next to predefined last value pdata.nvram.nvar.next = lastVariableFlag; - // Variable is marked as invalid - if ((variableHeader->Attributes & NVRAM_NVAR_VARIABLE_ATTRIB_VALID) == 0) { // Valid attribute is not set + // Entry is marked as invalid + if ((entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_VALID) == 0) { // Valid attribute is not set isInvalid = true; // Do not parse further goto parsing_done; } // Add next node information to parsing data - if (variableHeader->Next != lastVariableFlag) { - subtype = Subtypes::LinkNvarVariable; - pdata.nvram.nvar.next = variableHeader->Next; + if (entryHeader->Next != lastVariableFlag) { + subtype = Subtypes::LinkNvarEntry; + pdata.nvram.nvar.next = entryHeader->Next; } - // Variable with extended header - if (variableHeader->Attributes & NVRAM_NVAR_VARIABLE_ATTRIB_EXT_HEADER) { + // Exntry with extended header + if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_EXT_HEADER) { hasExtendedHeader = true; msgUnknownExtDataFormat = true; @@ -2995,24 +2995,24 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in extendedAttributes = *(UINT8*)(body.constData() + body.size() - extendedHeaderSize); // Variable with checksum - if (extendedAttributes & NVRAM_NVAR_VARIABLE_EXT_ATTRIB_CHECKSUM) { + if (extendedAttributes & NVRAM_NVAR_ENTRY_EXT_ATTRIB_CHECKSUM) { // Get stored checksum storedChecksum = *(UINT8*)(body.constData() + body.size() - sizeof(UINT16) - sizeof(UINT8)); // Recalculate checksum for the variable calculatedChecksum = 0; - // Include variable data - UINT8* start = (UINT8*)(variableHeader + 1); - for (UINT8* p = start; p < start + variableHeader->Size - sizeof(NVAR_VARIABLE_HEADER); p++) { + // Include entry data + UINT8* start = (UINT8*)(entryHeader + 1); + for (UINT8* p = start; p < start + entryHeader->Size - sizeof(NVAR_ENTRY_HEADER); p++) { calculatedChecksum += *p; } - // Include variable size and flags - start = (UINT8*)&variableHeader->Size; + // Include entry size and flags + start = (UINT8*)&entryHeader->Size; for (UINT8*p = start; p < start + sizeof(UINT16); p++) { calculatedChecksum += *p; } - // Include variable attributes - calculatedChecksum += variableHeader->Attributes; + // Include entry attributes + calculatedChecksum += entryHeader->Attributes; hasChecksum = true; msgUnknownExtDataFormat = false; @@ -3021,9 +3021,9 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in extendedData = body.mid(body.size() - extendedHeaderSize + sizeof(UINT8), extendedHeaderSize - sizeof(UINT16) - sizeof(UINT8) - (hasChecksum ? 1 : 0)); body = body.left(body.size() - extendedHeaderSize); - // Variable with authenticated write (for SecureBoot) - if (variableHeader->Attributes & NVRAM_NVAR_VARIABLE_ATTRIB_AUTH_WRITE) { - if (extendedData.size() < 40) { + // Entry with authenticated write (for SecureBoot) + if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_AUTH_WRITE) { + if (extendedData.size() < sizeof(UINT64) + SHA256_HASH_SIZE) { msgExtDataTooShort = true; isInvalid = true; // Do not parse further @@ -3031,17 +3031,17 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in } timestamp = *(UINT64*)(extendedData.constData()); - hash = extendedData.mid(sizeof(UINT64), 0x20); //Length of SHA256 hash + hash = extendedData.mid(sizeof(UINT64), SHA256_HASH_SIZE); hasTimestampAndHash = true; msgUnknownExtDataFormat = false; } } - // Variable is data-only (nameless and GUIDless link) - if (variableHeader->Attributes & NVRAM_NVAR_VARIABLE_ATTRIB_DATA_ONLY) { // Data-only attribute is set + // Entry is data-only (nameless and GUIDless entry or link) + if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_DATA_ONLY) { // Data-only attribute is set isInvalid = true; QModelIndex nvarIndex; - // Search prevously added variable for a link to this variable + // Search prevously added entries for a link to this variable //TODO:replace with linked lists for (int i = 0; i < model->rowCount(index); i++) { nvarIndex = index.child(i, 0); PARSING_DATA nvarPdata = parsingDataFromQModelIndex(nvarIndex); @@ -3056,8 +3056,8 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in name = model->name(nvarIndex); text = model->text(nvarIndex); - if (variableHeader->Next == lastVariableFlag) - subtype = Subtypes::DataNvarVariable; + if (entryHeader->Next == lastVariableFlag) + subtype = Subtypes::DataNvarEntry; } isDataOnly = true; @@ -3065,12 +3065,12 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in goto parsing_done; } - // Get variable name + // Get entry name { - UINT32 nameOffset = (variableHeader->Attributes & NVRAM_NVAR_VARIABLE_ATTRIB_GUID) ? sizeof(EFI_GUID) : 1; // GUID can be stored with the variable or in a separate store, so there will only be an index of it - CHAR8* namePtr = (CHAR8*)(variableHeader + 1) + nameOffset; + UINT32 nameOffset = (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_GUID) ? sizeof(EFI_GUID) : 1; // GUID can be stored with the variable or in a separate store, so there will only be an index of it + CHAR8* namePtr = (CHAR8*)(entryHeader + 1) + nameOffset; UINT32 nameSize = 0; - if (variableHeader->Attributes & NVRAM_NVAR_VARIABLE_ATTRIB_ASCII_NAME) { // Name is stored as ASCII string of CHAR8s + if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_ASCII_NAME) { // Name is stored as ASCII string of CHAR8s text = QString(namePtr); nameSize = text.length() + 1; } @@ -3079,13 +3079,13 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in nameSize = (text.length() + 1) * 2; } - // Get variable GUID - if (variableHeader->Attributes & NVRAM_NVAR_VARIABLE_ATTRIB_GUID) { // GUID is strored in the variable itself - name = guidToQString(*(EFI_GUID*)(variableHeader + 1)); + // Get entry GUID + if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_ATTRIB_GUID) { // GUID is strored in the variable itself + name = guidToQString(*(EFI_GUID*)(entryHeader + 1)); } // GUID is stored in GUID list at the end of the store else { - guidIndex = *(UINT8*)(variableHeader + 1); + guidIndex = *(UINT8*)(entryHeader + 1); if (guidsInStore < guidIndex + 1) guidsInStore = guidIndex + 1; @@ -3095,24 +3095,24 @@ STATUS FfsParser::parseNvarStore(const QByteArray & data, const QModelIndex & in hasGuidIndex = true; } - // Include variable name and GUID into the header and remove them from body - header = data.mid(offset, sizeof(NVAR_VARIABLE_HEADER) + nameOffset + nameSize); + // Include name and GUID into the header and remove them from body + header = data.mid(offset, sizeof(NVAR_ENTRY_HEADER) + nameOffset + nameSize); body = body.mid(nameOffset + nameSize); } parsing_done: QString info; - // Rename invalid variables according to their types + // Rename invalid entries according to their types if (isInvalid) { - if (variableHeader->Next != lastVariableFlag) { + if (entryHeader->Next != lastVariableFlag) { name = QObject::tr("Invalid link"); - subtype = Subtypes::InvalidLinkNvarVariable; + subtype = Subtypes::InvalidLinkNvarEntry; } else { name = QObject::tr("Invalid"); - subtype = Subtypes::InvalidNvarVariable; + subtype = Subtypes::InvalidNvarEntry; } } - else // Add GUID info for valid variables + else // Add GUID info for valid entries info += QObject::tr("Variable GUID: %1\n").arg(name); // Add GUID index information @@ -3121,20 +3121,20 @@ parsing_done: // Add header, body and extended data info info += QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)") - .hexarg(variableHeader->Size).arg(variableHeader->Size) + .hexarg(entryHeader->Size).arg(entryHeader->Size) .hexarg(header.size()).arg(header.size()) .hexarg(body.size()).arg(body.size()); // Add attributes info - info += QObject::tr("\nAttributes: %1h").hexarg2(variableHeader->Attributes, 2); + info += QObject::tr("\nAttributes: %1h").hexarg2(entryHeader->Attributes, 2); // Translate attributes to text - if (variableHeader->Attributes) - info += QObject::tr("\nAttributes as text: %1").arg(nvarAttributesToQString(variableHeader->Attributes)); - pdata.nvram.nvar.attributes = variableHeader->Attributes; + if (entryHeader->Attributes) + info += QObject::tr("\nAttributes as text: %1").arg(nvarAttributesToQString(entryHeader->Attributes)); + pdata.nvram.nvar.attributes = entryHeader->Attributes; // Add next node info - if (!isInvalid && variableHeader->Next != lastVariableFlag) - info += QObject::tr("\nNext node at offset: %1h").hexarg(parentOffset + offset + variableHeader->Next); + if (!isInvalid && entryHeader->Next != lastVariableFlag) + info += QObject::tr("\nNext node at offset: %1h").hexarg(parentOffset + offset + entryHeader->Next); // Add extended header info if (hasExtendedHeader) { @@ -3164,31 +3164,28 @@ parsing_done: pdata.offset = parentOffset + offset; // Add tree item - QModelIndex varIndex = model->addItem(Types::NvramVariableNvar, subtype, name, text, info, header, body, FALSE, parsingDataToQByteArray(pdata), index); + QModelIndex varIndex = model->addItem(Types::NvarEntry, subtype, name, text, info, header, body, FALSE, parsingDataToQByteArray(pdata), index); // Show messages - if (msgUnknownExtDataFormat) - msg(QObject::tr("parseNvarStore: unknown extended data format"), varIndex); - if (msgExtHeaderTooLong) - msg(QObject::tr("parseNvarStore: extended header size (%1h) is greater than body size (%2h)") - .hexarg(extendedHeaderSize).hexarg(body.size()), varIndex); - if (msgExtDataTooShort) - msg(QObject::tr("parseNvarStore: extended data size (%1h) is smaller than required for timestamp and hash (0x28)") - .hexarg(extendedData.size()), varIndex); + if (msgUnknownExtDataFormat) msg(QObject::tr("parseNvarStore: unknown extended data format"), varIndex); + if (msgExtHeaderTooLong) msg(QObject::tr("parseNvarStore: extended header size (%1h) is greater than body size (%2h)") + .hexarg(extendedHeaderSize).hexarg(body.size()), varIndex); + if (msgExtDataTooShort) msg(QObject::tr("parseNvarStore: extended data size (%1h) is smaller than required for timestamp and hash (0x28)") + .hexarg(extendedData.size()), varIndex); - // Try parsing the variable data as NVAR storage if it begins with NVAR signature - if ((subtype == Subtypes::DataNvarVariable || subtype == Subtypes::FullNvarVariable) && - *(const UINT32*)body.constData() == NVRAM_NVAR_VARIABLE_SIGNATURE) + // Try parsing the entry data as NVAR storage if it begins with NVAR signature + if ((subtype == Subtypes::DataNvarEntry || subtype == Subtypes::FullNvarEntry) + && *(const UINT32*)body.constData() == NVRAM_NVAR_ENTRY_SIGNATURE) parseNvarStore(body, varIndex); - // Move to next variable - offset += variableHeader->Size; + // Move to next exntry + offset += entryHeader->Size; } return ERR_SUCCESS; } -STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & index) +STATUS FfsParser::parseNvramVolumeBody(const QModelIndex & index) { // Sanity check if (!index.isValid()) @@ -3198,6 +3195,9 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in PARSING_DATA pdata = parsingDataFromQModelIndex(index); UINT32 parentOffset = pdata.offset + model->header(index).size(); + // Get item data + QByteArray data = model->body(index); + // Search for first volume STATUS result; UINT32 prevStoreOffset; @@ -3251,7 +3251,7 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in UINT32 storeSize = 0; result = getStoreSize(data, storeOffset, storeSize); if (result) { - msg(QObject::tr("parseStoreArea: getVssStoreSize failed with error \"%1\"").arg(errorCodeToQString(result)), index); + msg(QObject::tr("parseNvramVolumeBody: getStoreSize failed with error \"%1\"").arg(errorCodeToQString(result)), index); return result; } @@ -3270,7 +3270,7 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in // Add tree item QModelIndex paddingIndex = model->addItem(Types::Padding, getPaddingType(padding), name, QString(), info, QByteArray(), padding, TRUE, parsingDataToQByteArray(pdata), index); - msg(QObject::tr("parseStoreArea: one of stores inside overlaps the end of data"), paddingIndex); + msg(QObject::tr("parseNvramVolumeBody: one of stores inside overlaps the end of data"), paddingIndex); // Update variables prevStoreOffset = storeOffset; @@ -3283,7 +3283,7 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in QModelIndex storeIndex; result = parseStoreHeader(store, parentOffset + storeOffset, index, storeIndex); if (result) { - msg(QObject::tr("parseStoreArea: store header parsing failed with error \"%1\"").arg(errorCodeToQString(result)), index); + msg(QObject::tr("parseNvramVolumeBody: store header parsing failed with error \"%1\"").arg(errorCodeToQString(result)), index); } // Go to next volume @@ -3307,7 +3307,7 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in else { // Nothing is parsed yet, but the file is not empty if (!storeOffset) { - msg(QObject::tr("parseStoreArea: area can't be parsed as variable store"), index); + msg(QObject::tr("parseNvramVolumeBody: can't be parsed as NVRAM volume"), index); return ERR_SUCCESS; } @@ -3332,45 +3332,27 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in for (int i = 0; i < model->rowCount(index); i++) { QModelIndex current = index.child(i, 0); switch (model->type(current)) { - case Types::NvramStoreVss: - case Types::NvramStoreFdc: - parseVssStoreBody(current); - break; - case Types::NvramStoreFsys: - parseFsysStoreBody(current); - break; - case Types::NvramStoreEvsa: - parseEvsaStoreBody(current); - break; - case Types::NvramStoreFlashMap: - parseFlashMapBody(current); - break; - case Types::NvramStoreFtw: - case Types::NvramStoreCmdb: - case Types::Microcode: - case Types::SlicPubkey: - case Types::SlicMarker: - case Types::Padding: - // No parsing required - break; - default: - return ERR_UNKNOWN_ITEM_TYPE; + case Types::VssStore: + case Types::FdcStore: parseVssStoreBody(current); break; + case Types::FsysStore: parseFsysStoreBody(current); break; + case Types::EvsaStore: parseEvsaStoreBody(current); break; + case Types::FlashMapStore: parseFlashMapBody(current); break; } } return ERR_SUCCESS; } -STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & data, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset) +STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset) { - UINT32 dataSize = data.size(); + UINT32 dataSize = volume.size(); if (dataSize < sizeof(UINT32)) return ERR_STORES_NOT_FOUND; UINT32 offset = storeOffset; for (; offset < dataSize - sizeof(UINT32); offset++) { - const UINT32* currentPos = (const UINT32*)(data.constData() + offset); + const UINT32* currentPos = (const UINT32*)(volume.constData() + offset); 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) { @@ -3420,7 +3402,7 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da break; } else if (*currentPos == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *currentPos == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { //Possible FTW block signature found - QByteArray guid = QByteArray(data.constData() + offset, sizeof(EFI_GUID)); + QByteArray guid = QByteArray(volume.constData() + offset, sizeof(EFI_GUID)); if (guid != NVRAM_MAIN_STORE_VOLUME_GUID && guid != EDKII_WORKING_BLOCK_SIGNATURE_GUID) // Check the whole signature continue; @@ -3446,7 +3428,7 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da break; } else if (*currentPos == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) {// Phoenix SCT flash map - QByteArray signature = QByteArray(data.constData() + offset, NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH); + QByteArray signature = QByteArray(volume.constData() + offset, NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH); if (signature != NVRAM_PHOENIX_FLASH_MAP_SIGNATURE) // Check the whole signature continue; @@ -3500,7 +3482,7 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da offset < 26) // Check full windows flag and structure size continue; - const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)(data.constData() + offset - 26); + const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)(volume.constData() + offset - 26); // Check reserved bytes bool reservedBytesValid = true; for (UINT32 i = 0; i < sizeof(markerHeader->Reserved); i++) @@ -3626,7 +3608,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::NvramStoreVss, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::VssStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); } else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE) { // Check dataSize @@ -3694,7 +3676,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::NvramStoreFdc, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::FdcStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); } else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) { // Check dataSize @@ -3743,7 +3725,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::NvramStoreFsys, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::FsysStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); } else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) { // Check dataSize @@ -3790,7 +3772,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::NvramStoreEvsa, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::EvsaStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); } else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { // Check dataSize @@ -3852,7 +3834,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::NvramStoreFtw, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::FtwStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); } else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) { // Phoenix SCT flash map if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) { @@ -3891,7 +3873,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::NvramStoreFlashMap, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::FlashMapStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); } else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) { @@ -3929,7 +3911,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::NvramStoreCmdb, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::CmdbStore, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent); } else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) { @@ -3970,7 +3952,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::SlicPubkey, 0, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::SlicData, Subtypes::PubkeySlicData, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent); } else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) { // SLIC marker if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) { @@ -4010,7 +3992,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent pdata.offset = parentOffset; // Add tree item - index = model->addItem(Types::SlicMarker, 0, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent); + index = model->addItem(Types::SlicData, Subtypes::MarkerSlicData, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent); } else if (*signature == INTEL_MICROCODE_HEADER_VERSION) { // Intel microcode, , must be checked after SLIC marker because of the same *signature values if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) { @@ -4236,26 +4218,26 @@ STATUS FfsParser::parseVssStoreBody(const QModelIndex & index) // Set subtype and add related info if (isInvalid) - subtype = Subtypes::InvalidVssVariable; + subtype = Subtypes::InvalidVssEntry; else if (isAuthenticated) { - subtype = Subtypes::AuthVssVariable; + subtype = Subtypes::AuthVssEntry; info += QObject::tr("\nMonotonic counter: %1h\nTimestamp: %2\nPubKey index: %3") .hexarg(monotonicCounter).arg(efiTimeToQString(timestamp)).arg(pubKeyIndex); } else if (isAppleCrc32) { - subtype = Subtypes::Crc32VssVariable; + subtype = Subtypes::AppleVssEntry; info += QObject::tr("\nCRC32: %1h%2").hexarg2(storedCrc32, 8) .arg(storedCrc32 == calculatedCrc32 ? QObject::tr(", valid") : QObject::tr(", invalid, should be %1h").hexarg2(calculatedCrc32,8)); } else - subtype = Subtypes::StandardVssVariable; + subtype = Subtypes::StandardVssEntry; // Add correct offset to parsing data pdata.offset = parentOffset + offset; // Add tree item - model->addItem(Types::NvramVariableVss, subtype, name, text, info, header, body, FALSE, parsingDataToQByteArray(pdata), index); + model->addItem(Types::VssEntry, subtype, name, text, info, header, body, FALSE, parsingDataToQByteArray(pdata), index); // Move to next variable offset += variableSize; @@ -4305,7 +4287,7 @@ STATUS FfsParser::parseFsysStoreBody(const QModelIndex & index) pdata.offset = parentOffset + offset; // Add EOF tree item - model->addItem(Types::NvramEntryFsys, 0, name, QString(), info, header, QByteArray(), FALSE, parsingDataToQByteArray(pdata), index); + model->addItem(Types::FsysEntry, 0, name, QString(), info, header, QByteArray(), FALSE, parsingDataToQByteArray(pdata), index); // Add free space offset += header.size(); @@ -4361,7 +4343,7 @@ STATUS FfsParser::parseFsysStoreBody(const QModelIndex & index) pdata.offset = parentOffset + offset; // Add tree item - model->addItem(Types::NvramEntryFsys, 0, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), index); + model->addItem(Types::FsysEntry, 0, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), index); // Move to next variable offset += variableSize; @@ -4537,7 +4519,7 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index) pdata.offset = parentOffset + offset; // Add tree item - model->addItem(Types::NvramEntryEvsa, subtype, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), index); + model->addItem(Types::EvsaEntry, subtype, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), index); // Move to next variable offset += variableSize; @@ -4653,12 +4635,12 @@ STATUS FfsParser::parseFlashMapBody(const QModelIndex & index) subtype = Subtypes::VolumeFlashMapEntry; break; case NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_DATA_BLOCK: - subtype = Subtypes::DataBlockFlashMapEntry; + subtype = Subtypes::DataFlashMapEntry; break; } // Add tree item - model->addItem(Types::NvramEntryFlashMap, subtype, name, flashMapGuidToQString(entryHeader->Guid), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), index); + model->addItem(Types::FlashMapEntry, subtype, name, flashMapGuidToQString(entryHeader->Guid), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), index); // Move to next variable offset += sizeof(PHOENIX_FLASH_MAP_ENTRY); diff --git a/common/ffsparser.h b/common/ffsparser.h index d852b15..bc148d7 100644 --- a/common/ffsparser.h +++ b/common/ffsparser.h @@ -59,7 +59,7 @@ private: QModelIndex lastVtf; UINT32 capsuleOffsetFixup; - STATUS parseRawArea(const QByteArray & data, const QModelIndex & index); + STATUS parseRawArea(const QModelIndex & index); STATUS parseVolumeHeader(const QByteArray & volume, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); STATUS parseVolumeBody(const QModelIndex & index); STATUS parseFileHeader(const QByteArray & file, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); @@ -107,12 +107,22 @@ private: STATUS addMemoryAddressesRecursive(const QModelIndex & index, const UINT32 diff); // NVRAM parsing - STATUS parseNvarStore(const QByteArray & data, const QModelIndex & index); - - STATUS parseStoreArea(const QByteArray & data, const QModelIndex & index); - STATUS findNextStore(const QModelIndex & index, const QByteArray & data, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset); + STATUS parseNvramVolumeBody(const QModelIndex & index); + STATUS findNextStore(const QModelIndex & index, const QByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset); STATUS getStoreSize(const QByteArray & data, const UINT32 storeOffset, UINT32 & storeSize); STATUS parseStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index); + + STATUS parseNvarStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseVssStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseFtwStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseFdcStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseFsysStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseEvsaStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseFlashMapStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseCmdbStore(const QByteArray & data, const QModelIndex & index); + //STATUS parseSlicData(const QByteArray & data, const QModelIndex & index); + //STATUS parseMicrocode(const QByteArray & data, const QModelIndex & index); + STATUS parseVssStoreBody(const QModelIndex & index); STATUS parseFsysStoreBody(const QModelIndex & index); STATUS parseEvsaStoreBody(const QModelIndex & index); diff --git a/common/nvram.cpp b/common/nvram.cpp index 59a5d72..515652e 100644 --- a/common/nvram.cpp +++ b/common/nvram.cpp @@ -18,25 +18,16 @@ QString nvarAttributesToQString(const UINT8 attributes) { if (attributes == 0x00 || attributes == 0xFF) return QString(); - - QString str; - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_RUNTIME) - str += QObject::tr(", Runtime"); - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_ASCII_NAME) - str += QObject::tr(", AsciiName"); - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_GUID) - str += QObject::tr(", Guid"); - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_DATA_ONLY) - str += QObject::tr(", DataOnly"); - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_EXT_HEADER) - str += QObject::tr(", ExtHeader"); - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_HW_ERROR_RECORD) - str += QObject::tr(", HwErrorRecord"); - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_AUTH_WRITE) - str += QObject::tr(", AuthWrite"); - if (attributes & NVRAM_NVAR_VARIABLE_ATTRIB_VALID) - str += QObject::tr(", Valid"); + QString str; + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_RUNTIME) str += QObject::tr(", Runtime"); + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_ASCII_NAME) str += QObject::tr(", AsciiName"); + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_GUID) str += QObject::tr(", Guid"); + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_DATA_ONLY) str += QObject::tr(", DataOnly"); + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_EXT_HEADER) str += QObject::tr(", ExtHeader"); + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_HW_ERROR_RECORD) str += QObject::tr(", HwErrorRecord"); + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_AUTH_WRITE) str += QObject::tr(", AuthWrite"); + if (attributes & NVRAM_NVAR_ENTRY_ATTRIB_VALID) str += QObject::tr(", Valid"); return str.mid(2); // Remove first comma and space } @@ -56,26 +47,21 @@ QString efiTimeToQString(const EFI_TIME & time) QString flashMapGuidToQString(const EFI_GUID & guid) { const QByteArray baGuid((const char*)&guid, sizeof(EFI_GUID)); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER) - return QObject::tr("Volume header"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID) - return QObject::tr("Microcodes"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID) - return QObject::tr("CMDB"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID) - return QObject::tr("SLIC pubkey"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID) - return QObject::tr("SLIC marker"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID || - baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID || - baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA3_GUID || - baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA4_GUID || - baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA5_GUID || - baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID || - baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID) - return QObject::tr("EVSA store"); - if (baGuid == NVRAM_PHOENIX_FLASH_MAP_SELF_GUID) - return QObject::tr("Flash map"); + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER) return QObject::tr("Volume header"); + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID) return QObject::tr("Microcodes"); + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID) return QObject::tr("CMDB"); + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID) return QObject::tr("SLIC pubkey"); + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID) return QObject::tr("SLIC marker"); + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA3_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA4_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA5_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID + || baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID) return QObject::tr("EVSA store"); + if (baGuid == NVRAM_PHOENIX_FLASH_MAP_SELF_GUID) return QObject::tr("Flash map"); return QString(); } diff --git a/common/nvram.h b/common/nvram.h index 8f15e6a..0cf2574 100644 --- a/common/nvram.h +++ b/common/nvram.h @@ -23,7 +23,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #pragma pack(push, 1) // -// NVAR store and variables +// NVAR store and entry // // CEF5B9A3-476D-497F-9FDC-E98143E0422C @@ -38,33 +38,30 @@ extern QString nvarAttributesToQString(const UINT8 attributes); extern QString efiTimeToQString(const EFI_TIME & time); -// Variable header -typedef struct NVAR_VARIABLE_HEADER_ { +typedef struct NVAR_ENTRY_HEADER_ { UINT32 Signature; // NVAR - UINT16 Size; // Size of the variable including header - UINT32 Next : 24; // Offset to the next variable in a list, or empty if latest in the list + UINT16 Size; // Size of the entry including header + UINT32 Next : 24; // Offset to the next entry in a list, or empty if latest in the list UINT32 Attributes : 8; // Attributes -} NVAR_VARIABLE_HEADER; +} NVAR_ENTRY_HEADER; // NVAR signature -#define NVRAM_NVAR_VARIABLE_SIGNATURE 0x5241564E +#define NVRAM_NVAR_ENTRY_SIGNATURE 0x5241564E // Attributes -#define NVRAM_NVAR_VARIABLE_ATTRIB_RUNTIME 0x01 -#define NVRAM_NVAR_VARIABLE_ATTRIB_ASCII_NAME 0x02 -#define NVRAM_NVAR_VARIABLE_ATTRIB_GUID 0x04 -#define NVRAM_NVAR_VARIABLE_ATTRIB_DATA_ONLY 0x08 -#define NVRAM_NVAR_VARIABLE_ATTRIB_EXT_HEADER 0x10 -#define NVRAM_NVAR_VARIABLE_ATTRIB_HW_ERROR_RECORD 0x20 -#define NVRAM_NVAR_VARIABLE_ATTRIB_AUTH_WRITE 0x40 -#define NVRAM_NVAR_VARIABLE_ATTRIB_VALID 0x80 +#define NVRAM_NVAR_ENTRY_ATTRIB_RUNTIME 0x01 +#define NVRAM_NVAR_ENTRY_ATTRIB_ASCII_NAME 0x02 +#define NVRAM_NVAR_ENTRY_ATTRIB_GUID 0x04 +#define NVRAM_NVAR_ENTRY_ATTRIB_DATA_ONLY 0x08 +#define NVRAM_NVAR_ENTRY_ATTRIB_EXT_HEADER 0x10 +#define NVRAM_NVAR_ENTRY_ATTRIB_HW_ERROR_RECORD 0x20 +#define NVRAM_NVAR_ENTRY_ATTRIB_AUTH_WRITE 0x40 +#define NVRAM_NVAR_ENTRY_ATTRIB_VALID 0x80 // Extended attributes -#define NVRAM_NVAR_VARIABLE_EXT_ATTRIB_CHECKSUM 0x01 -#define NVRAM_NVAR_VARIABLE_EXT_ATTRIB_AUTH_WRITE 0x10 -#define NVRAM_NVAR_VARIABLE_EXT_ATTRIB_TIME_BASED 0x20 - - +#define NVRAM_NVAR_ENTRY_EXT_ATTRIB_CHECKSUM 0x01 +#define NVRAM_NVAR_ENTRY_EXT_ATTRIB_AUTH_WRITE 0x10 +#define NVRAM_NVAR_ENTRY_EXT_ATTRIB_TIME_BASED 0x20 // // TianoCore VSS store and variables @@ -273,7 +270,7 @@ typedef struct EVSA_DATA_ENTRY_ { #define NVRAM_EVSA_DATA_ATTRIBUTE_EXTENDED_HEADER 0x10000000 -typedef struct EVSA_DATA_ENTRY_EXTENDED { +typedef struct EVSA_DATA_ENTRY_EXTENDED_ { EVSA_ENTRY_HEADER Header; UINT16 GuidId; UINT16 VarId; diff --git a/common/parsingdata.h b/common/parsingdata.h index d90bd14..996bccf 100644 --- a/common/parsingdata.h +++ b/common/parsingdata.h @@ -87,7 +87,7 @@ typedef struct NVRAM_NVAR_PARSING_DATA_ { UINT8 attributes; UINT8 extendedAttributes; UINT64 timestamp; - UINT8 hash[0x20]; //SHA256 + UINT8 hash[SHA256_HASH_SIZE]; //SHA256 } NVRAM_NVAR_PARSING_DATA; typedef struct NVRAM_PARSING_DATA_ { diff --git a/common/types.cpp b/common/types.cpp index e413229..1c36bd4 100644 --- a/common/types.cpp +++ b/common/types.cpp @@ -19,84 +19,45 @@ QString regionTypeToQString(const UINT8 type) { switch (type) { - case Subtypes::DescriptorRegion: - return QObject::tr("Descriptor"); - case Subtypes::BiosRegion: - return QObject::tr("BIOS"); - case Subtypes::MeRegion: - return QObject::tr("ME"); - case Subtypes::GbeRegion: - return QObject::tr("GbE"); - case Subtypes::PdrRegion: - return QObject::tr("PDR"); - case Subtypes::Reserved1Region: - return QObject::tr("Reserved1"); - case Subtypes::Reserved2Region: - return QObject::tr("Reserved2"); - case Subtypes::Reserved3Region: - return QObject::tr("Reserved3"); - case Subtypes::EcRegion: - return QObject::tr("EC"); - case Subtypes::Reserved4Region: - return QObject::tr("Reserved4"); - default: - return QObject::tr("Unknown"); + case Subtypes::DescriptorRegion: return QObject::tr("Descriptor"); + case Subtypes::BiosRegion: return QObject::tr("BIOS"); + case Subtypes::MeRegion: return QObject::tr("ME"); + case Subtypes::GbeRegion: return QObject::tr("GbE"); + case Subtypes::PdrRegion: return QObject::tr("PDR"); + case Subtypes::Reserved1Region: return QObject::tr("Reserved1"); + case Subtypes::Reserved2Region: return QObject::tr("Reserved2"); + case Subtypes::Reserved3Region: return QObject::tr("Reserved3"); + case Subtypes::EcRegion: return QObject::tr("EC"); + case Subtypes::Reserved4Region: return QObject::tr("Reserved4"); }; } QString itemTypeToQString(const UINT8 type) { switch (type) { - case Types::Root: - return QObject::tr("Root"); - case Types::Image: - return QObject::tr("Image"); - case Types::Capsule: - return QObject::tr("Capsule"); - case Types::Region: - return QObject::tr("Region"); - case Types::Volume: - return QObject::tr("Volume"); - case Types::Padding: - return QObject::tr("Padding"); - case Types::File: - return QObject::tr("File"); - case Types::Section: - return QObject::tr("Section"); - case Types::FreeSpace: - return QObject::tr("Free space"); - case Types::NvramStoreVss: - return QObject::tr("VSS store"); - case Types::NvramStoreFdc: - return QObject::tr("FDC store"); - case Types::NvramStoreFsys: - return QObject::tr("Fsys store"); - case Types::NvramStoreEvsa: - return QObject::tr("EVSA store"); - case Types::NvramStoreFtw: - return QObject::tr("FTW store"); - case Types::NvramStoreCmdb: - return QObject::tr("CMDB store"); - case Types::NvramStoreFlashMap: - return QObject::tr("FlashMap store"); - case Types::NvramVariableNvar: - return QObject::tr("NVAR variable"); - case Types::NvramVariableVss: - return QObject::tr("VSS variable"); - case Types::NvramEntryFsys: - return QObject::tr("Fsys entry"); - case Types::NvramEntryEvsa: - return QObject::tr("EVSA entry"); - case Types::NvramEntryFlashMap: - return QObject::tr("FlashMap entry"); - case Types::Microcode: - return QObject::tr("Microcode"); - case Types::SlicPubkey: - return QObject::tr("SLIC pubkey"); - case Types::SlicMarker: - return QObject::tr("SLIC marker"); - default: - return QObject::tr("Unknown"); + case Types::Root: return QObject::tr("Root"); + case Types::Image: return QObject::tr("Image"); + case Types::Capsule: return QObject::tr("Capsule"); + case Types::Region: return QObject::tr("Region"); + case Types::Volume: return QObject::tr("Volume"); + case Types::Padding: return QObject::tr("Padding"); + case Types::File: return QObject::tr("File"); + case Types::Section: return QObject::tr("Section"); + case Types::FreeSpace: return QObject::tr("Free space"); + case Types::VssStore: return QObject::tr("VSS store"); + case Types::FtwStore: return QObject::tr("FTW store"); + case Types::FdcStore: return QObject::tr("FDC store"); + case Types::FsysStore: return QObject::tr("Fsys store"); + case Types::EvsaStore: return QObject::tr("EVSA store"); + case Types::CmdbStore: return QObject::tr("CMDB store"); + case Types::FlashMapStore: return QObject::tr("FlashMap store"); + case Types::NvarEntry: return QObject::tr("NVAR entry"); + case Types::VssEntry: return QObject::tr("VSS entry"); + case Types::FsysEntry: return QObject::tr("Fsys entry"); + case Types::EvsaEntry: return QObject::tr("EVSA entry"); + case Types::FlashMapEntry: return QObject::tr("FlashMap entry"); + case Types::Microcode: return QObject::tr("Microcode"); + case Types::SlicData: return QObject::tr("SLIC data"); } } @@ -105,146 +66,93 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype) switch (type) { case Types::Root: case Types::FreeSpace: - case Types::NvramStoreVss: - case Types::NvramStoreFdc: - case Types::NvramStoreFsys: - case Types::NvramStoreEvsa: - case Types::NvramStoreFtw: - case Types::NvramStoreFlashMap: - case Types::NvramStoreCmdb: - case Types::NvramEntryFsys: - case Types::SlicPubkey: - case Types::SlicMarker: - return QString(); + case Types::VssStore: + case Types::FdcStore: + case Types::FsysStore: + case Types::EvsaStore: + case Types::FtwStore: + case Types::FlashMapStore: + case Types::CmdbStore: + case Types::FsysEntry: + case Types::SlicData: return QString(); case Types::Image: - if (subtype == Subtypes::IntelImage) - return QObject::tr("Intel"); - if (Subtypes::UefiImage) - return QObject::tr("UEFI"); + if (subtype == Subtypes::IntelImage) return QObject::tr("Intel"); + if (subtype == Subtypes::UefiImage) return QObject::tr("UEFI"); break; case Types::Padding: - if (subtype == Subtypes::ZeroPadding) - return QObject::tr("Empty (0x00)"); - if (subtype == Subtypes::OnePadding) - return QObject::tr("Empty (0xFF)"); - if (subtype == Subtypes::DataPadding) - return QObject::tr("Non-empty"); + if (subtype == Subtypes::ZeroPadding) return QObject::tr("Empty (0x00)"); + if (subtype == Subtypes::OnePadding) return QObject::tr("Empty (0xFF)"); + if (subtype == Subtypes::DataPadding) return QObject::tr("Non-empty"); break; case Types::Volume: - if (subtype == Subtypes::UnknownVolume) - return QObject::tr("Unknown"); - if (subtype == Subtypes::Ffs2Volume) - return QObject::tr("FFSv2"); - if (subtype == Subtypes::Ffs3Volume) - return QObject::tr("FFSv3"); - if (subtype == Subtypes::NvramVolume) - return QObject::tr("NVRAM"); + if (subtype == Subtypes::UnknownVolume) return QObject::tr("Unknown"); + if (subtype == Subtypes::Ffs2Volume) return QObject::tr("FFSv2"); + if (subtype == Subtypes::Ffs3Volume) return QObject::tr("FFSv3"); + if (subtype == Subtypes::NvramVolume) return QObject::tr("NVRAM"); break; case Types::Capsule: - if (subtype == Subtypes::AptioSignedCapsule) - return QObject::tr("Aptio signed"); - if (subtype == Subtypes::AptioUnsignedCapsule) - return QObject::tr("Aptio unsigned"); - if (subtype == Subtypes::UefiCapsule) - return QObject::tr("UEFI 2.0"); - if (subtype == Subtypes::ToshibaCapsule) - return QObject::tr("Toshiba"); + if (subtype == Subtypes::AptioSignedCapsule) return QObject::tr("Aptio signed"); + if (subtype == Subtypes::AptioUnsignedCapsule) return QObject::tr("Aptio unsigned"); + if (subtype == Subtypes::UefiCapsule) return QObject::tr("UEFI 2.0"); + if (subtype == Subtypes::ToshibaCapsule) return QObject::tr("Toshiba"); break; - case Types::Region: - return regionTypeToQString(subtype); - case Types::File: - return fileTypeToQString(subtype); - case Types::Section: - return sectionTypeToQString(subtype); - case Types::NvramVariableNvar: - if (subtype == Subtypes::InvalidNvarVariable) - return QObject::tr("Invalid"); - if (subtype == Subtypes::InvalidLinkNvarVariable) - return QObject::tr("Invalid link"); - if (subtype == Subtypes::LinkNvarVariable) - return QObject::tr("Link"); - if (subtype == Subtypes::DataNvarVariable) - return QObject::tr("Data"); - if (subtype == Subtypes::FullNvarVariable) - return QObject::tr("Full"); + case Types::Region: return regionTypeToQString(subtype); + case Types::File: return fileTypeToQString(subtype); + case Types::Section: return sectionTypeToQString(subtype); + case Types::NvarEntry: + if (subtype == Subtypes::InvalidNvarEntry) return QObject::tr("Invalid"); + if (subtype == Subtypes::InvalidLinkNvarEntry) return QObject::tr("Invalid link"); + if (subtype == Subtypes::LinkNvarEntry) return QObject::tr("Link"); + if (subtype == Subtypes::DataNvarEntry) return QObject::tr("Data"); + if (subtype == Subtypes::FullNvarEntry) return QObject::tr("Full"); break; - case Types::NvramVariableVss: - if (subtype == Subtypes::InvalidVssVariable) - return QObject::tr("Invalid"); - if (subtype == Subtypes::StandardVssVariable) - return QObject::tr("Standard"); - if (subtype == Subtypes::Crc32VssVariable) - return QObject::tr("Apple CRC32"); - if (subtype == Subtypes::AuthVssVariable) - return QObject::tr("Auth"); + case Types::VssEntry: + if (subtype == Subtypes::InvalidVssEntry) return QObject::tr("Invalid"); + if (subtype == Subtypes::StandardVssEntry) return QObject::tr("Standard"); + if (subtype == Subtypes::AppleVssEntry) return QObject::tr("Apple"); + if (subtype == Subtypes::AuthVssEntry) return QObject::tr("Auth"); break; - case Types::NvramEntryEvsa: - if (subtype == Subtypes::InvalidEvsaEntry) - return QObject::tr("Invalid"); - if (subtype == Subtypes::UnknownEvsaEntry) - return QObject::tr("Unknown"); - if (subtype == Subtypes::GuidEvsaEntry) - return QObject::tr("GUID"); - if (subtype == Subtypes::NameEvsaEntry) - return QObject::tr("Name"); - if (subtype == Subtypes::DataEvsaEntry) - return QObject::tr("Data"); + case Types::EvsaEntry: + if (subtype == Subtypes::InvalidEvsaEntry) return QObject::tr("Invalid"); + if (subtype == Subtypes::UnknownEvsaEntry) return QObject::tr("Unknown"); + if (subtype == Subtypes::GuidEvsaEntry) return QObject::tr("GUID"); + if (subtype == Subtypes::NameEvsaEntry) return QObject::tr("Name"); + if (subtype == Subtypes::DataEvsaEntry) return QObject::tr("Data"); break; - case Types::NvramEntryFlashMap: - if (subtype == Subtypes::VolumeFlashMapEntry) - return QObject::tr("Volume"); - if (subtype == Subtypes::DataBlockFlashMapEntry) - return QObject::tr("Data block"); + case Types::FlashMapEntry: + if (subtype == Subtypes::VolumeFlashMapEntry) return QObject::tr("Volume"); + if (subtype == Subtypes::DataFlashMapEntry) return QObject::tr("Data"); break; case Types::Microcode: - if (subtype == Subtypes::IntelMicrocode) - return QObject::tr("Intel"); - if (subtype == Subtypes::AmdMicrocode) - return QObject::tr("AMD"); + if (subtype == Subtypes::IntelMicrocode) return QObject::tr("Intel"); + if (subtype == Subtypes::AmdMicrocode) return QObject::tr("AMD"); break; } - - return QObject::tr("Unknown subtype"); } QString compressionTypeToQString(const UINT8 algorithm) { switch (algorithm) { - case COMPRESSION_ALGORITHM_NONE: - return QObject::tr("None"); - case COMPRESSION_ALGORITHM_EFI11: - return QObject::tr("EFI 1.1"); - case COMPRESSION_ALGORITHM_TIANO: - return QObject::tr("Tiano"); - case COMPRESSION_ALGORITHM_UNDECIDED: - return QObject::tr("Undecided Tiano/EFI 1.1"); - case COMPRESSION_ALGORITHM_LZMA: - return QObject::tr("LZMA"); - case COMPRESSION_ALGORITHM_IMLZMA: - return QObject::tr("Intel modified LZMA"); - default: - return QObject::tr("Unknown"); + case COMPRESSION_ALGORITHM_NONE: return QObject::tr("None"); + case COMPRESSION_ALGORITHM_EFI11: return QObject::tr("EFI 1.1"); + case COMPRESSION_ALGORITHM_TIANO: return QObject::tr("Tiano"); + case COMPRESSION_ALGORITHM_UNDECIDED: return QObject::tr("Undecided Tiano/EFI 1.1"); + case COMPRESSION_ALGORITHM_LZMA: return QObject::tr("LZMA"); + case COMPRESSION_ALGORITHM_IMLZMA: return QObject::tr("Intel modified LZMA"); } + + return QObject::tr("Unknown"); } QString actionTypeToQString(const UINT8 action) { switch (action) { - case Actions::NoAction: - return QString(); - case Actions::Create: - return QObject::tr("Create"); - case Actions::Insert: - return QObject::tr("Insert"); - case Actions::Replace: - return QObject::tr("Replace"); - case Actions::Remove: - return QObject::tr("Remove"); - case Actions::Rebuild: - return QObject::tr("Rebuild"); - case Actions::Rebase: - return QObject::tr("Rebase"); - default: - return QObject::tr("Unknown"); + case Actions::NoAction: return QString(); + case Actions::Create: return QObject::tr("Create"); + case Actions::Insert: return QObject::tr("Insert"); + case Actions::Replace: return QObject::tr("Replace"); + case Actions::Remove: return QObject::tr("Remove"); + case Actions::Rebuild: return QObject::tr("Rebuild"); + case Actions::Rebase: return QObject::tr("Rebase"); } } \ No newline at end of file diff --git a/common/types.h b/common/types.h index ad887b1..e232da3 100644 --- a/common/types.h +++ b/common/types.h @@ -43,21 +43,20 @@ namespace Types { File, Section, FreeSpace, - NvramStoreVss, - NvramStoreFdc, - NvramStoreFsys, - NvramStoreEvsa, - NvramStoreFlashMap, - NvramStoreFtw, - NvramStoreCmdb, - NvramVariableNvar, - NvramVariableVss, - NvramEntryFsys, - NvramEntryEvsa, - NvramEntryFlashMap, + VssStore, + FtwStore, + FdcStore, + FsysStore, + EvsaStore, + FlashMapStore, + CmdbStore, + NvarEntry, + VssEntry, + FsysEntry, + EvsaEntry, + FlashMapEntry, Microcode, - SlicPubkey, - SlicMarker, + SlicData, }; } @@ -100,22 +99,22 @@ namespace Subtypes { DataPadding }; - enum NvarVariableSubtypes { - InvalidNvarVariable = 130, - InvalidLinkNvarVariable, - LinkNvarVariable, - DataNvarVariable, - FullNvarVariable + enum NvarEntrySubtypes { + InvalidNvarEntry = 130, + InvalidLinkNvarEntry, + LinkNvarEntry, + DataNvarEntry, + FullNvarEntry }; - enum VssVariableSubtypes { - InvalidVssVariable = 140, - StandardVssVariable, - Crc32VssVariable, - AuthVssVariable + enum VssEntrySubtypes { + InvalidVssEntry = 140, + StandardVssEntry, + AppleVssEntry, + AuthVssEntry }; - enum EvsaVariableSubtypes { + enum EvsaEntrySubtypes { InvalidEvsaEntry = 150, UnknownEvsaEntry, GuidEvsaEntry, @@ -125,13 +124,18 @@ namespace Subtypes { enum FlashMapEntrySubtypes { VolumeFlashMapEntry = 160, - DataBlockFlashMapEntry + DataFlashMapEntry }; enum MicrocodeSubtypes { IntelMicrocode = 170, AmdMicrocode }; + + enum SlicDataSubtypes { + PubkeySlicData = 180, + MarkerSlicData + }; }; // *ToQString conversion routines