mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-21 23:48:22 +08:00
Merge recent updates but without broken builder and with minor refactoring and bugfixes
This commit is contained in:
parent
b064495db8
commit
0a634ebcbd
4
.gitignore
vendored
4
.gitignore
vendored
@ -3,6 +3,7 @@
|
||||
#################
|
||||
moc_*.*
|
||||
ui_*.*
|
||||
qrc_*.*
|
||||
|
||||
#################
|
||||
## Qt Creator
|
||||
@ -234,6 +235,8 @@ Makefile
|
||||
|
||||
uefitool_plugin_import.cpp
|
||||
UEFITool.app/
|
||||
UEFITool/Info.plist
|
||||
UEFITool/XCBuildData
|
||||
UEFIDump/UEFIDump
|
||||
UEFIExtract/UEFIExtract
|
||||
UEFIFind/UEFIFind
|
||||
@ -245,3 +248,4 @@ DerivedData
|
||||
*.xcodeproj
|
||||
compile_commands.json
|
||||
CMakeScripts
|
||||
UEFITool/qrc_uefitool.cpp
|
||||
|
@ -35,6 +35,7 @@ There are some other projects that use UEFITool's engine:
|
||||
## Alternatives
|
||||
|
||||
Right now there are some alternatives to UEFITool that you could find useful too:
|
||||
* **[Fiano](https://github.com/linuxboot/fiano) by Google. Go-based cross-platform open source toolset for modifying UEFI firmware images.
|
||||
* **[PhoenixTool](http://forums.mydigitallife.info/threads/13194-Tool-to-Insert-Replace-SLIC-in-Phoenix-Insyde-Dell-EFI-BIOSes)** by [AndyP](http://forums.mydigitallife.info/members/39295-andyp). Windows-only freeware GUI application written in C#. Used mostly for SLIC-related modifications, but it not limited to this task. Requires Microsoft .NET 3.5 to work properly. Supports unpacking firmware images from various vendor-specific formats like encrypted HP update files and Dell installers.
|
||||
* **[uefi-firmware-parser](https://github.com/theopolis/uefi-firmware-parser)** by [Teddy Reed](https://github.com/theopolis). Cross-platform open source console application written in Python. Very tinker-friendly due to use of Python. Can be used in scripts to automate firmware patching.
|
||||
* **[Chipsec](https://github.com/chipsec/chipsec)** by Intel. Cross-platform partially open source console application written in Python and C. Can be used to test Intel-based platforms for various security-related misconfigurations, but also has NVRAM parser and other components aimed to firmware modification.
|
||||
@ -46,7 +47,7 @@ Right now there are some alternatives to UEFITool that you could find useful too
|
||||
|
||||
You can either use [pre-built binaries for Windows and macOS](https://github.com/LongSoft/UEFITool/releases) or build a binary yourself.
|
||||
* To build a binary that uses Qt library (UEFITool) you need a C++ compiler and an instance of [Qt5](https://www.qt.io) library. Install both of them, get the sources, generate makefiles using qmake (`qmake UEFITool.pro`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on).
|
||||
* To build a binary that doesn't use Qt (UEFIExtract, UEFIFind), you need a C++ compiler and [CMAKE](https://cmake.org) utility to generate a makefile for your OS and build environment. Install both of them, get the sources, generate makefiles using cmake (`cmake UEFIDump`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on).
|
||||
* To build a binary that doesn't use Qt (UEFIExtract, UEFIFind), you need a C++ compiler and [CMAKE](https://cmake.org) utility to generate a makefile for your OS and build environment. Install both of them, get the sources, generate makefiles using cmake (`cmake UEFIExtract`) and use your system's make command on that generated files (i.e. `nmake release`, `make release` and so on).
|
||||
|
||||
## Known issues
|
||||
|
||||
|
@ -23,7 +23,7 @@ USTATUS FfsDumper::dump(const UModelIndex & root, const UString & path, const Du
|
||||
if (changeDirectory(path))
|
||||
return U_DIR_ALREADY_EXIST;
|
||||
|
||||
UINT8 result = recursiveDump(root, path, dumpMode, sectionType, guid);
|
||||
USTATUS result = recursiveDump(root, path, dumpMode, sectionType, guid);
|
||||
if (result)
|
||||
return result;
|
||||
else if (!dumped)
|
||||
@ -123,7 +123,7 @@ USTATUS FfsDumper::recursiveDump(const UModelIndex & index, const UString & path
|
||||
dumped = true;
|
||||
}
|
||||
|
||||
UINT8 result;
|
||||
USTATUS result;
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
UModelIndex childIndex = index.child(i, 0);
|
||||
bool useText = FALSE;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ffsdumper.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -90,7 +90,7 @@ USTATUS UEFIDumper::dump(const UByteArray & buffer, const UString & inPath, cons
|
||||
return U_DIR_CHANGE;
|
||||
|
||||
dumped = false;
|
||||
UINT8 result = recursiveDump(model.index(0,0));
|
||||
USTATUS result = recursiveDump(model.index(0,0));
|
||||
if (result)
|
||||
return result;
|
||||
else if (!dumped)
|
||||
@ -133,7 +133,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
|
||||
if (!data.isEmpty()) {
|
||||
std::ofstream file;
|
||||
UString str = name + UString("_header.bin");
|
||||
file.open((const char*)str, std::ios::out | std::ios::binary);
|
||||
file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary);
|
||||
file.write(data.constData(), data.size());
|
||||
file.close();
|
||||
}
|
||||
@ -143,7 +143,7 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
|
||||
if (!data.isEmpty()) {
|
||||
std::ofstream file;
|
||||
UString str = name + UString("_body.bin");
|
||||
file.open((const char*)str, std::ios::out | std::ios::binary);
|
||||
file.open(str.toLocal8Bit(), std::ios::out | std::ios::binary);
|
||||
file.write(data.constData(), data.size());
|
||||
file.close();
|
||||
}
|
||||
@ -157,15 +157,15 @@ USTATUS UEFIDumper::recursiveDump(const UModelIndex & index)
|
||||
|
||||
std::ofstream file;
|
||||
UString str = name + UString("_info.txt");
|
||||
file.open((const char*)str, std::ios::out);
|
||||
file.write((const char*)info, info.length());
|
||||
file.open(str.toLocal8Bit(), std::ios::out);
|
||||
file.write(info.toLocal8Bit(), info.length());
|
||||
file.close();
|
||||
|
||||
dumped = true;
|
||||
//}
|
||||
|
||||
// Process child items
|
||||
UINT8 result;
|
||||
USTATUS result;
|
||||
for (int i = 0; i < model.rowCount(index); i++) {
|
||||
result = recursiveDump(index.child(i, 0));
|
||||
if (result)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* uefidump.h
|
||||
|
||||
Copyright (c) 2016, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -36,17 +36,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (argc > 1) {
|
||||
// Check that input file exists
|
||||
USTATUS result;
|
||||
UByteArray buffer;
|
||||
UString path = argv[1];
|
||||
if (!isExistOnFs(path))
|
||||
return U_FILE_OPEN;
|
||||
|
||||
// Open the input file
|
||||
std::ifstream inputFile(argv[1], std::ios::in | std::ios::binary);
|
||||
if (!inputFile)
|
||||
return U_FILE_OPEN;
|
||||
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
inputFile.close();
|
||||
result = readFileIntoBuffer(path, buffer);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
// Hack to support legacy UEFIDump mode.
|
||||
if (argc == 3 && !std::strcmp(argv[2], "unpack")) {
|
||||
@ -58,7 +53,7 @@ int main(int argc, char *argv[])
|
||||
TreeModel model;
|
||||
FfsParser ffsParser(&model);
|
||||
// Parse input buffer
|
||||
USTATUS result = ffsParser.parse(buffer);
|
||||
result = ffsParser.parse(buffer);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
|
@ -32,16 +32,10 @@ UEFIFind::~UEFIFind()
|
||||
USTATUS UEFIFind::init(const UString & path)
|
||||
{
|
||||
USTATUS result;
|
||||
|
||||
if (!isExistOnFs(path))
|
||||
return U_FILE_OPEN;
|
||||
|
||||
std::ifstream inputFile(path.toLocal8Bit(), std::ios::in | std::ios::binary);
|
||||
if (!inputFile)
|
||||
return U_FILE_OPEN;
|
||||
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
inputFile.close();
|
||||
UByteArray buffer;
|
||||
result = readFileIntoBuffer(path, buffer);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = ffsParser->parse(buffer);
|
||||
if (result)
|
||||
|
@ -22,7 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
UEFIFind w;
|
||||
UINT8 result;
|
||||
USTATUS result;
|
||||
|
||||
initGuidDatabase("guids.csv");
|
||||
|
||||
|
@ -112,7 +112,7 @@ int QHexEdit::addressWidth()
|
||||
if (size > Q_INT64_C(0x100000000)){ n += 8; size /= Q_INT64_C(0x100000000);}
|
||||
if (size > 0x10000){ n += 4; size /= 0x10000;}
|
||||
if (size > 0x100){ n += 2; size /= 0x100;}
|
||||
if (size > 0x10){ n += 1; size /= 0x10;}
|
||||
if (size > 0x10){ n += 1; }
|
||||
|
||||
if (n > _addressWidth)
|
||||
return n;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,8 @@
|
||||
UEFITool::UEFITool(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::UEFITool),
|
||||
version(tr(PROGRAM_VERSION))
|
||||
version(tr(PROGRAM_VERSION)),
|
||||
markingEnabled(true)
|
||||
{
|
||||
clipboard = QApplication::clipboard();
|
||||
|
||||
@ -72,7 +73,7 @@ version(tr(PROGRAM_VERSION))
|
||||
setAcceptDrops(true);
|
||||
|
||||
// Disable Builder tab, doesn't work right now
|
||||
ui->messagesTabWidget->setTabEnabled(4, false);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, false);
|
||||
|
||||
// Set current directory
|
||||
currentDir = ".";
|
||||
@ -109,9 +110,11 @@ void UEFITool::init()
|
||||
ui->fitTableWidget->setRowCount(0);
|
||||
ui->fitTableWidget->setColumnCount(0);
|
||||
ui->infoEdit->clear();
|
||||
ui->bootGuardEdit->clear();
|
||||
ui->messagesTabWidget->setTabEnabled(1, false);
|
||||
ui->messagesTabWidget->setTabEnabled(2, false);
|
||||
ui->securityEdit->clear();
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_FIT, false);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, false);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_SEARCH, false);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, false);
|
||||
|
||||
// Set window title
|
||||
setWindowTitle(tr("UEFITool %1").arg(version));
|
||||
@ -233,25 +236,6 @@ bool UEFITool::enableExtractBodyUncompressed(const QModelIndex ¤t)
|
||||
{
|
||||
// TODO: rewrite based on model->compressed()
|
||||
U_UNUSED_PARAMETER(current);
|
||||
/*if (current.isValid() && model->type(current) == Types::Section &&
|
||||
(model->subtype(current) == EFI_SECTION_COMPRESSION || model->subtype(current) == EFI_SECTION_GUID_DEFINED)) {
|
||||
// Get parsing data
|
||||
PARSING_DATA pdata = parsingDataFromUModelIndex(current);
|
||||
|
||||
if (model->subtype(current) == EFI_SECTION_COMPRESSION &&
|
||||
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_NONE &&
|
||||
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_UNKNOWN &&
|
||||
pdata.section.compressed.algorithm != COMPRESSION_ALGORITHM_UNDECIDED) { //Compressed section
|
||||
return true;
|
||||
}
|
||||
else if (model->subtype(current) == EFI_SECTION_GUID_DEFINED) {
|
||||
QByteArray guid = QByteArray((const char*)&pdata.section.guidDefined.guid, sizeof(EFI_GUID));
|
||||
if (guid == EFI_GUIDED_SECTION_TIANO || guid == EFI_GUIDED_SECTION_LZMA) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -400,57 +384,6 @@ void UEFITool::goToData()
|
||||
void UEFITool::insert(const UINT8 mode)
|
||||
{
|
||||
U_UNUSED_PARAMETER(mode);
|
||||
|
||||
/*QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
UINT8 type;
|
||||
|
||||
if (mode == CREATE_MODE_BEFORE || mode == CREATE_MODE_AFTER)
|
||||
type = model->type(index.parent());
|
||||
else
|
||||
type = model->type(index);
|
||||
|
||||
QString path;
|
||||
switch (type) {
|
||||
case Types::Volume:
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to insert"), currentDir, "FFS files (*.ffs *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::File:
|
||||
case Types::Section:
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select section file to insert"), currentDir, "Section files (*.sct *.bin);;All files (*)");
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (path.trimmed().isEmpty())
|
||||
return;
|
||||
|
||||
QFileInfo fileInfo = QFileInfo(path);
|
||||
if (!fileInfo.exists()) {
|
||||
ui->statusBar->showMessage(tr("Please select existing file"));
|
||||
return;
|
||||
}
|
||||
|
||||
QFile inputFile;
|
||||
inputFile.setFileName(path);
|
||||
|
||||
if (!inputFile.open(QFile::ReadOnly)) {
|
||||
QMessageBox::critical(this, tr("Insertion failed"), tr("Can't open output file for reading"), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray buffer = inputFile.readAll();
|
||||
inputFile.close();
|
||||
|
||||
UINT8 result = ffsEngine->insert(index, buffer, mode);
|
||||
if (result) {
|
||||
QMessageBox::critical(this, tr("Insertion failed"), errorMessage(result), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
ui->actionSaveImageFile->setEnabled(true);*/
|
||||
}
|
||||
|
||||
void UEFITool::insertInto()
|
||||
@ -482,97 +415,6 @@ void UEFITool::replace(const UINT8 mode)
|
||||
{
|
||||
U_UNUSED_PARAMETER(mode);
|
||||
|
||||
/*
|
||||
QModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
QString path;
|
||||
if (model->type(index) == Types::Region) {
|
||||
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 (*)");
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else if (model->type(index) == Types::Volume) {
|
||||
if (mode == REPLACE_MODE_AS_IS) {
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace selected volume"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
|
||||
}
|
||||
else if (mode == REPLACE_MODE_BODY) {
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select volume body file to replace the body of selected volume"), currentDir, "Volume body files (*.vbd *.bin);;All files (*)");
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else if (model->type(index) == Types::File) {
|
||||
if (mode == REPLACE_MODE_AS_IS) {
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file to replace %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)),
|
||||
currentDir, "FFS files (*.ffs *.bin);;All files (*)");
|
||||
}
|
||||
else if (mode == REPLACE_MODE_BODY) {
|
||||
if (model->subtype(index) == EFI_FV_FILETYPE_ALL || model->subtype(index) == EFI_FV_FILETYPE_RAW)
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace the body of %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)),
|
||||
currentDir, "Raw files (*.raw *.bin);;All files (*)");
|
||||
else if (model->subtype(index) == EFI_FV_FILETYPE_PAD) // Pad file body can't be replaced
|
||||
//!TODO: handle non-empty pad files
|
||||
return;
|
||||
else
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body to replace the body of %1 file").arg(model->text(index).isEmpty() ? model->name(index) : model->text(index)),
|
||||
currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else if (model->type(index) == Types::Section) {
|
||||
if (mode == REPLACE_MODE_AS_IS) {
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected section"), currentDir, "Section files (*.sct *.bin);;All files (*)");
|
||||
}
|
||||
else if (mode == REPLACE_MODE_BODY) {
|
||||
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE)
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select FFS file body file to replace the body of selected section"), currentDir, "FFS file body files (*.fbd *.bin);;All files (*)");
|
||||
else if (model->subtype(index) == EFI_SECTION_FIRMWARE_VOLUME_IMAGE)
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select volume file to replace the body of selected section"), currentDir, "Volume files (*.vol *.bin);;All files (*)");
|
||||
else if (model->subtype(index) == EFI_SECTION_RAW)
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select raw file to replace the body of selected section"), currentDir, "Raw files (*.raw *.bin);;All files (*)");
|
||||
else if (model->subtype(index) == EFI_SECTION_PE32 || model->subtype(index) == EFI_SECTION_TE || model->subtype(index) == EFI_SECTION_PIC)
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select EFI executable file to replace the body of selected section"), currentDir, "EFI executable files (*.efi *.dxe *.pei *.bin);;All files (*)");
|
||||
else
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select file to replace the body of selected section"), currentDir, "Binary files (*.bin);;All files (*)");
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
if (path.trimmed().isEmpty())
|
||||
return;
|
||||
|
||||
QFileInfo fileInfo = QFileInfo(path);
|
||||
if (!fileInfo.exists()) {
|
||||
ui->statusBar->showMessage(tr("Please select an existing file"));
|
||||
return;
|
||||
}
|
||||
|
||||
QFile inputFile;
|
||||
inputFile.setFileName(path);
|
||||
|
||||
if (!inputFile.open(QFile::ReadOnly)) {
|
||||
QMessageBox::critical(this, tr("Replacing failed"), tr("Can't open input file for reading"), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray buffer = inputFile.readAll();
|
||||
inputFile.close();
|
||||
|
||||
UINT8 result = ffsOps->replace(index, buffer, mode);
|
||||
if (result) {
|
||||
QMessageBox::critical(this, tr("Replacing failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
ui->actionSaveImageFile->setEnabled(true);
|
||||
*/
|
||||
}
|
||||
|
||||
void UEFITool::extractAsIs()
|
||||
@ -699,26 +541,12 @@ void UEFITool::extract(const UINT8 mode)
|
||||
|
||||
void UEFITool::rebuild()
|
||||
{
|
||||
/*
|
||||
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (U_SUCCESS == ffsOps->rebuild(index))
|
||||
ui->actionSaveImageFile->setEnabled(true);
|
||||
*/
|
||||
}
|
||||
|
||||
void UEFITool::remove()
|
||||
{
|
||||
/*
|
||||
UModelIndex index = ui->structureTreeView->selectionModel()->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
if (U_SUCCESS == ffsOps->remove(index))
|
||||
ui->actionSaveImageFile->setEnabled(true);
|
||||
*/
|
||||
}
|
||||
|
||||
void UEFITool::about()
|
||||
@ -748,35 +576,7 @@ void UEFITool::exit()
|
||||
|
||||
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 (*)"));
|
||||
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
QByteArray reconstructed;
|
||||
// Create ffsBuilder
|
||||
delete ffsBuilder;
|
||||
ffsBuilder = new FfsBuilder(model);
|
||||
USTATUS result = ffsBuilder->build(model->index(0,0), reconstructed);
|
||||
showBuilderMessages();
|
||||
if (result) {
|
||||
QMessageBox::critical(this, tr("Image build failed"), errorCodeToUString(result), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
QFile outputFile;
|
||||
outputFile.setFileName(path);
|
||||
if (!outputFile.open(QFile::WriteOnly)) {
|
||||
QMessageBox::critical(this, tr("Image build failed"), tr("Can't open output file for rewriting"), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
outputFile.resize(0);
|
||||
outputFile.write(reconstructed);
|
||||
outputFile.close();
|
||||
if (QMessageBox::Yes == QMessageBox::information(this, tr("Image build successful"), tr("Open the resulting file?"), QMessageBox::Yes, QMessageBox::No))
|
||||
openImageFile(path);
|
||||
*/
|
||||
}
|
||||
|
||||
void UEFITool::openImageFile()
|
||||
@ -832,6 +632,9 @@ void UEFITool::openImageFile(QString path)
|
||||
// Enable or disable FIT tab
|
||||
showFitTable();
|
||||
|
||||
// Enable or disable Security tab
|
||||
showSecurityInfo();
|
||||
|
||||
// Enable search ...
|
||||
delete ffsFinder;
|
||||
ffsFinder = new FfsFinder(model);
|
||||
@ -869,11 +672,11 @@ void UEFITool::enableMessagesCopyActions(QListWidgetItem* item)
|
||||
void UEFITool::copyMessage()
|
||||
{
|
||||
clipboard->clear();
|
||||
if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab
|
||||
if (ui->messagesTabWidget->currentIndex() == TAB_PARSER) // Parser tab
|
||||
clipboard->setText(ui->parserMessagesListWidget->currentItem()->text());
|
||||
else if (ui->messagesTabWidget->currentIndex() == 3) // Search tab
|
||||
else if (ui->messagesTabWidget->currentIndex() == TAB_SEARCH) // Search tab
|
||||
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
|
||||
else if (ui->messagesTabWidget->currentIndex() == 4) // Builder tab
|
||||
else if (ui->messagesTabWidget->currentIndex() == TAB_BUILDER) // Builder tab
|
||||
clipboard->setText(ui->builderMessagesListWidget->currentItem()->text());
|
||||
}
|
||||
|
||||
@ -881,17 +684,17 @@ void UEFITool::copyAllMessages()
|
||||
{
|
||||
QString text;
|
||||
clipboard->clear();
|
||||
if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab
|
||||
if (ui->messagesTabWidget->currentIndex() == TAB_PARSER) { // Parser tab
|
||||
for (INT32 i = 0; i < ui->parserMessagesListWidget->count(); i++)
|
||||
text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n");
|
||||
clipboard->setText(text);
|
||||
}
|
||||
else if (ui->messagesTabWidget->currentIndex() == 3) { // Search tab
|
||||
else if (ui->messagesTabWidget->currentIndex() == TAB_SEARCH) { // Search tab
|
||||
for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++)
|
||||
text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n");
|
||||
clipboard->setText(text);
|
||||
}
|
||||
else if (ui->messagesTabWidget->currentIndex() == 4) { // Builder tab
|
||||
else if (ui->messagesTabWidget->currentIndex() == TAB_BUILDER) { // Builder tab
|
||||
for (INT32 i = 0; i < ui->builderMessagesListWidget->count(); i++)
|
||||
text.append(ui->builderMessagesListWidget->item(i)->text()).append("\n");
|
||||
clipboard->setText(text);
|
||||
@ -900,15 +703,15 @@ void UEFITool::copyAllMessages()
|
||||
|
||||
void UEFITool::clearMessages()
|
||||
{
|
||||
if (ui->messagesTabWidget->currentIndex() == 0) { // Parser tab
|
||||
if (ui->messagesTabWidget->currentIndex() == TAB_PARSER) { // Parser tab
|
||||
if (ffsParser) ffsParser->clearMessages();
|
||||
ui->parserMessagesListWidget->clear();
|
||||
}
|
||||
else if (ui->messagesTabWidget->currentIndex() == 3) { // Search tab
|
||||
else if (ui->messagesTabWidget->currentIndex() == TAB_SEARCH) { // Search tab
|
||||
if (ffsFinder) ffsFinder->clearMessages();
|
||||
ui->finderMessagesListWidget->clear();
|
||||
}
|
||||
else if (ui->messagesTabWidget->currentIndex() == 4) { // Builder tab
|
||||
else if (ui->messagesTabWidget->currentIndex() == TAB_BUILDER) { // Builder tab
|
||||
if (ffsBuilder) ffsBuilder->clearMessages();
|
||||
ui->builderMessagesListWidget->clear();
|
||||
}
|
||||
@ -951,7 +754,7 @@ void UEFITool::showParserMessages()
|
||||
ui->parserMessagesListWidget->addItem(item);
|
||||
}
|
||||
|
||||
ui->messagesTabWidget->setCurrentIndex(0);
|
||||
ui->messagesTabWidget->setCurrentIndex(TAB_PARSER);
|
||||
ui->parserMessagesListWidget->scrollToBottom();
|
||||
}
|
||||
|
||||
@ -969,7 +772,8 @@ void UEFITool::showFinderMessages()
|
||||
ui->finderMessagesListWidget->addItem(item);
|
||||
}
|
||||
|
||||
ui->messagesTabWidget->setCurrentIndex(3);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_SEARCH, true);
|
||||
ui->messagesTabWidget->setCurrentIndex(TAB_SEARCH);
|
||||
ui->finderMessagesListWidget->scrollToBottom();
|
||||
}
|
||||
|
||||
@ -987,7 +791,8 @@ void UEFITool::showBuilderMessages()
|
||||
ui->builderMessagesListWidget->addItem(item);
|
||||
}
|
||||
|
||||
ui->messagesTabWidget->setCurrentIndex(4);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_BUILDER, true);
|
||||
ui->messagesTabWidget->setCurrentIndex(TAB_BUILDER);
|
||||
ui->builderMessagesListWidget->scrollToBottom();
|
||||
}
|
||||
|
||||
@ -1013,16 +818,19 @@ void UEFITool::scrollTreeView(QTableWidgetItem* item)
|
||||
|
||||
void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
if (ui->parserMessagesListWidget->underMouse() ||
|
||||
ui->finderMessagesListWidget->underMouse() ||
|
||||
ui->builderMessagesListWidget->underMouse()) {
|
||||
// The checks involving underMouse do not work well enough on macOS, and result in right-click sometimes
|
||||
// not showing any context menu at all. Most likely it is a bug in Qt, which does not affect other systems.
|
||||
// For this reason we reimplement this manually.
|
||||
if (ui->parserMessagesListWidget->rect().contains(ui->parserMessagesListWidget->mapFromGlobal(event->globalPos())) ||
|
||||
ui->finderMessagesListWidget->rect().contains(ui->finderMessagesListWidget->mapFromGlobal(event->globalPos())) ||
|
||||
ui->builderMessagesListWidget->rect().contains(ui->builderMessagesListWidget->mapFromGlobal(event->globalPos()))) {
|
||||
ui->menuMessageActions->exec(event->globalPos());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ui->structureTreeView->underMouse()) {
|
||||
|
||||
if (!ui->structureTreeView->rect().contains(ui->structureTreeView->mapFromGlobal(event->globalPos())))
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint pt = event->pos();
|
||||
QModelIndex index = ui->structureTreeView->indexAt(ui->structureTreeView->viewport()->mapFrom(this, pt));
|
||||
@ -1039,11 +847,6 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||
case Types::Volume: ui->menuVolumeActions->exec(event->globalPos()); break;
|
||||
case Types::File: ui->menuFileActions->exec(event->globalPos()); break;
|
||||
case Types::Section: ui->menuSectionActions->exec(event->globalPos()); break;
|
||||
case Types::NvarEntry:
|
||||
case Types::VssEntry:
|
||||
case Types::FsysEntry:
|
||||
case Types::EvsaEntry:
|
||||
case Types::FlashMapEntry: ui->menuEntryActions->exec(event->globalPos()); break;
|
||||
case Types::VssStore:
|
||||
case Types::Vss2Store:
|
||||
case Types::FdcStore:
|
||||
@ -1051,9 +854,9 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||
case Types::EvsaStore:
|
||||
case Types::FtwStore:
|
||||
case Types::FlashMapStore:
|
||||
case Types::CmdbStore:
|
||||
case Types::Microcode:
|
||||
case Types::SlicData: ui->menuStoreActions->exec(event->globalPos()); break;
|
||||
case Types::CmdbStore: ui->menuStoreActions->exec(event->globalPos()); break;
|
||||
case Types::FreeSpace: break;
|
||||
default: ui->menuEntryActions->exec(event->globalPos()); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1095,7 +898,7 @@ void UEFITool::readSettings()
|
||||
ui->finderMessagesListWidget->setFont(currentFont);
|
||||
ui->builderMessagesListWidget->setFont(currentFont);
|
||||
ui->fitTableWidget->setFont(currentFont);
|
||||
ui->bootGuardEdit->setFont(currentFont);
|
||||
ui->securityEdit->setFont(currentFont);
|
||||
ui->structureTreeView->setFont(currentFont);
|
||||
searchDialog->ui->guidEdit->setFont(currentFont);
|
||||
searchDialog->ui->hexEdit->setFont(currentFont);
|
||||
@ -1127,14 +930,12 @@ void UEFITool::showFitTable()
|
||||
std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable = ffsParser->getFitTable();
|
||||
if (fitTable.empty()) {
|
||||
// Disable FIT tab
|
||||
ui->messagesTabWidget->setTabEnabled(1, false);
|
||||
// Disable BootGuard tab
|
||||
ui->messagesTabWidget->setTabEnabled(2, false);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_FIT, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable FIT tab
|
||||
ui->messagesTabWidget->setTabEnabled(1, true);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_FIT, true);
|
||||
|
||||
// Set up the FIT table
|
||||
ui->fitTableWidget->clear();
|
||||
@ -1157,19 +958,21 @@ void UEFITool::showFitTable()
|
||||
|
||||
ui->fitTableWidget->resizeColumnsToContents();
|
||||
ui->fitTableWidget->resizeRowsToContents();
|
||||
ui->messagesTabWidget->setCurrentIndex(1);
|
||||
ui->messagesTabWidget->setCurrentIndex(TAB_FIT);
|
||||
}
|
||||
|
||||
// Get BootGuard info
|
||||
UString bgInfo = ffsParser->getBootGuardInfo();
|
||||
if (bgInfo.isEmpty()) {
|
||||
// Disable BootGuard tab
|
||||
ui->messagesTabWidget->setTabEnabled(2, false);
|
||||
void UEFITool::showSecurityInfo()
|
||||
{
|
||||
// Get security info
|
||||
UString secInfo = ffsParser->getSecurityInfo();
|
||||
if (secInfo.isEmpty()) {
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, false);
|
||||
return;
|
||||
}
|
||||
|
||||
ui->messagesTabWidget->setTabEnabled(2, true);
|
||||
ui->bootGuardEdit->setPlainText(bgInfo);
|
||||
ui->messagesTabWidget->setCurrentIndex(2);
|
||||
ui->messagesTabWidget->setTabEnabled(TAB_SECURITY, true);
|
||||
ui->securityEdit->setPlainText(secInfo);
|
||||
ui->messagesTabWidget->setCurrentIndex(TAB_SECURITY);
|
||||
}
|
||||
|
||||
void UEFITool::currentTabChanged(int index)
|
||||
@ -1206,8 +1009,6 @@ void UEFITool::loadDefaultGuidDatabase()
|
||||
openImageFile(currentPath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void UEFITool::generateReport()
|
||||
{
|
||||
QString path = QFileDialog::getSaveFileName(this, tr("Save report to text file"), currentPath + ".report.txt", tr("Text files (*.txt);;All files (*)"));
|
||||
|
@ -152,7 +152,16 @@ private:
|
||||
void showParserMessages();
|
||||
void showFinderMessages();
|
||||
void showFitTable();
|
||||
void showSecurityInfo();
|
||||
void showBuilderMessages();
|
||||
|
||||
enum {
|
||||
TAB_PARSER,
|
||||
TAB_FIT,
|
||||
TAB_SECURITY,
|
||||
TAB_SEARCH,
|
||||
TAB_BUILDER
|
||||
};
|
||||
};
|
||||
|
||||
#endif // UEFITOOL_H
|
||||
|
@ -203,12 +203,12 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="bootGuardTab">
|
||||
<widget class="QWidget" name="securityTab">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>BootGuard</string>
|
||||
<string>Security</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
@ -227,7 +227,7 @@
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPlainTextEdit" name="bootGuardEdit">
|
||||
<widget class="QPlainTextEdit" name="securityEdit">
|
||||
<property name="acceptDrops">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
@ -536,39 +536,14 @@ Returns: (VOID)
|
||||
|
||||
--*/
|
||||
{
|
||||
if (mText) {
|
||||
free (mText);
|
||||
}
|
||||
|
||||
if (mLevel) {
|
||||
free (mLevel);
|
||||
}
|
||||
|
||||
if (mChildCount) {
|
||||
free (mChildCount);
|
||||
}
|
||||
|
||||
if (mPosition) {
|
||||
free (mPosition);
|
||||
}
|
||||
|
||||
if (mParent) {
|
||||
free (mParent);
|
||||
}
|
||||
|
||||
if (mPrev) {
|
||||
free (mPrev);
|
||||
}
|
||||
|
||||
if (mNext) {
|
||||
free (mNext);
|
||||
}
|
||||
|
||||
if (mBuf) {
|
||||
free (mBuf);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -580,39 +580,14 @@ VOID
|
||||
|
||||
--*/
|
||||
{
|
||||
if (mText != NULL) {
|
||||
free (mText);
|
||||
}
|
||||
|
||||
if (mLevel != NULL) {
|
||||
free (mLevel);
|
||||
}
|
||||
|
||||
if (mChildCount != NULL) {
|
||||
free (mChildCount);
|
||||
}
|
||||
|
||||
if (mPosition != NULL) {
|
||||
free (mPosition);
|
||||
}
|
||||
|
||||
if (mParent != NULL) {
|
||||
free (mParent);
|
||||
}
|
||||
|
||||
if (mPrev != NULL) {
|
||||
free (mPrev);
|
||||
}
|
||||
|
||||
if (mNext != NULL) {
|
||||
free (mNext);
|
||||
}
|
||||
|
||||
if (mBuf != NULL) {
|
||||
free (mBuf);
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
STATIC
|
||||
|
@ -65,7 +65,8 @@ typedef size_t USTATUS;
|
||||
#define U_INVALID_ACM 43
|
||||
#define U_INVALID_BG_KEY_MANIFEST 44
|
||||
#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_NOT_IMPLEMENTED 0xFF
|
||||
|
||||
// UDK porting definitions
|
||||
@ -87,6 +88,10 @@ typedef ptrdiff_t INTN;
|
||||
#define VOID void
|
||||
#define STATIC static
|
||||
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX 0x7fffffff
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE ((BOOLEAN)(1==1))
|
||||
#endif
|
||||
|
@ -72,11 +72,15 @@ typedef struct BG_MICROSOFT_PMDA_ENTRY_
|
||||
// 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_SUBTYPE_BOOTGUARD 0x3
|
||||
#define INTEL_ACM_MODULE_VENDOR 0x8086
|
||||
|
||||
typedef struct INTEL_ACM_HEADER_ {
|
||||
UINT32 ModuleType;
|
||||
UINT16 ModuleType;
|
||||
UINT16 ModuleSubtype;
|
||||
UINT32 HeaderType;
|
||||
UINT32 HeaderVersion;
|
||||
UINT16 ChipsetId;
|
||||
|
@ -363,6 +363,7 @@ struct CBString : public tagbstring {
|
||||
|
||||
// QString compatibility methods
|
||||
const char *toLocal8Bit() const { return *this; }
|
||||
bool contains(const char *str) { return find(str) >= 0; }
|
||||
bool isEmpty() const { return slen == 0; }
|
||||
void clear() { *this = ""; }
|
||||
CBString left(int len) const { return midstr(0, len); }
|
||||
|
@ -10,6 +10,8 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "ffs.h"
|
||||
#include "guiddatabase.h"
|
||||
|
||||
@ -17,8 +19,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
const UByteArray FFSv2VolumesInt[] = {
|
||||
EFI_FIRMWARE_FILE_SYSTEM_GUID,
|
||||
EFI_FIRMWARE_FILE_SYSTEM2_GUID,
|
||||
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID,
|
||||
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID,
|
||||
EFI_APPLE_AUTHENTICATION_FV_GUID,
|
||||
EFI_APPLE_IMMUTABLE_FV_GUID,
|
||||
EFI_INTEL_FILE_SYSTEM_GUID,
|
||||
EFI_INTEL_FILE_SYSTEM2_GUID,
|
||||
EFI_SONY_FILE_SYSTEM_GUID
|
||||
@ -69,6 +71,32 @@ UString guidToUString(const EFI_GUID & guid, bool convertToString)
|
||||
guid.Data4[7]);
|
||||
}
|
||||
|
||||
|
||||
bool ustringToGuid(const UString & str, EFI_GUID & guid)
|
||||
{
|
||||
unsigned long p0;
|
||||
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
|
||||
|
||||
int err = std::sscanf(str.toLocal8Bit(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
|
||||
if (err == 0)
|
||||
return false;
|
||||
|
||||
guid.Data1 = p0;
|
||||
guid.Data2 = p1;
|
||||
guid.Data3 = p2;
|
||||
guid.Data4[0] = p3;
|
||||
guid.Data4[1] = p4;
|
||||
guid.Data4[2] = p5;
|
||||
guid.Data4[3] = p6;
|
||||
guid.Data4[4] = p7;
|
||||
guid.Data4[5] = p8;
|
||||
guid.Data4[6] = p9;
|
||||
guid.Data4[7] = p10;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UString fileTypeToUString(const UINT8 type)
|
||||
{
|
||||
switch (type)
|
||||
|
55
common/ffs.h
55
common/ffs.h
@ -23,9 +23,11 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#pragma pack(push,1)
|
||||
|
||||
extern UString guidToUString(const EFI_GUID& guid, bool convertToString = true);
|
||||
extern bool ustringToGuid(const UString& str, EFI_GUID& guid);
|
||||
extern UString fileTypeToUString(const UINT8 type);
|
||||
extern UString sectionTypeToUString(const UINT8 type);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// EFI Capsule
|
||||
//*****************************************************************************
|
||||
@ -113,38 +115,43 @@ typedef struct EFI_FIRMWARE_VOLUME_HEADER_ {
|
||||
} EFI_FIRMWARE_VOLUME_HEADER;
|
||||
|
||||
// Standard file system GUIDs
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID // 7A9354D9-0468-444A-81CE-0BF617D890DF
|
||||
("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16);
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID
|
||||
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID // 8C8CE578-8A3D-4F1C-9935-896185C32DD3
|
||||
("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16);
|
||||
// Vendor-specific file system GUIDs
|
||||
const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID
|
||||
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
|
||||
const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
|
||||
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
|
||||
|
||||
// AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 // Intel 1
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM_GUID
|
||||
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
|
||||
// D6A1CD70-4B33-4994-A6EA-375F2CCC5437 // Intel 2
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID
|
||||
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
|
||||
// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1
|
||||
const UByteArray EFI_SONY_FILE_SYSTEM_GUID
|
||||
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
|
||||
|
||||
|
||||
// Vector of volume GUIDs with FFSv2-compatible files
|
||||
extern const std::vector<UByteArray> FFSv2Volumes;
|
||||
|
||||
const UByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A
|
||||
("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16);
|
||||
|
||||
// Vendor-specific file system GUIDs
|
||||
const UByteArray EFI_APPLE_IMMUTABLE_FV_GUID // 04ADEEAD-61FF-4D31-B6BA-64F8BF901F5A
|
||||
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
|
||||
|
||||
const UByteArray EFI_APPLE_AUTHENTICATION_FV_GUID // BD001B8C-6A71-487B-A14F-0C2A2DCF7A5D
|
||||
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
|
||||
|
||||
const UByteArray EFI_APPLE_MICROCODE_VOLUME_GUID // 153D2197-29BD-44DC-AC59-887F70E41A6B
|
||||
("\x97\x21\x3D\x15\xBD\x29\xDC\x44\xAC\x59\x88\x7F\x70\xE4\x1A\x6B", 16);
|
||||
#define EFI_APPLE_MICROCODE_VOLUME_HEADER_SIZE 0x100
|
||||
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM_GUID // AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0
|
||||
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
|
||||
|
||||
const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID // D6A1CD70-4B33-4994-A6EA-375F2CCC5437
|
||||
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
|
||||
|
||||
const UByteArray EFI_SONY_FILE_SYSTEM_GUID // 4F494156-AED6-4D64-A537-B8A5557BCEEC
|
||||
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
|
||||
|
||||
// Vector of volume GUIDs with FFSv2-compatible files
|
||||
extern const std::vector<UByteArray> FFSv2Volumes;
|
||||
|
||||
// Vector of volume GUIDs with FFSv3-compatible files
|
||||
extern const std::vector<UByteArray> FFSv3Volumes;
|
||||
|
||||
// Firmware volume signature
|
||||
const UByteArray EFI_FV_SIGNATURE("_FVH", 4);
|
||||
#define EFI_FV_SIGNATURE 0x4856465F // _FVH
|
||||
#define EFI_FV_SIGNATURE_OFFSET 0x28
|
||||
|
||||
// Firmware volume attributes
|
||||
@ -369,6 +376,10 @@ const UByteArray AMI_CORE_DXE_GUID // 5AE3F37E-4EAE-41AE-8240-35465B5E81EB
|
||||
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);
|
||||
|
||||
// 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
|
||||
extern VOID uint32ToUint24(UINT32 size, UINT8* ffsSize);
|
||||
extern UINT32 uint24ToUint32(const UINT8* ffsSize);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* fssbuilder.cpp
|
||||
/* fssbuilder.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
@ -16,6 +16,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include "ffs.h"
|
||||
#include "peimage.h"
|
||||
#include "utility.h"
|
||||
#include "nvram.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased)
|
||||
{
|
||||
@ -36,7 +39,7 @@ USTATUS FfsBuilder::erase(const UModelIndex & index, UByteArray & erased)
|
||||
}
|
||||
}
|
||||
|
||||
erased = QByteArray(model->header(index).size() + model->body(index).size() + model->tail(index).size(), emptyByte);
|
||||
erased = UByteArray(model->header(index).size() + model->body(index).size() + model->tail(index).size(), emptyByte);
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
@ -112,7 +115,7 @@ USTATUS FfsBuilder::buildCapsule(const UModelIndex & index, UByteArray & capsule
|
||||
return result;
|
||||
}
|
||||
else
|
||||
capsule.append(imageData);
|
||||
capsule += imageData;
|
||||
}
|
||||
else {
|
||||
msg(UString("buildCapsule: unexpected item type ") + itemTypeToUString(model->type(imageIndex)), imageIndex);
|
||||
@ -176,7 +179,7 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
|
||||
UINT8 type = model->type(currentRegion);
|
||||
if (type == Types::Padding) {
|
||||
// Add padding as is
|
||||
intelImage.append(model->header(currentRegion) + model->body(currentRegion) + model->tail(currentRegion));
|
||||
intelImage += model->header(currentRegion) + model->body(currentRegion) + model->tail(currentRegion);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -207,7 +210,7 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
|
||||
case Subtypes::Reserved2Region:
|
||||
case Subtypes::PttRegion:
|
||||
// Add region as is
|
||||
region = model->header(currentRegion).append(model->body(currentRegion));
|
||||
region = model->header(currentRegion) + model->body(currentRegion);
|
||||
break;
|
||||
default:
|
||||
msg(UString("buildIntelImage: unknown region type"), currentRegion);
|
||||
@ -215,7 +218,7 @@ USTATUS FfsBuilder::buildIntelImage(const UModelIndex & index, UByteArray & inte
|
||||
}
|
||||
|
||||
// Append the resulting region
|
||||
intelImage.append(region);
|
||||
intelImage += region;
|
||||
}
|
||||
|
||||
// Check size of new image, it must be same as old one
|
||||
@ -285,7 +288,7 @@ USTATUS FfsBuilder::buildRawArea(const UModelIndex & index, UByteArray & rawArea
|
||||
return result;
|
||||
}
|
||||
// Append current data
|
||||
rawArea.append(currentData);
|
||||
rawArea += currentData;
|
||||
}
|
||||
|
||||
// Check size of new raw area, it must be same as original one
|
||||
|
@ -28,29 +28,29 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
|
||||
if (mode == EXTRACT_MODE_AS_IS) {
|
||||
// Extract as is, with header body and tail
|
||||
extracted.clear();
|
||||
extracted.append(model->header(index));
|
||||
extracted.append(model->body(index));
|
||||
extracted.append(model->tail(index));
|
||||
extracted += model->header(index);
|
||||
extracted += model->body(index);
|
||||
extracted += model->tail(index);
|
||||
}
|
||||
else if (mode == EXTRACT_MODE_BODY) {
|
||||
name += QObject::tr("_body");
|
||||
name += UString("_body");
|
||||
// Extract without header and tail
|
||||
extracted.clear();
|
||||
extracted.append(model->body(index));
|
||||
extracted += model->body(index);
|
||||
}
|
||||
else if (mode == EXTRACT_MODE_BODY_UNCOMPRESSED) {
|
||||
name += QObject::tr("_body_unc");
|
||||
name += UString("_body_unc");
|
||||
// Extract without header and tail, uncompressed
|
||||
extracted.clear();
|
||||
// There is no need to redo decompression, we can use child items
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
UModelIndex childIndex = index.child(i, 0);
|
||||
// Ensure 4-byte alignment of current section
|
||||
extracted.append(UByteArray('\x00', ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size()));
|
||||
extracted += UByteArray(ALIGN4((UINT32)extracted.size()) - (UINT32)extracted.size(), '\x00');
|
||||
// Add current section header, body and tail
|
||||
extracted.append(model->header(childIndex));
|
||||
extracted.append(model->body(childIndex));
|
||||
extracted.append(model->tail(childIndex));
|
||||
extracted += model->header(childIndex);
|
||||
extracted += model->body(childIndex);
|
||||
extracted += model->tail(childIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -59,7 +59,7 @@ USTATUS FfsOperations::extract(const UModelIndex & index, UString & name, UByteA
|
||||
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);
|
||||
|
||||
|
@ -20,6 +20,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include "ubytearray.h"
|
||||
#include "ustring.h"
|
||||
#include "treemodel.h"
|
||||
#include "ffsparser.h"
|
||||
|
||||
class FfsOperations
|
||||
{
|
||||
@ -32,13 +33,14 @@ public:
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
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 rebuild(const UModelIndex & index);
|
||||
|
||||
private:
|
||||
TreeModel* model;
|
||||
TreeModel * model;
|
||||
|
||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
||||
|
||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,9 +20,9 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include "ubytearray.h"
|
||||
#include "treemodel.h"
|
||||
#include "bootguard.h"
|
||||
#include "fit.h"
|
||||
|
||||
typedef struct BG_PROTECTED_RANGE_
|
||||
{
|
||||
typedef struct BG_PROTECTED_RANGE_ {
|
||||
UINT32 Offset;
|
||||
UINT32 Size;
|
||||
UINT8 Type;
|
||||
@ -57,8 +57,8 @@ public:
|
||||
// Obtain parsed FIT table
|
||||
std::vector<std::pair<std::vector<UString>, UModelIndex> > getFitTable() const { return fitTable; }
|
||||
|
||||
// Obtain BootGuardInfo
|
||||
UString getBootGuardInfo() const { return bootGuardInfo; }
|
||||
// Obtain Security Info
|
||||
UString getSecurityInfo() const { return securityInfo; }
|
||||
|
||||
// Obtain offset/address difference
|
||||
UINT64 getAddressDiff() { return addressDiff; }
|
||||
@ -79,7 +79,7 @@ private:
|
||||
UINT64 addressDiff;
|
||||
std::vector<std::pair<std::vector<UString>, UModelIndex> > fitTable;
|
||||
|
||||
UString bootGuardInfo;
|
||||
UString securityInfo;
|
||||
bool bgAcmFound;
|
||||
bool bgKeyManifestFound;
|
||||
bool bgBootPolicyFound;
|
||||
@ -87,19 +87,20 @@ private:
|
||||
UByteArray bgBpHash;
|
||||
UByteArray bgBpDigest;
|
||||
std::vector<BG_PROTECTED_RANGE> bgProtectedRanges;
|
||||
UINT64 bgFirstVolumeOffset;
|
||||
UINT64 bgProtectedRegionsBase;
|
||||
UModelIndex bgDxeCoreIndex;
|
||||
|
||||
// First pass
|
||||
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
|
||||
|
||||
USTATUS parseCapsule(const UByteArray & capsule, UModelIndex & index);
|
||||
USTATUS parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseGenericImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
|
||||
USTATUS parseRawArea(const UModelIndex & index);
|
||||
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseVolumeBody(const UModelIndex & index);
|
||||
USTATUS parseMicrocodeVolumeBody(const UModelIndex & index);
|
||||
USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseFileBody(const UModelIndex & index);
|
||||
USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree);
|
||||
@ -132,8 +133,7 @@ private:
|
||||
USTATUS parseTeImageSectionBody(const UModelIndex & index);
|
||||
|
||||
USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed);
|
||||
USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
|
||||
USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
|
||||
USTATUS findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset, UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize);
|
||||
UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
|
||||
UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
|
||||
|
||||
@ -147,16 +147,17 @@ private:
|
||||
|
||||
USTATUS parseFit(const UModelIndex & index);
|
||||
USTATUS parseVendorHashFile(const UByteArray & fileGuid, const UModelIndex & index);
|
||||
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
|
||||
#ifdef U_ENABLE_FIT_PARSING_SUPPORT
|
||||
USTATUS findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset);
|
||||
|
||||
// FIT entries
|
||||
USTATUS parseIntelMicrocode(const UByteArray & microcode, 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 parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
|
||||
USTATUS parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
|
||||
USTATUS findNextBootGuardBootPolicyElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
|
||||
#endif
|
||||
|
||||
#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT
|
||||
|
@ -16,7 +16,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include "basetypes.h"
|
||||
#include "ustring.h"
|
||||
#include "ubytearray.h"
|
||||
#include <sys/stat.h>
|
||||
#include <fstream>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <direct.h>
|
||||
@ -48,4 +50,20 @@ static inline bool changeDirectory(const UString & dir) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline USTATUS readFileIntoBuffer(const UString & inPath, UByteArray &buf) {
|
||||
if (!isExistOnFs(inPath))
|
||||
return U_FILE_OPEN;
|
||||
|
||||
std::ifstream inputFile(inPath.toLocal8Bit(), std::ios::in | std::ios::binary);
|
||||
if (!inputFile)
|
||||
return U_FILE_OPEN;
|
||||
std::vector<char> buffer(std::istreambuf_iterator<char>(inputFile),
|
||||
(std::istreambuf_iterator<char>()));
|
||||
inputFile.close();
|
||||
|
||||
buf = buffer;
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -65,6 +65,14 @@ typedef struct INTEL_MICROCODE_HEADER_ {
|
||||
UINT8 Reserved[12];
|
||||
} INTEL_MICROCODE_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UINT16 IndexRegisterAddress;
|
||||
UINT16 DataRegisterAddress;
|
||||
UINT8 AccessWidth;
|
||||
UINT8 BitPosition;
|
||||
UINT16 Index;
|
||||
} FIT_ENTRY_VERSION_0_CONFIG_POLICY;
|
||||
|
||||
#define INTEL_MICROCODE_HEADER_VERSION 0x00000001
|
||||
#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))
|
||||
|
@ -12,14 +12,15 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include "guiddatabase.h"
|
||||
#include "ubytearray.h"
|
||||
#include "ffs.h"
|
||||
|
||||
#if defined(U_ENABLE_GUID_DATABASE_SUPPORT)
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
struct OperatorLessForGuids : public std::binary_function<EFI_GUID, EFI_GUID, bool>
|
||||
{
|
||||
@ -86,27 +87,9 @@ void initGuidDatabase(const UString & path, UINT32* numEntries)
|
||||
continue;
|
||||
|
||||
EFI_GUID guid;
|
||||
|
||||
unsigned long p0;
|
||||
int p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
|
||||
|
||||
int err = std::sscanf(lineParts[0].toLocal8Bit(), "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
&p0, &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10);
|
||||
if (err == 0)
|
||||
if (!ustringToGuid(lineParts[0], guid))
|
||||
continue;
|
||||
|
||||
guid.Data1 = p0;
|
||||
guid.Data2 = p1;
|
||||
guid.Data3 = p2;
|
||||
guid.Data4[0] = p3;
|
||||
guid.Data4[1] = p4;
|
||||
guid.Data4[2] = p5;
|
||||
guid.Data4[3] = p6;
|
||||
guid.Data4[4] = p7;
|
||||
guid.Data4[5] = p8;
|
||||
guid.Data4[6] = p9;
|
||||
guid.Data4[7] = p10;
|
||||
|
||||
gGuidToUStringMap.insert(GuidToUStringMap::value_type(guid, lineParts[1]));
|
||||
}
|
||||
|
||||
|
12
common/me.h
12
common/me.h
@ -22,12 +22,12 @@ const UByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN
|
||||
const UByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2
|
||||
|
||||
typedef struct ME_VERSION_ {
|
||||
UINT32 signature;
|
||||
UINT32 reserved;
|
||||
UINT16 major;
|
||||
UINT16 minor;
|
||||
UINT16 bugfix;
|
||||
UINT16 build;
|
||||
UINT32 Signature;
|
||||
UINT32 Reserved;
|
||||
UINT16 Major;
|
||||
UINT16 Minor;
|
||||
UINT16 Bugfix;
|
||||
UINT16 Build;
|
||||
} ME_VERSION;
|
||||
|
||||
// Restore previous packing rules
|
||||
|
@ -108,6 +108,6 @@ UString flashMapGuidToUString(const EFI_GUID & guid)
|
||||
|| baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID
|
||||
|| baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID) return UString("EVSA store");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_SELF_GUID) return UString("Flash map");
|
||||
return UString();
|
||||
return UString("Unknown");
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
||||
hasExtendedHeader = true;
|
||||
msgUnknownExtDataFormat = true;
|
||||
|
||||
extendedHeaderSize = *(UINT16*)(body.constData() + body.size() - sizeof(UINT16));
|
||||
extendedHeaderSize = readMisaligned((UINT16*)(body.constData() + body.size() - sizeof(UINT16)));
|
||||
if (extendedHeaderSize > (UINT32)body.size()) {
|
||||
msgExtHeaderTooLong = true;
|
||||
isInvalid = true;
|
||||
@ -203,7 +203,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
||||
goto parsing_done;
|
||||
}
|
||||
|
||||
timestamp = *(UINT64*)(tail.constData() + sizeof(UINT8));
|
||||
timestamp = readMisaligned(tail.constData() + sizeof(UINT8));
|
||||
hasTimestamp = true;
|
||||
msgUnknownExtDataFormat = false;
|
||||
}
|
||||
@ -215,7 +215,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
||||
goto parsing_done;
|
||||
}
|
||||
|
||||
timestamp = *(UINT64*)(tail.constData() + sizeof(UINT8));
|
||||
timestamp = readMisaligned((UINT64*)(tail.constData()) + sizeof(UINT8));
|
||||
hash = tail.mid(sizeof(UINT64) + sizeof(UINT8), SHA256_HASH_SIZE);
|
||||
hasTimestamp = true;
|
||||
hasHash = true;
|
||||
@ -272,8 +272,8 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
||||
|
||||
// Get entry GUID
|
||||
if (entryHeader->Attributes & NVRAM_NVAR_ENTRY_GUID) { // GUID is strored in the variable itself
|
||||
name = guidToUString(*(EFI_GUID*)(entryHeader + 1));
|
||||
guid = guidToUString(*(EFI_GUID*)(entryHeader + 1), false);
|
||||
name = guidToUString(readMisaligned((EFI_GUID*)(entryHeader + 1)));
|
||||
guid = guidToUString(readMisaligned((EFI_GUID*)(entryHeader + 1)), false);
|
||||
}
|
||||
// GUID is stored in GUID list at the end of the store
|
||||
else {
|
||||
@ -283,8 +283,8 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
||||
|
||||
// The list begins at the end of the store and goes backwards
|
||||
const EFI_GUID* guidPtr = (const EFI_GUID*)(data.constData() + data.size()) - 1 - guidIndex;
|
||||
name = guidToUString(*guidPtr);
|
||||
guid = guidToUString(*guidPtr, false);
|
||||
name = guidToUString(readMisaligned(guidPtr));
|
||||
guid = guidToUString(readMisaligned(guidPtr), false);
|
||||
hasGuidIndex = true;
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
||||
|
||||
// Try parsing the entry data as NVAR storage if it begins with NVAR signature
|
||||
if ((subtype == Subtypes::DataNvarEntry || subtype == Subtypes::FullNvarEntry)
|
||||
&& *(const UINT32*)body.constData() == NVRAM_NVAR_ENTRY_SIGNATURE)
|
||||
&& body.size() >= 4 && *(const UINT32*)body.constData() == NVRAM_NVAR_ENTRY_SIGNATURE)
|
||||
parseNvarStore(varIndex);
|
||||
|
||||
// Move to next exntry
|
||||
@ -1223,55 +1223,6 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
||||
{
|
||||
const UINT32 dataSize = (const UINT32)store.size();
|
||||
|
||||
// Check data size
|
||||
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
|
||||
msg(usprintf("%s: volume body is too small even for Intel microcode header", __FUNCTION__), parent);
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Get Intel microcode header
|
||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)store.constData();
|
||||
|
||||
// Check store size
|
||||
if (dataSize < ucodeHeader->TotalSize) {
|
||||
msg(usprintf("%s: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
|
||||
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
|
||||
dataSize, dataSize), parent);
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
// Construct header and body
|
||||
UByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER));
|
||||
UByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
|
||||
|
||||
//TODO: recalculate microcode checksum
|
||||
|
||||
// Add info
|
||||
UString name("Intel microcode");
|
||||
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n"
|
||||
"Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh",
|
||||
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
|
||||
header.size(), header.size(),
|
||||
body.size(), body.size(),
|
||||
ucodeHeader->DateDay,
|
||||
ucodeHeader->DateMonth,
|
||||
ucodeHeader->DateYear,
|
||||
ucodeHeader->CpuSignature,
|
||||
ucodeHeader->Revision,
|
||||
ucodeHeader->Checksum,
|
||||
ucodeHeader->LoaderRevision,
|
||||
ucodeHeader->CpuFlags);
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
||||
|
||||
return U_SUCCESS;
|
||||
}
|
||||
|
||||
USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
|
||||
{
|
||||
const UINT32 dataSize = (const UINT32)store.size();
|
||||
@ -1316,7 +1267,7 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc
|
||||
// Intel microcode
|
||||
// Must be checked after SLIC marker because of the same *signature values
|
||||
else if (*signature == INTEL_MICROCODE_HEADER_VERSION)
|
||||
return parseIntelMicrocodeHeader(store, localOffset, parent, index);
|
||||
return ffsParser->parseIntelMicrocodeHeader(store, localOffset, parent, index);
|
||||
|
||||
msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent);
|
||||
return U_SUCCESS;
|
||||
@ -1545,8 +1496,8 @@ USTATUS NvramParser::parseVssStoreBody(const UModelIndex & index, UINT8 alignmen
|
||||
name = UString("Invalid");
|
||||
}
|
||||
else { // Add GUID and text for valid variables
|
||||
name = guidToUString(*variableGuid);
|
||||
info += UString("Variable GUID: ") + guidToUString(*variableGuid, false) + UString("\n");
|
||||
name = guidToUString(readMisaligned(variableGuid));
|
||||
info += UString("Variable GUID: ") + guidToUString(readMisaligned(variableGuid), false) + UString("\n");
|
||||
text = UString::fromUtf16(variableName);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,6 @@ private:
|
||||
USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
|
||||
|
||||
USTATUS parseFdcStoreBody(const UModelIndex & index);
|
||||
USTATUS parseVssStoreBody(const UModelIndex & index, const UINT8 alignment);
|
||||
|
@ -187,7 +187,7 @@ int sha256_done(struct sha256_state *md, unsigned char *out)
|
||||
if (md->curlen >= sizeof(md->buf))
|
||||
return -1;
|
||||
/* increase the length of the message */
|
||||
md->length += md->curlen * 8;
|
||||
md->length += (uint64_t)md->curlen * 8;
|
||||
/* append the '1' bit */
|
||||
md->buf[md->curlen++] = (unsigned char) 0x80;
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
|
@ -74,17 +74,6 @@ UString itemTypeToUString(const UINT8 type)
|
||||
UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
|
||||
{
|
||||
switch (type) {
|
||||
case Types::Root:
|
||||
case Types::FreeSpace:
|
||||
case Types::VssStore:
|
||||
case Types::Vss2Store:
|
||||
case Types::FdcStore:
|
||||
case Types::FsysStore:
|
||||
case Types::EvsaStore:
|
||||
case Types::FtwStore:
|
||||
case Types::FlashMapStore:
|
||||
case Types::CmdbStore:
|
||||
case Types::SlicData: return UString();
|
||||
case Types::Image:
|
||||
if (subtype == Subtypes::IntelImage) return UString("Intel");
|
||||
if (subtype == Subtypes::UefiImage) return UString("UEFI");
|
||||
@ -99,6 +88,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
|
||||
if (subtype == Subtypes::Ffs2Volume) return UString("FFSv2");
|
||||
if (subtype == Subtypes::Ffs3Volume) return UString("FFSv3");
|
||||
if (subtype == Subtypes::NvramVolume) return UString("NVRAM");
|
||||
if (subtype == Subtypes::MicrocodeVolume) return UString("Microcode");
|
||||
break;
|
||||
case Types::Capsule:
|
||||
if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed");
|
||||
@ -144,7 +134,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
|
||||
break;
|
||||
}
|
||||
|
||||
return UString("Unknown");
|
||||
return UString();
|
||||
}
|
||||
|
||||
UString compressionTypeToUString(const UINT8 algorithm)
|
||||
|
@ -78,7 +78,8 @@ namespace Subtypes {
|
||||
UnknownVolume = 110,
|
||||
Ffs2Volume,
|
||||
Ffs3Volume,
|
||||
NvramVolume
|
||||
NvramVolume,
|
||||
MicrocodeVolume
|
||||
};
|
||||
|
||||
enum RegionSubtypes {
|
||||
|
@ -55,4 +55,12 @@ BOOLEAN makePattern(const CHAR8 *textPattern, std::vector<UINT8> &pattern, std::
|
||||
INTN findPattern(const UINT8 *pattern, const UINT8 *patternMask, UINTN patternSize,
|
||||
const UINT8 *data, UINTN dataSize, UINTN dataOff);
|
||||
|
||||
// Safely dereferences misaligned pointers
|
||||
template <typename T>
|
||||
inline T readMisaligned(const T *v) {
|
||||
T tmp;
|
||||
memcpy(&tmp, v, sizeof(T));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#endif // UTILITY_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* types.h
|
||||
/* version.h
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -14,6 +14,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#ifndef __VERSION_H__
|
||||
#define __VERSION_H__
|
||||
|
||||
#define PROGRAM_VERSION "NE alpha 51"
|
||||
#define PROGRAM_VERSION "NE alpha 52"
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user