mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 07:58:22 +08:00
UT 0.19.6, UE 0.3.5, UP 0.2.5
- added support for firmware volumes with CRC32 stored in ZeroVector (Apple UEFI feature) - ZeroVector included to FV information - added new volume types AppleCRC, AppleCRC Boot and AppleCRC Unknown - added support for HP POSTCode sections - size information split into header size and body size - decimal sizes are added, shown in braces after hexadecimal sizes - corrected small bug with Extract Body action being enabled for items with empty body
This commit is contained in:
parent
476929bc4f
commit
fb7e1c4c89
@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout << "UEFIExtract 0.3.3" << std::endl << std::endl <<
|
std::cout << "UEFIExtract 0.3.5" << std::endl << std::endl <<
|
||||||
"Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ... FileGUID_31]" << std::endl <<
|
"Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ... FileGUID_31]" << std::endl <<
|
||||||
"Returned value is a bit mask where 0 on position N meant File with GUID_N was found and unpacked, 1 otherwise" << std::endl;
|
"Returned value is a bit mask where 0 on position N meant File with GUID_N was found and unpacked, 1 otherwise" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -31,7 +31,7 @@ int main(int argc, char *argv[])
|
|||||||
result = w.patchFromFile(a.arguments().at(1));
|
result = w.patchFromFile(a.arguments().at(1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout << "UEFIPatch 0.2.4 - UEFI image file patching utility" << std::endl << std::endl <<
|
std::cout << "UEFIPatch 0.2.5 - UEFI image file patching utility" << std::endl << std::endl <<
|
||||||
"Usage: UEFIPatch image_file" << std::endl << std::endl <<
|
"Usage: UEFIPatch image_file" << std::endl << std::endl <<
|
||||||
"Patches will be read from patches.txt file\n";
|
"Patches will be read from patches.txt file\n";
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
6
ffs.cpp
6
ffs.cpp
@ -160,6 +160,8 @@ QString sectionTypeToQString(const UINT8 type)
|
|||||||
return QObject::tr("PEI dependency");
|
return QObject::tr("PEI dependency");
|
||||||
case EFI_SECTION_SMM_DEPEX:
|
case EFI_SECTION_SMM_DEPEX:
|
||||||
return QObject::tr("SMM dependency");
|
return QObject::tr("SMM dependency");
|
||||||
|
case HP_SECTION_POSTCODE:
|
||||||
|
return QObject::tr("HP postcode");
|
||||||
case SCT_SECTION_POSTCODE:
|
case SCT_SECTION_POSTCODE:
|
||||||
return QObject::tr("SCT postcode");
|
return QObject::tr("SCT postcode");
|
||||||
default:
|
default:
|
||||||
@ -205,8 +207,10 @@ UINT32 sizeOfSectionHeader(EFI_COMMON_SECTION_HEADER* header)
|
|||||||
return sizeof(EFI_PEI_DEPEX_SECTION);
|
return sizeof(EFI_PEI_DEPEX_SECTION);
|
||||||
case EFI_SECTION_SMM_DEPEX:
|
case EFI_SECTION_SMM_DEPEX:
|
||||||
return sizeof(EFI_SMM_DEPEX_SECTION);
|
return sizeof(EFI_SMM_DEPEX_SECTION);
|
||||||
|
case HP_SECTION_POSTCODE:
|
||||||
|
return sizeof(POSTCODE_SECTION);
|
||||||
case SCT_SECTION_POSTCODE:
|
case SCT_SECTION_POSTCODE:
|
||||||
return sizeof(SCT_POSTCODE_SECTION);
|
return sizeof(POSTCODE_SECTION);
|
||||||
default:
|
default:
|
||||||
return sizeof(EFI_COMMON_SECTION_HEADER);
|
return sizeof(EFI_COMMON_SECTION_HEADER);
|
||||||
}
|
}
|
||||||
|
5
ffs.h
5
ffs.h
@ -361,6 +361,7 @@ typedef struct {
|
|||||||
#define EFI_SECTION_PEI_DEPEX 0x1B
|
#define EFI_SECTION_PEI_DEPEX 0x1B
|
||||||
#define EFI_SECTION_SMM_DEPEX 0x1C
|
#define EFI_SECTION_SMM_DEPEX 0x1C
|
||||||
#define SCT_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
|
#define SCT_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
|
||||||
|
#define HP_SECTION_POSTCODE 0x20 // Specific to HP images
|
||||||
|
|
||||||
// Compression section
|
// Compression section
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -415,12 +416,12 @@ typedef struct {
|
|||||||
EFI_GUID SubTypeGuid;
|
EFI_GUID SubTypeGuid;
|
||||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
||||||
|
|
||||||
// Phoenix SCT postcode section
|
// Phoenix SCT and HP postcode section
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT8 Size[3];
|
UINT8 Size[3];
|
||||||
UINT8 Type;
|
UINT8 Type;
|
||||||
UINT32 Postcode;
|
UINT32 Postcode;
|
||||||
} SCT_POSTCODE_SECTION;
|
} POSTCODE_SECTION;
|
||||||
|
|
||||||
// Other sections
|
// Other sections
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
|
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
|
||||||
|
223
ffsengine.cpp
223
ffsengine.cpp
@ -257,10 +257,10 @@ UINT8 FfsEngine::parseImageFile(const QByteArray & buffer)
|
|||||||
QByteArray header = buffer.left(capsuleHeaderSize);
|
QByteArray header = buffer.left(capsuleHeaderSize);
|
||||||
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
|
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
|
||||||
QString name = tr("UEFI capsule");
|
QString name = tr("UEFI capsule");
|
||||||
QString info = tr("Header size: 0x%1\nFlags: 0x%2\nImage size: 0x%3")
|
QString info = tr("Header size: 0x%1(%2)\nFlags: 0x%3\nImage size: 0x%4(%5)")
|
||||||
.hexarg(capsuleHeader->HeaderSize, 8)
|
.hexarg(capsuleHeader->HeaderSize, 4).arg(capsuleHeader->HeaderSize)
|
||||||
.hexarg(capsuleHeader->Flags, 8)
|
.hexarg(capsuleHeader->Flags, 8)
|
||||||
.hexarg(capsuleHeader->CapsuleImageSize, 8);
|
.hexarg(capsuleHeader->CapsuleImageSize, 8).arg(capsuleHeader->HeaderSize);
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body);
|
index = model->addItem(Types::Capsule, Subtypes::UefiCapsule, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body);
|
||||||
}
|
}
|
||||||
@ -273,10 +273,10 @@ UINT8 FfsEngine::parseImageFile(const QByteArray & buffer)
|
|||||||
QByteArray header = buffer.left(capsuleHeaderSize);
|
QByteArray header = buffer.left(capsuleHeaderSize);
|
||||||
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
|
QByteArray body = buffer.right(buffer.size() - capsuleHeaderSize);
|
||||||
QString name = tr("AMI Aptio capsule");
|
QString name = tr("AMI Aptio capsule");
|
||||||
QString info = tr("Header size: 0x%1\nFlags: 0x%2\nImage size: 0x%3")
|
QString info = tr("Header size: 0x%1(%2)\nFlags: 0x%3\nImage size: 0x%4(%5)")
|
||||||
.hexarg(aptioCapsuleHeader->RomImageOffset, 4)
|
.hexarg(capsuleHeaderSize, 4).arg(capsuleHeaderSize)
|
||||||
.hexarg(aptioCapsuleHeader->CapsuleHeader.Flags, 8)
|
.hexarg(aptioCapsuleHeader->CapsuleHeader.Flags, 8)
|
||||||
.hexarg(aptioCapsuleHeader->CapsuleHeader.CapsuleImageSize - aptioCapsuleHeader->RomImageOffset, 8);
|
.hexarg(aptioCapsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize, 8).arg(aptioCapsuleHeader->CapsuleHeader.CapsuleImageSize - capsuleHeaderSize);
|
||||||
//!TODO: more info about Aptio capsule
|
//!TODO: more info about Aptio capsule
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Capsule, Subtypes::AptioCapsule, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body);
|
index = model->addItem(Types::Capsule, Subtypes::AptioCapsule, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body);
|
||||||
@ -300,8 +300,8 @@ UINT8 FfsEngine::parseImageFile(const QByteArray & buffer)
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("BIOS image");
|
QString name = tr("BIOS image");
|
||||||
QString info = tr("Size: 0x%1")
|
QString info = tr("Size: 0x%1(%2)")
|
||||||
.hexarg(flashImage.size(), 8);
|
.hexarg(flashImage.size(), 8).arg(flashImage.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Image, Subtypes::BiosImage, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), flashImage, QByteArray(), index);
|
index = model->addItem(Types::Image, Subtypes::BiosImage, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), flashImage, QByteArray(), index);
|
||||||
@ -436,8 +436,8 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
|
|
||||||
// Intel image
|
// Intel image
|
||||||
name = tr("Intel image");
|
name = tr("Intel image");
|
||||||
info = tr("Size: 0x%1\nFlash chips: %2\nRegions: %3\nMasters: %4\nPCH straps: %5\nPROC straps: %6\nICC table entries: %7")
|
info = tr("Size: 0x%1(%2)\nFlash chips: %3\nRegions: %4\nMasters: %5\nPCH straps: %6\nPROC straps: %7\nICC table entries: %8")
|
||||||
.hexarg(intelImage.size(), 8)
|
.hexarg(intelImage.size(), 8).arg(intelImage.size())
|
||||||
.arg(descriptorMap->NumberOfFlashChips + 1) //
|
.arg(descriptorMap->NumberOfFlashChips + 1) //
|
||||||
.arg(descriptorMap->NumberOfRegions + 1) // Zero-based numbers in storage
|
.arg(descriptorMap->NumberOfRegions + 1) // Zero-based numbers in storage
|
||||||
.arg(descriptorMap->NumberOfMasters + 1) //
|
.arg(descriptorMap->NumberOfMasters + 1) //
|
||||||
@ -452,7 +452,7 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
// Get descriptor info
|
// Get descriptor info
|
||||||
body = intelImage.left(FLASH_DESCRIPTOR_SIZE);
|
body = intelImage.left(FLASH_DESCRIPTOR_SIZE);
|
||||||
name = tr("Descriptor region");
|
name = tr("Descriptor region");
|
||||||
info = tr("Size: 0x%1").hexarg(FLASH_DESCRIPTOR_SIZE, 8);
|
info = tr("Size: 0x%1(%2)").hexarg(FLASH_DESCRIPTOR_SIZE, 8).arg(FLASH_DESCRIPTOR_SIZE);
|
||||||
|
|
||||||
// Check regions presence once again
|
// Check regions presence once again
|
||||||
QVector<UINT32> offsets;
|
QVector<UINT32> offsets;
|
||||||
@ -557,8 +557,8 @@ UINT8 FfsEngine::parseGbeRegion(const QByteArray & gbe, QModelIndex & index, con
|
|||||||
QString name = tr("GbE region");
|
QString name = tr("GbE region");
|
||||||
GBE_MAC* mac = (GBE_MAC*)gbe.constData();
|
GBE_MAC* mac = (GBE_MAC*)gbe.constData();
|
||||||
GBE_VERSION* version = (GBE_VERSION*)(gbe.constData() + GBE_VERSION_OFFSET);
|
GBE_VERSION* version = (GBE_VERSION*)(gbe.constData() + GBE_VERSION_OFFSET);
|
||||||
QString info = tr("Size: 0x%1\nMAC: %2:%3:%4:%5:%6:%7\nVersion: %8.%9")
|
QString info = tr("Size: 0x%1(%2)\nMAC: %3:%4:%5:%6:%7:%8\nVersion: %9.%10")
|
||||||
.hexarg(gbe.size(), 8)
|
.hexarg(gbe.size(), 8).arg(gbe.size())
|
||||||
.hexarg(mac->vendor[0], 2)
|
.hexarg(mac->vendor[0], 2)
|
||||||
.hexarg(mac->vendor[1], 2)
|
.hexarg(mac->vendor[1], 2)
|
||||||
.hexarg(mac->vendor[2], 2)
|
.hexarg(mac->vendor[2], 2)
|
||||||
@ -581,8 +581,8 @@ UINT8 FfsEngine::parseMeRegion(const QByteArray & me, QModelIndex & index, const
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("ME region");
|
QString name = tr("ME region");
|
||||||
QString info = tr("Size: 0x%1").
|
QString info = tr("Size: 0x%1(%2)").
|
||||||
hexarg(me.size(), 8);
|
hexarg(me.size(), 8).arg(me.size());
|
||||||
|
|
||||||
// Search for new signature
|
// Search for new signature
|
||||||
INT32 versionOffset = me.indexOf(ME_VERSION_SIGNATURE2);
|
INT32 versionOffset = me.indexOf(ME_VERSION_SIGNATURE2);
|
||||||
@ -622,8 +622,8 @@ UINT8 FfsEngine::parsePdrRegion(const QByteArray & pdr, QModelIndex & index, con
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("PDR region");
|
QString name = tr("PDR region");
|
||||||
QString info = tr("Size: 0x%1").
|
QString info = tr("Size: 0x%1(%2)").
|
||||||
hexarg(pdr.size(), 8);
|
hexarg(pdr.size(), 8).arg(pdr.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Region, Subtypes::PdrRegion, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), pdr, QByteArray(), parent, mode);
|
index = model->addItem(Types::Region, Subtypes::PdrRegion, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), pdr, QByteArray(), parent, mode);
|
||||||
@ -643,8 +643,8 @@ UINT8 FfsEngine::parseBiosRegion(const QByteArray & bios, QModelIndex & index, c
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = tr("BIOS region");
|
QString name = tr("BIOS region");
|
||||||
QString info = tr("Size: 0x%1").
|
QString info = tr("Size: 0x%1(%2)").
|
||||||
hexarg(bios.size(), 8);
|
hexarg(bios.size(), 8).arg(bios.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Region, Subtypes::BiosRegion, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), bios, QByteArray(), parent, mode);
|
index = model->addItem(Types::Region, Subtypes::BiosRegion, COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), bios, QByteArray(), parent, mode);
|
||||||
@ -678,8 +678,8 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
|
|||||||
// Get info
|
// Get info
|
||||||
QByteArray padding = bios.left(prevVolumeOffset);
|
QByteArray padding = bios.left(prevVolumeOffset);
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
info = tr("Size: 0x%1")
|
info = tr("Size: 0x%1(%2)")
|
||||||
.hexarg(padding.size(), 8);
|
.hexarg(padding.size(), 8).arg(padding.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::Padding, getPaddingType(padding), COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, QByteArray(), parent);
|
model->addItem(Types::Padding, getPaddingType(padding), COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, QByteArray(), parent);
|
||||||
@ -704,8 +704,8 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
|
|||||||
QByteArray padding = bios.mid(prevVolumeOffset + prevVolumeSize, paddingSize);
|
QByteArray padding = bios.mid(prevVolumeOffset + prevVolumeSize, paddingSize);
|
||||||
// Get info
|
// Get info
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
info = tr("Size: 0x%1")
|
info = tr("Size: 0x%1(%2)")
|
||||||
.hexarg(padding.size(), 8);
|
.hexarg(padding.size(), 8).arg(padding.size());
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::Padding, getPaddingType(padding), COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, QByteArray(), parent);
|
model->addItem(Types::Padding, getPaddingType(padding), COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, QByteArray(), parent);
|
||||||
}
|
}
|
||||||
@ -778,8 +778,8 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
|
|||||||
QByteArray padding = bios.right(endPaddingSize);
|
QByteArray padding = bios.right(endPaddingSize);
|
||||||
// Get info
|
// Get info
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
info = tr("Size: 0x%1")
|
info = tr("Size: 0x%1(%2)")
|
||||||
.hexarg(padding.size(), 8);
|
.hexarg(padding.size(), 8).arg(padding.size());
|
||||||
// Add tree item
|
// Add tree item
|
||||||
model->addItem(Types::Padding, getPaddingType(padding), COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, QByteArray(), parent);
|
model->addItem(Types::Padding, getPaddingType(padding), COMPRESSION_ALGORITHM_NONE, name, "", info, QByteArray(), padding, QByteArray(), parent);
|
||||||
}
|
}
|
||||||
@ -857,7 +857,7 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
|
|||||||
else if (QByteArray((const char*)&volumeHeader->FileSystemGuid, sizeof(EFI_GUID)) == EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID) {
|
else if (QByteArray((const char*)&volumeHeader->FileSystemGuid, sizeof(EFI_GUID)) == EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID) {
|
||||||
// Code can be added here
|
// Code can be added here
|
||||||
}
|
}
|
||||||
// Apple Boot Volume FFS GUID
|
// Apple Boot Volume 2 FFS GUID
|
||||||
else if (QByteArray((const char*)&volumeHeader->FileSystemGuid, sizeof(EFI_GUID)) == EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID) {
|
else if (QByteArray((const char*)&volumeHeader->FileSystemGuid, sizeof(EFI_GUID)) == EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID) {
|
||||||
// Code can be added here
|
// Code can be added here
|
||||||
}
|
}
|
||||||
@ -880,32 +880,52 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
|
|||||||
char empty = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00';
|
char empty = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00';
|
||||||
|
|
||||||
// Get volume size
|
// Get volume size
|
||||||
UINT8 result;
|
|
||||||
UINT32 volumeSize;
|
UINT32 volumeSize;
|
||||||
UINT32 bmVolumeSize;
|
UINT32 bmVolumeSize;
|
||||||
|
|
||||||
result = getVolumeSize(volume, 0, volumeSize, bmVolumeSize);
|
UINT8 result = getVolumeSize(volume, 0, volumeSize, bmVolumeSize);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
// Check for Apple CRC32 in ZeroVector
|
||||||
|
UINT32 crc32FromZeroVector = *(UINT32*)(volume.constData() + 8);
|
||||||
|
if (crc32FromZeroVector != 0) {
|
||||||
|
// Calculate CRC32 of the volume body
|
||||||
|
UINT32 crc = crc32(0, NULL, 0);
|
||||||
|
crc = crc32(crc, (const UINT8*)(volume.constData() + volumeHeader->HeaderLength), volumeSize - volumeHeader->HeaderLength);
|
||||||
|
if (crc == crc32FromZeroVector) {
|
||||||
|
subtype = (subtype == Subtypes::UnknownVolume) ? Subtypes::UnknownAppleCrcVolume : Subtypes::AppleCrcVolume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check header checksum by recalculating it
|
// Check header checksum by recalculating it
|
||||||
if (subtype == Subtypes::NormalVolume && calculateChecksum16((UINT16*)volumeHeader, volumeHeader->HeaderLength))
|
if ((subtype == Subtypes::NormalVolume || subtype == Subtypes::AppleCrcVolume) && calculateChecksum16((UINT16*)volumeHeader, volumeHeader->HeaderLength))
|
||||||
msgInvalidChecksum = true;
|
msgInvalidChecksum = true;
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = guidToQString(volumeHeader->FileSystemGuid);
|
QString name = guidToQString(volumeHeader->FileSystemGuid);
|
||||||
QString info = tr("FileSystem GUID: %1\nSize: 0x%2\nRevision: %3\nAttributes: 0x%4\nErase polarity: %5\nHeader size: 0x%6")
|
QString info = tr("FileSystem GUID: %1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)\nRevision: %6\nAttributes: 0x%7\nErase polarity: %8\nZeroVector:\n%9 %10 %11 %12 %13 %14 %15 %16\n%17 %18 %19 %20 %21 %22 %23 %24")
|
||||||
.arg(guidToQString(volumeHeader->FileSystemGuid))
|
.arg(guidToQString(volumeHeader->FileSystemGuid))
|
||||||
.hexarg(volumeSize, 8)
|
.hexarg(headerSize, 8).arg(headerSize)
|
||||||
|
.hexarg(volumeSize - headerSize, 8).arg(volumeSize - headerSize)
|
||||||
.arg(volumeHeader->Revision)
|
.arg(volumeHeader->Revision)
|
||||||
.hexarg(volumeHeader->Attributes, 8)
|
.hexarg(volumeHeader->Attributes, 8)
|
||||||
.arg(empty ? "1" : "0")
|
.arg(empty ? "1" : "0")
|
||||||
.hexarg(headerSize, 8);
|
.hexarg(volumeHeader->ZeroVector[0], 2).hexarg(volumeHeader->ZeroVector[1], 2).hexarg(volumeHeader->ZeroVector[2], 2).hexarg(volumeHeader->ZeroVector[3], 2)
|
||||||
|
.hexarg(volumeHeader->ZeroVector[4], 2).hexarg(volumeHeader->ZeroVector[5], 2).hexarg(volumeHeader->ZeroVector[6], 2).hexarg(volumeHeader->ZeroVector[7], 2)
|
||||||
|
.hexarg(volumeHeader->ZeroVector[8], 2).hexarg(volumeHeader->ZeroVector[9], 2).hexarg(volumeHeader->ZeroVector[10], 2).hexarg(volumeHeader->ZeroVector[11], 2)
|
||||||
|
.hexarg(volumeHeader->ZeroVector[12], 2).hexarg(volumeHeader->ZeroVector[13], 2).hexarg(volumeHeader->ZeroVector[14], 2).hexarg(volumeHeader->ZeroVector[15], 2);
|
||||||
|
|
||||||
|
// Apple CRC32 volume
|
||||||
|
if (subtype == Subtypes::AppleCrcVolume || subtype == Subtypes::UnknownAppleCrcVolume) {
|
||||||
|
info += tr("\nCRC32 in ZeroVector: valid");
|
||||||
|
}
|
||||||
|
|
||||||
// Extended header present
|
// Extended header present
|
||||||
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
|
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
|
||||||
EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(volume.constData() + volumeHeader->ExtHeaderOffset);
|
EFI_FIRMWARE_VOLUME_EXT_HEADER* extendedHeader = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(volume.constData() + volumeHeader->ExtHeaderOffset);
|
||||||
info += tr("\nExtended header size: 0x%1\nVolume name: %2")
|
info += tr("\nExtended header size: 0x%1(%2)\nVolume GUID: %3")
|
||||||
.hexarg(extendedHeader->ExtHeaderSize, 8)
|
.hexarg(extendedHeader->ExtHeaderSize, 8).arg(extendedHeader->ExtHeaderSize)
|
||||||
.arg(guidToQString(extendedHeader->FvName));
|
.arg(guidToQString(extendedHeader->FvName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -921,7 +941,7 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
|
|||||||
msg(tr("parseVolume: Volume header checksum is invalid"), index);
|
msg(tr("parseVolume: Volume header checksum is invalid"), index);
|
||||||
|
|
||||||
// Do not parse the contents of volumes other then normal
|
// Do not parse the contents of volumes other then normal
|
||||||
if (subtype != Subtypes::NormalVolume)
|
if (subtype != Subtypes::NormalVolume && subtype != Subtypes::AppleCrcVolume)
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
|
|
||||||
// Search for and parse all files
|
// Search for and parse all files
|
||||||
@ -1069,11 +1089,17 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, QModelIndex & index, const U
|
|||||||
break;
|
break;
|
||||||
case EFI_FV_FILETYPE_SECURITY_CORE:
|
case EFI_FV_FILETYPE_SECURITY_CORE:
|
||||||
// Set parent volume type to BootVolume
|
// Set parent volume type to BootVolume
|
||||||
model->setSubtype(parent, Subtypes::BootVolume);
|
if (model->subtype(parent) == Subtypes::AppleCrcVolume || model->subtype(parent) == Subtypes::BootAppleCrcVolume)
|
||||||
|
model->setSubtype(parent, Subtypes::BootAppleCrcVolume);
|
||||||
|
else
|
||||||
|
model->setSubtype(parent, Subtypes::BootVolume);
|
||||||
break;
|
break;
|
||||||
case EFI_FV_FILETYPE_PEI_CORE:
|
case EFI_FV_FILETYPE_PEI_CORE:
|
||||||
// Set parent volume type to BootVolume
|
// Set parent volume type to BootVolume
|
||||||
model->setSubtype(parent, Subtypes::BootVolume);
|
if (model->subtype(parent) == Subtypes::AppleCrcVolume || model->subtype(parent) == Subtypes::BootAppleCrcVolume)
|
||||||
|
model->setSubtype(parent, Subtypes::BootAppleCrcVolume);
|
||||||
|
else
|
||||||
|
model->setSubtype(parent, Subtypes::BootVolume);
|
||||||
break;
|
break;
|
||||||
case EFI_FV_FILETYPE_DXE_CORE:
|
case EFI_FV_FILETYPE_DXE_CORE:
|
||||||
break;
|
break;
|
||||||
@ -1118,11 +1144,12 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, QModelIndex & index, const U
|
|||||||
name = guidToQString(fileHeader->Name);
|
name = guidToQString(fileHeader->Name);
|
||||||
else
|
else
|
||||||
name = tr("Padding");
|
name = tr("Padding");
|
||||||
info = tr("Name: %1\nType: 0x%2\nAttributes: 0x%3\nSize: 0x%4\nState: 0x%5")
|
info = tr("Name: %1\nType: 0x%2\nAttributes: 0x%3\nHeader size: 0x%4(%5)\nBody size: 0x%6(%7)\nState: 0x%8")
|
||||||
.arg(guidToQString(fileHeader->Name))
|
.arg(guidToQString(fileHeader->Name))
|
||||||
.hexarg(fileHeader->Type, 2)
|
.hexarg(fileHeader->Type, 2)
|
||||||
.hexarg(fileHeader->Attributes, 2)
|
.hexarg(fileHeader->Attributes, 2)
|
||||||
.hexarg(uint24ToUint32(fileHeader->Size), 6)
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(uint24ToUint32(fileHeader->Size) - header.size(), 6).arg(uint24ToUint32(fileHeader->Size) - header.size())
|
||||||
.hexarg(fileHeader->State, 2);
|
.hexarg(fileHeader->State, 2);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
@ -1333,11 +1360,12 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
parseCurrentSection = false;
|
parseCurrentSection = false;
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2\nCompression type: %3\nDecompressed size: 0x%4")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)\nCompression type: %6\nDecompressed size: 0x%7(%8)")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6)
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size())
|
||||||
.arg(compressionTypeToQString(algorithm))
|
.arg(compressionTypeToQString(algorithm))
|
||||||
.hexarg(compressedSectionHeader->UncompressedLength, 8);
|
.hexarg(compressedSectionHeader->UncompressedLength, 8).arg(compressedSectionHeader->UncompressedLength);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, algorithm, name, "", info, header, body, QByteArray(), parent, mode);
|
index = model->addItem(Types::Section, sectionHeader->Type, algorithm, name, "", info, header, body, QByteArray(), parent, mode);
|
||||||
@ -1370,10 +1398,11 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
name = guidToQString(guidDefinedSectionHeader->SectionDefinitionGuid);
|
name = guidToQString(guidDefinedSectionHeader->SectionDefinitionGuid);
|
||||||
info = tr("GUID: %1\nType: 0x%2\nSize: 0x%3\nData offset: 0x%4\nAttributes: 0x%5")
|
info = tr("GUID: %1\nType: 0x%2\nHeader size: 0x%3(%4)\nBody size: 0x%5(%6)\nData offset: 0x%7\nAttributes: 0x%8")
|
||||||
.arg(name)
|
.arg(name)
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6)
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size())
|
||||||
.hexarg(guidDefinedSectionHeader->DataOffset, 4)
|
.hexarg(guidDefinedSectionHeader->DataOffset, 4)
|
||||||
.hexarg(guidDefinedSectionHeader->Attributes, 4);
|
.hexarg(guidDefinedSectionHeader->Attributes, 4);
|
||||||
|
|
||||||
@ -1390,11 +1419,11 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
|
|
||||||
if (algorithm == COMPRESSION_ALGORITHM_TIANO) {
|
if (algorithm == COMPRESSION_ALGORITHM_TIANO) {
|
||||||
info += tr("\nCompression type: Tiano");
|
info += tr("\nCompression type: Tiano");
|
||||||
info += tr("\nDecompressed size: 0x%1").hexarg(decompressed.length(), 8);
|
info += tr("\nDecompressed size: 0x%1(%2)").hexarg(decompressed.length(), 8).arg(decompressed.length());
|
||||||
}
|
}
|
||||||
else if (algorithm == COMPRESSION_ALGORITHM_EFI11) {
|
else if (algorithm == COMPRESSION_ALGORITHM_EFI11) {
|
||||||
info += tr("\nCompression type: EFI 1.1");
|
info += tr("\nCompression type: EFI 1.1");
|
||||||
info += tr("\nDecompressed size: 0x%1").hexarg(decompressed.length(), 8);
|
info += tr("\nDecompressed size: 0x%1(%2)").hexarg(decompressed.length(), 8).arg(decompressed.length());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
info += tr("\nCompression type: unknown");
|
info += tr("\nCompression type: unknown");
|
||||||
@ -1409,7 +1438,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
|
|
||||||
if (algorithm == COMPRESSION_ALGORITHM_LZMA) {
|
if (algorithm == COMPRESSION_ALGORITHM_LZMA) {
|
||||||
info += tr("\nCompression type: LZMA");
|
info += tr("\nCompression type: LZMA");
|
||||||
info += tr("\nDecompressed size: 0x%1").hexarg(decompressed.length(), 8);
|
info += tr("\nDecompressed size: 0x%1(%2)").hexarg(decompressed.length(), 8).arg(decompressed.length());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
info += tr("\nCompression type: unknown");
|
info += tr("\nCompression type: unknown");
|
||||||
@ -1461,15 +1490,15 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
if (!parseCurrentSection) {
|
if (!parseCurrentSection) {
|
||||||
msg(tr("parseSection: GUID defined section can not be processed"), index);
|
msg(tr("parseSection: GUID defined section can not be processed"), index);
|
||||||
}
|
}
|
||||||
else if (parseAsIntelSigned) { // Parse as intel signed sections
|
else if (parseAsIntelSigned) { // Parse as Intel signed sections
|
||||||
// Get signature
|
// Get signature
|
||||||
QByteArray signature = body.left(*(UINT32*)body.constData());
|
QByteArray signature = body.left(*(UINT32*)body.constData());
|
||||||
// Get info for it
|
// Get info for it
|
||||||
QString signatureInfo = tr("Size: 0x%1").hexarg(signature.size(), 8);
|
QString signatureInfo = tr("Size: 0x%1(%2)").hexarg(signature.size(), 8).arg(signature.size());
|
||||||
// Add it to the tree
|
// Add it to the tree
|
||||||
model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Padding"), tr("Intel signature"), signatureInfo, QByteArray(), signature, QByteArray(), index, mode);
|
model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Padding"), tr("Intel signature"), signatureInfo, QByteArray(), signature, QByteArray(), index, mode);
|
||||||
|
|
||||||
// Get internal lzma section data
|
// Get internal LZMA section data
|
||||||
QByteArray lzmaSection = body.mid(signature.size());
|
QByteArray lzmaSection = body.mid(signature.size());
|
||||||
// Parse internal sections
|
// Parse internal sections
|
||||||
result = parseSections(lzmaSection, index);
|
result = parseSections(lzmaSection, index);
|
||||||
@ -1489,9 +1518,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
body = section.mid(sizeof(EFI_DISPOSABLE_SECTION), sectionSize - sizeof(EFI_DISPOSABLE_SECTION));
|
body = section.mid(sizeof(EFI_DISPOSABLE_SECTION), sectionSize - sizeof(EFI_DISPOSABLE_SECTION));
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("parseSection: 0x%1\nSize: 0x%2")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6);
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
||||||
@ -1513,9 +1543,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
body = section.mid(headerSize, sectionSize - headerSize);
|
body = section.mid(headerSize, sectionSize - headerSize);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6);
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size());
|
||||||
|
|
||||||
// Parse dependency expression
|
// Parse dependency expression
|
||||||
QString str;
|
QString str;
|
||||||
@ -1542,9 +1573,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
body = section.mid(headerSize, sectionSize - headerSize);
|
body = section.mid(headerSize, sectionSize - headerSize);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6);
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
||||||
@ -1565,9 +1597,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
|
|
||||||
EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgHeader = (EFI_FREEFORM_SUBTYPE_GUID_SECTION*)sectionHeader;
|
EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgHeader = (EFI_FREEFORM_SUBTYPE_GUID_SECTION*)sectionHeader;
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2\nSubtype GUID: %3")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)\nSubtype GUID: %6")
|
||||||
.hexarg(fsgHeader->Type, 2)
|
.hexarg(fsgHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6)
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size())
|
||||||
.arg(guidToQString(fsgHeader->SubTypeGuid));
|
.arg(guidToQString(fsgHeader->SubTypeGuid));
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
@ -1581,9 +1614,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
EFI_VERSION_SECTION* versionHeader = (EFI_VERSION_SECTION*)sectionHeader;
|
EFI_VERSION_SECTION* versionHeader = (EFI_VERSION_SECTION*)sectionHeader;
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2\nBuild number: %3\nVersion string: %4")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)\nBuild number: %6\nVersion string: %7")
|
||||||
.hexarg(versionHeader->Type, 2)
|
.hexarg(versionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6)
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size())
|
||||||
.arg(versionHeader->BuildNumber)
|
.arg(versionHeader->BuildNumber)
|
||||||
.arg(QString::fromUtf16((const ushort*)body.constData()));
|
.arg(QString::fromUtf16((const ushort*)body.constData()));
|
||||||
|
|
||||||
@ -1597,9 +1631,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
QString text = QString::fromUtf16((const ushort*)body.constData());
|
QString text = QString::fromUtf16((const ushort*)body.constData());
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2\nText: %3")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)\nText: %6")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6)
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size())
|
||||||
.arg(text);
|
.arg(text);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
@ -1614,9 +1649,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
body = section.mid(sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION), sectionSize - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));
|
body = section.mid(sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION), sectionSize - sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION));
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6);
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
||||||
@ -1635,9 +1671,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
body = section.mid(sizeof(EFI_RAW_SECTION), sectionSize - sizeof(EFI_RAW_SECTION));
|
body = section.mid(sizeof(EFI_RAW_SECTION), sectionSize - sizeof(EFI_RAW_SECTION));
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6);
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size());
|
||||||
|
|
||||||
// Check for apriori file
|
// Check for apriori file
|
||||||
QModelIndex parentFile = model->findParentOfType(parent, Types::File);
|
QModelIndex parentFile = model->findParentOfType(parent, Types::File);
|
||||||
@ -1682,16 +1719,35 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCT_SECTION_POSTCODE: {
|
|
||||||
header = section.left(sizeof(SCT_POSTCODE_SECTION));
|
|
||||||
body = section.mid(sizeof(SCT_POSTCODE_SECTION), sectionSize - sizeof(SCT_POSTCODE_SECTION));
|
|
||||||
|
|
||||||
SCT_POSTCODE_SECTION* postcodeHeader = (SCT_POSTCODE_SECTION*)sectionHeader;
|
case HP_SECTION_POSTCODE: {
|
||||||
|
header = section.left(sizeof(POSTCODE_SECTION));
|
||||||
|
body = section.mid(sizeof(POSTCODE_SECTION), sectionSize - sizeof(POSTCODE_SECTION));
|
||||||
|
|
||||||
|
POSTCODE_SECTION* postcodeHeader = (POSTCODE_SECTION*)sectionHeader;
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2\nPostcode: 0x%3")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)\nPostcode: 0x%6")
|
||||||
.hexarg(postcodeHeader->Type, 2)
|
.hexarg(postcodeHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6)
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size())
|
||||||
|
.hexarg(postcodeHeader->Postcode, 2);
|
||||||
|
|
||||||
|
// Add tree item
|
||||||
|
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCT_SECTION_POSTCODE: {
|
||||||
|
header = section.left(sizeof(POSTCODE_SECTION));
|
||||||
|
body = section.mid(sizeof(POSTCODE_SECTION), sectionSize - sizeof(POSTCODE_SECTION));
|
||||||
|
|
||||||
|
POSTCODE_SECTION* postcodeHeader = (POSTCODE_SECTION*)sectionHeader;
|
||||||
|
|
||||||
|
// Get info
|
||||||
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)\nPostcode: 0x%6")
|
||||||
|
.hexarg(postcodeHeader->Type, 2)
|
||||||
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size())
|
||||||
.hexarg(postcodeHeader->Postcode, 2);
|
.hexarg(postcodeHeader->Postcode, 2);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
@ -1703,9 +1759,10 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
header = section.left(sizeof(EFI_COMMON_SECTION_HEADER));
|
header = section.left(sizeof(EFI_COMMON_SECTION_HEADER));
|
||||||
body = section.mid(sizeof(EFI_COMMON_SECTION_HEADER), sectionSize - sizeof(EFI_COMMON_SECTION_HEADER));
|
body = section.mid(sizeof(EFI_COMMON_SECTION_HEADER), sectionSize - sizeof(EFI_COMMON_SECTION_HEADER));
|
||||||
// Get info
|
// Get info
|
||||||
info = tr("Type: 0x%1\nSize: 0x%2")
|
info = tr("Type: 0x%1\nHeader size: 0x%2(%3)\nBody size: 0x%4(%5)")
|
||||||
.hexarg(sectionHeader->Type, 2)
|
.hexarg(sectionHeader->Type, 2)
|
||||||
.hexarg(body.size(), 6);
|
.hexarg(header.size(), 2).arg(header.size())
|
||||||
|
.hexarg(body.size(), 6).arg(body.size());
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
index = model->addItem(Types::Section, sectionHeader->Type, COMPRESSION_ALGORITHM_NONE, name, "", info, header, body, QByteArray(), parent, mode);
|
||||||
@ -2844,6 +2901,24 @@ UINT8 FfsEngine::reconstructVolume(const QModelIndex & index, QByteArray & recon
|
|||||||
|
|
||||||
// Reconstruction successful
|
// Reconstruction successful
|
||||||
reconstructed = header.append(reconstructed);
|
reconstructed = header.append(reconstructed);
|
||||||
|
|
||||||
|
// Recalculate CRC32 in ZeroVector, if needed
|
||||||
|
if (model->subtype(index) == Subtypes::AppleCrcVolume || model->subtype(index) == Subtypes::UnknownAppleCrcVolume) {
|
||||||
|
// Get current CRC32 value from volume header
|
||||||
|
UINT32 current = *(UINT32*)(reconstructed.constData() + 8);
|
||||||
|
// Calculate new value
|
||||||
|
UINT32 crc = crc32(0, NULL, 0);
|
||||||
|
crc = crc32(crc, (const UINT8*)reconstructed.constData() + volumeHeader->HeaderLength, reconstructed.size() - volumeHeader->HeaderLength);
|
||||||
|
// Update the value
|
||||||
|
if (current != crc) {
|
||||||
|
*(UINT32*)(reconstructed.data() + 8) = crc;
|
||||||
|
|
||||||
|
// Recalculate header checksum again
|
||||||
|
volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)reconstructed.data();
|
||||||
|
volumeHeader->Checksum = 0;
|
||||||
|
volumeHeader->Checksum = calculateChecksum16((UINT16*)volumeHeader, volumeHeader->HeaderLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +85,12 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
|||||||
return QObject::tr("Unknown");
|
return QObject::tr("Unknown");
|
||||||
else if (subtype == Subtypes::NvramVolume)
|
else if (subtype == Subtypes::NvramVolume)
|
||||||
return QObject::tr("NVRAM");
|
return QObject::tr("NVRAM");
|
||||||
|
else if (subtype == Subtypes::AppleCrcVolume)
|
||||||
|
return QObject::tr("AppleCRC");
|
||||||
|
else if (subtype == Subtypes::UnknownAppleCrcVolume)
|
||||||
|
return QObject::tr("AppleCRC Unknown");
|
||||||
|
else if (subtype == Subtypes::BootAppleCrcVolume)
|
||||||
|
return QObject::tr("AppleCRC Boot");
|
||||||
else
|
else
|
||||||
return "";
|
return "";
|
||||||
case Types::Capsule:
|
case Types::Capsule:
|
||||||
|
5
types.h
5
types.h
@ -59,7 +59,10 @@ namespace Subtypes {
|
|||||||
NormalVolume = 90,
|
NormalVolume = 90,
|
||||||
BootVolume,
|
BootVolume,
|
||||||
UnknownVolume,
|
UnknownVolume,
|
||||||
NvramVolume
|
NvramVolume,
|
||||||
|
AppleCrcVolume,
|
||||||
|
UnknownAppleCrcVolume,
|
||||||
|
BootAppleCrcVolume
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RegionSubtypes {
|
enum RegionSubtypes {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
UEFITool::UEFITool(QWidget *parent) :
|
UEFITool::UEFITool(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::UEFITool),
|
ui(new Ui::UEFITool),
|
||||||
version(tr("0.19.5"))
|
version(tr("0.19.6"))
|
||||||
{
|
{
|
||||||
clipboard = QApplication::clipboard();
|
clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ void UEFITool::populateUi(const QModelIndex ¤t)
|
|||||||
// Enable actions
|
// Enable actions
|
||||||
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current) && model->hasEmptyTail(current));
|
||||||
ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
ui->actionRebuild->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
||||||
ui->actionExtractBody->setDisabled(model->hasEmptyHeader(current));
|
ui->actionExtractBody->setDisabled(model->hasEmptyBody(current));
|
||||||
ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
ui->actionRemove->setEnabled(type == Types::Volume || type == Types::File || type == Types::Section);
|
||||||
ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
|
ui->actionInsertInto->setEnabled((type == Types::Volume && subtype != Subtypes::UnknownVolume) ||
|
||||||
(type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) ||
|
(type == Types::File && subtype != EFI_FV_FILETYPE_ALL && subtype != EFI_FV_FILETYPE_RAW && subtype != EFI_FV_FILETYPE_PAD) ||
|
||||||
|
Loading…
Reference in New Issue
Block a user