mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 07:58:22 +08:00
Move fitParser to ffsParser
- required to set fixed properly
This commit is contained in:
parent
feb74c3299
commit
59a6f298ee
@ -9,7 +9,6 @@ SET(PROJECT_SOURCES
|
|||||||
../common/nvram.cpp
|
../common/nvram.cpp
|
||||||
../common/ffsparser.cpp
|
../common/ffsparser.cpp
|
||||||
../common/ffsreport.cpp
|
../common/ffsreport.cpp
|
||||||
../common/fitparser.cpp
|
|
||||||
../common/peimage.cpp
|
../common/peimage.cpp
|
||||||
../common/treeitem.cpp
|
../common/treeitem.cpp
|
||||||
../common/treemodel.cpp
|
../common/treemodel.cpp
|
||||||
@ -32,7 +31,6 @@ SET(PROJECT_HEADERS
|
|||||||
../common/nvram.h
|
../common/nvram.h
|
||||||
../common/ffsparser.h
|
../common/ffsparser.h
|
||||||
../common/ffsreport.h
|
../common/ffsreport.h
|
||||||
../common/fitparser.h
|
|
||||||
../common/peimage.h
|
../common/peimage.h
|
||||||
../common/types.h
|
../common/types.h
|
||||||
../common/treeitem.h
|
../common/treeitem.h
|
||||||
|
@ -15,7 +15,6 @@ SOURCES += \
|
|||||||
../common/nvram.cpp \
|
../common/nvram.cpp \
|
||||||
../common/ffsparser.cpp \
|
../common/ffsparser.cpp \
|
||||||
../common/ffsreport.cpp \
|
../common/ffsreport.cpp \
|
||||||
../common/fitparser.cpp \
|
|
||||||
../common/peimage.cpp \
|
../common/peimage.cpp \
|
||||||
../common/treeitem.cpp \
|
../common/treeitem.cpp \
|
||||||
../common/treemodel.cpp \
|
../common/treemodel.cpp \
|
||||||
@ -35,7 +34,6 @@ HEADERS += \
|
|||||||
../common/nvram.h \
|
../common/nvram.h \
|
||||||
../common/ffsparser.h \
|
../common/ffsparser.h \
|
||||||
../common/ffsreport.h \
|
../common/ffsreport.h \
|
||||||
../common/fitparser.h \
|
|
||||||
../common/peimage.h \
|
../common/peimage.h \
|
||||||
../common/types.h \
|
../common/types.h \
|
||||||
../common/treeitem.h \
|
../common/treeitem.h \
|
||||||
|
@ -15,7 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#include "../common/ffsparser.h"
|
#include "../common/ffsparser.h"
|
||||||
#include "../common/ffsreport.h"
|
#include "../common/ffsreport.h"
|
||||||
#include "../common/fitparser.h"
|
|
||||||
#include "ffsdumper.h"
|
#include "ffsdumper.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -62,36 +61,39 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get last VTF
|
// Get last VTF
|
||||||
QModelIndex lastVtf = ffsParser.getLastVtf();
|
std::vector<std::vector<QString> > fitTable = ffsParser.getFitTable();
|
||||||
if (lastVtf.isValid()) {
|
if (fitTable.size()) {
|
||||||
// Create fitParser
|
std::cout << "-------------------------------------------------------------------" << std::endl;
|
||||||
FitParser fitParser(&model);
|
std::cout << " Address | Size | Ver | CS | Type " << std::endl;
|
||||||
// Find and parse FIT table
|
std::cout << "-------------------------------------------------------------------" << std::endl;
|
||||||
result = fitParser.parse(model.index(0, 0), lastVtf);
|
for (size_t i = 0; i < fitTable.size(); i++) {
|
||||||
if (U_SUCCESS == result) {
|
std::cout << fitTable[i][0].toLatin1().constData() << " | "
|
||||||
// Show fitParser's messages
|
|
||||||
std::vector<std::pair<QString, QModelIndex> > fitMessages = fitParser.getMessages();
|
|
||||||
for (size_t i = 0; i < fitMessages.size(); i++) {
|
|
||||||
std::cout << fitMessages[i].first.toLatin1().constData() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show FIT table
|
|
||||||
std::vector<std::vector<QString> > fitTable = fitParser.getFitTable();
|
|
||||||
if (fitTable.size()) {
|
|
||||||
std::cout << "-------------------------------------------------------------------" << std::endl;
|
|
||||||
std::cout << " Address | Size | Ver | Type | CS " << std::endl;
|
|
||||||
std::cout << "-------------------------------------------------------------------" << std::endl;
|
|
||||||
for (size_t i = 0; i < fitTable.size(); i++) {
|
|
||||||
std::cout << fitTable[i][0].toLatin1().constData() << " | "
|
|
||||||
<< fitTable[i][1].toLatin1().constData() << " | "
|
<< fitTable[i][1].toLatin1().constData() << " | "
|
||||||
<< fitTable[i][2].toLatin1().constData() << " | "
|
<< fitTable[i][2].toLatin1().constData() << " | "
|
||||||
<< fitTable[i][3].toLatin1().constData() << " | "
|
<< fitTable[i][3].toLatin1().constData() << " | "
|
||||||
<< fitTable[i][4].toLatin1().constData() << std::endl;
|
<< fitTable[i][4].toLatin1().constData() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create ffsDumper
|
||||||
|
FfsDumper ffsDumper(&model);
|
||||||
|
|
||||||
|
// Dump only leaf elements, no report
|
||||||
|
if (a.arguments().length() == 3 && a.arguments().at(2) == QString("dump")) {
|
||||||
|
return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump")) != U_SUCCESS);
|
||||||
|
}
|
||||||
|
else if (a.arguments().length() > 3 ||
|
||||||
|
(a.arguments().length() == 3 && a.arguments().at(2) != QString("all") && a.arguments().at(2) != QString("report"))) { // Dump specific files, without report
|
||||||
|
UINT32 returned = 0;
|
||||||
|
for (int i = 2; i < a.arguments().length(); i++) {
|
||||||
|
result = ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true, a.arguments().at(i));
|
||||||
|
if (result)
|
||||||
|
returned |= (1 << (i - 1));
|
||||||
|
}
|
||||||
|
return returned;
|
||||||
|
}
|
||||||
|
|
||||||
// Create ffsReport
|
// Create ffsReport
|
||||||
FfsReport ffsReport(&model);
|
FfsReport ffsReport(&model);
|
||||||
std::vector<QString> report = ffsReport.generate();
|
std::vector<QString> report = ffsReport.generate();
|
||||||
@ -105,39 +107,25 @@ int main(int argc, char *argv[])
|
|||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create ffsDumper
|
// Dump all non-leaf elements, with report, default
|
||||||
FfsDumper ffsDumper(&model);
|
|
||||||
|
|
||||||
// Dump all non-leaf elements
|
|
||||||
if (a.arguments().length() == 2) {
|
if (a.arguments().length() == 2) {
|
||||||
return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump")) != U_SUCCESS);
|
return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump")) != U_SUCCESS);
|
||||||
}
|
}
|
||||||
else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("all")) { // Dump everything
|
else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("all")) { // Dump every elementm with report
|
||||||
return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true) != U_SUCCESS);
|
return (ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true) != U_SUCCESS);
|
||||||
}
|
}
|
||||||
else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("none")) { // Skip dumping
|
else if (a.arguments().length() == 3 && a.arguments().at(2) == QString("report")) { // Skip dumping
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else { // Dump specific files
|
|
||||||
UINT32 returned = 0;
|
|
||||||
for (int i = 2; i < a.arguments().length(); i++) {
|
|
||||||
result = ffsDumper.dump(model.index(0, 0), fileInfo.fileName().append(".dump"), true, a.arguments().at(i));
|
|
||||||
if (result)
|
|
||||||
returned |= (1 << (i - 1));
|
|
||||||
}
|
|
||||||
return returned;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else { // Show version and usage information
|
|
||||||
std::cout << "UEFIExtract 0.12.2" << std::endl << std::endl
|
|
||||||
<< "Usage: UEFIExtract imagefile - generate report and dump only leaf tree items into .dump folder" << std::endl
|
|
||||||
<< " UEFIExtract imagefile all - generate report and dump all tree items" << std::endl
|
|
||||||
<< " UEFIExtract imagefile none - only generate report, no dump needed" << std::endl
|
|
||||||
<< " UIFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dump only FFS file(s) with specific GUID(s)" << std::endl
|
|
||||||
<< "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
// If parameters are different, show version and usage information
|
||||||
|
std::cout << "UEFIExtract 0.13.0" << std::endl << std::endl
|
||||||
|
<< "Usage: UEFIExtract imagefile - generate report and dump only leaf tree items into .dump folder." << std::endl
|
||||||
|
<< " UEFIExtract imagefile all - generate report and dump all tree items." << std::endl
|
||||||
|
<< " UEFIExtract imagefile dump - only generate dump, no report needed." << std::endl
|
||||||
|
<< " UEFIExtract imagefile report - only generate report, no dump needed." << std::endl
|
||||||
|
<< " UEFIExtract imagefile GUID_1 GUID_2 ... GUID_31 - dump only FFS file(s) with specific GUID(s), without report." << std::endl
|
||||||
|
<< "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise." << std::endl;
|
||||||
|
return 1;
|
||||||
}
|
}
|
@ -27,7 +27,6 @@ version(tr("NE Alpha32"))
|
|||||||
hexViewDialog = new HexViewDialog(this);
|
hexViewDialog = new HexViewDialog(this);
|
||||||
model = NULL;
|
model = NULL;
|
||||||
ffsParser = NULL;
|
ffsParser = NULL;
|
||||||
fitParser = NULL;
|
|
||||||
ffsFinder = NULL;
|
ffsFinder = NULL;
|
||||||
ffsOps = NULL;
|
ffsOps = NULL;
|
||||||
ffsBuilder = NULL;
|
ffsBuilder = NULL;
|
||||||
@ -72,7 +71,6 @@ version(tr("NE Alpha32"))
|
|||||||
#endif
|
#endif
|
||||||
ui->infoEdit->setFont(font);
|
ui->infoEdit->setFont(font);
|
||||||
ui->parserMessagesListWidget->setFont(font);
|
ui->parserMessagesListWidget->setFont(font);
|
||||||
ui->fitMessagesListWidget->setFont(font);
|
|
||||||
ui->finderMessagesListWidget->setFont(font);
|
ui->finderMessagesListWidget->setFont(font);
|
||||||
ui->builderMessagesListWidget->setFont(font);
|
ui->builderMessagesListWidget->setFont(font);
|
||||||
ui->fitTableWidget->setFont(font);
|
ui->fitTableWidget->setFont(font);
|
||||||
@ -93,7 +91,6 @@ UEFITool::~UEFITool()
|
|||||||
delete ffsBuilder;
|
delete ffsBuilder;
|
||||||
delete ffsOps;
|
delete ffsOps;
|
||||||
delete ffsFinder;
|
delete ffsFinder;
|
||||||
delete fitParser;
|
|
||||||
delete ffsParser;
|
delete ffsParser;
|
||||||
delete model;
|
delete model;
|
||||||
delete hexViewDialog;
|
delete hexViewDialog;
|
||||||
@ -136,17 +133,12 @@ void UEFITool::init()
|
|||||||
// ... and ffsParser
|
// ... and ffsParser
|
||||||
delete ffsParser;
|
delete ffsParser;
|
||||||
ffsParser = new FfsParser(model);
|
ffsParser = new FfsParser(model);
|
||||||
// ... and fitParser
|
|
||||||
delete fitParser;
|
|
||||||
fitParser = new FitParser(model);
|
|
||||||
|
|
||||||
// Connect
|
// Connect
|
||||||
connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
|
connect(ui->structureTreeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
|
||||||
this, SLOT(populateUi(const QModelIndex &)));
|
this, SLOT(populateUi(const QModelIndex &)));
|
||||||
connect(ui->parserMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
connect(ui->parserMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
||||||
connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
|
connect(ui->parserMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
|
||||||
connect(ui->fitMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
|
||||||
connect(ui->fitMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
|
|
||||||
connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
connect(ui->finderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
||||||
connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
|
connect(ui->finderMessagesListWidget, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(enableMessagesCopyActions(QListWidgetItem*)));
|
||||||
connect(ui->builderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
connect(ui->builderMessagesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(scrollTreeView(QListWidgetItem*)));
|
||||||
@ -748,13 +740,6 @@ void UEFITool::openImageFile(QString path)
|
|||||||
else
|
else
|
||||||
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
|
ui->statusBar->showMessage(tr("Opened: %1").arg(fileInfo.fileName()));
|
||||||
|
|
||||||
// Parse FIT
|
|
||||||
result = fitParser->parse(model->index(0, 0), ffsParser->getLastVtf());
|
|
||||||
showFitMessages();
|
|
||||||
if (!result) {
|
|
||||||
showFitTable();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable search ...
|
// Enable search ...
|
||||||
delete ffsFinder;
|
delete ffsFinder;
|
||||||
ffsFinder = new FfsFinder(model);
|
ffsFinder = new FfsFinder(model);
|
||||||
@ -763,6 +748,9 @@ void UEFITool::openImageFile(QString path)
|
|||||||
delete ffsOps;
|
delete ffsOps;
|
||||||
ffsOps = new FfsOperations(model);
|
ffsOps = new FfsOperations(model);
|
||||||
|
|
||||||
|
// Enable or disable FIT tab
|
||||||
|
showFitTable();
|
||||||
|
|
||||||
// Set current directory
|
// Set current directory
|
||||||
currentDir = fileInfo.absolutePath();
|
currentDir = fileInfo.absolutePath();
|
||||||
}
|
}
|
||||||
@ -772,8 +760,6 @@ void UEFITool::copyMessage()
|
|||||||
clipboard->clear();
|
clipboard->clear();
|
||||||
if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab
|
if (ui->messagesTabWidget->currentIndex() == 0) // Parser tab
|
||||||
clipboard->setText(ui->parserMessagesListWidget->currentItem()->text());
|
clipboard->setText(ui->parserMessagesListWidget->currentItem()->text());
|
||||||
else if (ui->messagesTabWidget->currentIndex() == 1) // FIT tab
|
|
||||||
clipboard->setText(ui->fitMessagesListWidget->currentItem()->text());
|
|
||||||
else if (ui->messagesTabWidget->currentIndex() == 2) // Search tab
|
else if (ui->messagesTabWidget->currentIndex() == 2) // Search tab
|
||||||
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
|
clipboard->setText(ui->finderMessagesListWidget->currentItem()->text());
|
||||||
else if (ui->messagesTabWidget->currentIndex() == 3) // Builder tab
|
else if (ui->messagesTabWidget->currentIndex() == 3) // Builder tab
|
||||||
@ -789,11 +775,6 @@ void UEFITool::copyAllMessages()
|
|||||||
text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n");
|
text.append(ui->parserMessagesListWidget->item(i)->text()).append("\n");
|
||||||
clipboard->setText(text);
|
clipboard->setText(text);
|
||||||
}
|
}
|
||||||
else if (ui->messagesTabWidget->currentIndex() == 1) { // FIT tab
|
|
||||||
for (INT32 i = 0; i < ui->fitMessagesListWidget->count(); i++)
|
|
||||||
text.append(ui->fitMessagesListWidget->item(i)->text()).append("\n");
|
|
||||||
clipboard->setText(text);
|
|
||||||
}
|
|
||||||
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab
|
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab
|
||||||
for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++)
|
for (INT32 i = 0; i < ui->finderMessagesListWidget->count(); i++)
|
||||||
text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n");
|
text.append(ui->finderMessagesListWidget->item(i)->text()).append("\n");
|
||||||
@ -818,10 +799,6 @@ void UEFITool::clearMessages()
|
|||||||
if (ffsParser) ffsParser->clearMessages();
|
if (ffsParser) ffsParser->clearMessages();
|
||||||
ui->parserMessagesListWidget->clear();
|
ui->parserMessagesListWidget->clear();
|
||||||
}
|
}
|
||||||
else if (ui->messagesTabWidget->currentIndex() == 1) { // FIT tab
|
|
||||||
if (fitParser) fitParser->clearMessages();
|
|
||||||
ui->fitMessagesListWidget->clear();
|
|
||||||
}
|
|
||||||
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab
|
else if (ui->messagesTabWidget->currentIndex() == 2) { // Search tab
|
||||||
if (ffsFinder) ffsFinder->clearMessages();
|
if (ffsFinder) ffsFinder->clearMessages();
|
||||||
ui->finderMessagesListWidget->clear();
|
ui->finderMessagesListWidget->clear();
|
||||||
@ -863,21 +840,6 @@ void UEFITool::showParserMessages()
|
|||||||
ui->parserMessagesListWidget->scrollToBottom();
|
ui->parserMessagesListWidget->scrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UEFITool::showFitMessages()
|
|
||||||
{
|
|
||||||
ui->fitMessagesListWidget->clear();
|
|
||||||
if (!fitParser)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::vector<std::pair<QString, QModelIndex> > messages = fitParser->getMessages();
|
|
||||||
std::pair<QString, QModelIndex> msg;
|
|
||||||
foreach (msg, messages) {
|
|
||||||
ui->fitMessagesListWidget->addItem(new MessageListItem(msg.first, NULL, 0, msg.second));
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->fitMessagesListWidget->scrollToBottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UEFITool::showFinderMessages()
|
void UEFITool::showFinderMessages()
|
||||||
{
|
{
|
||||||
ui->finderMessagesListWidget->clear();
|
ui->finderMessagesListWidget->clear();
|
||||||
@ -923,7 +885,6 @@ void UEFITool::scrollTreeView(QListWidgetItem* item)
|
|||||||
void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||||
{
|
{
|
||||||
if (ui->parserMessagesListWidget->underMouse() ||
|
if (ui->parserMessagesListWidget->underMouse() ||
|
||||||
ui->fitMessagesListWidget->underMouse() ||
|
|
||||||
ui->finderMessagesListWidget->underMouse() ||
|
ui->finderMessagesListWidget->underMouse() ||
|
||||||
ui->builderMessagesListWidget->underMouse()) {
|
ui->builderMessagesListWidget->underMouse()) {
|
||||||
ui->menuMessages->exec(event->globalPos());
|
ui->menuMessages->exec(event->globalPos());
|
||||||
@ -999,10 +960,13 @@ void UEFITool::writeSettings()
|
|||||||
|
|
||||||
void UEFITool::showFitTable()
|
void UEFITool::showFitTable()
|
||||||
{
|
{
|
||||||
std::vector<std::vector<QString> > fitTable = fitParser->getFitTable();
|
std::vector<std::vector<QString> > fitTable = ffsParser->getFitTable();
|
||||||
if (fitTable.empty()) {
|
if (fitTable.empty()) {
|
||||||
|
// Disable FIT tab
|
||||||
|
ui->messagesTabWidget->setTabEnabled(1, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable FIT tab
|
// Enable FIT tab
|
||||||
ui->messagesTabWidget->setTabEnabled(1, true);
|
ui->messagesTabWidget->setTabEnabled(1, true);
|
||||||
|
|
||||||
@ -1010,7 +974,7 @@ void UEFITool::showFitTable()
|
|||||||
ui->fitTableWidget->clear();
|
ui->fitTableWidget->clear();
|
||||||
ui->fitTableWidget->setRowCount(fitTable.size());
|
ui->fitTableWidget->setRowCount(fitTable.size());
|
||||||
ui->fitTableWidget->setColumnCount(5);
|
ui->fitTableWidget->setColumnCount(5);
|
||||||
ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Type") << tr("Checksum"));
|
ui->fitTableWidget->setHorizontalHeaderLabels(QStringList() << tr("Address") << tr("Size") << tr("Version") << tr("Checksum") << tr("Type"));
|
||||||
ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
ui->fitTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
ui->fitTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
ui->fitTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "../common/utility.h"
|
#include "../common/utility.h"
|
||||||
#include "../common/ffs.h"
|
#include "../common/ffs.h"
|
||||||
#include "../common/ffsparser.h"
|
#include "../common/ffsparser.h"
|
||||||
#include "../common/fitparser.h"
|
|
||||||
#include "../common/ffsops.h"
|
#include "../common/ffsops.h"
|
||||||
#include "../common/ffsbuilder.h"
|
#include "../common/ffsbuilder.h"
|
||||||
|
|
||||||
@ -109,7 +108,6 @@ private:
|
|||||||
Ui::UEFITool* ui;
|
Ui::UEFITool* ui;
|
||||||
TreeModel* model;
|
TreeModel* model;
|
||||||
FfsParser* ffsParser;
|
FfsParser* ffsParser;
|
||||||
FitParser* fitParser;
|
|
||||||
FfsFinder* ffsFinder;
|
FfsFinder* ffsFinder;
|
||||||
FfsOperations* ffsOps;
|
FfsOperations* ffsOps;
|
||||||
FfsBuilder* ffsBuilder;
|
FfsBuilder* ffsBuilder;
|
||||||
@ -128,7 +126,6 @@ private:
|
|||||||
void readSettings();
|
void readSettings();
|
||||||
void showParserMessages();
|
void showParserMessages();
|
||||||
void showFinderMessages();
|
void showFinderMessages();
|
||||||
void showFitMessages();
|
|
||||||
void showFitTable();
|
void showFitTable();
|
||||||
void showBuilderMessages();
|
void showBuilderMessages();
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,6 @@ HEADERS += uefitool.h \
|
|||||||
../common/parsingdata.h \
|
../common/parsingdata.h \
|
||||||
../common/ffsbuilder.h \
|
../common/ffsbuilder.h \
|
||||||
../common/ffsparser.h \
|
../common/ffsparser.h \
|
||||||
../common/fitparser.h \
|
|
||||||
../common/treeitem.h \
|
../common/treeitem.h \
|
||||||
../common/treemodel.h \
|
../common/treemodel.h \
|
||||||
../common/LZMA/LzmaCompress.h \
|
../common/LZMA/LzmaCompress.h \
|
||||||
@ -53,7 +52,6 @@ SOURCES += uefitool_main.cpp \
|
|||||||
../common/utility.cpp \
|
../common/utility.cpp \
|
||||||
../common/ffsbuilder.cpp \
|
../common/ffsbuilder.cpp \
|
||||||
../common/ffsparser.cpp \
|
../common/ffsparser.cpp \
|
||||||
../common/fitparser.cpp \
|
|
||||||
../common/treeitem.cpp \
|
../common/treeitem.cpp \
|
||||||
../common/treemodel.cpp \
|
../common/treemodel.cpp \
|
||||||
../common/LZMA/LzmaCompress.c \
|
../common/LZMA/LzmaCompress.c \
|
||||||
|
@ -199,11 +199,6 @@
|
|||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QTableWidget" name="fitTableWidget"/>
|
<widget class="QTableWidget" name="fitTableWidget"/>
|
||||||
<widget class="QListWidget" name="fitMessagesListWidget">
|
|
||||||
<property name="mouseTracking">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -2853,7 +2853,7 @@ USTATUS FfsParser::parseTeImageSectionBody(const UModelIndex & index)
|
|||||||
usprintf("\nNumber of sections: %u\nSubsystem: %02Xh\nStripped size: %Xh (%u)\n"
|
usprintf("\nNumber of sections: %u\nSubsystem: %02Xh\nStripped size: %Xh (%u)\n"
|
||||||
"Base of code: %Xh\nAddress of entry point: %Xh\nImage base: %" PRIX64 "h\nAdjusted image base: %" PRIX64 "h",
|
"Base of code: %Xh\nAddress of entry point: %Xh\nImage base: %" PRIX64 "h\nAdjusted image base: %" PRIX64 "h",
|
||||||
teHeader->NumberOfSections,
|
teHeader->NumberOfSections,
|
||||||
teHeader->Subsystem,
|
teHeader->Subsystem,
|
||||||
teHeader->StrippedSize, teHeader->StrippedSize,
|
teHeader->StrippedSize, teHeader->StrippedSize,
|
||||||
teHeader->BaseOfCode,
|
teHeader->BaseOfCode,
|
||||||
teHeader->AddressOfEntryPoint,
|
teHeader->AddressOfEntryPoint,
|
||||||
@ -2887,7 +2887,7 @@ USTATUS FfsParser::performSecondPass(const UModelIndex & index)
|
|||||||
msg(UString("performSecondPass: the last VTF appears inside compressed item, the image may be damaged"), lastVtf);
|
msg(UString("performSecondPass: the last VTF appears inside compressed item, the image may be damaged"), lastVtf);
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get parsing data for the last VTF
|
// Get parsing data for the last VTF
|
||||||
PARSING_DATA pdata = parsingDataFromUModelIndex(lastVtf);
|
PARSING_DATA pdata = parsingDataFromUModelIndex(lastVtf);
|
||||||
|
|
||||||
@ -2895,9 +2895,168 @@ USTATUS FfsParser::performSecondPass(const UModelIndex & index)
|
|||||||
const UINT32 vtfSize = model->header(lastVtf).size() + model->body(lastVtf).size() + model->tail(lastVtf).size();
|
const UINT32 vtfSize = model->header(lastVtf).size() + model->body(lastVtf).size() + model->tail(lastVtf).size();
|
||||||
const UINT32 diff = 0xFFFFFFFFUL - pdata.offset - vtfSize + 1;
|
const UINT32 diff = 0xFFFFFFFFUL - pdata.offset - vtfSize + 1;
|
||||||
|
|
||||||
|
// Find and parse FIT
|
||||||
|
parseFit(index, diff);
|
||||||
|
|
||||||
// Apply address information to index and all it's child items
|
// Apply address information to index and all it's child items
|
||||||
addMemoryAddressesRecursive(index, diff);
|
addMemoryAddressesRecursive(index, diff);
|
||||||
|
|
||||||
|
// Add fixed and compressed
|
||||||
|
addFixedAndCompressedRecursive(index);
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS FfsParser::addFixedAndCompressedRecursive(const UModelIndex & index) {
|
||||||
|
// Sanity check
|
||||||
|
if (!index.isValid())
|
||||||
|
return U_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
// Get parsing data for the current item
|
||||||
|
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
|
||||||
|
|
||||||
|
// Add fixed and compressed info
|
||||||
|
model->addInfo(index, usprintf("\nCompressed: %s", model->compressed(index) ? "Yes" : "No"));
|
||||||
|
model->addInfo(index, usprintf("\nFixed: %s", model->fixed(index) ? "Yes" : "No"));
|
||||||
|
|
||||||
|
// Process child items
|
||||||
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
|
addFixedAndCompressedRecursive(index.child(i, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS FfsParser::parseFit(const UModelIndex & index, const UINT32 diff)
|
||||||
|
{
|
||||||
|
// Check sanity
|
||||||
|
if (!index.isValid())
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
// Search for FIT
|
||||||
|
UModelIndex fitIndex;
|
||||||
|
UINT32 fitOffset;
|
||||||
|
USTATUS result = findFitRecursive(index, diff, fitIndex, fitOffset);
|
||||||
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// FIT not found
|
||||||
|
if (!fitIndex.isValid())
|
||||||
|
return U_SUCCESS;
|
||||||
|
|
||||||
|
// Explicitly set the item as fixed
|
||||||
|
model->setFixed(fitIndex, true);
|
||||||
|
|
||||||
|
// Special case of FIT header
|
||||||
|
UByteArray fitBody = model->body(fitIndex);
|
||||||
|
const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(fitBody.constData() + fitOffset);
|
||||||
|
|
||||||
|
// Check FIT checksum, if present
|
||||||
|
UINT32 fitSize = (fitHeader->Size & 0xFFFFFF) << 4;
|
||||||
|
if (fitHeader->Type & 0x80) {
|
||||||
|
// Calculate FIT entry checksum
|
||||||
|
UByteArray tempFIT = model->body(fitIndex).mid(fitOffset, fitSize);
|
||||||
|
FIT_ENTRY* tempFitHeader = (FIT_ENTRY*)tempFIT.data();
|
||||||
|
tempFitHeader->Checksum = 0;
|
||||||
|
UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize);
|
||||||
|
if (calculated != fitHeader->Checksum) {
|
||||||
|
msg(usprintf("Invalid FIT table checksum %02Xh, should be %02Xh", fitHeader->Checksum, calculated), fitIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check fit header type
|
||||||
|
if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) {
|
||||||
|
msg(("Invalid FIT header type"), fitIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add FIT header to fitTable
|
||||||
|
std::vector<UString> currentStrings;
|
||||||
|
currentStrings.push_back(UString("_FIT_ "));
|
||||||
|
currentStrings.push_back(usprintf("%08Xh", fitSize));
|
||||||
|
currentStrings.push_back(usprintf("%04Xh", fitHeader->Version));
|
||||||
|
currentStrings.push_back(usprintf("%02Xh", fitHeader->Checksum));
|
||||||
|
currentStrings.push_back(fitEntryTypeToUString(fitHeader->Type));
|
||||||
|
fitTable.push_back(currentStrings);
|
||||||
|
|
||||||
|
// Process all other entries
|
||||||
|
bool msgModifiedImageMayNotWork = false;
|
||||||
|
for (UINT32 i = 1; i < fitHeader->Size; i++) {
|
||||||
|
currentStrings.clear();
|
||||||
|
const FIT_ENTRY* currentEntry = fitHeader + i;
|
||||||
|
|
||||||
|
// Check entry type
|
||||||
|
switch (currentEntry->Type & 0x7F) {
|
||||||
|
case FIT_TYPE_HEADER:
|
||||||
|
msg(UString("Second FIT header found, the table is damaged"), fitIndex);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIT_TYPE_EMPTY:
|
||||||
|
case FIT_TYPE_MICROCODE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIT_TYPE_BIOS_AC_MODULE:
|
||||||
|
case FIT_TYPE_BIOS_INIT_MODULE:
|
||||||
|
case FIT_TYPE_TPM_POLICY:
|
||||||
|
case FIT_TYPE_BIOS_POLICY_DATA:
|
||||||
|
case FIT_TYPE_TXT_CONF_POLICY:
|
||||||
|
case FIT_TYPE_AC_KEY_MANIFEST:
|
||||||
|
case FIT_TYPE_AC_BOOT_POLICY:
|
||||||
|
default:
|
||||||
|
msgModifiedImageMayNotWork = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add entry to fitTable
|
||||||
|
currentStrings.push_back(usprintf("%016" PRIX64, currentEntry->Address));
|
||||||
|
currentStrings.push_back(usprintf("%08Xh", currentEntry->Size, currentEntry->Size));
|
||||||
|
currentStrings.push_back(usprintf("%04Xh", currentEntry->Version));
|
||||||
|
currentStrings.push_back(usprintf("%02Xh", currentEntry->Checksum));
|
||||||
|
currentStrings.push_back(fitEntryTypeToUString(currentEntry->Type));
|
||||||
|
fitTable.push_back(currentStrings);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msgModifiedImageMayNotWork)
|
||||||
|
msg(UString("Opened image may not work after any modification"), fitIndex);
|
||||||
|
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
USTATUS FfsParser::findFitRecursive(const UModelIndex & index, const UINT32 diff, UModelIndex & found, UINT32 & fitOffset)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (!index.isValid())
|
||||||
|
return U_SUCCESS;
|
||||||
|
|
||||||
|
// Process child items
|
||||||
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
|
findFitRecursive(index.child(i, 0), diff, found, fitOffset);
|
||||||
|
if (found.isValid())
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get parsing data for the current item
|
||||||
|
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
|
||||||
|
|
||||||
|
// Check for all FIT signatures in item's body
|
||||||
|
UByteArray lastVtfBody = model->body(lastVtf);
|
||||||
|
UINT32 storedFitAddress = *(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET);
|
||||||
|
for (INT32 offset = model->body(index).indexOf(FIT_SIGNATURE);
|
||||||
|
offset >= 0;
|
||||||
|
offset = model->body(index).indexOf(FIT_SIGNATURE, offset + 1)) {
|
||||||
|
// FIT candidate found, calculate it's physical address
|
||||||
|
UINT32 fitAddress = pdata.offset + diff + model->header(index).size() + (UINT32)offset;
|
||||||
|
|
||||||
|
// Check FIT address to be stored in the last VTF
|
||||||
|
if (fitAddress == storedFitAddress) {
|
||||||
|
found = index;
|
||||||
|
fitOffset = offset;
|
||||||
|
msg(usprintf("Real FIT table found at physical address %08Xh", fitAddress), found);
|
||||||
|
return U_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (model->rowCount(index) == 0) // Show messages only to leaf items
|
||||||
|
msg(UString("FIT table candidate found, but not referenced from the last VTF"), index);
|
||||||
|
}
|
||||||
|
|
||||||
return U_SUCCESS;
|
return U_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2968,10 +3127,6 @@ USTATUS FfsParser::addOffsetsRecursive(const UModelIndex & index)
|
|||||||
model->addInfo(index, usprintf("Offset: %Xh\n", pdata.offset), false);
|
model->addInfo(index, usprintf("Offset: %Xh\n", pdata.offset), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: show FIT file fixed attribute correctly
|
|
||||||
model->addInfo(index, usprintf("\nCompressed: %s", model->compressed(index) ? "Yes" : "No"));
|
|
||||||
model->addInfo(index, usprintf("\nFixed: %s", model->fixed(index) ? "Yes" : "No"));
|
|
||||||
|
|
||||||
// Process child items
|
// Process child items
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
for (int i = 0; i < model->rowCount(index); i++) {
|
||||||
addOffsetsRecursive(index.child(i, 0));
|
addOffsetsRecursive(index.child(i, 0));
|
||||||
|
@ -48,8 +48,8 @@ public:
|
|||||||
// Firmware image parsing
|
// Firmware image parsing
|
||||||
USTATUS parse(const UByteArray &buffer);
|
USTATUS parse(const UByteArray &buffer);
|
||||||
|
|
||||||
// Retuns index of the last VTF after parsing is done
|
// Obtain parsed FIT table
|
||||||
const UModelIndex getLastVtf() {return lastVtf;};
|
std::vector<std::vector<UString> > getFitTable() const { return fitTable; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TreeModel *model;
|
TreeModel *model;
|
||||||
@ -60,6 +60,10 @@ private:
|
|||||||
|
|
||||||
UModelIndex lastVtf;
|
UModelIndex lastVtf;
|
||||||
UINT32 capsuleOffsetFixup;
|
UINT32 capsuleOffsetFixup;
|
||||||
|
std::vector<std::vector<UString> > fitTable;
|
||||||
|
|
||||||
|
// First pass
|
||||||
|
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
|
||||||
|
|
||||||
USTATUS parseRawArea(const UModelIndex & index);
|
USTATUS parseRawArea(const UModelIndex & index);
|
||||||
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index);
|
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 parentOffset, const UModelIndex & parent, UModelIndex & index);
|
||||||
@ -103,11 +107,6 @@ private:
|
|||||||
UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
|
UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
|
||||||
UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
|
UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
|
||||||
|
|
||||||
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
|
|
||||||
USTATUS performSecondPass(const UModelIndex & index);
|
|
||||||
USTATUS addOffsetsRecursive(const UModelIndex & index);
|
|
||||||
USTATUS addMemoryAddressesRecursive(const UModelIndex & index, const UINT32 diff);
|
|
||||||
|
|
||||||
// NVRAM parsing
|
// NVRAM parsing
|
||||||
USTATUS parseNvramVolumeBody(const UModelIndex & index);
|
USTATUS parseNvramVolumeBody(const UModelIndex & index);
|
||||||
USTATUS findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset);
|
USTATUS findNextStore(const UModelIndex & index, const UByteArray & volume, const UINT32 parentOffset, const UINT32 storeOffset, UINT32 & nextStoreOffset);
|
||||||
@ -130,6 +129,14 @@ private:
|
|||||||
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);
|
||||||
|
|
||||||
|
// Second pass
|
||||||
|
USTATUS performSecondPass(const UModelIndex & index);
|
||||||
|
USTATUS addOffsetsRecursive(const UModelIndex & index);
|
||||||
|
USTATUS addMemoryAddressesRecursive(const UModelIndex & index, const UINT32 diff);
|
||||||
|
USTATUS addFixedAndCompressedRecursive(const UModelIndex & index);
|
||||||
|
USTATUS parseFit(const UModelIndex & index, const UINT32 diff);
|
||||||
|
USTATUS findFitRecursive(const UModelIndex & index, const UINT32 diff, UModelIndex & found, UINT32 & fitOffset);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FFSPARSER_H
|
#endif // FFSPARSER_H
|
||||||
|
@ -1,164 +0,0 @@
|
|||||||
/* fitparser.cpp
|
|
||||||
|
|
||||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
*/
|
|
||||||
#include "fitparser.h"
|
|
||||||
|
|
||||||
USTATUS FitParser::parse(const UModelIndex & index, const UModelIndex & lastVtfIndex)
|
|
||||||
{
|
|
||||||
// Check sanity
|
|
||||||
if (!index.isValid() || !lastVtfIndex.isValid())
|
|
||||||
return EFI_INVALID_PARAMETER;
|
|
||||||
|
|
||||||
// Store lastVtfIndex
|
|
||||||
lastVtf = lastVtfIndex;
|
|
||||||
|
|
||||||
// Search for FIT
|
|
||||||
UModelIndex fitIndex;
|
|
||||||
UINT32 fitOffset;
|
|
||||||
USTATUS result = findFitRecursive(index, fitIndex, fitOffset);
|
|
||||||
if (result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// FIT not found
|
|
||||||
if (!fitIndex.isValid())
|
|
||||||
return U_SUCCESS;
|
|
||||||
|
|
||||||
// Explicitly set the item as fixed
|
|
||||||
model->setFixed(index, true);
|
|
||||||
|
|
||||||
// Special case of FIT header
|
|
||||||
UByteArray fitBody = model->body(fitIndex);
|
|
||||||
const FIT_ENTRY* fitHeader = (const FIT_ENTRY*)(fitBody.constData() + fitOffset);
|
|
||||||
|
|
||||||
// Check FIT checksum, if present
|
|
||||||
UINT32 fitSize = (fitHeader->Size & 0xFFFFFF) << 4;
|
|
||||||
if (fitHeader->Type & 0x80) {
|
|
||||||
// Calculate FIT entry checksum
|
|
||||||
UByteArray tempFIT = model->body(fitIndex).mid(fitOffset, fitSize);
|
|
||||||
FIT_ENTRY* tempFitHeader = (FIT_ENTRY*)tempFIT.data();
|
|
||||||
tempFitHeader->Checksum = 0;
|
|
||||||
UINT8 calculated = calculateChecksum8((const UINT8*)tempFitHeader, fitSize);
|
|
||||||
if (calculated != fitHeader->Checksum) {
|
|
||||||
msg(usprintf("Invalid FIT table checksum %02Xh, should be %02Xh", fitHeader->Checksum, calculated), fitIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check fit header type
|
|
||||||
if ((fitHeader->Type & 0x7F) != FIT_TYPE_HEADER) {
|
|
||||||
msg(("Invalid FIT header type"), fitIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add FIT header to fitTable
|
|
||||||
std::vector<UString> currentStrings;
|
|
||||||
currentStrings.push_back(UString("_FIT_ "));
|
|
||||||
currentStrings.push_back(usprintf("%08X", fitSize));
|
|
||||||
currentStrings.push_back(usprintf("%04X", fitHeader->Version));
|
|
||||||
currentStrings.push_back(fitEntryTypeToUString(fitHeader->Type));
|
|
||||||
currentStrings.push_back(usprintf("%02X", fitHeader->Checksum));
|
|
||||||
fitTable.push_back(currentStrings);
|
|
||||||
|
|
||||||
// Process all other entries
|
|
||||||
bool msgModifiedImageMayNotWork = false;
|
|
||||||
for (UINT32 i = 1; i < fitHeader->Size; i++) {
|
|
||||||
currentStrings.clear();
|
|
||||||
const FIT_ENTRY* currentEntry = fitHeader + i;
|
|
||||||
|
|
||||||
// Check entry type
|
|
||||||
switch (currentEntry->Type & 0x7F) {
|
|
||||||
case FIT_TYPE_HEADER:
|
|
||||||
msg(UString("Second FIT header found, the table is damaged"), fitIndex);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIT_TYPE_EMPTY:
|
|
||||||
case FIT_TYPE_MICROCODE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FIT_TYPE_BIOS_AC_MODULE:
|
|
||||||
case FIT_TYPE_BIOS_INIT_MODULE:
|
|
||||||
case FIT_TYPE_TPM_POLICY:
|
|
||||||
case FIT_TYPE_BIOS_POLICY_DATA:
|
|
||||||
case FIT_TYPE_TXT_CONF_POLICY:
|
|
||||||
case FIT_TYPE_AC_KEY_MANIFEST:
|
|
||||||
case FIT_TYPE_AC_BOOT_POLICY:
|
|
||||||
default:
|
|
||||||
msgModifiedImageMayNotWork = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add entry to fitTable
|
|
||||||
currentStrings.push_back(usprintf("%016X",currentEntry->Address));
|
|
||||||
currentStrings.push_back(usprintf("%08X", currentEntry->Size));
|
|
||||||
currentStrings.push_back(usprintf("%04X", currentEntry->Version));
|
|
||||||
currentStrings.push_back(fitEntryTypeToUString(currentEntry->Type));
|
|
||||||
currentStrings.push_back(usprintf("%02X", currentEntry->Checksum));
|
|
||||||
fitTable.push_back(currentStrings);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msgModifiedImageMayNotWork)
|
|
||||||
msg(("Opened image may not work after any modification"));
|
|
||||||
|
|
||||||
return U_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
UString FitParser::fitEntryTypeToUString(UINT8 type)
|
|
||||||
{
|
|
||||||
switch (type & 0x7F) {
|
|
||||||
case FIT_TYPE_HEADER: return ("Header ");
|
|
||||||
case FIT_TYPE_MICROCODE: return ("Microcode ");
|
|
||||||
case FIT_TYPE_BIOS_AC_MODULE: return ("BIOS ACM ");
|
|
||||||
case FIT_TYPE_BIOS_INIT_MODULE: return ("BIOS Init ");
|
|
||||||
case FIT_TYPE_TPM_POLICY: return ("TPM Policy ");
|
|
||||||
case FIT_TYPE_BIOS_POLICY_DATA: return ("BIOS Policy Data ");
|
|
||||||
case FIT_TYPE_TXT_CONF_POLICY: return ("TXT Configuration Policy");
|
|
||||||
case FIT_TYPE_AC_KEY_MANIFEST: return ("BootGuard Key Manifest ");
|
|
||||||
case FIT_TYPE_AC_BOOT_POLICY: return ("BootGuard Boot Policy ");
|
|
||||||
case FIT_TYPE_EMPTY: return ("Empty ");
|
|
||||||
default: return ("Unknown ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
USTATUS FitParser::findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset)
|
|
||||||
{
|
|
||||||
// Sanity check
|
|
||||||
if (!index.isValid())
|
|
||||||
return U_SUCCESS;
|
|
||||||
|
|
||||||
// Process child items
|
|
||||||
for (int i = 0; i < model->rowCount(index); i++) {
|
|
||||||
findFitRecursive(index.child(i, 0), found, fitOffset);
|
|
||||||
if (found.isValid())
|
|
||||||
return U_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get parsing data for the current item
|
|
||||||
PARSING_DATA pdata = parsingDataFromUModelIndex(index);
|
|
||||||
|
|
||||||
// Check for all FIT signatures in item's body
|
|
||||||
for (INT32 offset = model->body(index).indexOf(FIT_SIGNATURE);
|
|
||||||
offset >= 0;
|
|
||||||
offset = model->body(index).indexOf(FIT_SIGNATURE, offset + 1)) {
|
|
||||||
// FIT candidate found, calculate it's physical address
|
|
||||||
UINT32 fitAddress = pdata.address + model->header(index).size() + (UINT32)offset;
|
|
||||||
|
|
||||||
// Check FIT address to be in the last VTF
|
|
||||||
UByteArray lastVtfBody = model->body(lastVtf);
|
|
||||||
if (*(const UINT32*)(lastVtfBody.constData() + lastVtfBody.size() - FIT_POINTER_OFFSET) == fitAddress) {
|
|
||||||
found = index;
|
|
||||||
fitOffset = offset;
|
|
||||||
msg(usprintf("Real FIT table found at physical address %Xh", fitAddress), found);
|
|
||||||
return U_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (model->rowCount(index) == 0) // Show messages only to leaf items
|
|
||||||
msg(("FIT table candidate found, but not referenced from the last VTF"), index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return U_SUCCESS;
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/* fitparser.h
|
|
||||||
|
|
||||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
|
||||||
This program and the accompanying materials
|
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
|
||||||
http://opensource.org/licenses/bsd-license.php
|
|
||||||
|
|
||||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
||||||
WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FITPARSER_H
|
|
||||||
#define FITPARSER_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "ustring.h"
|
|
||||||
#include "ubytearray.h"
|
|
||||||
#include "treemodel.h"
|
|
||||||
#include "utility.h"
|
|
||||||
#include "parsingdata.h"
|
|
||||||
#include "fit.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "treemodel.h"
|
|
||||||
|
|
||||||
class TreeModel;
|
|
||||||
|
|
||||||
class FitParser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Default constructor and destructor
|
|
||||||
FitParser(TreeModel* treeModel) : model(treeModel) {}
|
|
||||||
~FitParser() {}
|
|
||||||
|
|
||||||
// Returns messages
|
|
||||||
std::vector<std::pair<UString, UModelIndex> > getMessages() const { return messagesVector; };
|
|
||||||
// Clears messages
|
|
||||||
void clearMessages() { messagesVector.clear(); }
|
|
||||||
|
|
||||||
USTATUS parse(const UModelIndex & index, const UModelIndex & lastVtf);
|
|
||||||
std::vector<std::vector<UString> > getFitTable() const { return fitTable; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
TreeModel *model;
|
|
||||||
std::vector<std::pair<UString, UModelIndex> > messagesVector;
|
|
||||||
UModelIndex lastVtf;
|
|
||||||
std::vector<std::vector<UString> > fitTable;
|
|
||||||
|
|
||||||
USTATUS findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset);
|
|
||||||
UString fitEntryTypeToUString(UINT8 type);
|
|
||||||
|
|
||||||
// Message helper
|
|
||||||
void msg(const UString & message, const UModelIndex &index = UModelIndex()) {
|
|
||||||
messagesVector.push_back(std::pair<UString, UModelIndex>(message, index));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FITPARSER_H
|
|
@ -13,6 +13,7 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
#include "ustring.h"
|
#include "ustring.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "ffs.h"
|
#include "ffs.h"
|
||||||
|
#include "fit.h"
|
||||||
|
|
||||||
UString regionTypeToUString(const UINT8 type)
|
UString regionTypeToUString(const UINT8 type)
|
||||||
{
|
{
|
||||||
@ -161,4 +162,21 @@ UString actionTypeToUString(const UINT8 action)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return UString("Unknown");
|
return UString("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
UString fitEntryTypeToUString(const UINT8 type)
|
||||||
|
{
|
||||||
|
switch (type & 0x7F) {
|
||||||
|
case FIT_TYPE_HEADER: return ("FIT Header ");
|
||||||
|
case FIT_TYPE_MICROCODE: return ("Microcode ");
|
||||||
|
case FIT_TYPE_BIOS_AC_MODULE: return ("BIOS ACM ");
|
||||||
|
case FIT_TYPE_BIOS_INIT_MODULE: return ("BIOS Init ");
|
||||||
|
case FIT_TYPE_TPM_POLICY: return ("TPM Policy ");
|
||||||
|
case FIT_TYPE_BIOS_POLICY_DATA: return ("BIOS Policy Data ");
|
||||||
|
case FIT_TYPE_TXT_CONF_POLICY: return ("TXT Configuration Policy");
|
||||||
|
case FIT_TYPE_AC_KEY_MANIFEST: return ("BootGuard Key Manifest ");
|
||||||
|
case FIT_TYPE_AC_BOOT_POLICY: return ("BootGuard Boot Policy ");
|
||||||
|
case FIT_TYPE_EMPTY: return ("Empty ");
|
||||||
|
default: return ("Unknown ");
|
||||||
|
}
|
||||||
}
|
}
|
@ -144,5 +144,6 @@ extern UString itemTypeToUString(const UINT8 type);
|
|||||||
extern UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype);
|
extern UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype);
|
||||||
extern UString compressionTypeToUString(const UINT8 algorithm);
|
extern UString compressionTypeToUString(const UINT8 algorithm);
|
||||||
extern UString regionTypeToUString(const UINT8 type);
|
extern UString regionTypeToUString(const UINT8 type);
|
||||||
|
extern UString fitEntryTypeToUString(const UINT8 type);
|
||||||
|
|
||||||
#endif // TYPES_H
|
#endif // TYPES_H
|
||||||
|
@ -113,14 +113,14 @@ class QHexEdit : public QAbstractScrollArea
|
|||||||
*/
|
*/
|
||||||
Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor)
|
Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor)
|
||||||
|
|
||||||
/*! Porperty readOnly sets (setReadOnly()) or gets (isReadOnly) the mode
|
/*! Property readOnly sets (setReadOnly()) or gets (isReadOnly) the mode
|
||||||
in which the editor works. In readonly mode the the user can only navigate
|
in which the editor works. In readonly mode the the user can only navigate
|
||||||
through the data and select data; modifying is not possible. This
|
through the data and select data; modifying is not possible. This
|
||||||
property's default is false.
|
property's default is false.
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
|
Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly)
|
||||||
|
|
||||||
/*! Porperty upperCase sets (setUpperCase()) or gets (isUpperCase) the case of hex
|
/*! Property upperCase sets (setUpperCase()) or gets (isUpperCase) the case of hex
|
||||||
data. Default is lowercase.
|
data. Default is lowercase.
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(bool upperCase READ isUpperCase WRITE setUpperCase)
|
Q_PROPERTY(bool upperCase READ isUpperCase WRITE setUpperCase)
|
||||||
|
Loading…
Reference in New Issue
Block a user