mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-02-13 15:22:42 +08:00
UT NE A25
- support for Phoenix SCT FlashMap - support for Apple Gaid stores - UI for EVSA and FlashMap store and entries - small fixes
This commit is contained in:
parent
d6909fe9b6
commit
1100cead24
@ -17,7 +17,7 @@
|
||||
UEFITool::UEFITool(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::UEFITool),
|
||||
version(tr("0.30.0_alpha24"))
|
||||
version(tr("0.30.0_alpha25"))
|
||||
{
|
||||
clipboard = QApplication::clipboard();
|
||||
|
||||
@ -172,8 +172,10 @@ void UEFITool::populateUi(const QModelIndex ¤t)
|
||||
ui->menuVolumeActions->setEnabled(type == Types::Volume);
|
||||
ui->menuFileActions->setEnabled(type == Types::File);
|
||||
ui->menuSectionActions->setEnabled(type == Types::Section);
|
||||
ui->menuVariableActions->setEnabled(type == Types::NvramVariableNvar || type == Types::NvramVariableVss || type == Types::NvramVariableFsys);
|
||||
ui->menuStoreActions->setEnabled(type == Types::NvramStoreVss || type == Types::NvramStoreFdc || type == Types::NvramStoreFsys || type == Types::NvramStoreEvsa || type == Types::NvramFtwBlock);
|
||||
ui->menuVariableActions->setEnabled(type == Types::NvramVariableNvar || type == Types::NvramVariableVss || type == Types::NvramEntryFsys
|
||||
|| type == Types::NvramEntryEvsa || type == Types::NvramEntryFlashMap);
|
||||
ui->menuStoreActions->setEnabled(type == Types::NvramStoreVss || type == Types::NvramStoreFdc || type == Types::NvramStoreFsys
|
||||
|| type == Types::NvramStoreEvsa || type == Types::NvramStoreFtw || type == Types::NvramStoreFlashMap);
|
||||
|
||||
// Enable actions
|
||||
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current));
|
||||
@ -537,12 +539,25 @@ void UEFITool::extract(const UINT8 mode)
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save section to file"), name + ".sct", "Section files (*.sct *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramVariableNvar:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save NVAR variable to file"), name + ".nvar", "NVAR variable files (*.nvar *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramVariableVss:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save variable to file"), name + ".var", "Variable files (*.var *.bin);;All files (*)");
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save VSS variable to file"), name + ".var", "VSS variable files (*.var *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramEntryFsys:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save Fsys entry to file"), name + ".fse", "Fsys entry files (*.fse *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramEntryEvsa:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save EVSA entry to file"), name + ".evse", "EVSA entry files (*.evse *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramEntryFlashMap:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FlashMap entry to file"), name + ".fme", "FlashMap entry files (*.fme *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramStoreVss:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save VSS store to file"), name + ".vss", "VSS store files (*.vss *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramStoreFdc:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save variable store to file"), name + ".vss", "Variable store files (*.vss *.bin);;All files (*)");
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FDC store to file"), name + ".fdc", "FDC store files (*.fdc *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramStoreFsys:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save Fsys store to file"), name + ".fsys", "Fsys store files (*.fsys *.bin);;All files (*)");
|
||||
@ -550,8 +565,11 @@ void UEFITool::extract(const UINT8 mode)
|
||||
case Types::NvramStoreEvsa:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save EVSA store to file"), name + ".evsa", "EVSA store files (*.evsa *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramFtwBlock:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FTW block to file"), name + ".ftw", "FTW block files (*.ftw *.bin);;All files (*)");
|
||||
case Types::NvramStoreFtw:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FTW store to file"), name + ".ftw", "FTW store files (*.ftw *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramStoreFlashMap:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store to file"), name + ".fmap", "FlashMap store files (*.fmap *.bin);;All files (*)");
|
||||
break;
|
||||
default:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)");
|
||||
@ -587,11 +605,12 @@ void UEFITool::extract(const UINT8 mode)
|
||||
break;
|
||||
case Types::NvramVariableNvar:
|
||||
case Types::NvramVariableVss:
|
||||
case Types::NvramEntryEvsa:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save variable body to file"), name + ".bin", "Binary files (*.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramStoreVss:
|
||||
case Types::NvramStoreFdc:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save variable store body to file"), name + ".vsb", "Variable store body files (*.vsb *.bin);;All files (*)");
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save VSS variable store body to file"), name + ".vsb", "VSS variable store body files (*.vsb *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramStoreFsys:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save Fsys store body to file"), name + ".fsb", "Fsys store body files (*.fsb *.bin);;All files (*)");
|
||||
@ -599,8 +618,11 @@ void UEFITool::extract(const UINT8 mode)
|
||||
case Types::NvramStoreEvsa:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save EVSA store body to file"), name + ".esb", "EVSA store body files (*.esb *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramFtwBlock:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FTW block body to file"), name + ".ftb", "FTW block body files (*.ftb *.bin);;All files (*)");
|
||||
case Types::NvramStoreFtw:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FTW store body to file"), name + ".ftb", "FTW store body files (*.ftb *.bin);;All files (*)");
|
||||
break;
|
||||
case Types::NvramStoreFlashMap:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save FlashMap store body to file"), name + ".fmb", "FlashMap store body files (*.fmb *.bin);;All files (*)");
|
||||
break;
|
||||
default:
|
||||
path = QFileDialog::getSaveFileName(this, tr("Save object to file"), name + ".bin", "Binary files (*.bin);;All files (*)");
|
||||
@ -962,14 +984,17 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||
break;
|
||||
case Types::NvramVariableNvar:
|
||||
case Types::NvramVariableVss:
|
||||
case Types::NvramVariableFsys:
|
||||
case Types::NvramEntryFsys:
|
||||
case Types::NvramEntryEvsa:
|
||||
case Types::NvramEntryFlashMap:
|
||||
ui->menuVariableActions->exec(event->globalPos());
|
||||
break;
|
||||
case Types::NvramStoreVss:
|
||||
case Types::NvramStoreFdc:
|
||||
case Types::NvramStoreFsys:
|
||||
case Types::NvramStoreEvsa:
|
||||
case Types::NvramFtwBlock:
|
||||
case Types::NvramStoreFtw:
|
||||
case Types::NvramStoreFlashMap:
|
||||
ui->menuStoreActions->exec(event->globalPos());
|
||||
break;
|
||||
}
|
||||
|
@ -59,27 +59,18 @@ STATUS FfsOperations::extract(const QModelIndex & index, QString & name, QByteAr
|
||||
case Types::NvramVariableNvar:
|
||||
case Types::NvramVariableVss:
|
||||
case Types::File: {
|
||||
name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_');
|
||||
name = itemText.isEmpty() ? itemName : itemText.replace(' ', '_').replace('-', '_');
|
||||
} break;
|
||||
case Types::Section: {
|
||||
// Get parent file name
|
||||
QModelIndex fileIndex = model->findParentOfType(index, Types::File);
|
||||
QString fileText = model->text(fileIndex);
|
||||
name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_');
|
||||
name = fileText.isEmpty() ? model->name(fileIndex) : fileText.replace(' ', '_').replace('-', '_');
|
||||
// Append section subtype name
|
||||
name += QChar('_') + itemName.replace(' ', '_');
|
||||
} break;
|
||||
case Types::Capsule:
|
||||
case Types::Image:
|
||||
case Types::Region:
|
||||
case Types::Padding:
|
||||
case Types::NvramStoreVss:
|
||||
case Types::NvramStoreFdc:
|
||||
case Types::NvramStoreFsys:
|
||||
case Types::NvramStoreEvsa:
|
||||
case Types::NvramFtwBlock:
|
||||
default:
|
||||
name = itemName.replace(' ', '_').replace('/', '_');
|
||||
name = itemName.replace(' ', '_').replace('/', '_').replace('-', '_');
|
||||
}
|
||||
|
||||
// Get extracted data
|
||||
|
@ -3366,7 +3366,10 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in
|
||||
case Types::NvramStoreEvsa:
|
||||
parseEvsaStoreBody(current);
|
||||
break;
|
||||
case Types::NvramFtwBlock:
|
||||
case Types::NvramStoreFlashMap:
|
||||
parseFlashMapBody(current);
|
||||
break;
|
||||
case Types::NvramStoreFtw:
|
||||
case Types::Padding:
|
||||
// No parsing required
|
||||
break;
|
||||
@ -3410,7 +3413,7 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da
|
||||
// All checks passed, store found
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE) { //Fsys signature found
|
||||
else if (*currentPos == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *currentPos == NVRAM_APPLE_GAID_STORE_SIGNATURE) { //Fsys or Gaid signature found
|
||||
const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)currentPos;
|
||||
if (fsysHeader->Size == 0 || fsysHeader->Size == 0xFFFF) {
|
||||
msg(QObject::tr("findNextStore: Fsys store candidate at offset %1h skipped, has invalid size %2h").hexarg(parentOffset + offset).hexarg2(fsysHeader->Size, 4), index);
|
||||
@ -3435,8 +3438,9 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da
|
||||
offset -= 4;
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1) { //Possible FTW block signature found
|
||||
if (QByteArray(data.constData() + offset, sizeof(EFI_GUID)) != NVRAM_MAIN_STORE_VOLUME_GUID) // Check the whole signature
|
||||
else if (*currentPos == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *currentPos == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { //Possible FTW block signature found
|
||||
QByteArray guid = QByteArray(data.constData() + offset, sizeof(EFI_GUID));
|
||||
if (guid != NVRAM_MAIN_STORE_VOLUME_GUID && guid != EDKII_WORKING_BLOCK_SIGNATURE_GUID) // Check the whole signature
|
||||
continue;
|
||||
|
||||
// Detect header variant based on WriteQueueSize
|
||||
@ -3460,6 +3464,14 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da
|
||||
// All checks passed, store found
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) {// Phoenix SCT flash map
|
||||
QByteArray signature = QByteArray(data.constData() + offset, NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH);
|
||||
if (signature != NVRAM_PHOENIX_FLASH_MAP_SIGNATURE) // Check the whole signature
|
||||
continue;
|
||||
|
||||
// All checks passed, store found
|
||||
break;
|
||||
}
|
||||
}
|
||||
// No more stores found
|
||||
if (offset >= dataSize - sizeof(UINT32))
|
||||
@ -3481,7 +3493,7 @@ STATUS FfsParser::getStoreSize(const QByteArray & data, const UINT32 storeOffset
|
||||
const FDC_VOLUME_HEADER* fdcHeader = (const FDC_VOLUME_HEADER*)signature;
|
||||
storeSize = fdcHeader->Size;
|
||||
}
|
||||
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE) {
|
||||
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) {
|
||||
const APPLE_FSYS_STORE_HEADER* fsysHeader = (const APPLE_FSYS_STORE_HEADER*)signature;
|
||||
storeSize = fsysHeader->Size;
|
||||
}
|
||||
@ -3489,7 +3501,7 @@ STATUS FfsParser::getStoreSize(const QByteArray & data, const UINT32 storeOffset
|
||||
const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)signature;
|
||||
storeSize = evsaHeader->StoreSize;
|
||||
}
|
||||
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1) {
|
||||
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) {
|
||||
const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32* ftwHeader = (const EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32*)signature;
|
||||
if (ftwHeader->WriteQueueSize % 0x10 == 0x04) { // Header with 32 bit WriteQueueSize
|
||||
storeSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32) + ftwHeader->WriteQueueSize;
|
||||
@ -3499,6 +3511,10 @@ STATUS FfsParser::getStoreSize(const QByteArray & data, const UINT32 storeOffset
|
||||
storeSize = sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64) + ftw64Header->WriteQueueSize;
|
||||
}
|
||||
}
|
||||
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) { // Phoenix SCT flash map
|
||||
const PHOENIX_FLASH_MAP_HEADER* flashMapHeader = (const PHOENIX_FLASH_MAP_HEADER*)signature;
|
||||
storeSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + sizeof(PHOENIX_FLASH_MAP_ENTRY) * flashMapHeader->NumEntries;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3516,7 +3532,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
|
||||
// VSS variable stores
|
||||
if (*signature == NVRAM_VSS_STORE_SIGNATURE || *signature == NVRAM_APPLE_SVS_STORE_SIGNATURE) {
|
||||
// The volume must begin with a store to be valid, but after the first one, there can be many variants
|
||||
// Check dataSize
|
||||
if (dataSize < sizeof(VSS_VARIABLE_STORE_HEADER)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for VSS store header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
@ -3528,8 +3544,8 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
// Check store size
|
||||
if (dataSize < vssStoreHeader->Size) {
|
||||
msg(QObject::tr("parseStoreHeader: VSS store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg2(vssStoreHeader->Size, 8).arg(vssStoreHeader->Size)
|
||||
.hexarg2(dataSize, 8).arg(dataSize), parent);
|
||||
.hexarg(vssStoreHeader->Size).arg(vssStoreHeader->Size)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3541,18 +3557,15 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
QByteArray body = store.mid(sizeof(VSS_VARIABLE_STORE_HEADER), vssStoreHeader->Size - sizeof(VSS_VARIABLE_STORE_HEADER));
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("VSS store");
|
||||
QString info = QObject::tr("Signature: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nFormat: %8h\nState: %9h")
|
||||
QString name = (*signature == NVRAM_APPLE_SVS_STORE_SIGNATURE) ? QObject::tr("SVS store") : QObject::tr("VSS store");
|
||||
QString info = QObject::tr("Signature: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nFormat: %8h\nState: %9h\nUnknown: %10h")
|
||||
.hexarg2(vssStoreHeader->Signature, 8)
|
||||
.hexarg(vssStoreHeader->Size).arg(vssStoreHeader->Size)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg(body.size()).arg(body.size())
|
||||
.hexarg2(vssStoreHeader->Format, 2)
|
||||
.hexarg2(vssStoreHeader->State, 2);
|
||||
|
||||
// Add unknown field for $SVS stores
|
||||
if (*signature == NVRAM_APPLE_SVS_STORE_SIGNATURE)
|
||||
info += QObject::tr("\nUnknown: %1h").hexarg2(vssStoreHeader->Unknown, 4);
|
||||
.hexarg2(vssStoreHeader->State, 2)
|
||||
.hexarg2(vssStoreHeader->Unknown, 4);
|
||||
|
||||
// Add correct offset
|
||||
pdata.offset = parentOffset;
|
||||
@ -3561,7 +3574,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
index = model->addItem(Types::NvramStoreVss, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*signature == NVRAM_FDC_VOLUME_SIGNATURE) {
|
||||
// The volume must begin with a store to be valid, but after the first one, there can be many variants
|
||||
// Check dataSize
|
||||
if (dataSize < sizeof(FDC_VOLUME_HEADER)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for FDC store header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
@ -3573,8 +3586,8 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
// Check store size
|
||||
if (dataSize < fdcStoreHeader->Size) {
|
||||
msg(QObject::tr("parseStoreHeader: FDC store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg2(fdcStoreHeader->Size, 8).arg(fdcStoreHeader->Size)
|
||||
.hexarg2(dataSize, 8).arg(dataSize), parent);
|
||||
.hexarg(fdcStoreHeader->Size).arg(fdcStoreHeader->Size)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3628,8 +3641,8 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
// Add tree item
|
||||
index = model->addItem(Types::NvramStoreFdc, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE) {
|
||||
// The volume must begin with a store to be valid, but after the first one, there can be many variants
|
||||
else if (*signature == NVRAM_APPLE_FSYS_STORE_SIGNATURE || *signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) {
|
||||
// Check dataSize
|
||||
if (dataSize < sizeof(APPLE_FSYS_STORE_HEADER)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for Fsys store header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
@ -3641,8 +3654,8 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
// Check store size
|
||||
if (dataSize < fsysStoreHeader->Size) {
|
||||
msg(QObject::tr("parseStoreHeader: Fsys store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg2(fsysStoreHeader->Size, 4).arg(fsysStoreHeader->Size)
|
||||
.hexarg2(dataSize, 8).arg(dataSize), parent);
|
||||
.hexarg(fsysStoreHeader->Size).arg(fsysStoreHeader->Size)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3658,7 +3671,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
UINT32 calculatedCrc = calculatedCrc = crc32(0, (const UINT8*)store.constData(), (const UINT32)store.size() - sizeof(UINT32));
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("Fsys store");
|
||||
QString name = (*signature == NVRAM_APPLE_GAID_STORE_SIGNATURE) ? QObject::tr("Gaid store") : QObject::tr("Fsys store");
|
||||
QString info = QObject::tr("Signature: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nUnknown: %9 %10 %11 %12 %13\nCRC32: %14")
|
||||
.hexarg2(fsysStoreHeader->Signature, 8)
|
||||
.hexarg(fsysStoreHeader->Size).arg(fsysStoreHeader->Size)
|
||||
@ -3678,7 +3691,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
index = model->addItem(Types::NvramStoreFsys, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*(signature + 1) == NVRAM_EVSA_STORE_SIGNATURE) {
|
||||
// The volume must begin with a store to be valid, but after the first one, there can be many variants
|
||||
// Check dataSize
|
||||
if (dataSize < sizeof(EVSA_STORE_ENTRY)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for EVSA store header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
@ -3690,8 +3703,8 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
// Check store size
|
||||
if (dataSize < evsaStoreHeader->StoreSize) {
|
||||
msg(QObject::tr("parseStoreHeader: EVSA store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg2(evsaStoreHeader->StoreSize, 4).arg(evsaStoreHeader->StoreSize)
|
||||
.hexarg2(dataSize, 8).arg(dataSize), parent);
|
||||
.hexarg(evsaStoreHeader->StoreSize).arg(evsaStoreHeader->StoreSize)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3724,8 +3737,8 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
// Add tree item
|
||||
index = model->addItem(Types::NvramStoreEvsa, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1) {
|
||||
// The volume must begin with a store to be valid, but after the first one, there can be many variants
|
||||
else if (*signature == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *signature == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) {
|
||||
// Check dataSize
|
||||
if (dataSize < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for FTW block header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
@ -3748,8 +3761,8 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
}
|
||||
if (dataSize < ftwBlockSize) {
|
||||
msg(QObject::tr("parseStoreHeader: FTW block size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg2(ftwBlockSize, 4).arg(ftwBlockSize)
|
||||
.hexarg2(dataSize, 8).arg(dataSize), parent);
|
||||
.hexarg(ftwBlockSize).arg(ftwBlockSize)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3784,7 +3797,46 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
pdata.offset = parentOffset;
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(Types::NvramFtwBlock, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
index = model->addItem(Types::NvramStoreFtw, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*signature == NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1) { // Phoenix SCT flash map
|
||||
if (dataSize < sizeof(PHOENIX_FLASH_MAP_HEADER)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for FlashMap block header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get FlashMap block header
|
||||
const PHOENIX_FLASH_MAP_HEADER* flashMapHeader = (const PHOENIX_FLASH_MAP_HEADER*)signature;
|
||||
|
||||
// Check store size
|
||||
UINT32 flashMapSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + flashMapHeader->NumEntries * sizeof(PHOENIX_FLASH_MAP_ENTRY);
|
||||
if (dataSize < flashMapSize) {
|
||||
msg(QObject::tr("parseStoreHeader: FlashMap block size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg(flashMapSize).arg(flashMapSize)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||
|
||||
// Construct header and body
|
||||
QByteArray header = store.left(sizeof(PHOENIX_FLASH_MAP_HEADER));
|
||||
QByteArray body = store.mid(sizeof(PHOENIX_FLASH_MAP_HEADER), flashMapSize - sizeof(PHOENIX_FLASH_MAP_HEADER));
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("Phoenix SCT FlashMap");
|
||||
QString info = QObject::tr("Signature: _FLASH_MAP\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)\nNumber of entries: %7")
|
||||
.hexarg(flashMapSize).arg(flashMapSize)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg(body.size()).arg(body.size())
|
||||
.arg(flashMapHeader->NumEntries);
|
||||
|
||||
// Add correct offset
|
||||
pdata.offset = parentOffset;
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(Types::NvramStoreFlashMap, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
@ -4036,7 +4088,7 @@ STATUS FfsParser::parseFsysStoreBody(const QModelIndex & index)
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Add EOF tree item
|
||||
model->addItem(Types::NvramVariableFsys, 0, name, QString(), info, header, QByteArray(), FALSE, parsingDataToQByteArray(pdata), index);
|
||||
model->addItem(Types::NvramEntryFsys, 0, name, QString(), info, header, QByteArray(), FALSE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
// Add free space
|
||||
offset += header.size();
|
||||
@ -4092,7 +4144,7 @@ STATUS FfsParser::parseFsysStoreBody(const QModelIndex & index)
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Add tree item
|
||||
model->addItem(Types::NvramVariableFsys, 0, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), index);
|
||||
model->addItem(Types::NvramEntryFsys, 0, name, QString(), info, header, body, FALSE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
// Move to next variable
|
||||
offset += variableSize;
|
||||
@ -4162,7 +4214,9 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
||||
entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_GUID2) {
|
||||
const EVSA_GUID_ENTRY* guidHeader = (const EVSA_GUID_ENTRY*)entryHeader;
|
||||
header = data.mid(offset, sizeof(EVSA_GUID_ENTRY));
|
||||
name = guidToQString(guidHeader->Guid);
|
||||
body = data.mid(offset + sizeof(EVSA_GUID_ENTRY), guidHeader->Header.Size - sizeof(EVSA_GUID_ENTRY));
|
||||
EFI_GUID guid = *(EFI_GUID*)body.constData();
|
||||
name = guidToQString(guid);
|
||||
info = QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8\nGuidId: %9h")
|
||||
.hexarg(variableSize).arg(variableSize)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
@ -4173,7 +4227,7 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
||||
QObject::tr("%1h, invalid, should be %2h").hexarg2(guidHeader->Header.Checksum, 2).hexarg2(calculated, 2))
|
||||
.hexarg2(guidHeader->GuidId, 4);
|
||||
subtype = Subtypes::GuidEvsaEntry;
|
||||
guidMap.insert(std::pair<UINT16, EFI_GUID>(guidHeader->GuidId, guidHeader->Guid));
|
||||
guidMap.insert(std::pair<UINT16, EFI_GUID>(guidHeader->GuidId, guid));
|
||||
}
|
||||
// Name entry
|
||||
else if (entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_NAME1 ||
|
||||
@ -4282,3 +4336,69 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
||||
}
|
||||
|
||||
|
||||
STATUS FfsParser::parseFlashMapBody(const QModelIndex & index)
|
||||
{
|
||||
// Sanity check
|
||||
if (!index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
|
||||
// Get parsing data for the current item
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(index);
|
||||
UINT32 parentOffset = pdata.offset + model->header(index).size();
|
||||
const QByteArray data = model->body(index);
|
||||
|
||||
|
||||
const UINT32 dataSize = (UINT32)data.size();
|
||||
UINT32 offset = 0;
|
||||
UINT32 unparsedSize = dataSize;
|
||||
// Parse all entries
|
||||
while (unparsedSize) {
|
||||
const PHOENIX_FLASH_MAP_ENTRY* entryHeader = (const PHOENIX_FLASH_MAP_ENTRY*)(data.constData() + offset);
|
||||
|
||||
// Check entry size
|
||||
if (unparsedSize < sizeof(PHOENIX_FLASH_MAP_ENTRY)) {
|
||||
// Last variable is bad, add the rest as padding and return
|
||||
QByteArray body = data.mid(offset);
|
||||
QString info = QObject::tr("Full size: %1h (%2)")
|
||||
.hexarg(body.size()).arg(body.size());
|
||||
|
||||
// Add correct offset to parsing data
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Add free space tree item
|
||||
model->addItem(Types::Padding, getPaddingType(body), QObject::tr("Padding"), QString(), info, QByteArray(), body, FALSE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
// Show message
|
||||
if (unparsedSize < entryHeader->Size)
|
||||
msg(QObject::tr("parseFlashMapBody: next entry appears too big, added as padding"), index);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
QString name = guidToQString(entryHeader->Guid);
|
||||
|
||||
// Construct header
|
||||
QByteArray header = data.mid(offset, sizeof(PHOENIX_FLASH_MAP_ENTRY));
|
||||
|
||||
// Add info
|
||||
QString info = QObject::tr("Entry GUID: %1\nFull size: 24h (36)\nHeader size %2h (%3)\nBody size: 0h (0)\nType %4h\nMemory address: %5h\nSize: %6h\nOffset: %7h")
|
||||
.arg(name)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg2(entryHeader->Type, 8)
|
||||
.hexarg2(entryHeader->PhysicalAddress, 8)
|
||||
.hexarg2(entryHeader->Size, 8)
|
||||
.hexarg2(entryHeader->Offset, 8);
|
||||
|
||||
// Add correct offset to parsing data
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Add tree item
|
||||
model->addItem(Types::NvramEntryFlashMap, 0, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
// Move to next variable
|
||||
offset += sizeof(PHOENIX_FLASH_MAP_ENTRY);
|
||||
unparsedSize = dataSize - offset;
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ private:
|
||||
STATUS parseVssStoreBody(const QModelIndex & index);
|
||||
STATUS parseFsysStoreBody(const QModelIndex & index);
|
||||
STATUS parseEvsaStoreBody(const QModelIndex & index);
|
||||
STATUS parseFlashMapBody(const QModelIndex & index);
|
||||
|
||||
// Message helper
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||
|
@ -73,7 +73,6 @@ typedef struct NVAR_VARIABLE_HEADER_ {
|
||||
// FFF12B8D-7696-4C8B-A985-2747075B4F50
|
||||
const QByteArray NVRAM_MAIN_STORE_VOLUME_GUID
|
||||
("\x8D\x2B\xF1\xFF\x96\x76\x8B\x4C\xA9\x85\x27\x47\x07\x5B\x4F\x50", 16);
|
||||
#define NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 0xFFF12B8D
|
||||
|
||||
// 00504624-8A59-4EEB-BD0F-6B36E96128E0
|
||||
const QByteArray NVRAM_ADDITIONAL_STORE_VOLUME_GUID
|
||||
@ -82,6 +81,7 @@ const QByteArray NVRAM_ADDITIONAL_STORE_VOLUME_GUID
|
||||
#define NVRAM_VSS_STORE_SIGNATURE 0x53535624 // $VSS
|
||||
#define NVRAM_APPLE_SVS_STORE_SIGNATURE 0x53565324 // $SVS
|
||||
#define NVRAM_APPLE_FSYS_STORE_SIGNATURE 0x73797346 // Fsys
|
||||
#define NVRAM_APPLE_GAID_STORE_SIGNATURE 0x64696147 // Gaid
|
||||
#define NVRAM_VSS_VARIABLE_START_ID 0x55AA
|
||||
|
||||
// Variable store header flags
|
||||
@ -158,14 +158,14 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ {
|
||||
#define NVRAM_VSS_VARIABLE_APPEND_WRITE 0x00000040
|
||||
#define NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM 0x80000000
|
||||
|
||||
// FDC region can be found in some VSS volumes
|
||||
// FDC region can be found in Insyde VSS volumes
|
||||
// It has another VSS volume inside
|
||||
// _FDC header structure
|
||||
#define NVRAM_FDC_VOLUME_SIGNATURE 0x4344465F
|
||||
|
||||
typedef struct FDC_VOLUME_HEADER_ {
|
||||
UINT32 Signature; //_FDC
|
||||
UINT32 Size;
|
||||
UINT32 Size; // Size of the whole region
|
||||
//EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
|
||||
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2];
|
||||
//VSS_VARIABLE_STORE_HEADER VssHeader;
|
||||
@ -175,20 +175,28 @@ typedef struct FDC_VOLUME_HEADER_ {
|
||||
// EFI Fault tolerant working block header
|
||||
#define EFI_FAULT_TOLERANT_WORKING_BLOCK_VALID 0x1
|
||||
#define EFI_FAULT_TOLERANT_WORKING_BLOCK_INVALID 0x2
|
||||
typedef struct {
|
||||
|
||||
// 9E58292B-7C68-497D-0ACE6500FD9F1B95
|
||||
const QByteArray EDKII_WORKING_BLOCK_SIGNATURE_GUID
|
||||
("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\x0A\xCE\x65\x00\xFD\x9F\x1B\x95", 16);
|
||||
|
||||
#define NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 0xFFF12B8D
|
||||
#define EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1 0x9E58292B
|
||||
|
||||
typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32_ {
|
||||
EFI_GUID Signature; // NVRAM_MAIN_STORE_VOLUME_GUID
|
||||
UINT32 Crc; // Crc32 of the header with empty Crc and State fields
|
||||
UINT8 State;
|
||||
UINT8 Reserved3[3];
|
||||
UINT8 Reserved[3];
|
||||
UINT32 WriteQueueSize; // Size of the FTW block without the header
|
||||
//UINT8 WriteQueue[WriteQueueSize];
|
||||
} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32;
|
||||
|
||||
typedef struct {
|
||||
typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64_ {
|
||||
EFI_GUID Signature; // NVRAM_MAIN_STORE_VOLUME_GUID
|
||||
UINT32 Crc; // Crc32 of the header with empty Crc and State fields
|
||||
UINT8 State;
|
||||
UINT8 Reserved3[3];
|
||||
UINT8 Reserved[3];
|
||||
UINT64 WriteQueueSize; // Size of the FTW block without the header
|
||||
//UINT8 WriteQueue[WriteQueueSize];
|
||||
} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64;
|
||||
@ -203,7 +211,7 @@ typedef struct APPLE_FSYS_STORE_HEADER_ {
|
||||
UINT16 Size; // Size of variable store
|
||||
} APPLE_FSYS_STORE_HEADER;
|
||||
|
||||
// Apple Fsys variable format
|
||||
// Apple Fsys entry format
|
||||
// UINT8 NameLength;
|
||||
// CHAR8 Name[];
|
||||
// UINT16 DataLength;
|
||||
@ -244,7 +252,7 @@ typedef struct EVSA_STORE_ENTRY_ {
|
||||
typedef struct EVSA_GUID_ENTRY_ {
|
||||
EVSA_ENTRY_HEADER Header;
|
||||
UINT16 GuidId;
|
||||
EFI_GUID Guid;
|
||||
//EFI_GUID Guid;
|
||||
} EVSA_GUID_ENTRY;
|
||||
|
||||
typedef struct EVSA_NAME_ENTRY_ {
|
||||
@ -261,6 +269,36 @@ typedef struct EVSA_DATA_ENTRY_ {
|
||||
//UINT8 Data[];
|
||||
} EVSA_DATA_ENTRY;
|
||||
|
||||
|
||||
//
|
||||
// Phoenix SCT Flash Map
|
||||
//
|
||||
|
||||
#define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_PART1 0x414C465F
|
||||
#define NVRAM_PHOENIX_FLASH_MAP_SIGNATURE_LENGTH 10
|
||||
|
||||
// _FLASH_MAP
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_SIGNATURE
|
||||
("\x5F\x46\x4C\x41\x53\x48\x5F\x4D\x41\x50", 10);
|
||||
|
||||
typedef struct PHOENIX_FLASH_MAP_HEADER_ {
|
||||
UINT8 Signature[10]; // _FLASH_MAP signature
|
||||
UINT16 NumEntries; // Number of entries in the map
|
||||
UINT32 : 32; // Reserved field
|
||||
} PHOENIX_FLASH_MAP_HEADER;
|
||||
|
||||
typedef struct PHOENIX_FLASH_MAP_ENTRY_ {
|
||||
EFI_GUID Guid;
|
||||
UINT32 Type;
|
||||
UINT64 PhysicalAddress;
|
||||
UINT32 Size;
|
||||
UINT32 Offset;
|
||||
} PHOENIX_FLASH_MAP_ENTRY;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
|
||||
|
@ -73,16 +73,20 @@ QString itemTypeToQString(const UINT8 type)
|
||||
return QObject::tr("Fsys store");
|
||||
case Types::NvramStoreEvsa:
|
||||
return QObject::tr("EVSA store");
|
||||
case Types::NvramFtwBlock:
|
||||
return QObject::tr("FTW block");
|
||||
case Types::NvramStoreFtw:
|
||||
return QObject::tr("FTW store");
|
||||
case Types::NvramStoreFlashMap:
|
||||
return QObject::tr("FlashMap store");
|
||||
case Types::NvramVariableNvar:
|
||||
return QObject::tr("NVAR variable");
|
||||
case Types::NvramVariableVss:
|
||||
return QObject::tr("VSS variable");
|
||||
case Types::NvramVariableFsys:
|
||||
return QObject::tr("Fsys variable");
|
||||
case Types::NvramEntryFsys:
|
||||
return QObject::tr("Fsys entry");
|
||||
case Types::NvramEntryEvsa:
|
||||
return QObject::tr("EVSA entry");
|
||||
case Types::NvramEntryFlashMap:
|
||||
return QObject::tr("FlashMap entry");
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
}
|
||||
@ -142,8 +146,10 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
||||
case Types::NvramStoreFdc:
|
||||
case Types::NvramStoreFsys:
|
||||
case Types::NvramStoreEvsa:
|
||||
case Types::NvramFtwBlock:
|
||||
case Types::NvramVariableFsys:
|
||||
case Types::NvramStoreFtw:
|
||||
case Types::NvramStoreFlashMap:
|
||||
case Types::NvramEntryFsys:
|
||||
case Types::NvramEntryFlashMap:
|
||||
return QString();
|
||||
case Types::NvramVariableNvar:
|
||||
if (subtype == Subtypes::InvalidNvarVariable)
|
||||
|
@ -47,11 +47,13 @@ namespace Types {
|
||||
NvramStoreFdc,
|
||||
NvramStoreFsys,
|
||||
NvramStoreEvsa,
|
||||
NvramFtwBlock,
|
||||
NvramStoreFlashMap,
|
||||
NvramStoreFtw,
|
||||
NvramVariableNvar,
|
||||
NvramVariableVss,
|
||||
NvramVariableFsys,
|
||||
NvramEntryEvsa
|
||||
NvramEntryFsys,
|
||||
NvramEntryEvsa,
|
||||
NvramEntryFlashMap,
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user