mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-25 01:18:22 +08:00
modification support & other
+ Replace and rebuild functions + NVRAM volumes rebuild support (without changing the size of volume) + 'TXT' and 'Microcode' parsing tabs + 'Inspect with IDA' function
This commit is contained in:
parent
b064495db8
commit
856ea2a3aa
@ -39,6 +39,7 @@ version(tr(PROGRAM_VERSION))
|
|||||||
connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile()));
|
connect(ui->actionOpenImageFile, SIGNAL(triggered()), this, SLOT(openImageFile()));
|
||||||
connect(ui->actionOpenImageFileInNewWindow, SIGNAL(triggered()), this, SLOT(openImageFileInNewWindow()));
|
connect(ui->actionOpenImageFileInNewWindow, SIGNAL(triggered()), this, SLOT(openImageFileInNewWindow()));
|
||||||
connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile()));
|
connect(ui->actionSaveImageFile, SIGNAL(triggered()), this, SLOT(saveImageFile()));
|
||||||
|
connect(ui->actionSpecifyPathIDA, SIGNAL(triggered()), this, SLOT(specifyPathIDA()));
|
||||||
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
|
connect(ui->actionSearch, SIGNAL(triggered()), this, SLOT(search()));
|
||||||
connect(ui->actionHexView, SIGNAL(triggered()), this, SLOT(hexView()));
|
connect(ui->actionHexView, SIGNAL(triggered()), this, SLOT(hexView()));
|
||||||
connect(ui->actionBodyHexView, SIGNAL(triggered()), this, SLOT(bodyHexView()));
|
connect(ui->actionBodyHexView, SIGNAL(triggered()), this, SLOT(bodyHexView()));
|
||||||
@ -52,6 +53,8 @@ version(tr(PROGRAM_VERSION))
|
|||||||
connect(ui->actionReplaceBody, SIGNAL(triggered()), this, SLOT(replaceBody()));
|
connect(ui->actionReplaceBody, SIGNAL(triggered()), this, SLOT(replaceBody()));
|
||||||
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove()));
|
connect(ui->actionRemove, SIGNAL(triggered()), this, SLOT(remove()));
|
||||||
connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild()));
|
connect(ui->actionRebuild, SIGNAL(triggered()), this, SLOT(rebuild()));
|
||||||
|
connect(ui->actionInspectBodyIDA, SIGNAL(triggered()), this, SLOT(inspectIDA32()));
|
||||||
|
connect(ui->actionInspectBodyIDA64, SIGNAL(triggered()), this, SLOT(inspectIDA64()));
|
||||||
connect(ui->actionMessagesCopy, SIGNAL(triggered()), this, SLOT(copyMessage()));
|
connect(ui->actionMessagesCopy, SIGNAL(triggered()), this, SLOT(copyMessage()));
|
||||||
connect(ui->actionMessagesCopyAll, SIGNAL(triggered()), this, SLOT(copyAllMessages()));
|
connect(ui->actionMessagesCopyAll, SIGNAL(triggered()), this, SLOT(copyAllMessages()));
|
||||||
connect(ui->actionMessagesClear, SIGNAL(triggered()), this, SLOT(clearMessages()));
|
connect(ui->actionMessagesClear, SIGNAL(triggered()), this, SLOT(clearMessages()));
|
||||||
@ -71,8 +74,8 @@ version(tr(PROGRAM_VERSION))
|
|||||||
// Enable Drag-and-Drop actions
|
// Enable Drag-and-Drop actions
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
// Disable Builder tab, doesn't work right now
|
// Disable Builder tab
|
||||||
ui->messagesTabWidget->setTabEnabled(4, false);
|
ui->messagesTabWidget->setTabEnabled(6, false);
|
||||||
|
|
||||||
// Set current directory
|
// Set current directory
|
||||||
currentDir = ".";
|
currentDir = ".";
|
||||||
@ -110,8 +113,12 @@ void UEFITool::init()
|
|||||||
ui->fitTableWidget->setColumnCount(0);
|
ui->fitTableWidget->setColumnCount(0);
|
||||||
ui->infoEdit->clear();
|
ui->infoEdit->clear();
|
||||||
ui->bootGuardEdit->clear();
|
ui->bootGuardEdit->clear();
|
||||||
|
ui->txtEdit->clear();
|
||||||
|
ui->microcodeEdit->clear();
|
||||||
ui->messagesTabWidget->setTabEnabled(1, false);
|
ui->messagesTabWidget->setTabEnabled(1, false);
|
||||||
ui->messagesTabWidget->setTabEnabled(2, false);
|
ui->messagesTabWidget->setTabEnabled(2, false);
|
||||||
|
ui->messagesTabWidget->setTabEnabled(3, false);
|
||||||
|
ui->messagesTabWidget->setTabEnabled(4, false);
|
||||||
|
|
||||||
// Set window title
|
// Set window title
|
||||||
setWindowTitle(tr("UEFITool %1").arg(version));
|
setWindowTitle(tr("UEFITool %1").arg(version));
|
||||||
@ -139,13 +146,21 @@ void UEFITool::init()
|
|||||||
delete ffsParser;
|
delete ffsParser;
|
||||||
ffsParser = new FfsParser(model);
|
ffsParser = new FfsParser(model);
|
||||||
|
|
||||||
|
// Create ffsBuilder
|
||||||
|
delete ffsBuilder;
|
||||||
|
ffsBuilder = new FfsBuilder(model, ffsParser);
|
||||||
|
|
||||||
|
// Create ffsOps
|
||||||
|
delete ffsOps;
|
||||||
|
ffsOps = new FfsOperations(model);
|
||||||
|
|
||||||
// Set proper marking state
|
// Set proper marking state
|
||||||
model->setMarkingEnabled(markingEnabled);
|
model->setMarkingEnabled(markingEnabled);
|
||||||
ui->actionToggleBootGuardMarking->setChecked(markingEnabled);
|
ui->actionToggleBootGuardMarking->setChecked(markingEnabled);
|
||||||
|
|
||||||
// Connect
|
// Connect
|
||||||
connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
|
connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const UModelIndex &, const UModelIndex &)),
|
||||||
this, SLOT(populateUi(const QModelIndex &)));
|
this, SLOT(populateUi(const UModelIndex &)));
|
||||||
connect(ui->structureTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
|
connect(ui->structureTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
|
||||||
this, SLOT(populateUi(const QItemSelection &)));
|
this, SLOT(populateUi(const QItemSelection &)));
|
||||||
connect(ui->parserMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
connect(ui->parserMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
||||||
@ -167,7 +182,7 @@ void UEFITool::populateUi(const QItemSelection &selected)
|
|||||||
populateUi(selected.indexes().at(0));
|
populateUi(selected.indexes().at(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::populateUi(const QModelIndex ¤t)
|
void UEFITool::populateUi(const UModelIndex ¤t)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if (!current.isValid()) {
|
if (!current.isValid()) {
|
||||||
@ -210,26 +225,42 @@ void UEFITool::populateUi(const QModelIndex ¤t)
|
|||||||
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
||||||
ui->actionGoToData->setEnabled(type == Types::NvarEntry && subtype == Subtypes::LinkNvarEntry);
|
ui->actionGoToData->setEnabled(type == Types::NvarEntry && subtype == Subtypes::LinkNvarEntry);
|
||||||
|
|
||||||
// Disable rebuild for now
|
// Enable rebuild
|
||||||
//ui->actionRebuild->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion);
|
ui->actionRebuild->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion);
|
||||||
//ui->actionReplace->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion);
|
ui->actionReplace->setDisabled(type == Types::Region && subtype == Subtypes::DescriptorRegion);
|
||||||
|
ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section ||
|
||||||
|
type == Types::EvsaStore || type == Types::FdcStore ||
|
||||||
|
type == Types::FlashMapStore || type == Types::FsysStore ||
|
||||||
|
type == Types::FtwStore || type == Types::Vss2Store ||
|
||||||
|
type == Types::VssStore);
|
||||||
|
|
||||||
//ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
|
||||||
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
|
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
|
||||||
ui->actionExtractBodyUncompressed->setEnabled(enableExtractBodyUncompressed(current));
|
ui->actionExtractBodyUncompressed->setEnabled(enableExtractBodyUncompressed(current));
|
||||||
//ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
|
||||||
|
ui->actionInspectBodyIDA->setDisabled(model->hasEmptyBody(current));
|
||||||
|
ui->actionInspectBodyIDA64->setDisabled(model->hasEmptyBody(current));
|
||||||
|
|
||||||
|
ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
||||||
//ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
|
//ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
|
||||||
// (type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) ||
|
// (type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) ||
|
||||||
// (type == Types::Section && (subtype == EFI_SECTION_COMPRESSION || subtype == EFI_SECTION_GUID_DEFINED || subtype == EFI_SECTION_DISPOSABLE)));
|
// (type == Types::Section && (subtype == EFI_SECTION_COMPRESSION || subtype == EFI_SECTION_GUID_DEFINED || subtype == EFI_SECTION_DISPOSABLE)));
|
||||||
//ui->actionInsertBefore->setEnabled(type == Types::File || type == Types::Section);
|
//ui->actionInsertBefore->setEnabled(type == Types::File || type == Types::Section);
|
||||||
//ui->actionInsertAfter->setEnabled(type == Types::File || type == Types::Section);
|
//ui->actionInsertAfter->setEnabled(type == Types::File || type == Types::Section);
|
||||||
//ui->actionReplace->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::Volume || type == Types::File || type == Types::Section);
|
ui->actionReplace->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::Volume || type == Types::File || type == Types::Section ||
|
||||||
//ui->actionReplaceBody->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
type == Types::EvsaStore || type == Types::FdcStore ||
|
||||||
|
type == Types::FlashMapStore || type == Types::FsysStore ||
|
||||||
|
type == Types::FtwStore || type == Types::Vss2Store ||
|
||||||
|
type == Types::VssStore || type == Types::CmdbStore);
|
||||||
|
ui->actionReplaceBody->setEnabled((type == Types::Region && subtype != Subtypes::DescriptorRegion) || type == Types::Volume || type == Types::File || type == Types::Section ||
|
||||||
|
type == Types::EvsaStore || type == Types::FdcStore ||
|
||||||
|
type == Types::FlashMapStore || type == Types::FsysStore ||
|
||||||
|
type == Types::FtwStore || type == Types::Vss2Store ||
|
||||||
|
type == Types::VssStore || type == Types::CmdbStore);
|
||||||
|
|
||||||
ui->menuMessageActions->setEnabled(false);
|
ui->menuMessageActions->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UEFITool::enableExtractBodyUncompressed(const QModelIndex ¤t)
|
bool UEFITool::enableExtractBodyUncompressed(const UModelIndex ¤t)
|
||||||
{
|
{
|
||||||
// TODO: rewrite based on model->compressed()
|
// TODO: rewrite based on model->compressed()
|
||||||
U_UNUSED_PARAMETER(current);
|
U_UNUSED_PARAMETER(current);
|
||||||
@ -245,7 +276,7 @@ bool UEFITool::enableExtractBodyUncompressed(const QModelIndex ¤t)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (model->subtype(current) == EFI_SECTION_GUID_DEFINED) {
|
else if (model->subtype(current) == EFI_SECTION_GUID_DEFINED) {
|
||||||
QByteArray guid = QByteArray((const char*)&pdata.section.guidDefined.guid, sizeof(EFI_GUID));
|
UByteArray guid = UByteArray((const char*)&pdata.section.guidDefined.guid, sizeof(EFI_GUID));
|
||||||
if (guid == EFI_GUIDED_SECTION_TIANO || guid == EFI_GUIDED_SECTION_LZMA) {
|
if (guid == EFI_GUIDED_SECTION_TIANO || guid == EFI_GUIDED_SECTION_LZMA) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -260,12 +291,12 @@ void UEFITool::search()
|
|||||||
if (searchDialog->exec() != QDialog::Accepted)
|
if (searchDialog->exec() != QDialog::Accepted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QModelIndex rootIndex = model->index(0, 0);
|
UModelIndex rootIndex = model->index(0, 0);
|
||||||
|
|
||||||
int index = searchDialog->ui->tabWidget->currentIndex();
|
int index = searchDialog->ui->tabWidget->currentIndex();
|
||||||
if (index == 0) { // Hex pattern
|
if (index == 0) { // Hex pattern
|
||||||
searchDialog->ui->hexEdit->setFocus();
|
searchDialog->ui->hexEdit->setFocus();
|
||||||
QByteArray pattern = searchDialog->ui->hexEdit->text().toLatin1().replace(" ", "");
|
UByteArray pattern = searchDialog->ui->hexEdit->text().toLatin1().replace(" ", "");
|
||||||
if (pattern.isEmpty())
|
if (pattern.isEmpty())
|
||||||
return;
|
return;
|
||||||
UINT8 mode;
|
UINT8 mode;
|
||||||
@ -281,7 +312,7 @@ void UEFITool::search()
|
|||||||
else if (index == 1) { // GUID
|
else if (index == 1) { // GUID
|
||||||
searchDialog->ui->guidEdit->setFocus();
|
searchDialog->ui->guidEdit->setFocus();
|
||||||
searchDialog->ui->guidEdit->setCursorPosition(0);
|
searchDialog->ui->guidEdit->setCursorPosition(0);
|
||||||
QByteArray pattern = searchDialog->ui->guidEdit->text().toLatin1();
|
UByteArray pattern = searchDialog->ui->guidEdit->text().toLatin1();
|
||||||
if (pattern.isEmpty())
|
if (pattern.isEmpty())
|
||||||
return;
|
return;
|
||||||
UINT8 mode;
|
UINT8 mode;
|
||||||
@ -296,7 +327,7 @@ void UEFITool::search()
|
|||||||
}
|
}
|
||||||
else if (index == 2) { // Text string
|
else if (index == 2) { // Text string
|
||||||
searchDialog->ui->textEdit->setFocus();
|
searchDialog->ui->textEdit->setFocus();
|
||||||
QString pattern = searchDialog->ui->textEdit->text();
|
UString pattern = searchDialog->ui->textEdit->text();
|
||||||
if (pattern.isEmpty())
|
if (pattern.isEmpty())
|
||||||
return;
|
return;
|
||||||
UINT8 mode;
|
UINT8 mode;
|
||||||
@ -314,7 +345,7 @@ void UEFITool::search()
|
|||||||
|
|
||||||
void UEFITool::hexView()
|
void UEFITool::hexView()
|
||||||
{
|
{
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -324,7 +355,7 @@ void UEFITool::hexView()
|
|||||||
|
|
||||||
void UEFITool::bodyHexView()
|
void UEFITool::bodyHexView()
|
||||||
{
|
{
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -340,7 +371,7 @@ void UEFITool::goToOffset()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
UINT32 offset = (UINT32)goToOffsetDialog->ui->hexSpinBox->value();
|
UINT32 offset = (UINT32)goToOffsetDialog->ui->hexSpinBox->value();
|
||||||
QModelIndex index = model->findByOffset(offset);
|
UModelIndex index = model->findByOffset(offset);
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
||||||
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
||||||
@ -355,7 +386,7 @@ void UEFITool::goToAddress()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
UINT32 address = (UINT32)goToAddressDialog->ui->hexSpinBox->value();
|
UINT32 address = (UINT32)goToAddressDialog->ui->hexSpinBox->value();
|
||||||
QModelIndex index = model->findByOffset(address - (UINT32)ffsParser->getAddressDiff());
|
UModelIndex index = model->findByOffset(address - (UINT32)ffsParser->getAddressDiff());
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
ui->structureTreeView->scrollTo(index, QAbstractItemView::PositionAtCenter);
|
||||||
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
ui->structureTreeView->selectionModel()->select(index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
||||||
@ -364,12 +395,12 @@ void UEFITool::goToAddress()
|
|||||||
|
|
||||||
void UEFITool::goToData()
|
void UEFITool::goToData()
|
||||||
{
|
{
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid() || model->type(index) != Types::NvarEntry || model->subtype(index) != Subtypes::LinkNvarEntry)
|
if (!index.isValid() || model->type(index) != Types::NvarEntry || model->subtype(index) != Subtypes::LinkNvarEntry)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get parent
|
// Get parent
|
||||||
QModelIndex parent = model->parent(index);
|
UModelIndex parent = model->parent(index);
|
||||||
|
|
||||||
for (int i = index.row(); i < model->rowCount(parent); i++) {
|
for (int i = index.row(); i < model->rowCount(parent); i++) {
|
||||||
if (model->hasEmptyParsingData(index))
|
if (model->hasEmptyParsingData(index))
|
||||||
@ -385,7 +416,7 @@ void UEFITool::goToData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int j = i + 1; j < model->rowCount(parent); j++) {
|
for (int j = i + 1; j < model->rowCount(parent); j++) {
|
||||||
QModelIndex currentIndex = parent.child(j, 0);
|
UModelIndex currentIndex = parent.child(j, 0);
|
||||||
if (model->hasEmptyParsingData(currentIndex))
|
if (model->hasEmptyParsingData(currentIndex))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -401,7 +432,7 @@ void UEFITool::insert(const UINT8 mode)
|
|||||||
{
|
{
|
||||||
U_UNUSED_PARAMETER(mode);
|
U_UNUSED_PARAMETER(mode);
|
||||||
|
|
||||||
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
/*UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -412,7 +443,7 @@ void UEFITool::insert(const UINT8 mode)
|
|||||||
else
|
else
|
||||||
type = model->type(index);
|
type = model->type(index);
|
||||||
|
|
||||||
QString path;
|
UString path;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Types::Volume:
|
case Types::Volume:
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"), currentDir, "FFS files (*.ffs *.bin);;All files (*)");
|
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"), currentDir, "FFS files (*.ffs *.bin);;All files (*)");
|
||||||
@ -442,10 +473,10 @@ void UEFITool::insert(const UINT8 mode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray buffer = inputFile.readAll();
|
UByteArray buffer = inputFile.readAll();
|
||||||
inputFile.close();
|
inputFile.close();
|
||||||
|
|
||||||
UINT8 result = ffsEngine->insert(index, buffer, mode);
|
USTATUS result = ffsEngine->insert(index, buffer, mode);
|
||||||
if (result) {
|
if (result) {
|
||||||
QMessageBox::critical(this, tr("Insertion failed"), errorMessage(result), QMessageBox::Ok);
|
QMessageBox::critical(this, tr("Insertion failed"), errorMessage(result), QMessageBox::Ok);
|
||||||
return;
|
return;
|
||||||
@ -480,14 +511,11 @@ void UEFITool::replaceBody()
|
|||||||
|
|
||||||
void UEFITool::replace(const UINT8 mode)
|
void UEFITool::replace(const UINT8 mode)
|
||||||
{
|
{
|
||||||
U_UNUSED_PARAMETER(mode);
|
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
|
|
||||||
/*
|
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString path;
|
UString path;
|
||||||
if (model->type(index) == Types::Region) {
|
if (model->type(index) == Types::Region) {
|
||||||
if (mode == REPLACE_MODE_AS_IS) {
|
if (mode == REPLACE_MODE_AS_IS) {
|
||||||
path = QFileDialog::getOpenFileName(this, tr("Select region file to replace %1").arg(model->name(index)), currentDir, "Region files (*.rgn *.bin);;All files (*)");
|
path = QFileDialog::getOpenFileName(this, tr("Select region file to replace %1").arg(model->name(index)), currentDir, "Region files (*.rgn *.bin);;All files (*)");
|
||||||
@ -543,6 +571,19 @@ void UEFITool::replace(const UINT8 mode)
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(model->type(index) == Types::EvsaStore || model->type(index) == Types::CmdbStore ||
|
||||||
|
model->type(index) == Types::FdcStore || model->type(index) == Types::FlashMapStore ||
|
||||||
|
model->type(index) == Types::FsysStore || model->type(index) == Types::FtwStore ||
|
||||||
|
model->type(index) == Types::Vss2Store || model->type(index) == Types::VssStore) {
|
||||||
|
if (mode == REPLACE_MODE_AS_IS) {
|
||||||
|
path = QFileDialog::getOpenFileName(this, tr("Select NVRAM store file to replace selected store"), currentDir, "All files (*)");
|
||||||
|
}
|
||||||
|
else if (mode == REPLACE_MODE_BODY) {
|
||||||
|
path = QFileDialog::getOpenFileName(this, tr("Select NVRAM store body file to replace selected store body"), currentDir, "All files (*)");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -563,16 +604,16 @@ void UEFITool::replace(const UINT8 mode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray buffer = inputFile.readAll();
|
UByteArray buffer = inputFile.readAll();
|
||||||
inputFile.close();
|
inputFile.close();
|
||||||
|
|
||||||
UINT8 result = ffsOps->replace(index, buffer, mode);
|
USTATUS result = ffsOps->replace(index, buffer, mode);
|
||||||
if (result) {
|
if (result) {
|
||||||
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToUString(result), QMessageBox::Ok);
|
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ui->actionSaveImageFile->setEnabled(true);
|
ui->actionSaveImageFile->setEnabled(true);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::extractAsIs()
|
void UEFITool::extractAsIs()
|
||||||
@ -590,14 +631,14 @@ void UEFITool::extractBodyUncompressed()
|
|||||||
extract(EXTRACT_MODE_BODY_UNCOMPRESSED);
|
extract(EXTRACT_MODE_BODY_UNCOMPRESSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::extract(const UINT8 mode)
|
void UEFITool::extract(const UINT8 mode, UString* pathOut)
|
||||||
{
|
{
|
||||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QByteArray extracted;
|
UByteArray extracted;
|
||||||
QString name;
|
UString name;
|
||||||
USTATUS result = ffsOps->extract(index, name, extracted, mode);
|
USTATUS result = ffsOps->extract(index, name, extracted, mode);
|
||||||
if (result) {
|
if (result) {
|
||||||
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToUString(result), QMessageBox::Ok);
|
QMessageBox::critical(this, tr("Extraction failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||||
@ -610,7 +651,7 @@ void UEFITool::extract(const UINT8 mode)
|
|||||||
|
|
||||||
UINT8 type = model->type(index);
|
UINT8 type = model->type(index);
|
||||||
UINT8 subtype = model->subtype(index);
|
UINT8 subtype = model->subtype(index);
|
||||||
QString path;
|
UString path;
|
||||||
if (mode == EXTRACT_MODE_AS_IS) {
|
if (mode == EXTRACT_MODE_AS_IS) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Types::Capsule: path = QFileDialog::getSaveFileName(this, tr("Save capsule to file"), name + ".cap", tr("Capsule files (*.cap *.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;
|
||||||
@ -695,30 +736,67 @@ void UEFITool::extract(const UINT8 mode)
|
|||||||
outputFile.resize(0);
|
outputFile.resize(0);
|
||||||
outputFile.write(extracted);
|
outputFile.write(extracted);
|
||||||
outputFile.close();
|
outputFile.close();
|
||||||
|
|
||||||
|
if(pathOut) {
|
||||||
|
pathOut->clear();
|
||||||
|
pathOut->append(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UEFITool::inspectIDA32()
|
||||||
|
{
|
||||||
|
if(idaPath32.trimmed().isEmpty())
|
||||||
|
specifyPathIDA32();
|
||||||
|
|
||||||
|
inspect(INSPECT_MODE_IDA32);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UEFITool::inspectIDA64()
|
||||||
|
{
|
||||||
|
if(idaPath64.trimmed().isEmpty())
|
||||||
|
specifyPathIDA64();
|
||||||
|
|
||||||
|
inspect(INSPECT_MODE_IDA64);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UEFITool::inspect(const UINT8 mode)
|
||||||
|
{
|
||||||
|
UString filePath;
|
||||||
|
|
||||||
|
extract(EXTRACT_MODE_BODY, &filePath);
|
||||||
|
if(filePath.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QStringList arg;
|
||||||
|
arg << filePath;
|
||||||
|
|
||||||
|
QProcess idaProcess;
|
||||||
|
idaProcess.setProgram(mode == INSPECT_MODE_IDA32 ? idaPath32 : idaPath64);
|
||||||
|
idaProcess.setArguments(arg);
|
||||||
|
if(!idaProcess.startDetached()) {
|
||||||
|
QMessageBox::critical(this, tr("Inspect failed"), tr("Can't start IDA process"), QMessageBox::Ok);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::rebuild()
|
void UEFITool::rebuild()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (U_SUCCESS == ffsOps->rebuild(index))
|
if (U_SUCCESS == ffsOps->rebuild(index))
|
||||||
ui->actionSaveImageFile->setEnabled(true);
|
ui->actionSaveImageFile->setEnabled(true);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::remove()
|
void UEFITool::remove()
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (U_SUCCESS == ffsOps->remove(index))
|
if (U_SUCCESS == ffsOps->remove(index))
|
||||||
ui->actionSaveImageFile->setEnabled(true);
|
ui->actionSaveImageFile->setEnabled(true);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::about()
|
void UEFITool::about()
|
||||||
@ -748,15 +826,12 @@ void UEFITool::exit()
|
|||||||
|
|
||||||
void UEFITool::saveImageFile()
|
void UEFITool::saveImageFile()
|
||||||
{
|
{
|
||||||
/*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 (*)"));
|
UString 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())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QByteArray reconstructed;
|
UByteArray reconstructed;
|
||||||
// Create ffsBuilder
|
|
||||||
delete ffsBuilder;
|
|
||||||
ffsBuilder = new FfsBuilder(model);
|
|
||||||
USTATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
|
USTATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
|
||||||
showBuilderMessages();
|
showBuilderMessages();
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -776,24 +851,24 @@ void UEFITool::saveImageFile()
|
|||||||
outputFile.close();
|
outputFile.close();
|
||||||
if (QMessageBox::Yes == QMessageBox::information(this, tr("Image build successful"), tr("Open the resulting file?"), QMessageBox::Yes, QMessageBox::No))
|
if (QMessageBox::Yes == QMessageBox::information(this, tr("Image build successful"), tr("Open the resulting file?"), QMessageBox::Yes, QMessageBox::No))
|
||||||
openImageFile(path);
|
openImageFile(path);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::openImageFile()
|
void UEFITool::openImageFile()
|
||||||
{
|
{
|
||||||
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 (*)"));
|
UString 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);
|
openImageFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::openImageFileInNewWindow()
|
void UEFITool::openImageFileInNewWindow()
|
||||||
{
|
{
|
||||||
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 (*)"));
|
UString 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())
|
if (path.trimmed().isEmpty())
|
||||||
return;
|
return;
|
||||||
QProcess::startDetached(currentProgramPath, QStringList(path));
|
QProcess::startDetached(currentProgramPath, QStringList(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::openImageFile(QString path)
|
void UEFITool::openImageFile(UString path)
|
||||||
{
|
{
|
||||||
if (path.trimmed().isEmpty())
|
if (path.trimmed().isEmpty())
|
||||||
return;
|
return;
|
||||||
@ -813,7 +888,7 @@ void UEFITool::openImageFile(QString path)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray buffer = inputFile.readAll();
|
UByteArray buffer = inputFile.readAll();
|
||||||
inputFile.close();
|
inputFile.close();
|
||||||
|
|
||||||
init();
|
init();
|
||||||
@ -858,6 +933,36 @@ void UEFITool::openImageFile(QString path)
|
|||||||
currentPath = path;
|
currentPath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UEFITool::specifyPathIDA()
|
||||||
|
{
|
||||||
|
specifyPathIDA32();
|
||||||
|
specifyPathIDA64();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UEFITool::specifyPathIDA32()
|
||||||
|
{
|
||||||
|
QString path;
|
||||||
|
|
||||||
|
path = QFileDialog::getOpenFileName(this, tr("Specify path to ida.exe"), "ida.exe", tr("IDA Pro executable (ida.exe);;All files (*)"));
|
||||||
|
|
||||||
|
if (path.trimmed().isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
idaPath32 = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UEFITool::specifyPathIDA64()
|
||||||
|
{
|
||||||
|
QString path;
|
||||||
|
|
||||||
|
path = QFileDialog::getOpenFileName(this, tr("Specify path to ida64.exe"), "ida64.exe", tr("IDA Pro 64 executable (ida64.exe);;All files (*)"));
|
||||||
|
|
||||||
|
if (path.trimmed().isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
idaPath64 = path;
|
||||||
|
}
|
||||||
|
|
||||||
void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
|
void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
|
||||||
{
|
{
|
||||||
ui->menuMessageActions->setEnabled(item != NULL);
|
ui->menuMessageActions->setEnabled(item != NULL);
|
||||||
@ -879,7 +984,7 @@ void UEFITool::copyMessage()
|
|||||||
|
|
||||||
void UEFITool::copyAllMessages()
|
void UEFITool::copyAllMessages()
|
||||||
{
|
{
|
||||||
QString text;
|
UString text;
|
||||||
clipboard->clear();
|
clipboard->clear();
|
||||||
if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab
|
if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab
|
||||||
for (INT32 i = 0; i < ui->parserMessagesListWidget->count(); i++)
|
for (INT32 i = 0; i < ui->parserMessagesListWidget->count(); i++)
|
||||||
@ -933,7 +1038,7 @@ void UEFITool::dragEnterEvent(QDragEnterEvent* event)
|
|||||||
|
|
||||||
void UEFITool::dropEvent(QDropEvent* event)
|
void UEFITool::dropEvent(QDropEvent* event)
|
||||||
{
|
{
|
||||||
QString path = event->mimeData()->urls().at(0).toLocalFile();
|
UString path = event->mimeData()->urls().at(0).toLocalFile();
|
||||||
openImageFile(path);
|
openImageFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,11 +1048,11 @@ void UEFITool::showParserMessages()
|
|||||||
if (!ffsParser)
|
if (!ffsParser)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<std::pair<QString, QModelIndex> > messages = ffsParser->getMessages();
|
std::vector<std::pair<UString, UModelIndex> > messages = ffsParser->getMessages();
|
||||||
std::pair<QString, QModelIndex> msg;
|
std::pair<UString, UModelIndex> msg;
|
||||||
foreach (msg, messages) {
|
foreach (msg, messages) {
|
||||||
QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0);
|
QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0);
|
||||||
item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second)));
|
item->setData(Qt::UserRole, UByteArray((const char*)&msg.second, sizeof(msg.second)));
|
||||||
ui->parserMessagesListWidget->addItem(item);
|
ui->parserMessagesListWidget->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,11 +1066,11 @@ void UEFITool::showFinderMessages()
|
|||||||
if (!ffsParser)
|
if (!ffsParser)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<std::pair<QString, QModelIndex> > messages = ffsFinder->getMessages();
|
std::vector<std::pair<UString, UModelIndex> > messages = ffsFinder->getMessages();
|
||||||
std::pair<QString, QModelIndex> msg;
|
std::pair<UString, UModelIndex> msg;
|
||||||
foreach (msg, messages) {
|
foreach (msg, messages) {
|
||||||
QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0);
|
QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0);
|
||||||
item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second)));;
|
item->setData(Qt::UserRole, UByteArray((const char*)&msg.second, sizeof(msg.second)));;
|
||||||
ui->finderMessagesListWidget->addItem(item);
|
ui->finderMessagesListWidget->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -979,22 +1084,23 @@ void UEFITool::showBuilderMessages()
|
|||||||
if (!ffsBuilder)
|
if (!ffsBuilder)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<std::pair<QString, QModelIndex> > messages = ffsBuilder->getMessages();
|
std::vector<std::pair<UString, UModelIndex> > messages = ffsBuilder->getMessages();
|
||||||
std::pair<QString, QModelIndex> msg;
|
std::pair<UString, UModelIndex> msg;
|
||||||
foreach (msg, messages) {
|
foreach (msg, messages) {
|
||||||
QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0);
|
QListWidgetItem* item = new QListWidgetItem(msg.first, NULL, 0);
|
||||||
item->setData(Qt::UserRole, QByteArray((const char*)&msg.second, sizeof(msg.second)));
|
item->setData(Qt::UserRole, UByteArray((const char*)&msg.second, sizeof(msg.second)));
|
||||||
ui->builderMessagesListWidget->addItem(item);
|
ui->builderMessagesListWidget->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->messagesTabWidget->setCurrentIndex(4);
|
ui->messagesTabWidget->setTabEnabled(6, true);
|
||||||
|
ui->messagesTabWidget->setCurrentIndex(6);
|
||||||
ui->builderMessagesListWidget->scrollToBottom();
|
ui->builderMessagesListWidget->scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::scrollTreeView(QListWidgetItem* item)
|
void UEFITool::scrollTreeView(QListWidgetItem* item)
|
||||||
{
|
{
|
||||||
QByteArray second = item->data(Qt::UserRole).toByteArray();
|
UByteArray second = item->data(Qt::UserRole).toByteArray();
|
||||||
QModelIndex *index = (QModelIndex *)second.data();
|
UModelIndex *index = (UModelIndex *)second.data();
|
||||||
if (index && index->isValid()) {
|
if (index && index->isValid()) {
|
||||||
ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter);
|
ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter);
|
||||||
ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
||||||
@ -1003,8 +1109,8 @@ void UEFITool::scrollTreeView(QListWidgetItem* item)
|
|||||||
|
|
||||||
void UEFITool::scrollTreeView(QTableWidgetItem* item)
|
void UEFITool::scrollTreeView(QTableWidgetItem* item)
|
||||||
{
|
{
|
||||||
QByteArray second = item->data(Qt::UserRole).toByteArray();
|
UByteArray second = item->data(Qt::UserRole).toByteArray();
|
||||||
QModelIndex *index = (QModelIndex *)second.data();
|
UModelIndex *index = (UModelIndex *)second.data();
|
||||||
if (index && index->isValid()) {
|
if (index && index->isValid()) {
|
||||||
ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter);
|
ui->structureTreeView->scrollTo(*index, QAbstractItemView::PositionAtCenter);
|
||||||
ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
ui->structureTreeView->selectionModel()->select(*index, QItemSelectionModel::Select | QItemSelectionModel::Rows | QItemSelectionModel::Clear);
|
||||||
@ -1025,7 +1131,7 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QPoint pt = event->pos();
|
QPoint pt = event->pos();
|
||||||
QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
|
UModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
|
||||||
if (!index.isValid()) {
|
if (!index.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1076,17 +1182,21 @@ void UEFITool::readSettings()
|
|||||||
markingEnabled = settings.value("tree/markingEnabled", true).toBool();
|
markingEnabled = settings.value("tree/markingEnabled", true).toBool();
|
||||||
ui->actionToggleBootGuardMarking->setChecked(markingEnabled);
|
ui->actionToggleBootGuardMarking->setChecked(markingEnabled);
|
||||||
|
|
||||||
|
// Get IDA Path
|
||||||
|
idaPath32 = settings.value("idaPath32").toString();
|
||||||
|
idaPath64 = settings.value("idaPath64").toString();
|
||||||
|
|
||||||
// Set monospace font for some controls
|
// Set monospace font for some controls
|
||||||
QString fontName;
|
UString fontName;
|
||||||
int fontSize;
|
int fontSize;
|
||||||
#if defined Q_OS_OSX
|
#if defined Q_OS_OSX
|
||||||
fontName = settings.value("mainWindow/fontName", QString("Menlo")).toString();
|
fontName = settings.value("mainWindow/fontName", UString("Menlo")).toString();
|
||||||
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
|
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
|
||||||
#elif defined Q_OS_WIN
|
#elif defined Q_OS_WIN
|
||||||
fontName = settings.value("mainWindow/fontName", QString("Consolas")).toString();
|
fontName = settings.value("mainWindow/fontName", UString("Consolas")).toString();
|
||||||
fontSize = settings.value("mainWindow/fontSize", 9).toInt();
|
fontSize = settings.value("mainWindow/fontSize", 9).toInt();
|
||||||
#else
|
#else
|
||||||
fontName = settings.value("mainWindow/fontName", QString("Courier New")).toString();
|
fontName = settings.value("mainWindow/fontName", UString("Courier New")).toString();
|
||||||
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
|
fontSize = settings.value("mainWindow/fontSize", 10).toInt();
|
||||||
#endif
|
#endif
|
||||||
currentFont = QFont(fontName, fontSize);
|
currentFont = QFont(fontName, fontSize);
|
||||||
@ -1096,6 +1206,8 @@ void UEFITool::readSettings()
|
|||||||
ui->builderMessagesListWidget->setFont(currentFont);
|
ui->builderMessagesListWidget->setFont(currentFont);
|
||||||
ui->fitTableWidget->setFont(currentFont);
|
ui->fitTableWidget->setFont(currentFont);
|
||||||
ui->bootGuardEdit->setFont(currentFont);
|
ui->bootGuardEdit->setFont(currentFont);
|
||||||
|
ui->txtEdit->setFont(currentFont);
|
||||||
|
ui->microcodeEdit->setFont(currentFont);
|
||||||
ui->structureTreeView->setFont(currentFont);
|
ui->structureTreeView->setFont(currentFont);
|
||||||
searchDialog->ui->guidEdit->setFont(currentFont);
|
searchDialog->ui->guidEdit->setFont(currentFont);
|
||||||
searchDialog->ui->hexEdit->setFont(currentFont);
|
searchDialog->ui->hexEdit->setFont(currentFont);
|
||||||
@ -1120,6 +1232,8 @@ void UEFITool::writeSettings()
|
|||||||
settings.setValue("tree/markingEnabled", markingEnabled);
|
settings.setValue("tree/markingEnabled", markingEnabled);
|
||||||
settings.setValue("mainWindow/fontName", currentFont.family());
|
settings.setValue("mainWindow/fontName", currentFont.family());
|
||||||
settings.setValue("mainWindow/fontSize", currentFont.pointSize());
|
settings.setValue("mainWindow/fontSize", currentFont.pointSize());
|
||||||
|
settings.setValue("idaPath32", idaPath32);
|
||||||
|
settings.setValue("idaPath64", idaPath64);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::showFitTable()
|
void UEFITool::showFitTable()
|
||||||
@ -1150,7 +1264,7 @@ void UEFITool::showFitTable()
|
|||||||
for (size_t i = 0; i < fitTable.size(); i++) {
|
for (size_t i = 0; i < fitTable.size(); i++) {
|
||||||
for (UINT8 j = 0; j < 6; j++) {
|
for (UINT8 j = 0; j < 6; j++) {
|
||||||
QTableWidgetItem* item = new QTableWidgetItem(fitTable[i].first[j]);
|
QTableWidgetItem* item = new QTableWidgetItem(fitTable[i].first[j]);
|
||||||
item->setData(Qt::UserRole, QByteArray((const char*)&fitTable[i].second, sizeof(fitTable[i].second)));
|
item->setData(Qt::UserRole, UByteArray((const char*)&fitTable[i].second, sizeof(fitTable[i].second)));
|
||||||
ui->fitTableWidget->setItem((int)i, j, item);
|
ui->fitTableWidget->setItem((int)i, j, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1161,15 +1275,27 @@ void UEFITool::showFitTable()
|
|||||||
|
|
||||||
// Get BootGuard info
|
// Get BootGuard info
|
||||||
UString bgInfo = ffsParser->getBootGuardInfo();
|
UString bgInfo = ffsParser->getBootGuardInfo();
|
||||||
if (bgInfo.isEmpty()) {
|
if (!bgInfo.isEmpty()) {
|
||||||
// Disable BootGuard tab
|
|
||||||
ui->messagesTabWidget->setTabEnabled(2, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->messagesTabWidget->setTabEnabled(2, true);
|
ui->messagesTabWidget->setTabEnabled(2, true);
|
||||||
ui->bootGuardEdit->setPlainText(bgInfo);
|
ui->bootGuardEdit->setPlainText(bgInfo);
|
||||||
ui->messagesTabWidget->setCurrentIndex(2);
|
ui->messagesTabWidget->setCurrentIndex(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Microcode info
|
||||||
|
UString microcodeInfo = ffsParser->getMicrocodeInfo();
|
||||||
|
if (!microcodeInfo.isEmpty()) {
|
||||||
|
ui->messagesTabWidget->setTabEnabled(4, true);
|
||||||
|
ui->microcodeEdit->setPlainText(microcodeInfo);
|
||||||
|
ui->messagesTabWidget->setCurrentIndex(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get TXT ACM info
|
||||||
|
UString txtInfo = ffsParser->getTxtInfo();
|
||||||
|
if (!txtInfo.isEmpty()) {
|
||||||
|
ui->messagesTabWidget->setTabEnabled(3, true);
|
||||||
|
ui->txtEdit->setPlainText(txtInfo);
|
||||||
|
ui->messagesTabWidget->setCurrentIndex(3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::currentTabChanged(int index)
|
void UEFITool::currentTabChanged(int index)
|
||||||
@ -1184,7 +1310,7 @@ void UEFITool::currentTabChanged(int index)
|
|||||||
|
|
||||||
void UEFITool::loadGuidDatabase()
|
void UEFITool::loadGuidDatabase()
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, tr("Comma-separated values files (*.csv);;All files (*)"));
|
UString path = QFileDialog::getOpenFileName(this, tr("Select GUID database file to load"), currentDir, tr("Comma-separated values files (*.csv);;All files (*)"));
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
initGuidDatabase(path);
|
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))
|
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))
|
||||||
@ -1210,9 +1336,9 @@ void UEFITool::loadDefaultGuidDatabase()
|
|||||||
|
|
||||||
void UEFITool::generateReport()
|
void UEFITool::generateReport()
|
||||||
{
|
{
|
||||||
QString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)"));
|
UString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)"));
|
||||||
if (!path.isEmpty()) {
|
if (!path.isEmpty()) {
|
||||||
std::vector<QString> report = ffsReport->generate();
|
std::vector<UString> report = ffsReport->generate();
|
||||||
if (report.size()) {
|
if (report.size()) {
|
||||||
QFile file;
|
QFile file;
|
||||||
file.setFileName(path);
|
file.setFileName(path);
|
||||||
|
@ -77,6 +77,10 @@ private slots:
|
|||||||
void openImageFileInNewWindow();
|
void openImageFileInNewWindow();
|
||||||
void saveImageFile();
|
void saveImageFile();
|
||||||
|
|
||||||
|
void specifyPathIDA();
|
||||||
|
void specifyPathIDA32();
|
||||||
|
void specifyPathIDA64();
|
||||||
|
|
||||||
void search();
|
void search();
|
||||||
void goToOffset();
|
void goToOffset();
|
||||||
void goToAddress();
|
void goToAddress();
|
||||||
@ -85,7 +89,7 @@ private slots:
|
|||||||
void bodyHexView();
|
void bodyHexView();
|
||||||
void goToData();
|
void goToData();
|
||||||
|
|
||||||
void extract(const UINT8 mode);
|
void extract(const UINT8 mode, UString* pathOut = NULL);
|
||||||
void extractAsIs();
|
void extractAsIs();
|
||||||
void extractBody();
|
void extractBody();
|
||||||
void extractBodyUncompressed();
|
void extractBodyUncompressed();
|
||||||
@ -103,6 +107,10 @@ private slots:
|
|||||||
|
|
||||||
void remove();
|
void remove();
|
||||||
|
|
||||||
|
void inspectIDA32();
|
||||||
|
void inspectIDA64();
|
||||||
|
void inspect(const UINT8 mode);
|
||||||
|
|
||||||
void copyMessage();
|
void copyMessage();
|
||||||
void copyAllMessages();
|
void copyAllMessages();
|
||||||
void enableMessagesCopyActions(QListWidgetItem* item);
|
void enableMessagesCopyActions(QListWidgetItem* item);
|
||||||
@ -139,6 +147,8 @@ private:
|
|||||||
QString currentDir;
|
QString currentDir;
|
||||||
QString currentPath;
|
QString currentPath;
|
||||||
QString currentProgramPath;
|
QString currentProgramPath;
|
||||||
|
QString idaPath32;
|
||||||
|
QString idaPath64;
|
||||||
QFont currentFont;
|
QFont currentFont;
|
||||||
const QString version;
|
const QString version;
|
||||||
bool markingEnabled;
|
bool markingEnabled;
|
||||||
|
@ -142,7 +142,7 @@
|
|||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="parserTab">
|
<widget class="QWidget" name="parserTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
@ -241,6 +241,82 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="txtTab">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>TXT</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="txtEdit">
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="undoRedoEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="microcodeTab">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Microcode</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPlainTextEdit" name="microcodeEdit">
|
||||||
|
<property name="acceptDrops">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="undoRedoEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<widget class="QWidget" name="finderTab">
|
<widget class="QWidget" name="finderTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Search</string>
|
<string>Search</string>
|
||||||
@ -311,7 +387,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>851</width>
|
<width>851</width>
|
||||||
<height>31</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menuFile">
|
<widget class="QMenu" name="menuFile">
|
||||||
@ -328,6 +404,8 @@
|
|||||||
<addaction name="actionLoadDefaultGuidDatabase"/>
|
<addaction name="actionLoadDefaultGuidDatabase"/>
|
||||||
<addaction name="actionUnloadGuidDatabase"/>
|
<addaction name="actionUnloadGuidDatabase"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionSpecifyPathIDA"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionQuit"/>
|
<addaction name="actionQuit"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuHelp">
|
<widget class="QMenu" name="menuHelp">
|
||||||
@ -424,6 +502,9 @@
|
|||||||
<addaction name="actionExtract"/>
|
<addaction name="actionExtract"/>
|
||||||
<addaction name="actionExtractBody"/>
|
<addaction name="actionExtractBody"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionInspectBodyIDA"/>
|
||||||
|
<addaction name="actionInspectBodyIDA64"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
<addaction name="actionRebuild"/>
|
<addaction name="actionRebuild"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionInsertInto"/>
|
<addaction name="actionInsertInto"/>
|
||||||
@ -907,6 +988,30 @@
|
|||||||
<string>Ctrl+Alt+D</string>
|
<string>Ctrl+Alt+D</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionSpecifyPathIDA">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Specify path to IDA Pro</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionInspectBodyIDA">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Inspect body with IDA</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionInspectBodyIDA64">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Inspect body with IDA64</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
@ -65,7 +65,10 @@ typedef size_t USTATUS;
|
|||||||
#define U_INVALID_ACM 43
|
#define U_INVALID_ACM 43
|
||||||
#define U_INVALID_BG_KEY_MANIFEST 44
|
#define U_INVALID_BG_KEY_MANIFEST 44
|
||||||
#define U_INVALID_BG_BOOT_POLICY 45
|
#define U_INVALID_BG_BOOT_POLICY 45
|
||||||
#define U_ELEMENTS_NOT_FOUND 46
|
#define U_INVALID_TXT_CONF 46
|
||||||
|
#define U_ELEMENTS_NOT_FOUND 47
|
||||||
|
#define U_PEI_CORE_ENTRY_POINT_NOT_FOUND 48
|
||||||
|
#define U_INVALID_STORE_SIZE 49
|
||||||
#define U_NOT_IMPLEMENTED 0xFF
|
#define U_NOT_IMPLEMENTED 0xFF
|
||||||
|
|
||||||
// UDK porting definitions
|
// UDK porting definitions
|
||||||
@ -87,6 +90,10 @@ typedef ptrdiff_t INTN;
|
|||||||
#define VOID void
|
#define VOID void
|
||||||
#define STATIC static
|
#define STATIC static
|
||||||
|
|
||||||
|
#ifndef INT32_MAX
|
||||||
|
#define INT32_MAX 0x7fffffff
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
#define TRUE ((BOOLEAN)(1==1))
|
#define TRUE ((BOOLEAN)(1==1))
|
||||||
#endif
|
#endif
|
||||||
@ -125,6 +132,10 @@ typedef ptrdiff_t INTN;
|
|||||||
#define EXTRACT_MODE_BODY 1
|
#define EXTRACT_MODE_BODY 1
|
||||||
#define EXTRACT_MODE_BODY_UNCOMPRESSED 2
|
#define EXTRACT_MODE_BODY_UNCOMPRESSED 2
|
||||||
|
|
||||||
|
// Item inspect modes
|
||||||
|
#define INSPECT_MODE_IDA32 0
|
||||||
|
#define INSPECT_MODE_IDA64 1
|
||||||
|
|
||||||
// Item replace modes
|
// Item replace modes
|
||||||
#define REPLACE_MODE_AS_IS 0
|
#define REPLACE_MODE_AS_IS 0
|
||||||
#define REPLACE_MODE_BODY 1
|
#define REPLACE_MODE_BODY 1
|
||||||
|
@ -72,11 +72,14 @@ typedef struct BG_MICROSOFT_PMDA_ENTRY_
|
|||||||
// Intel ACM
|
// Intel ACM
|
||||||
//
|
//
|
||||||
|
|
||||||
#define INTEL_ACM_MODULE_TYPE 0x00030002
|
#define INTEL_ACM_MODULE_TYPE 0x2
|
||||||
|
#define INTEL_ACM_MODULE_SUBTYPE_TXT_ACM 0x0
|
||||||
|
#define INTEL_ACM_MODULE_SUBTYPE_S_ACM 0x1
|
||||||
#define INTEL_ACM_MODULE_VENDOR 0x8086
|
#define INTEL_ACM_MODULE_VENDOR 0x8086
|
||||||
|
|
||||||
typedef struct INTEL_ACM_HEADER_ {
|
typedef struct INTEL_ACM_HEADER_ {
|
||||||
UINT32 ModuleType;
|
UINT16 ModuleType;
|
||||||
|
UINT16 ModuleSubtype;
|
||||||
UINT32 HeaderType;
|
UINT32 HeaderType;
|
||||||
UINT32 HeaderVersion;
|
UINT32 HeaderVersion;
|
||||||
UINT16 ChipsetId;
|
UINT16 ChipsetId;
|
||||||
|
@ -118,3 +118,52 @@ UString sectionTypeToUString(const UINT8 type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header)
|
||||||
|
{
|
||||||
|
if (!header)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
bool extended = false;
|
||||||
|
if (uint24ToUint32(header->Size) == EFI_SECTION2_IS_USED) {
|
||||||
|
extended = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (header->Type)
|
||||||
|
{
|
||||||
|
case EFI_SECTION_GUID_DEFINED: {
|
||||||
|
if (!extended) {
|
||||||
|
const EFI_GUID_DEFINED_SECTION* gdsHeader = (const EFI_GUID_DEFINED_SECTION*)header;
|
||||||
|
if (QByteArray((const char*)&gdsHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||||
|
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)(gdsHeader + 1);
|
||||||
|
return gdsHeader->DataOffset + certificateHeader->Length;
|
||||||
|
}
|
||||||
|
return gdsHeader->DataOffset;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const EFI_GUID_DEFINED_SECTION2* gdsHeader = (const EFI_GUID_DEFINED_SECTION2*)header;
|
||||||
|
if (QByteArray((const char*)&gdsHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||||
|
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)(gdsHeader + 1);
|
||||||
|
return gdsHeader->DataOffset + certificateHeader->Length;
|
||||||
|
}
|
||||||
|
return gdsHeader->DataOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case EFI_SECTION_COMPRESSION: return extended ? sizeof(EFI_COMPRESSION_SECTION2) : sizeof(EFI_COMPRESSION_SECTION);
|
||||||
|
case EFI_SECTION_DISPOSABLE: return extended ? sizeof(EFI_DISPOSABLE_SECTION2) : sizeof(EFI_DISPOSABLE_SECTION);
|
||||||
|
case EFI_SECTION_PE32: return extended ? sizeof(EFI_PE32_SECTION2) : sizeof(EFI_PE32_SECTION);
|
||||||
|
case EFI_SECTION_PIC: return extended ? sizeof(EFI_PIC_SECTION2) : sizeof(EFI_PIC_SECTION);
|
||||||
|
case EFI_SECTION_TE: return extended ? sizeof(EFI_TE_SECTION2) : sizeof(EFI_TE_SECTION);
|
||||||
|
case EFI_SECTION_DXE_DEPEX: return extended ? sizeof(EFI_DXE_DEPEX_SECTION2) : sizeof(EFI_DXE_DEPEX_SECTION);
|
||||||
|
case EFI_SECTION_VERSION: return extended ? sizeof(EFI_VERSION_SECTION2) : sizeof(EFI_VERSION_SECTION);
|
||||||
|
case EFI_SECTION_USER_INTERFACE: return extended ? sizeof(EFI_USER_INTERFACE_SECTION2) : sizeof(EFI_USER_INTERFACE_SECTION);
|
||||||
|
case EFI_SECTION_COMPATIBILITY16: return extended ? sizeof(EFI_COMPATIBILITY16_SECTION2) : sizeof(EFI_COMPATIBILITY16_SECTION);
|
||||||
|
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return extended ? sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION2) : sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION);
|
||||||
|
case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return extended ? sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION2) : sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
|
||||||
|
case EFI_SECTION_RAW: return extended ? sizeof(EFI_RAW_SECTION2) : sizeof(EFI_RAW_SECTION);
|
||||||
|
case EFI_SECTION_PEI_DEPEX: return extended ? sizeof(EFI_PEI_DEPEX_SECTION2) : sizeof(EFI_PEI_DEPEX_SECTION);
|
||||||
|
case EFI_SECTION_MM_DEPEX: return extended ? sizeof(EFI_SMM_DEPEX_SECTION2) : sizeof(EFI_SMM_DEPEX_SECTION);
|
||||||
|
case INSYDE_SECTION_POSTCODE: return extended ? sizeof(POSTCODE_SECTION2) : sizeof(POSTCODE_SECTION);
|
||||||
|
case PHOENIX_SECTION_POSTCODE: return extended ? sizeof(POSTCODE_SECTION2) : sizeof(POSTCODE_SECTION);
|
||||||
|
default: return extended ? sizeof(EFI_COMMON_SECTION_HEADER2) : sizeof(EFI_COMMON_SECTION_HEADER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
71
common/ffs.h
71
common/ffs.h
@ -26,6 +26,7 @@ extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true);
|
|||||||
extern UString fileTypeToUString(const UINT8 type);
|
extern UString fileTypeToUString(const UINT8 type);
|
||||||
extern UString sectionTypeToUString(const UINT8 type);
|
extern UString sectionTypeToUString(const UINT8 type);
|
||||||
|
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// EFI Capsule
|
// EFI Capsule
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
@ -369,6 +370,10 @@ const UByteArray AMI_CORE_DXE_GUID // 5AE3F37E-4EAE-41AE-8240-35465B5E81EB
|
|||||||
const UByteArray EFI_DXE_CORE_GUID // D6A2CB7F-6A18-4E2F-B43B-9920A733700A
|
const UByteArray EFI_DXE_CORE_GUID // D6A2CB7F-6A18-4E2F-B43B-9920A733700A
|
||||||
("\x7F\xCB\xA2\xD6\x18\x6A\x2F\x4E\xB4\x3B\x99\x20\xA7\x33\x70\x0A", 16);
|
("\x7F\xCB\xA2\xD6\x18\x6A\x2F\x4E\xB4\x3B\x99\x20\xA7\x33\x70\x0A", 16);
|
||||||
|
|
||||||
|
// TXT ACM
|
||||||
|
const UByteArray EFI_TXT_ACM_GUID // 2D27C618-7DCD-41F5-BB10-21166BE7E143
|
||||||
|
("\x18\xC6\x27\x2D\xCD\x7D\xF5\x41\xBB\x10\x21\x16\x6B\xE7\xE1\x43", 16);
|
||||||
|
|
||||||
// FFS size conversion routines
|
// FFS size conversion routines
|
||||||
extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize);
|
extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize);
|
||||||
extern UINT32 uint24ToUint32(const UINT8* ffsSize);
|
extern UINT32 uint24ToUint32(const UINT8* ffsSize);
|
||||||
@ -432,6 +437,14 @@ typedef struct EFI_COMPRESSION_SECTION_ {
|
|||||||
UINT8 CompressionType;
|
UINT8 CompressionType;
|
||||||
} EFI_COMPRESSION_SECTION;
|
} EFI_COMPRESSION_SECTION;
|
||||||
|
|
||||||
|
typedef struct _EFI_COMPRESSION_SECTION2 {
|
||||||
|
UINT8 Size[3];
|
||||||
|
UINT8 Type;
|
||||||
|
UINT32 ExtendedSize;
|
||||||
|
UINT32 UncompressedLength;
|
||||||
|
UINT8 CompressionType;
|
||||||
|
} EFI_COMPRESSION_SECTION2;
|
||||||
|
|
||||||
typedef struct EFI_COMPRESSION_SECTION_APPLE_ {
|
typedef struct EFI_COMPRESSION_SECTION_APPLE_ {
|
||||||
UINT32 UncompressedLength;
|
UINT32 UncompressedLength;
|
||||||
UINT32 CompressionType;
|
UINT32 CompressionType;
|
||||||
@ -456,6 +469,16 @@ typedef struct EFI_GUID_DEFINED_SECTION_APPLE_ {
|
|||||||
UINT32 Reserved;
|
UINT32 Reserved;
|
||||||
} EFI_GUID_DEFINED_SECTION_APPLE;
|
} EFI_GUID_DEFINED_SECTION_APPLE;
|
||||||
|
|
||||||
|
typedef struct _EFI_GUID_DEFINED_SECTION2 {
|
||||||
|
UINT8 Size[3];
|
||||||
|
UINT8 Type;
|
||||||
|
UINT32 ExtendedSize;
|
||||||
|
EFI_GUID SectionDefinitionGuid;
|
||||||
|
UINT16 DataOffset;
|
||||||
|
UINT16 Attributes;
|
||||||
|
} EFI_GUID_DEFINED_SECTION2;
|
||||||
|
|
||||||
|
|
||||||
// Attributes for GUID defined section
|
// Attributes for GUID defined section
|
||||||
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
|
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
|
||||||
#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02
|
#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02
|
||||||
@ -511,16 +534,64 @@ typedef struct EFI_VERSION_SECTION_ {
|
|||||||
UINT16 BuildNumber;
|
UINT16 BuildNumber;
|
||||||
} EFI_VERSION_SECTION;
|
} EFI_VERSION_SECTION;
|
||||||
|
|
||||||
|
typedef struct _EFI_VERSION_SECTION2 {
|
||||||
|
UINT8 Size[3];
|
||||||
|
UINT8 Type;
|
||||||
|
UINT32 ExtendedSize;
|
||||||
|
UINT16 BuildNumber;
|
||||||
|
} EFI_VERSION_SECTION2;
|
||||||
|
|
||||||
// Freeform subtype GUID section
|
// Freeform subtype GUID section
|
||||||
typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION_ {
|
typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION_ {
|
||||||
EFI_GUID SubTypeGuid;
|
EFI_GUID SubTypeGuid;
|
||||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
||||||
|
|
||||||
|
typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION2 {
|
||||||
|
UINT8 Size[3];
|
||||||
|
UINT8 Type;
|
||||||
|
UINT32 ExtendedSize;
|
||||||
|
EFI_GUID SubTypeGuid;
|
||||||
|
} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
|
||||||
|
|
||||||
// Phoenix SCT and Insyde postcode section
|
// Phoenix SCT and Insyde postcode section
|
||||||
typedef struct POSTCODE_SECTION_ {
|
typedef struct POSTCODE_SECTION_ {
|
||||||
UINT32 Postcode;
|
UINT32 Postcode;
|
||||||
} POSTCODE_SECTION;
|
} POSTCODE_SECTION;
|
||||||
|
|
||||||
|
typedef struct _POSTCODE_SECTION2 {
|
||||||
|
UINT8 Size[3];
|
||||||
|
UINT8 Type;
|
||||||
|
UINT32 ExtendedSize;
|
||||||
|
UINT32 Postcode;
|
||||||
|
} POSTCODE_SECTION2;
|
||||||
|
|
||||||
|
// Other sections
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
|
||||||
|
typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
|
||||||
|
|
||||||
|
// Section routines
|
||||||
|
UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header);
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// EFI Dependency Expression
|
// EFI Dependency Expression
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,11 +20,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "ubytearray.h"
|
#include "ubytearray.h"
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
#include "treemodel.h"
|
#include "treemodel.h"
|
||||||
|
#include "ffsparser.h"
|
||||||
|
|
||||||
class FfsBuilder
|
class FfsBuilder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FfsBuilder(const TreeModel * treeModel) : model(treeModel) {}
|
FfsBuilder(const TreeModel * treeModel) : model(treeModel) {}
|
||||||
|
FfsBuilder(const TreeModel * treeModel, FfsParser * ffsParser) : model(treeModel), parser(ffsParser) {}
|
||||||
|
|
||||||
~FfsBuilder() {}
|
~FfsBuilder() {}
|
||||||
|
|
||||||
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
|
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; }
|
||||||
@ -33,7 +36,9 @@ public:
|
|||||||
USTATUS build(const UModelIndex & root, UByteArray & image);
|
USTATUS build(const UModelIndex & root, UByteArray & image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TreeModel* model;
|
const TreeModel * model;
|
||||||
|
FfsParser * parser;
|
||||||
|
|
||||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
||||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
||||||
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
||||||
@ -41,17 +46,23 @@ private:
|
|||||||
|
|
||||||
USTATUS buildCapsule(const UModelIndex & index, UByteArray & capsule);
|
USTATUS buildCapsule(const UModelIndex & index, UByteArray & capsule);
|
||||||
USTATUS buildIntelImage(const UModelIndex & index, UByteArray & intelImage);
|
USTATUS buildIntelImage(const UModelIndex & index, UByteArray & intelImage);
|
||||||
USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea);
|
USTATUS buildRawArea(const UModelIndex & index, UByteArray & rawArea, bool includeHeader = true);
|
||||||
USTATUS buildPadding(const UModelIndex & index, UByteArray & padding);
|
USTATUS buildPadding(const UModelIndex & index, UByteArray & padding);
|
||||||
USTATUS buildVolume(const UModelIndex & index, UByteArray & volume);
|
USTATUS buildVolume(const UModelIndex & index, UByteArray & volume);
|
||||||
|
USTATUS buildNvramVolume(const UModelIndex & index, UByteArray & volume);
|
||||||
|
USTATUS buildNvramStore(const UModelIndex & index, UByteArray & store);
|
||||||
|
USTATUS buildNvarStore(const UModelIndex & index, UByteArray & store);
|
||||||
USTATUS buildNonUefiData(const UModelIndex & index, UByteArray & data);
|
USTATUS buildNonUefiData(const UModelIndex & index, UByteArray & data);
|
||||||
USTATUS buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace);
|
USTATUS buildFreeSpace(const UModelIndex & index, UByteArray & freeSpace);
|
||||||
USTATUS buildPadFile(const UModelIndex & index, UByteArray & padFile);
|
USTATUS buildPadFile(const UByteArray &guid, const UINT32 size, const UINT8 revision, const UINT8 erasePolarity, UByteArray & pad);
|
||||||
USTATUS buildFile(const UModelIndex & index, UByteArray & file);
|
USTATUS buildFile(const UModelIndex & index, const UINT8 revision, const UINT8 erasePolarity, const UINT32 base, UByteArray & reconstructed);
|
||||||
USTATUS buildSection(const UModelIndex & index, UByteArray & section);
|
USTATUS buildSection(const UModelIndex & index, const UINT32 base, UByteArray & reconstructed);
|
||||||
|
USTATUS buildRegion(const UModelIndex& index, UByteArray & reconstructed, bool includeHeader = true);
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
USTATUS erase(const UModelIndex & index, UByteArray & erased);
|
USTATUS erase(const UModelIndex & index, UByteArray & erased);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FFSBUILDER_H
|
#endif // FFSBUILDER_H
|
||||||
|
@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "ffsops.h"
|
#include "ffsops.h"
|
||||||
#include "ffs.h"
|
#include "ffs.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
#include "nvramparser.h"
|
||||||
|
|
||||||
USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode)
|
USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode)
|
||||||
{
|
{
|
||||||
@ -59,22 +60,114 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsOperations::replace(const UModelIndex & index, const UString & data, const UINT8 mode)
|
USTATUS FfsOperations::replace(const UModelIndex & index, UByteArray & data, const UINT8 mode)
|
||||||
{
|
{
|
||||||
U_UNUSED_PARAMETER(data);
|
if (!index.isValid() || !index.parent().isValid())
|
||||||
|
|
||||||
// Sanity check
|
|
||||||
if (!index.isValid())
|
|
||||||
return U_INVALID_PARAMETER;
|
return U_INVALID_PARAMETER;
|
||||||
|
|
||||||
if (mode == REPLACE_MODE_AS_IS) {
|
USTATUS result;
|
||||||
return U_NOT_IMPLEMENTED;
|
UByteArray empty = "";
|
||||||
}
|
FfsParser parser(model);
|
||||||
else if (mode == REPLACE_MODE_BODY) {
|
UINT32 localOffset = model->offset(index) + model->header(index).size();
|
||||||
|
UModelIndex index_out;
|
||||||
|
|
||||||
|
if(mode == REPLACE_MODE_BODY)
|
||||||
|
data = model->header(index) + data;
|
||||||
|
|
||||||
|
if (model->type(index) == Types::Region) {
|
||||||
|
UINT8 type = model->subtype(index);
|
||||||
|
switch (type) {
|
||||||
|
case Subtypes::BiosRegion:
|
||||||
|
result = parser.parseBiosRegion(data, localOffset, index, index_out, CREATE_MODE_AFTER);
|
||||||
|
break;
|
||||||
|
case Subtypes::MeRegion:
|
||||||
|
result = parser.parseMeRegion(data, localOffset, index, index_out, CREATE_MODE_AFTER);
|
||||||
|
break;
|
||||||
|
case Subtypes::GbeRegion:
|
||||||
|
result = parser.parseGbeRegion(data, localOffset, index, index_out, CREATE_MODE_AFTER);
|
||||||
|
break;
|
||||||
|
case Subtypes::PdrRegion:
|
||||||
|
result = parser.parsePdrRegion(data, localOffset, index, index_out, CREATE_MODE_AFTER);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return U_NOT_IMPLEMENTED;
|
return U_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_UNKNOWN_REPLACE_MODE;
|
if (result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (model->type(index) == Types::Padding) {
|
||||||
|
// Get info
|
||||||
|
QString name = usprintf("Padding");
|
||||||
|
QString info = usprintf("Full size: %Xh (%u)", data.size(), data.size());
|
||||||
|
// Add tree item
|
||||||
|
//!TODO UModelIndex fileIndex = model->addItem(Types::Padding, getPaddingType(body), COMPRESSION_ALGORITHM_NONE, name, "", info, UByteArray(), body, index, mode);
|
||||||
|
}
|
||||||
|
else if (model->type(index) == Types::Volume) {
|
||||||
|
result = parser.parseVolumeHeader(data, localOffset, index, index_out, CREATE_MODE_AFTER);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = parser.parseVolumeBody(index_out);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (model->type(index) == Types::File) {
|
||||||
|
result = parser.parseFileHeader(data, localOffset, index, index_out, CREATE_MODE_AFTER);
|
||||||
|
if (result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = parser.parseFileBody(index_out);
|
||||||
|
if (result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if (model->type(index) == Types::Section) {
|
||||||
|
result = parser.parseSectionHeader(data, localOffset, index, index_out, true, CREATE_MODE_AFTER);
|
||||||
|
if (result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = parser.parseSectionBody(index_out);
|
||||||
|
if(result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else if(model->type(index) == Types::EvsaStore || model->type(index) == Types::CmdbStore ||
|
||||||
|
model->type(index) == Types::FdcStore || model->type(index) == Types::FlashMapStore ||
|
||||||
|
model->type(index) == Types::FsysStore || model->type(index) == Types::FtwStore ||
|
||||||
|
model->type(index) == Types::Vss2Store || model->type(index) == Types::VssStore) {
|
||||||
|
if(data.size() != model->header(index).size() + model->body(index).size())
|
||||||
|
return U_INVALID_STORE_SIZE;
|
||||||
|
|
||||||
|
NvramParser nvramParser(model, &parser);
|
||||||
|
|
||||||
|
result = nvramParser.parseStoreHeader(data, localOffset, index, index_out, CREATE_MODE_AFTER);
|
||||||
|
if (result && result != U_VOLUMES_NOT_FOUND && result != U_INVALID_VOLUME)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
UINT8 type = model->type(index);
|
||||||
|
switch (type) {
|
||||||
|
case Types::FdcStore: nvramParser.parseFdcStoreBody(index_out); break;
|
||||||
|
case Types::VssStore: nvramParser.parseVssStoreBody(index_out, 0); break;
|
||||||
|
case Types::Vss2Store: nvramParser.parseVssStoreBody(index_out, 4); break;
|
||||||
|
case Types::FsysStore: nvramParser.parseFsysStoreBody(index_out); break;
|
||||||
|
case Types::EvsaStore: nvramParser.parseEvsaStoreBody(index_out); break;
|
||||||
|
case Types::FlashMapStore: nvramParser.parseFlashMapBody(index_out); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return U_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
// Set remove action to replaced item
|
||||||
|
model->setAction(index, Actions::Remove);
|
||||||
|
model->setAction(index_out, Actions::Replace);
|
||||||
|
|
||||||
|
// Rebuild parent, if it has no action now
|
||||||
|
UModelIndex parent = index.parent();
|
||||||
|
if (parent.isValid() && model->type(parent) != Types::Root
|
||||||
|
&& model->action(parent) == Actions::NoAction)
|
||||||
|
rebuild(parent);
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsOperations::remove(const UModelIndex & index)
|
USTATUS FfsOperations::remove(const UModelIndex & index)
|
||||||
|
@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "ubytearray.h"
|
#include "ubytearray.h"
|
||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
#include "treemodel.h"
|
#include "treemodel.h"
|
||||||
|
#include "ffsparser.h"
|
||||||
|
|
||||||
class FfsOperations
|
class FfsOperations
|
||||||
{
|
{
|
||||||
@ -32,13 +33,14 @@ public:
|
|||||||
void clearMessages() { messagesVector.clear(); }
|
void clearMessages() { messagesVector.clear(); }
|
||||||
|
|
||||||
USTATUS extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode);
|
USTATUS extract(const UModelIndex & index, UString & name, UByteArray & extracted, const UINT8 mode);
|
||||||
USTATUS replace(const UModelIndex & index, const UString & data, const UINT8 mode);
|
USTATUS replace(const UModelIndex & index, UByteArray & data, const UINT8 mode);
|
||||||
|
|
||||||
USTATUS remove(const UModelIndex & index);
|
USTATUS remove(const UModelIndex & index);
|
||||||
USTATUS rebuild(const UModelIndex & index);
|
USTATUS rebuild(const UModelIndex & index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeModel* model;
|
TreeModel * model;
|
||||||
|
|
||||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
||||||
|
|
||||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
||||||
|
@ -55,7 +55,7 @@ struct REGION_INFO {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
FfsParser::FfsParser(TreeModel* treeModel) : model(treeModel),
|
FfsParser::FfsParser(TreeModel* treeModel) : model(treeModel),
|
||||||
imageBase(0), addressDiff(0x100000000ULL),
|
imageBase(0), addressDiff(0x100000000ULL), peiCoreEntryPoint(0), newPeiCoreEntryPoint(0),
|
||||||
bgAcmFound(false), bgKeyManifestFound(false), bgBootPolicyFound(false), bgFirstVolumeOffset(0x100000000ULL) {
|
bgAcmFound(false), bgKeyManifestFound(false), bgBootPolicyFound(false), bgFirstVolumeOffset(0x100000000ULL) {
|
||||||
nvramParser = new NvramParser(treeModel, this);
|
nvramParser = new NvramParser(treeModel, this);
|
||||||
meParser = new MeParser(treeModel);
|
meParser = new MeParser(treeModel);
|
||||||
@ -101,6 +101,9 @@ USTATUS FfsParser::parse(const UByteArray & buffer)
|
|||||||
|
|
||||||
USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & index)
|
USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & index)
|
||||||
{
|
{
|
||||||
|
peiCoreEntryPoint = 0;
|
||||||
|
newPeiCoreEntryPoint = 0;
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (buffer.isEmpty()) {
|
if (buffer.isEmpty()) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
@ -630,7 +633,7 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
|
|||||||
return parseResult;
|
return parseResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS FfsParser::parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if (gbe.isEmpty())
|
if (gbe.isEmpty())
|
||||||
@ -650,12 +653,12 @@ USTATUS FfsParser::parseGbeRegion(const UByteArray & gbe, const UINT32 localOffs
|
|||||||
version->minor);
|
version->minor);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::GbeRegion, name, UString(), info, UByteArray(), gbe, UByteArray(), Fixed, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::GbeRegion, name, UString(), info, UByteArray(), gbe, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if (me.isEmpty())
|
if (me.isEmpty())
|
||||||
@ -702,7 +705,7 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::MeRegion, name, UString(), info, UByteArray(), me, UByteArray(), Fixed, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::MeRegion, name, UString(), info, UByteArray(), me, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
// Show messages
|
// Show messages
|
||||||
if (emptyRegion) {
|
if (emptyRegion) {
|
||||||
@ -718,7 +721,7 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if (pdr.isEmpty())
|
if (pdr.isEmpty())
|
||||||
@ -729,7 +732,7 @@ USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffs
|
|||||||
UString info = usprintf("Full size: %Xh (%u)", pdr.size(), pdr.size());
|
UString info = usprintf("Full size: %Xh (%u)", pdr.size(), pdr.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::PdrRegion, name, UString(), info, UByteArray(), pdr, UByteArray(), Fixed, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::PdrRegion, name, UString(), info, UByteArray(), pdr, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
// Parse PDR region as BIOS space
|
// Parse PDR region as BIOS space
|
||||||
USTATUS result = parseRawArea(index);
|
USTATUS result = parseRawArea(index);
|
||||||
@ -739,7 +742,7 @@ USTATUS FfsParser::parsePdrRegion(const UByteArray & pdr, const UINT32 localOffs
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseGenericRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS FfsParser::parseGenericRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if (region.isEmpty())
|
if (region.isEmpty())
|
||||||
@ -750,12 +753,12 @@ USTATUS FfsParser::parseGenericRegion(const UINT8 subtype, const UByteArray & re
|
|||||||
UString info = usprintf("Full size: %Xh (%u)", region.size(), region.size());
|
UString info = usprintf("Full size: %Xh (%u)", region.size(), region.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Region, subtype, name, UString(), info, UByteArray(), region, UByteArray(), Fixed, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Region, subtype, name, UString(), info, UByteArray(), region, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS FfsParser::parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (bios.isEmpty())
|
if (bios.isEmpty())
|
||||||
@ -766,7 +769,7 @@ USTATUS FfsParser::parseBiosRegion(const UByteArray & bios, const UINT32 localOf
|
|||||||
UString info = usprintf("Full size: %Xh (%u)", bios.size(), bios.size());
|
UString info = usprintf("Full size: %Xh (%u)", bios.size(), bios.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::BiosRegion, name, UString(), info, UByteArray(), bios, UByteArray(), Fixed, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::BiosRegion, name, UString(), info, UByteArray(), bios, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return parseRawArea(index);
|
return parseRawArea(index);
|
||||||
}
|
}
|
||||||
@ -907,7 +910,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (volume.isEmpty())
|
if (volume.isEmpty())
|
||||||
@ -1069,7 +1072,7 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
|
|||||||
else if (isNvramVolume)
|
else if (isNvramVolume)
|
||||||
subtype = Subtypes::NvramVolume;
|
subtype = Subtypes::NvramVolume;
|
||||||
}
|
}
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Volume, subtype, name, text, info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Volume, subtype, name, text, info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
// Set parsing data for created volume
|
// Set parsing data for created volume
|
||||||
VOLUME_PARSING_DATA pdata;
|
VOLUME_PARSING_DATA pdata;
|
||||||
@ -1376,7 +1379,7 @@ UINT32 FfsParser::getFileSize(const UByteArray & volume, const UINT32 fileOffset
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (file.isEmpty()) {
|
if (file.isEmpty()) {
|
||||||
@ -1496,6 +1499,7 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf
|
|||||||
usprintf("\nHeader checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.Header) + (msgInvalidHeaderChecksum ? usprintf(", invalid, should be %02Xh", calculatedHeader) : UString(", valid")) +
|
usprintf("\nHeader checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.Header) + (msgInvalidHeaderChecksum ? usprintf(", invalid, should be %02Xh", calculatedHeader) : UString(", valid")) +
|
||||||
usprintf("\nData checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.File) + (msgInvalidDataChecksum ? usprintf(", invalid, should be %02Xh", calculatedData) : UString(", valid"));
|
usprintf("\nData checksum: %02Xh", fileHeader->IntegrityCheck.Checksum.File) + (msgInvalidDataChecksum ? usprintf(", invalid, should be %02Xh", calculatedData) : UString(", valid"));
|
||||||
|
|
||||||
|
|
||||||
UString text;
|
UString text;
|
||||||
bool isVtf = false;
|
bool isVtf = false;
|
||||||
bool isDxeCore = false;
|
bool isDxeCore = false;
|
||||||
@ -1514,12 +1518,62 @@ USTATUS FfsParser::parseFileHeader(const UByteArray & file, const UINT32 localOf
|
|||||||
// This information may be used to determine DXE volume offset for old AMI or post-IBB protected ranges
|
// This information may be used to determine DXE volume offset for old AMI or post-IBB protected ranges
|
||||||
isDxeCore = true;
|
isDxeCore = true;
|
||||||
}
|
}
|
||||||
|
else if (fileGuid == EFI_TXT_ACM_GUID) {
|
||||||
|
// Detect TXT ACM and update TXT tab
|
||||||
|
const INTEL_ACM_HEADER* acmHeader = (const INTEL_ACM_HEADER*)body.constData();
|
||||||
|
|
||||||
|
// Add ACM header info
|
||||||
|
txtInfo += usprintf(
|
||||||
|
"TXT ACM found at offset %Xh\n"
|
||||||
|
"ModuleType: %04Xh ModuleSubtype: %04Xh HeaderLength: %08Xh\n"
|
||||||
|
"HeaderVersion: %08Xh ChipsetId: %04Xh Flags: %04Xh\n"
|
||||||
|
"ModuleVendor: %04Xh Date: %02X.%02X.%04X ModuleSize: %08Xh\n"
|
||||||
|
"EntryPoint: %08Xh AcmSvn: %04Xh Unknown1: %08Xh\n"
|
||||||
|
"Unknown2: %08Xh GdtBase: %08Xh GdtMax: %08Xh\n"
|
||||||
|
"SegSel: %08Xh KeySize: %08Xh Unknown3: %08Xh",
|
||||||
|
model->offset(parent) + localOffset,
|
||||||
|
acmHeader->ModuleType,
|
||||||
|
acmHeader->ModuleSubtype,
|
||||||
|
acmHeader->ModuleSize * sizeof(UINT32),
|
||||||
|
acmHeader->HeaderVersion,
|
||||||
|
acmHeader->ChipsetId,
|
||||||
|
acmHeader->Flags,
|
||||||
|
acmHeader->ModuleVendor,
|
||||||
|
acmHeader->DateDay, acmHeader->DateMonth, acmHeader->DateYear,
|
||||||
|
acmHeader->ModuleSize * sizeof(UINT32),
|
||||||
|
acmHeader->EntryPoint,
|
||||||
|
acmHeader->AcmSvn,
|
||||||
|
acmHeader->Unknown1,
|
||||||
|
acmHeader->Unknown2,
|
||||||
|
acmHeader->GdtBase,
|
||||||
|
acmHeader->GdtMax,
|
||||||
|
acmHeader->SegmentSel,
|
||||||
|
acmHeader->KeySize * sizeof(UINT32),
|
||||||
|
acmHeader->Unknown4 * sizeof(UINT32)
|
||||||
|
);
|
||||||
|
// Add PubKey
|
||||||
|
txtInfo += usprintf("\n\nACM RSA Public Key (Exponent: %Xh):", acmHeader->RsaPubExp);
|
||||||
|
for (UINT16 i = 0; i < sizeof(acmHeader->RsaPubKey); i++) {
|
||||||
|
if (i % 32 == 0)
|
||||||
|
txtInfo += UString("\n");
|
||||||
|
txtInfo += usprintf("%02X", acmHeader->RsaPubKey[i]);
|
||||||
|
}
|
||||||
|
// Add RsaSig
|
||||||
|
txtInfo += UString("\n\nACM RSA Signature:");
|
||||||
|
for (UINT16 i = 0; i < sizeof(acmHeader->RsaSig); i++) {
|
||||||
|
if (i % 32 == 0)
|
||||||
|
txtInfo += UString("\n");
|
||||||
|
txtInfo += usprintf("%02X", acmHeader->RsaSig[i]);
|
||||||
|
}
|
||||||
|
txtInfo += UString("\n------------------------------------------------------------------------\n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Construct fixed state
|
// Construct fixed state
|
||||||
ItemFixedState fixed = (ItemFixedState)((fileHeader->Attributes & FFS_ATTRIB_FIXED) != 0);
|
ItemFixedState fixed = (ItemFixedState)((fileHeader->Attributes & FFS_ATTRIB_FIXED) != 0);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::File, fileHeader->Type, name, text, info, header, body, tail, fixed, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::File, fileHeader->Type, name, text, info, header, body, tail, fixed, parent, mode);
|
||||||
|
|
||||||
// Set parsing data for created file
|
// Set parsing data for created file
|
||||||
FILE_PARSING_DATA pdata;
|
FILE_PARSING_DATA pdata;
|
||||||
@ -1763,7 +1817,7 @@ USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree)
|
USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) {
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) {
|
||||||
@ -1773,12 +1827,12 @@ USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 l
|
|||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
switch (sectionHeader->Type) {
|
switch (sectionHeader->Type) {
|
||||||
// Special
|
// Special
|
||||||
case EFI_SECTION_COMPRESSION: return parseCompressedSectionHeader(section, localOffset, parent, index, insertIntoTree);
|
case EFI_SECTION_COMPRESSION: return parseCompressedSectionHeader(section, localOffset, parent, index, insertIntoTree, mode);
|
||||||
case EFI_SECTION_GUID_DEFINED: return parseGuidedSectionHeader(section, localOffset, parent, index, insertIntoTree);
|
case EFI_SECTION_GUID_DEFINED: return parseGuidedSectionHeader(section, localOffset, parent, index, insertIntoTree, mode);
|
||||||
case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseFreeformGuidedSectionHeader(section, localOffset, parent, index, insertIntoTree);
|
case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return parseFreeformGuidedSectionHeader(section, localOffset, parent, index, insertIntoTree, mode);
|
||||||
case EFI_SECTION_VERSION: return parseVersionSectionHeader(section, localOffset, parent, index, insertIntoTree);
|
case EFI_SECTION_VERSION: return parseVersionSectionHeader(section, localOffset, parent, index, insertIntoTree, mode);
|
||||||
case PHOENIX_SECTION_POSTCODE:
|
case PHOENIX_SECTION_POSTCODE:
|
||||||
case INSYDE_SECTION_POSTCODE: return parsePostcodeSectionHeader(section, localOffset, parent, index, insertIntoTree);
|
case INSYDE_SECTION_POSTCODE: return parsePostcodeSectionHeader(section, localOffset, parent, index, insertIntoTree, mode);
|
||||||
// Common
|
// Common
|
||||||
case EFI_SECTION_DISPOSABLE:
|
case EFI_SECTION_DISPOSABLE:
|
||||||
case EFI_SECTION_DXE_DEPEX:
|
case EFI_SECTION_DXE_DEPEX:
|
||||||
@ -1790,16 +1844,16 @@ USTATUS FfsParser::parseSectionHeader(const UByteArray & section, const UINT32 l
|
|||||||
case EFI_SECTION_COMPATIBILITY16:
|
case EFI_SECTION_COMPATIBILITY16:
|
||||||
case EFI_SECTION_USER_INTERFACE:
|
case EFI_SECTION_USER_INTERFACE:
|
||||||
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
|
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE:
|
||||||
case EFI_SECTION_RAW: return parseCommonSectionHeader(section, localOffset, parent, index, insertIntoTree);
|
case EFI_SECTION_RAW: return parseCommonSectionHeader(section, localOffset, parent, index, insertIntoTree, mode);
|
||||||
// Unknown
|
// Unknown
|
||||||
default:
|
default:
|
||||||
USTATUS result = parseCommonSectionHeader(section, localOffset, parent, index, insertIntoTree);
|
USTATUS result = parseCommonSectionHeader(section, localOffset, parent, index, insertIntoTree, mode);
|
||||||
msg(usprintf("%s: section with unknown type %02Xh", __FUNCTION__, sectionHeader->Type), index);
|
msg(usprintf("%s: section with unknown type %02Xh", __FUNCTION__, sectionHeader->Type), index);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree)
|
USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) {
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER)) {
|
||||||
@ -1847,15 +1901,23 @@ USTATUS FfsParser::parseCommonSectionHeader(const UByteArray & section, const UI
|
|||||||
headerSize, headerSize,
|
headerSize, headerSize,
|
||||||
body.size(), body.size());
|
body.size(), body.size());
|
||||||
|
|
||||||
|
// Special case of PEI Core
|
||||||
|
if (model->subtype(parent) == EFI_FV_FILETYPE_PEI_CORE
|
||||||
|
&& peiCoreEntryPoint == 0) {
|
||||||
|
USTATUS result = getEntryPoint(body, peiCoreEntryPoint);
|
||||||
|
if (result)
|
||||||
|
msg("parseCommonSectionHeader: can't get original PEI core entry point", index);
|
||||||
|
}
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (insertIntoTree) {
|
if (insertIntoTree) {
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree)
|
USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
@ -1919,7 +1981,7 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (insertIntoTree) {
|
if (insertIntoTree) {
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent, mode);
|
||||||
|
|
||||||
// Set section parsing data
|
// Set section parsing data
|
||||||
COMPRESSED_SECTION_PARSING_DATA pdata;
|
COMPRESSED_SECTION_PARSING_DATA pdata;
|
||||||
@ -1931,7 +1993,7 @@ USTATUS FfsParser::parseCompressedSectionHeader(const UByteArray & section, cons
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree)
|
USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
@ -2097,7 +2159,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (insertIntoTree) {
|
if (insertIntoTree) {
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent, mode);
|
||||||
|
|
||||||
// Set parsing data
|
// Set parsing data
|
||||||
GUIDED_SECTION_PARSING_DATA pdata;
|
GUIDED_SECTION_PARSING_DATA pdata;
|
||||||
@ -2124,7 +2186,7 @@ USTATUS FfsParser::parseGuidedSectionHeader(const UByteArray & section, const UI
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree)
|
USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
@ -2186,7 +2248,7 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section,
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (insertIntoTree) {
|
if (insertIntoTree) {
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent, mode);
|
||||||
|
|
||||||
// Set parsing data
|
// Set parsing data
|
||||||
FREEFORM_GUIDED_SECTION_PARSING_DATA pdata;
|
FREEFORM_GUIDED_SECTION_PARSING_DATA pdata;
|
||||||
@ -2200,7 +2262,7 @@ USTATUS FfsParser::parseFreeformGuidedSectionHeader(const UByteArray & section,
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree)
|
USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
@ -2260,13 +2322,13 @@ USTATUS FfsParser::parseVersionSectionHeader(const UByteArray & section, const U
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (insertIntoTree) {
|
if (insertIntoTree) {
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Section, type, name, UString(), info, header, body, UByteArray(), Movable, parent, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree)
|
USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
@ -2326,7 +2388,7 @@ USTATUS FfsParser::parsePostcodeSectionHeader(const UByteArray & section, const
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (insertIntoTree) {
|
if (insertIntoTree) {
|
||||||
index = model->addItem(model->offset(parent) + localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent);
|
index = model->addItem(model->offset(parent) + localOffset, Types::Section, sectionHeader->Type, name, UString(), info, header, body, UByteArray(), Movable, parent, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
@ -3407,6 +3469,9 @@ USTATUS FfsParser::parseFit(const UModelIndex & index)
|
|||||||
return U_INVALID_FIT;
|
return U_INVALID_FIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentEntry->Type == FIT_TYPE_TXT_CONF_POLICY)
|
||||||
|
parseTxtConfigurationPolicy(currentEntry, info);
|
||||||
|
|
||||||
// Set item index
|
// Set item index
|
||||||
if (currentEntry->Address > addressDiff && currentEntry->Address < 0xFFFFFFFFUL) { // Only elements in the image need to be parsed
|
if (currentEntry->Address > addressDiff && currentEntry->Address < 0xFFFFFFFFUL) { // Only elements in the image need to be parsed
|
||||||
currentEntryOffset = (UINT32)(currentEntry->Address - addressDiff);
|
currentEntryOffset = (UINT32)(currentEntry->Address - addressDiff);
|
||||||
@ -3554,6 +3619,64 @@ USTATUS FfsParser::parseIntelMicrocode(const UByteArray & microcode, const UINT3
|
|||||||
header->DateYear
|
header->DateYear
|
||||||
);
|
);
|
||||||
realSize = mcSize;
|
realSize = mcSize;
|
||||||
|
|
||||||
|
// Add Microcode header info
|
||||||
|
microcodeInfo += usprintf(
|
||||||
|
"Microcode Update Capsule found at offset %Xh\n"
|
||||||
|
"Checksum: %08Xh CPU Flags: %08Xh CPU Signature: %08Xh\n"
|
||||||
|
"Data Size: %08Xh Date: %02X.%02X.%04X Loader Revision: %08Xh\n"
|
||||||
|
"Date: %02X.%02X.%04X ModuleSize: %08Xh EntryPoint: %08Xh\n"
|
||||||
|
"Reserved: %02Xh Revision: %08Xh TotalSize: %08Xh\n"
|
||||||
|
"Version: %08Xh"
|
||||||
|
"\n------------------------------------------------------------------------\n\n",
|
||||||
|
model->offset(parent) + localOffset,
|
||||||
|
header->Checksum,
|
||||||
|
header->CpuFlags,
|
||||||
|
header->CpuSignature,
|
||||||
|
header->DataSize,
|
||||||
|
header->DateDay, header->DateMonth, header->DateYear,
|
||||||
|
header->LoaderRevision,
|
||||||
|
header->Reserved,
|
||||||
|
header->Revision,
|
||||||
|
header->TotalSize,
|
||||||
|
header->Version
|
||||||
|
);
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS FfsParser::parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info)
|
||||||
|
{
|
||||||
|
U_UNUSED_PARAMETER(info);
|
||||||
|
const TXT_CONFIG_POLICY* txtCfg = (const TXT_CONFIG_POLICY*)entry;
|
||||||
|
|
||||||
|
if(entry->Version == 0) {
|
||||||
|
txtInfo += usprintf(
|
||||||
|
"TXT Configuration Policy found (Version = 0)\n"
|
||||||
|
"Index: %04Xh Bit Position: %02Xh\n"
|
||||||
|
"Access width in bytes: %02Xh\n"
|
||||||
|
"Data Register Address: %04Xh\n"
|
||||||
|
"Index Register Address: %04Xh",
|
||||||
|
txtCfg->IndexedIOPtrInfo.Index,
|
||||||
|
txtCfg->IndexedIOPtrInfo.BitPosition,
|
||||||
|
txtCfg->IndexedIOPtrInfo.AccessWidth,
|
||||||
|
txtCfg->IndexedIOPtrInfo.DataRegisterAddress,
|
||||||
|
txtCfg->IndexedIOPtrInfo.IndexRegisterAddress
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if(entry->Version == 1) {
|
||||||
|
txtInfo += usprintf(
|
||||||
|
"TXT Configuration Policy found (Version = 1)\n"
|
||||||
|
"Physical Address: %16Xh ",
|
||||||
|
txtCfg->FlatMemoryPtrInfo.FlatMemoryPhysicalAddress
|
||||||
|
);
|
||||||
|
txtInfo += txtCfg->FlatMemoryPtrInfo.TxtEnabled ?
|
||||||
|
"(Bit 0 is zero - Intel TXT disabled)" : "(Bit 0 is 1 - Intel TXT enabled)";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
txtInfo += "\nUnknown version of TXT Configuration Policy";
|
||||||
|
|
||||||
|
txtInfo += "\n------------------------------------------------------------------------\n\n";
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3585,16 +3708,18 @@ USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffse
|
|||||||
realSize = acmSize;
|
realSize = acmSize;
|
||||||
|
|
||||||
// Add ACM header info
|
// Add ACM header info
|
||||||
bootGuardInfo += usprintf(
|
UString acmInfo;
|
||||||
"Intel ACM found at offset %Xh\n"
|
acmInfo += usprintf(
|
||||||
"ModuleType: %08Xh HeaderLength: %08Xh HeaderVersion: %08Xh\n"
|
" found at offset %Xh\n"
|
||||||
"ChipsetId: %04Xh Flags: %04Xh ModuleVendor: %04Xh\n"
|
"ModuleType: %04Xh ModuleSubtype: %04Xh HeaderLength: %08Xh\n"
|
||||||
"Date: %02X.%02X.%04X ModuleSize: %08Xh EntryPoint: %08Xh\n"
|
"HeaderVersion: %08Xh ChipsetId: %04Xh Flags: %04Xh\n"
|
||||||
"AcmSvn: %04Xh Unknown1: %08Xh Unknown2: %08Xh\n"
|
"ModuleVendor: %04Xh Date: %02X.%02X.%04X ModuleSize: %08Xh\n"
|
||||||
"GdtBase: %08Xh GdtMax: %08Xh SegSel: %08Xh\n"
|
"EntryPoint: %08Xh AcmSvn: %04Xh Unknown1: %08Xh\n"
|
||||||
"KeySize: %08Xh Unknown3: %08Xh",
|
"Unknown2: %08Xh GdtBase: %08Xh GdtMax: %08Xh\n"
|
||||||
|
"SegSel: %08Xh KeySize: %08Xh Unknown3: %08Xh",
|
||||||
model->offset(parent) + localOffset,
|
model->offset(parent) + localOffset,
|
||||||
header->ModuleType,
|
header->ModuleType,
|
||||||
|
header->ModuleSubtype,
|
||||||
header->ModuleSize * sizeof(UINT32),
|
header->ModuleSize * sizeof(UINT32),
|
||||||
header->HeaderVersion,
|
header->HeaderVersion,
|
||||||
header->ChipsetId,
|
header->ChipsetId,
|
||||||
@ -3613,20 +3738,28 @@ USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffse
|
|||||||
header->Unknown4 * sizeof(UINT32)
|
header->Unknown4 * sizeof(UINT32)
|
||||||
);
|
);
|
||||||
// Add PubKey
|
// Add PubKey
|
||||||
bootGuardInfo += usprintf("\n\nACM RSA Public Key (Exponent: %Xh):", header->RsaPubExp);
|
acmInfo += usprintf("\n\nACM RSA Public Key (Exponent: %Xh):", header->RsaPubExp);
|
||||||
for (UINT16 i = 0; i < sizeof(header->RsaPubKey); i++) {
|
for (UINT16 i = 0; i < sizeof(header->RsaPubKey); i++) {
|
||||||
if (i % 32 == 0)
|
if (i % 32 == 0)
|
||||||
bootGuardInfo += UString("\n");
|
acmInfo += UString("\n");
|
||||||
bootGuardInfo += usprintf("%02X", header->RsaPubKey[i]);
|
acmInfo += usprintf("%02X", header->RsaPubKey[i]);
|
||||||
}
|
}
|
||||||
// Add RsaSig
|
// Add RsaSig
|
||||||
bootGuardInfo += UString("\n\nACM RSA Signature:");
|
acmInfo += UString("\n\nACM RSA Signature:");
|
||||||
for (UINT16 i = 0; i < sizeof(header->RsaSig); i++) {
|
for (UINT16 i = 0; i < sizeof(header->RsaSig); i++) {
|
||||||
if (i % 32 == 0)
|
if (i % 32 == 0)
|
||||||
bootGuardInfo += UString("\n");
|
acmInfo += UString("\n");
|
||||||
bootGuardInfo += usprintf("%02X", header->RsaSig[i]);
|
acmInfo += usprintf("%02X", header->RsaSig[i]);
|
||||||
}
|
}
|
||||||
bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n");
|
acmInfo += UString("\n------------------------------------------------------------------------\n\n");
|
||||||
|
|
||||||
|
if(header->ModuleSubtype == INTEL_ACM_MODULE_SUBTYPE_TXT_ACM)
|
||||||
|
txtInfo += "TXT ACM (From FIT)" + acmInfo;
|
||||||
|
else if(header->ModuleSubtype == INTEL_ACM_MODULE_SUBTYPE_S_ACM)
|
||||||
|
txtInfo += "S-ACM (From FIT)" + acmInfo;
|
||||||
|
else
|
||||||
|
bootGuardInfo += "Intel ACM" + acmInfo;
|
||||||
|
|
||||||
bgAcmFound = true;
|
bgAcmFound = true;
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "ubytearray.h"
|
#include "ubytearray.h"
|
||||||
#include "treemodel.h"
|
#include "treemodel.h"
|
||||||
#include "bootguard.h"
|
#include "bootguard.h"
|
||||||
|
#include "fit.h"
|
||||||
|
|
||||||
typedef struct BG_PROTECTED_RANGE_
|
typedef struct BG_PROTECTED_RANGE_
|
||||||
{
|
{
|
||||||
@ -60,9 +61,17 @@ public:
|
|||||||
// Obtain BootGuardInfo
|
// Obtain BootGuardInfo
|
||||||
UString getBootGuardInfo() const { return bootGuardInfo; }
|
UString getBootGuardInfo() const { return bootGuardInfo; }
|
||||||
|
|
||||||
|
// Obtain TXT ACM Info
|
||||||
|
UString getTxtInfo() const { return txtInfo; }
|
||||||
|
|
||||||
|
// Obtain Microcode Info
|
||||||
|
UString getMicrocodeInfo() const { return microcodeInfo; }
|
||||||
|
|
||||||
// Obtain offset/address difference
|
// Obtain offset/address difference
|
||||||
UINT64 getAddressDiff() { return addressDiff; }
|
UINT64 getAddressDiff() { return addressDiff; }
|
||||||
|
|
||||||
|
void setNewPeiCoreEntryPoint(UINT32 entry) { newPeiCoreEntryPoint = entry; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeModel *model;
|
TreeModel *model;
|
||||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
||||||
@ -77,6 +86,8 @@ private:
|
|||||||
UModelIndex lastVtf;
|
UModelIndex lastVtf;
|
||||||
UINT32 imageBase;
|
UINT32 imageBase;
|
||||||
UINT64 addressDiff;
|
UINT64 addressDiff;
|
||||||
|
UINT32 peiCoreEntryPoint;
|
||||||
|
UINT32 newPeiCoreEntryPoint;
|
||||||
std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable;
|
std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable;
|
||||||
|
|
||||||
UString bootGuardInfo;
|
UString bootGuardInfo;
|
||||||
@ -90,6 +101,9 @@ private:
|
|||||||
UINT64 bgFirstVolumeOffset;
|
UINT64 bgFirstVolumeOffset;
|
||||||
UModelIndex bgDxeCoreIndex;
|
UModelIndex bgDxeCoreIndex;
|
||||||
|
|
||||||
|
UString txtInfo;
|
||||||
|
UString microcodeInfo;
|
||||||
|
|
||||||
// First pass
|
// First pass
|
||||||
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
|
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
|
||||||
|
|
||||||
@ -98,29 +112,29 @@ private:
|
|||||||
USTATUS parseGenericImage(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 parseRawArea(const UModelIndex & index);
|
||||||
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseVolumeBody(const UModelIndex & index);
|
USTATUS parseVolumeBody(const UModelIndex & index);
|
||||||
USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseFileBody(const UModelIndex & index);
|
USTATUS parseFileBody(const UModelIndex & index);
|
||||||
USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseSectionBody(const UModelIndex & index);
|
USTATUS parseSectionBody(const UModelIndex & index);
|
||||||
|
|
||||||
USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseGbeRegion(const UByteArray & gbe, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseMeRegion(const UByteArray & me, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseBiosRegion(const UByteArray & bios, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parsePdrRegion(const UByteArray & pdr, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseGenericRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseGenericRegion(const UINT8 subtype, const UByteArray & region, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
|
|
||||||
USTATUS parsePadFileBody(const UModelIndex & index);
|
USTATUS parsePadFileBody(const UModelIndex & index);
|
||||||
USTATUS parseVolumeNonUefiData(const UByteArray & data, const UINT32 localOffset, const UModelIndex & index);
|
USTATUS parseVolumeNonUefiData(const UByteArray & data, const UINT32 localOffset, const UModelIndex & index);
|
||||||
|
|
||||||
USTATUS parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree);
|
USTATUS parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree);
|
||||||
USTATUS parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
USTATUS parseCommonSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
USTATUS parseCompressedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
USTATUS parseGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
USTATUS parseFreeformGuidedSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
USTATUS parseVersionSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
USTATUS parsePostcodeSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
|
|
||||||
USTATUS parseCompressedSectionBody(const UModelIndex & index);
|
USTATUS parseCompressedSectionBody(const UModelIndex & index);
|
||||||
USTATUS parseGuidedSectionBody(const UModelIndex & index);
|
USTATUS parseGuidedSectionBody(const UModelIndex & index);
|
||||||
@ -156,12 +170,15 @@ private:
|
|||||||
USTATUS parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
USTATUS parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||||
USTATUS parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
USTATUS parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||||
USTATUS parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
USTATUS parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||||
|
USTATUS parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info);
|
||||||
USTATUS findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
|
USTATUS findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT
|
#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT
|
||||||
friend class NvramParser; // Make FFS parsing routines accessible to NvramParser
|
friend class NvramParser; // Make FFS parsing routines accessible to NvramParser
|
||||||
#endif
|
#endif
|
||||||
|
friend class FfsOperations;
|
||||||
|
friend class FfsBuilder;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FFSPARSER_H
|
#endif // FFSPARSER_H
|
||||||
|
14
common/fit.h
14
common/fit.h
@ -65,6 +65,20 @@ typedef struct INTEL_MICROCODE_HEADER_ {
|
|||||||
UINT8 Reserved[12];
|
UINT8 Reserved[12];
|
||||||
} INTEL_MICROCODE_HEADER;
|
} INTEL_MICROCODE_HEADER;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
UINT16 IndexRegisterAddress;
|
||||||
|
UINT16 DataRegisterAddress;
|
||||||
|
UINT8 AccessWidth;
|
||||||
|
UINT8 BitPosition;
|
||||||
|
UINT16 Index;
|
||||||
|
} IndexedIOPtrInfo;
|
||||||
|
struct {
|
||||||
|
UINT64 FlatMemoryPhysicalAddress : 63;
|
||||||
|
UINT64 TxtEnabled : 1; // bit 0 - configuration policy (0 = TXT Disabled, 1 = TXT Enabled)
|
||||||
|
} FlatMemoryPtrInfo;
|
||||||
|
} TXT_CONFIG_POLICY;
|
||||||
|
|
||||||
#define INTEL_MICROCODE_HEADER_VERSION 0x00000001
|
#define INTEL_MICROCODE_HEADER_VERSION 0x00000001
|
||||||
#define INTEL_MICROCODE_HEADER_RESERVED_BYTE 0x00
|
#define INTEL_MICROCODE_HEADER_RESERVED_BYTE 0x00
|
||||||
#define INTEL_MICROCODE_HEADER_SIZES_VALID(ptr) (((INTEL_MICROCODE_HEADER*)ptr)->TotalSize - ((INTEL_MICROCODE_HEADER*)ptr)->DataSize == sizeof(INTEL_MICROCODE_HEADER))
|
#define INTEL_MICROCODE_HEADER_SIZES_VALID(ptr) (((INTEL_MICROCODE_HEADER*)ptr)->TotalSize - ((INTEL_MICROCODE_HEADER*)ptr)->DataSize == sizeof(INTEL_MICROCODE_HEADER))
|
||||||
|
@ -764,7 +764,7 @@ USTATUS NvramParser::getStoreSize(const UByteArray & data, const UINT32 storeOff
|
|||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -808,12 +808,12 @@ USTATUS NvramParser::parseVssStoreHeader(const UByteArray & store, const UINT32
|
|||||||
vssStoreHeader->Unknown);
|
vssStoreHeader->Unknown);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -856,12 +856,12 @@ USTATUS NvramParser::parseVss2StoreHeader(const UByteArray & store, const UINT32
|
|||||||
vssStoreHeader->Unknown);
|
vssStoreHeader->Unknown);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::Vss2Store, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::Vss2Store, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -926,12 +926,12 @@ USTATUS NvramParser::parseFtwStoreHeader(const UByteArray & store, const UINT32
|
|||||||
(ftw32BlockHeader->Crc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid"));
|
(ftw32BlockHeader->Crc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid"));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::FtwStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::FtwStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -964,12 +964,12 @@ USTATUS NvramParser::parseFdcStoreHeader(const UByteArray & store, const UINT32
|
|||||||
body.size(), body.size());
|
body.size(), body.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::FdcStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::FdcStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -1011,12 +1011,12 @@ USTATUS NvramParser::parseFsysStoreHeader(const UByteArray & store, const UINT32
|
|||||||
+ (storedCrc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid"));
|
+ (storedCrc != calculatedCrc ? usprintf(", invalid, should be %08Xh", calculatedCrc) : UString(", valid"));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::FsysStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::FsysStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -1056,12 +1056,12 @@ USTATUS NvramParser::parseEvsaStoreHeader(const UByteArray & store, const UINT32
|
|||||||
(evsaStoreHeader->Header.Checksum != calculated ? usprintf("%, invalid, should be %02Xh", calculated) : UString(", valid"));
|
(evsaStoreHeader->Header.Checksum != calculated ? usprintf("%, invalid, should be %02Xh", calculated) : UString(", valid"));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -1096,12 +1096,12 @@ USTATUS NvramParser::parseFlashMapStoreHeader(const UByteArray & store, const UI
|
|||||||
flashMapHeader->NumEntries);
|
flashMapHeader->NumEntries);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::FlashMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::FlashMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -1134,12 +1134,12 @@ USTATUS NvramParser::parseCmdbStoreHeader(const UByteArray & store, const UINT32
|
|||||||
body.size(), body.size());
|
body.size(), body.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::CmdbStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::CmdbStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -1176,12 +1176,12 @@ USTATUS NvramParser::parseSlicPubkeyHeader(const UByteArray & store, const UINT3
|
|||||||
pubkeyHeader->Exponent);
|
pubkeyHeader->Exponent);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::SlicData, Subtypes::PubkeySlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::SlicData, Subtypes::PubkeySlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -1218,12 +1218,12 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
|
|||||||
|
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::SlicData, Subtypes::MarkerSlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::SlicData, Subtypes::MarkerSlicData, name, UString(), info, header, UByteArray(), UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
|
|
||||||
@ -1267,12 +1267,12 @@ USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const U
|
|||||||
ucodeHeader->CpuFlags);
|
ucodeHeader->CpuFlags);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
|
||||||
{
|
{
|
||||||
const UINT32 dataSize = (const UINT32)store.size();
|
const UINT32 dataSize = (const UINT32)store.size();
|
||||||
const UINT32* signature = (const UINT32*)store.constData();
|
const UINT32* signature = (const UINT32*)store.constData();
|
||||||
@ -1285,38 +1285,38 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc
|
|||||||
// Check signature and run parser function needed
|
// Check signature and run parser function needed
|
||||||
// VSS/SVS store
|
// VSS/SVS store
|
||||||
if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE)
|
if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE)
|
||||||
return parseVssStoreHeader(store, localOffset, false, parent, index);
|
return parseVssStoreHeader(store, localOffset, false, parent, index, mode);
|
||||||
// VSS2 store
|
// VSS2 store
|
||||||
if (*signature == NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID_PART1 || *signature == NVRAM_VSS2_STORE_GUID_PART1)
|
if (*signature == NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID_PART1 || *signature == NVRAM_VSS2_STORE_GUID_PART1)
|
||||||
return parseVss2StoreHeader(store, localOffset, false, parent, index);
|
return parseVss2StoreHeader(store, localOffset, false, parent, index, mode);
|
||||||
// FTW store
|
// FTW store
|
||||||
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1)
|
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1)
|
||||||
return parseFtwStoreHeader(store, localOffset, parent, index);
|
return parseFtwStoreHeader(store, localOffset, parent, index, mode);
|
||||||
// FDC store
|
// FDC store
|
||||||
else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE)
|
else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE)
|
||||||
return parseFdcStoreHeader(store, localOffset, parent, index);
|
return parseFdcStoreHeader(store, localOffset, parent, index, mode);
|
||||||
// Apple Fsys/Gaid store
|
// Apple Fsys/Gaid store
|
||||||
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE)
|
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE)
|
||||||
return parseFsysStoreHeader(store, localOffset, parent, index);
|
return parseFsysStoreHeader(store, localOffset, parent, index, mode);
|
||||||
// EVSA store
|
// EVSA store
|
||||||
else if (dataSize >= 2 * sizeof(UINT32) && *(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE)
|
else if (dataSize >= 2 * sizeof(UINT32) && *(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE)
|
||||||
return parseEvsaStoreHeader(store, localOffset, parent, index);
|
return parseEvsaStoreHeader(store, localOffset, parent, index, mode);
|
||||||
// Phoenix SCT flash map
|
// Phoenix SCT flash map
|
||||||
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1)
|
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1)
|
||||||
return parseFlashMapStoreHeader(store, localOffset, parent, index);
|
return parseFlashMapStoreHeader(store, localOffset, parent, index, mode);
|
||||||
// Phoenix CMDB store
|
// Phoenix CMDB store
|
||||||
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE)
|
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE)
|
||||||
return parseCmdbStoreHeader(store, localOffset, parent, index);
|
return parseCmdbStoreHeader(store, localOffset, parent, index, mode);
|
||||||
// SLIC pubkey
|
// SLIC pubkey
|
||||||
else if (dataSize >= 5 * sizeof(UINT32) && *(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC)
|
else if (dataSize >= 5 * sizeof(UINT32) && *(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC)
|
||||||
return parseSlicPubkeyHeader(store, localOffset, parent, index);
|
return parseSlicPubkeyHeader(store, localOffset, parent, index, mode);
|
||||||
// SLIC marker
|
// SLIC marker
|
||||||
else if (dataSize >= 34 && *(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);
|
return parseSlicMarkerHeader(store, localOffset, parent, index, mode);
|
||||||
// Intel microcode
|
// Intel microcode
|
||||||
// Must be checked after SLIC marker because of the same *signature values
|
// Must be checked after SLIC marker because of the same *signature values
|
||||||
else if (*signature == INTEL_MICROCODE_HEADER_VERSION)
|
else if (*signature == INTEL_MICROCODE_HEADER_VERSION)
|
||||||
return parseIntelMicrocodeHeader(store, localOffset, parent, index);
|
return parseIntelMicrocodeHeader(store, localOffset, parent, index, mode);
|
||||||
|
|
||||||
msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent);
|
msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent);
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
|
@ -50,25 +50,27 @@ private:
|
|||||||
|
|
||||||
USTATUS findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 localOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset);
|
USTATUS findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 localOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset);
|
||||||
USTATUS getStoreSize(const UByteArray & data, const UINT32 storeOffset, UINT32 & storeSize);
|
USTATUS getStoreSize(const UByteArray & data, const UINT32 storeOffset, UINT32 & storeSize);
|
||||||
USTATUS parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
|
|
||||||
USTATUS parseVssStoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseVssStoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseVss2StoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseVss2StoreHeader(const UByteArray & store, const UINT32 localOffset, const bool sizeOverride, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseFtwStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseFtwStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseFdcStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseFdcStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseFsysStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseFsysStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseEvsaStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseEvsaStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseFlashMapStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseFlashMapStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
|
||||||
|
|
||||||
USTATUS parseFdcStoreBody(const UModelIndex & index);
|
USTATUS parseFdcStoreBody(const UModelIndex & index);
|
||||||
USTATUS parseVssStoreBody(const UModelIndex & index, const UINT8 alignment);
|
USTATUS parseVssStoreBody(const UModelIndex & index, const UINT8 alignment);
|
||||||
USTATUS parseFsysStoreBody(const UModelIndex & index);
|
USTATUS parseFsysStoreBody(const UModelIndex & index);
|
||||||
USTATUS parseEvsaStoreBody(const UModelIndex & index);
|
USTATUS parseEvsaStoreBody(const UModelIndex & index);
|
||||||
USTATUS parseFlashMapBody(const UModelIndex & index);
|
USTATUS parseFlashMapBody(const UModelIndex & index);
|
||||||
|
|
||||||
|
friend class FfsOperations;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
class NvramParser
|
class NvramParser
|
||||||
|
@ -17,7 +17,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#include "treemodel.h"
|
#include "treemodel.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
|
#include "peimage.h"
|
||||||
#include "ffs.h"
|
#include "ffs.h"
|
||||||
|
#include "basetypes.h"
|
||||||
#include "Tiano/EfiTianoCompress.h"
|
#include "Tiano/EfiTianoCompress.h"
|
||||||
#include "Tiano/EfiTianoDecompress.h"
|
#include "Tiano/EfiTianoDecompress.h"
|
||||||
#include "LZMA/LzmaCompress.h"
|
#include "LZMA/LzmaCompress.h"
|
||||||
@ -131,6 +133,7 @@ UString errorCodeToUString(USTATUS errorCode)
|
|||||||
case U_TRUNCATED_IMAGE: return UString("Image is truncated");
|
case U_TRUNCATED_IMAGE: return UString("Image is truncated");
|
||||||
case U_INVALID_CAPSULE: return UString("Invalid capsule");
|
case U_INVALID_CAPSULE: return UString("Invalid capsule");
|
||||||
case U_STORES_NOT_FOUND: return UString("Stores not found");
|
case U_STORES_NOT_FOUND: return UString("Stores not found");
|
||||||
|
case U_INVALID_STORE_SIZE: return UString("Invalid store size");
|
||||||
default: return usprintf("Unknown error %02X", errorCode);
|
default: return usprintf("Unknown error %02X", errorCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,6 +332,139 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UINT8 compress(const UByteArray & data, const UINT8 algorithm, UByteArray & compressedData)
|
||||||
|
{
|
||||||
|
UINT8* compressed;
|
||||||
|
|
||||||
|
switch (algorithm) {
|
||||||
|
case COMPRESSION_ALGORITHM_NONE:
|
||||||
|
{
|
||||||
|
compressedData = data;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMPRESSION_ALGORITHM_EFI11:
|
||||||
|
{
|
||||||
|
// Try legacy function first
|
||||||
|
UINT32 compressedSize = 0;
|
||||||
|
if (EfiCompressLegacy(data.constData(), data.size(), NULL, &compressedSize) != U_BUFFER_TOO_SMALL)
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
compressed = new UINT8[compressedSize];
|
||||||
|
if (EfiCompressLegacy(data.constData(), data.size(), compressed, &compressedSize) != U_SUCCESS) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
compressedData = UByteArray((const char*)compressed, compressedSize);
|
||||||
|
|
||||||
|
// Check that compressed data can be decompressed normally
|
||||||
|
UByteArray decompressed;
|
||||||
|
UByteArray efiDecompressed;
|
||||||
|
UINT8 alg = 0; // TODO !!
|
||||||
|
if (decompress(compressedData, EFI_STANDARD_COMPRESSION, alg, decompressed, efiDecompressed) == U_SUCCESS
|
||||||
|
&& decompressed == data) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
delete[] compressed;
|
||||||
|
|
||||||
|
// Legacy function failed, use current one
|
||||||
|
compressedSize = 0;
|
||||||
|
if (EfiCompress(data.constData(), data.size(), NULL, &compressedSize) != U_BUFFER_TOO_SMALL)
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
compressed = new UINT8[compressedSize];
|
||||||
|
if (EfiCompress(data.constData(), data.size(), compressed, &compressedSize) != U_SUCCESS) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
compressedData = UByteArray((const char*)compressed, compressedSize);
|
||||||
|
|
||||||
|
// New functions will be trusted here, because another check will reduce performance
|
||||||
|
delete[] compressed;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMPRESSION_ALGORITHM_TIANO:
|
||||||
|
{
|
||||||
|
// Try legacy function first
|
||||||
|
UINT32 compressedSize = 0;
|
||||||
|
if (TianoCompressLegacy(data.constData(), data.size(), NULL, &compressedSize) != U_BUFFER_TOO_SMALL)
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
compressed = new UINT8[compressedSize];
|
||||||
|
if (TianoCompressLegacy(data.constData(), data.size(), compressed, &compressedSize) != U_SUCCESS) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
compressedData = UByteArray((const char*)compressed, compressedSize);
|
||||||
|
|
||||||
|
// Check that compressed data can be decompressed normally
|
||||||
|
UByteArray decompressed;
|
||||||
|
UByteArray efiDecompressed;
|
||||||
|
UINT8 alg = 0; // TODO !!
|
||||||
|
if (decompress(compressedData, EFI_STANDARD_COMPRESSION, alg, decompressed, efiDecompressed) == U_SUCCESS
|
||||||
|
&& decompressed == data) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
delete[] compressed;
|
||||||
|
|
||||||
|
// Legacy function failed, use current one
|
||||||
|
compressedSize = 0;
|
||||||
|
if (TianoCompress(data.constData(), data.size(), NULL, &compressedSize) != U_BUFFER_TOO_SMALL)
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
compressed = new UINT8[compressedSize];
|
||||||
|
if (TianoCompress(data.constData(), data.size(), compressed, &compressedSize) != U_SUCCESS) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_STANDARD_COMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
compressedData = UByteArray((const char*)compressed, compressedSize);
|
||||||
|
|
||||||
|
// New functions will be trusted here, because another check will reduce performance
|
||||||
|
delete[] compressed;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMPRESSION_ALGORITHM_LZMA:
|
||||||
|
{
|
||||||
|
UINT32 compressedSize = 0;
|
||||||
|
if (LzmaCompress((const UINT8*)data.constData(), data.size(), NULL, &compressedSize) != U_BUFFER_TOO_SMALL)
|
||||||
|
return U_CUSTOMIZED_COMPRESSION_FAILED;
|
||||||
|
compressed = new UINT8[compressedSize];
|
||||||
|
if (LzmaCompress((const UINT8*)data.constData(), data.size(), compressed, &compressedSize) != U_SUCCESS) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_CUSTOMIZED_COMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
compressedData = UByteArray((const char*)compressed, compressedSize);
|
||||||
|
delete[] compressed;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case COMPRESSION_ALGORITHM_IMLZMA:
|
||||||
|
{
|
||||||
|
UINT32 compressedSize = 0;
|
||||||
|
UByteArray header = data.left(sizeof(EFI_COMMON_SECTION_HEADER));
|
||||||
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)header.constData();
|
||||||
|
UINT32 headerSize = sizeOfSectionHeader(sectionHeader);
|
||||||
|
header = data.left(headerSize);
|
||||||
|
UByteArray newData = data.mid(headerSize);
|
||||||
|
if (LzmaCompress((const UINT8*)newData.constData(), newData.size(), NULL, &compressedSize) != U_BUFFER_TOO_SMALL)
|
||||||
|
return U_CUSTOMIZED_COMPRESSION_FAILED;
|
||||||
|
compressed = new UINT8[compressedSize];
|
||||||
|
if (LzmaCompress((const UINT8*)newData.constData(), newData.size(), compressed, &compressedSize) != U_SUCCESS) {
|
||||||
|
delete[] compressed;
|
||||||
|
return U_CUSTOMIZED_COMPRESSION_FAILED;
|
||||||
|
}
|
||||||
|
compressedData = header.append(UByteArray((const char*)compressed, compressedSize));
|
||||||
|
delete[] compressed;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//msg(usprintf("compress: unknown compression algorithm %1").arg(algorithm));
|
||||||
|
//return U_UNKNOWN_COMPRESSION_ALGORITHM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 8bit sum calculation routine
|
// 8bit sum calculation routine
|
||||||
UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize)
|
UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize)
|
||||||
{
|
{
|
||||||
@ -414,7 +550,7 @@ INTN findPattern(const UINT8 *pattern, const UINT8 *patternMask, UINTN patternSi
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN makePattern(const CHAR8 *textPattern, std::vector<UINT8> &pattern, std::vector<UINT8> &patternMask) {
|
BOOLEAN makePattern(const CHAR8 *textPattern, std::vector<UINT8> &pattern, std::vector<UINT8> &patternMask) {
|
||||||
UINTN len = std::strlen(textPattern);
|
UINTN len = strlen(textPattern);
|
||||||
|
|
||||||
if (len == 0 || len % 2 != 0)
|
if (len == 0 || len % 2 != 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -444,3 +580,313 @@ BOOLEAN makePattern(const CHAR8 *textPattern, std::vector<UINT8> &pattern, std::
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
USTATUS getEntryPoint(const UByteArray &file, UINT32& entryPoint)
|
||||||
|
{
|
||||||
|
if (file.isEmpty())
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
|
||||||
|
// Populate DOS header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_DOS_HEADER))
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)file.constData();
|
||||||
|
|
||||||
|
// Check signature
|
||||||
|
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
||||||
|
UINT32 offset = dosHeader->e_lfanew;
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_PE_HEADER))
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
const EFI_IMAGE_PE_HEADER* peHeader = (const EFI_IMAGE_PE_HEADER*)(file.constData() + offset);
|
||||||
|
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
offset += sizeof(EFI_IMAGE_PE_HEADER);
|
||||||
|
|
||||||
|
// Skip file header
|
||||||
|
offset += sizeof(EFI_IMAGE_FILE_HEADER);
|
||||||
|
|
||||||
|
// Check optional header magic
|
||||||
|
const UINT16 magic = *(const UINT16*)(file.constData() + offset);
|
||||||
|
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER32))
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
const EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER32*)(file.constData() + offset);
|
||||||
|
entryPoint = optHeader->ImageBase + optHeader->AddressOfEntryPoint;
|
||||||
|
}
|
||||||
|
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER64))
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
const EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER64*)(file.constData() + offset);
|
||||||
|
entryPoint = optHeader->ImageBase + optHeader->AddressOfEntryPoint;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
}
|
||||||
|
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
||||||
|
// Populate TE header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_TE_HEADER))
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)file.constData();
|
||||||
|
UINT32 teFixup = teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
||||||
|
entryPoint = teHeader->ImageBase + teHeader->AddressOfEntryPoint - teFixup;
|
||||||
|
}
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS getBase(const UByteArray& file, UINT32& base)
|
||||||
|
{
|
||||||
|
if (file.isEmpty())
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
|
||||||
|
// Populate DOS header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_DOS_HEADER))
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)file.constData();
|
||||||
|
|
||||||
|
// Check signature
|
||||||
|
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
||||||
|
UINT32 offset = dosHeader->e_lfanew;
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_PE_HEADER))
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
const EFI_IMAGE_PE_HEADER* peHeader = (const EFI_IMAGE_PE_HEADER*)(file.constData() + offset);
|
||||||
|
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
offset += sizeof(EFI_IMAGE_PE_HEADER);
|
||||||
|
|
||||||
|
// Skip file header
|
||||||
|
offset += sizeof(EFI_IMAGE_FILE_HEADER);
|
||||||
|
|
||||||
|
// Check optional header magic
|
||||||
|
const UINT16 magic = *(const UINT16*)(file.constData() + offset);
|
||||||
|
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER32))
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
const EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER32*)(file.constData() + offset);
|
||||||
|
base = optHeader->ImageBase;
|
||||||
|
}
|
||||||
|
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER64))
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
const EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER64*)(file.constData() + offset);
|
||||||
|
base = optHeader->ImageBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
}
|
||||||
|
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
||||||
|
// Populate TE header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_TE_HEADER))
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)file.constData();
|
||||||
|
//!TODO: add handling
|
||||||
|
base = teHeader->ImageBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS growVolume(UByteArray & header, const UINT32 size, UINT32 & newSize)
|
||||||
|
{
|
||||||
|
// Check sanity
|
||||||
|
if ((UINT32)header.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER))
|
||||||
|
return U_INVALID_VOLUME;
|
||||||
|
|
||||||
|
// Adjust new size to be representable by current FvBlockMap
|
||||||
|
EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)header.data();
|
||||||
|
EFI_FV_BLOCK_MAP_ENTRY* blockMap = (EFI_FV_BLOCK_MAP_ENTRY*)(header.data() + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
|
||||||
|
|
||||||
|
// Get block map size
|
||||||
|
UINT32 blockMapSize = volumeHeader->HeaderLength - sizeof(EFI_FIRMWARE_VOLUME_HEADER);
|
||||||
|
if (blockMapSize % sizeof(EFI_FV_BLOCK_MAP_ENTRY))
|
||||||
|
return U_INVALID_VOLUME;
|
||||||
|
UINT32 blockMapCount = blockMapSize / sizeof(EFI_FV_BLOCK_MAP_ENTRY);
|
||||||
|
|
||||||
|
// Check blockMap validity
|
||||||
|
if (blockMap[blockMapCount - 1].NumBlocks != 0 || blockMap[blockMapCount - 1].Length != 0)
|
||||||
|
return U_INVALID_VOLUME;
|
||||||
|
|
||||||
|
// Case of complex blockMap
|
||||||
|
if (blockMapCount > 2)
|
||||||
|
return U_COMPLEX_BLOCK_MAP;
|
||||||
|
|
||||||
|
// Calculate new size
|
||||||
|
if (newSize <= size)
|
||||||
|
return U_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
newSize += blockMap[0].Length - newSize % blockMap[0].Length;
|
||||||
|
|
||||||
|
// Recalculate number of blocks
|
||||||
|
blockMap[0].NumBlocks = newSize / blockMap[0].Length;
|
||||||
|
|
||||||
|
// Set new volume size
|
||||||
|
volumeHeader->FvLength = 0;
|
||||||
|
for (UINT8 i = 0; i < blockMapCount; i++) {
|
||||||
|
volumeHeader->FvLength += blockMap[i].NumBlocks * blockMap[i].Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recalculate volume header checksum
|
||||||
|
volumeHeader->Checksum = 0;
|
||||||
|
volumeHeader->Checksum = calculateChecksum16((const UINT16*)volumeHeader, volumeHeader->HeaderLength);
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS rebase(UByteArray &executable, const UINT32 base)
|
||||||
|
{
|
||||||
|
UINT32 delta; // Difference between old and new base addresses
|
||||||
|
UINT32 relocOffset; // Offset of relocation region
|
||||||
|
UINT32 relocSize; // Size of relocation region
|
||||||
|
UINT32 teFixup = 0; // Bytes removed form PE header for TE images
|
||||||
|
|
||||||
|
// Copy input data to local storage
|
||||||
|
UByteArray file = executable;
|
||||||
|
|
||||||
|
// Populate DOS header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_DOS_HEADER))
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
EFI_IMAGE_DOS_HEADER* dosHeader = (EFI_IMAGE_DOS_HEADER*)file.data();
|
||||||
|
|
||||||
|
// Check signature
|
||||||
|
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
||||||
|
UINT32 offset = dosHeader->e_lfanew;
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_PE_HEADER))
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
EFI_IMAGE_PE_HEADER* peHeader = (EFI_IMAGE_PE_HEADER*)(file.data() + offset);
|
||||||
|
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
offset += sizeof(EFI_IMAGE_PE_HEADER);
|
||||||
|
// Skip file header
|
||||||
|
offset += sizeof(EFI_IMAGE_FILE_HEADER);
|
||||||
|
// Check optional header magic
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(UINT16))
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
UINT16 magic = *(UINT16*)(file.data() + offset);
|
||||||
|
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER32))
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (EFI_IMAGE_OPTIONAL_HEADER32*)(file.data() + offset);
|
||||||
|
delta = base - optHeader->ImageBase;
|
||||||
|
if (!delta)
|
||||||
|
// No need to rebase
|
||||||
|
return U_SUCCESS;
|
||||||
|
relocOffset = optHeader->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
|
relocSize = optHeader->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
// Set new base
|
||||||
|
optHeader->ImageBase = base;
|
||||||
|
}
|
||||||
|
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER64))
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (EFI_IMAGE_OPTIONAL_HEADER64*)(file.data() + offset);
|
||||||
|
delta = base - optHeader->ImageBase;
|
||||||
|
if (!delta)
|
||||||
|
// No need to rebase
|
||||||
|
return U_SUCCESS;
|
||||||
|
relocOffset = optHeader->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
|
relocSize = optHeader->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
// Set new base
|
||||||
|
optHeader->ImageBase = base;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return U_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
|
}
|
||||||
|
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
||||||
|
// Populate TE header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_TE_HEADER))
|
||||||
|
return U_INVALID_FILE;
|
||||||
|
EFI_IMAGE_TE_HEADER* teHeader = (EFI_IMAGE_TE_HEADER*)file.data();
|
||||||
|
delta = base - teHeader->ImageBase;
|
||||||
|
if (!delta)
|
||||||
|
// No need to rebase
|
||||||
|
return U_SUCCESS;
|
||||||
|
relocOffset = teHeader->DataDirectory[EFI_IMAGE_TE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
|
||||||
|
teFixup = teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
||||||
|
relocSize = teHeader->DataDirectory[EFI_IMAGE_TE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||||
|
// Set new base
|
||||||
|
teHeader->ImageBase = base;
|
||||||
|
|
||||||
|
// Warn the user about possible outcome of incorrect rebase of TE image
|
||||||
|
//msg(tr("rebase: can't determine if TE image base is adjusted or not, rebased TE image may stop working"), index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return U_UNKNOWN_IMAGE_TYPE;
|
||||||
|
|
||||||
|
// No relocations
|
||||||
|
if (relocOffset == 0) {
|
||||||
|
// No need to fix relocations
|
||||||
|
executable = file;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EFI_IMAGE_BASE_RELOCATION *RelocBase;
|
||||||
|
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
|
||||||
|
UINT16 *Reloc;
|
||||||
|
UINT16 *RelocEnd;
|
||||||
|
UINT16 *F16;
|
||||||
|
UINT32 *F32;
|
||||||
|
UINT64 *F64;
|
||||||
|
|
||||||
|
// Run the whole relocation block
|
||||||
|
RelocBase = (EFI_IMAGE_BASE_RELOCATION*)(file.data() + relocOffset - teFixup);
|
||||||
|
RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION*)(file.data() + relocOffset - teFixup + relocSize);
|
||||||
|
|
||||||
|
while (RelocBase < RelocBaseEnd) {
|
||||||
|
Reloc = (UINT16*)((UINT8*)RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));
|
||||||
|
RelocEnd = (UINT16*)((UINT8*)RelocBase + RelocBase->SizeOfBlock);
|
||||||
|
|
||||||
|
// Run this relocation record
|
||||||
|
while (Reloc < RelocEnd) {
|
||||||
|
if (*Reloc == 0x0000) {
|
||||||
|
// Skip last emtpy reloc entry
|
||||||
|
Reloc += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 RelocLocation = RelocBase->VirtualAddress - teFixup + (*Reloc & 0x0FFF);
|
||||||
|
if ((UINT32)file.size() < RelocLocation)
|
||||||
|
//return U_BAD_RELOCATION_ENTRY;
|
||||||
|
return U_UNKNOWN_RELOCATION_TYPE;
|
||||||
|
UINT8* data = (UINT8*)(file.data() + RelocLocation);
|
||||||
|
switch ((*Reloc) >> 12) {
|
||||||
|
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
||||||
|
// Do nothing
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_HIGH:
|
||||||
|
// Add second 16 bits of delta
|
||||||
|
F16 = (UINT16*)data;
|
||||||
|
*F16 = (UINT16)(*F16 + (UINT16)(((UINT32)delta) >> 16));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_LOW:
|
||||||
|
// Add first 16 bits of delta
|
||||||
|
F16 = (UINT16*)data;
|
||||||
|
*F16 = (UINT16)(*F16 + (UINT16)delta);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
||||||
|
// Add first 32 bits of delta
|
||||||
|
F32 = (UINT32*)data;
|
||||||
|
*F32 = *F32 + (UINT32)delta;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_DIR64:
|
||||||
|
// Add all 64 bits of delta
|
||||||
|
F64 = (UINT64*)data;
|
||||||
|
*F64 = *F64 + (UINT64)delta;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return U_UNKNOWN_RELOCATION_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next relocation record
|
||||||
|
Reloc += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next relocation block
|
||||||
|
RelocBase = (EFI_IMAGE_BASE_RELOCATION*)RelocEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
executable = file;
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
@ -31,6 +31,7 @@ UString errorCodeToUString(USTATUS errorCode);
|
|||||||
USTATUS decompress(const UByteArray & compressed, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressed, UByteArray & efiDecompressed);
|
USTATUS decompress(const UByteArray & compressed, const UINT8 compressionType, UINT8 & algorithm, UByteArray & decompressed, UByteArray & efiDecompressed);
|
||||||
|
|
||||||
// Compression routine
|
// Compression routine
|
||||||
|
UINT8 compress(const UByteArray & data, const UINT8 algorithm, UByteArray & compressedData);
|
||||||
//USTATUS compress(const UByteArray & decompressed, UByteArray & compressed, const UINT8 & algorithm);
|
//USTATUS compress(const UByteArray & decompressed, UByteArray & compressed, const UINT8 & algorithm);
|
||||||
|
|
||||||
// CRC32 calculation routine
|
// CRC32 calculation routine
|
||||||
@ -55,4 +56,13 @@ BOOLEAN makePattern(const CHAR8 *textPattern, std::vector<UINT8> &pattern, std::
|
|||||||
INTN findPattern(const UINT8 *pattern, const UINT8 *patternMask, UINTN patternSize,
|
INTN findPattern(const UINT8 *pattern, const UINT8 *patternMask, UINTN patternSize,
|
||||||
const UINT8 *data, UINTN dataSize, UINTN dataOff);
|
const UINT8 *data, UINTN dataSize, UINTN dataOff);
|
||||||
|
|
||||||
|
// Image base adress
|
||||||
|
USTATUS getBase(const UByteArray& file, UINT32& base);
|
||||||
|
// Entry point
|
||||||
|
USTATUS getEntryPoint(const UByteArray& file, UINT32 &entryPoint);
|
||||||
|
|
||||||
|
USTATUS growVolume(UByteArray & header, const UINT32 size, UINT32 & newSize);
|
||||||
|
|
||||||
|
USTATUS rebase(UByteArray &executable, const UINT32 base);
|
||||||
|
|
||||||
#endif // UTILITY_H
|
#endif // UTILITY_H
|
||||||
|
Loading…
Reference in New Issue
Block a user