mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 07:58:22 +08:00
Add support for Apple-specific section headers
- and some new PE machine types
This commit is contained in:
parent
cd1cc09b39
commit
2d932da1f3
@ -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.30.0_alpha27"))
|
version(tr("0.30.0_alpha28"))
|
||||||
{
|
{
|
||||||
clipboard = QApplication::clipboard();
|
clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
|
90
common/ffs.h
90
common/ffs.h
@ -368,14 +368,24 @@ typedef struct EFI_COMMON_SECTION_HEADER_ {
|
|||||||
|
|
||||||
// Large file common section header
|
// Large file common section header
|
||||||
typedef struct EFI_COMMON_SECTION_HEADER2_ {
|
typedef struct EFI_COMMON_SECTION_HEADER2_ {
|
||||||
UINT8 Size[3]; //Must be 0xFFFFFF for this header to be used
|
UINT8 Size[3]; // Must be 0xFFFFFF for this header to be used
|
||||||
UINT8 Type;
|
UINT8 Type;
|
||||||
UINT32 ExtendedSize;
|
UINT32 ExtendedSize;
|
||||||
} EFI_COMMON_SECTION_HEADER2;
|
} EFI_COMMON_SECTION_HEADER2;
|
||||||
|
|
||||||
|
// Apple common section header
|
||||||
|
typedef struct EFI_COMMON_SECTION_HEADER_APPLE {
|
||||||
|
UINT8 Size[3];
|
||||||
|
UINT8 Type;
|
||||||
|
UINT32 Reserved; // Must be 0x7FFF for this header to be used
|
||||||
|
} EFI_COMMON_SECTION_HEADER_APPLE;
|
||||||
|
|
||||||
// Section2 usage indicator
|
// Section2 usage indicator
|
||||||
#define EFI_SECTION2_IS_USED 0xFFFFFF
|
#define EFI_SECTION2_IS_USED 0xFFFFFF
|
||||||
|
|
||||||
|
// Apple section usage indicator
|
||||||
|
#define EFI_SECTION_APPLE_USED 0x7FFF
|
||||||
|
|
||||||
// File section types
|
// File section types
|
||||||
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
|
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
|
||||||
|
|
||||||
@ -398,23 +408,18 @@ typedef struct EFI_COMMON_SECTION_HEADER2_ {
|
|||||||
#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 PHOENIX_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
|
#define PHOENIX_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
|
||||||
#define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde images
|
#define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde H2O images
|
||||||
|
|
||||||
// Compression section
|
// Compression section
|
||||||
typedef struct EFI_COMPRESSION_SECTION_ {
|
typedef struct EFI_COMPRESSION_SECTION_ {
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT32 UncompressedLength;
|
UINT32 UncompressedLength;
|
||||||
UINT8 CompressionType;
|
UINT8 CompressionType;
|
||||||
} EFI_COMPRESSION_SECTION;
|
} EFI_COMPRESSION_SECTION;
|
||||||
|
|
||||||
typedef struct EFI_COMPRESSION_SECTION2_ {
|
typedef struct EFI_COMPRESSION_SECTION_APPLE_ {
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT32 ExtendedSize;
|
|
||||||
UINT32 UncompressedLength;
|
UINT32 UncompressedLength;
|
||||||
UINT8 CompressionType;
|
UINT32 CompressionType;
|
||||||
} EFI_COMPRESSION_SECTION2;
|
} EFI_COMPRESSION_SECTION_APPLE;
|
||||||
|
|
||||||
// Compression types
|
// Compression types
|
||||||
#define EFI_NOT_COMPRESSED 0x00
|
#define EFI_NOT_COMPRESSED 0x00
|
||||||
@ -423,21 +428,17 @@ typedef struct EFI_COMPRESSION_SECTION2_ {
|
|||||||
|
|
||||||
//GUID defined section
|
//GUID defined section
|
||||||
typedef struct EFI_GUID_DEFINED_SECTION_ {
|
typedef struct EFI_GUID_DEFINED_SECTION_ {
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
EFI_GUID SectionDefinitionGuid;
|
EFI_GUID SectionDefinitionGuid;
|
||||||
UINT16 DataOffset;
|
UINT16 DataOffset;
|
||||||
UINT16 Attributes;
|
UINT16 Attributes;
|
||||||
} EFI_GUID_DEFINED_SECTION;
|
} EFI_GUID_DEFINED_SECTION;
|
||||||
|
|
||||||
typedef struct EFI_GUID_DEFINED_SECTION2_ {
|
typedef struct EFI_GUID_DEFINED_SECTION_APPLE_ {
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT32 ExtendedSize;
|
|
||||||
EFI_GUID SectionDefinitionGuid;
|
EFI_GUID SectionDefinitionGuid;
|
||||||
UINT16 DataOffset;
|
UINT16 DataOffset;
|
||||||
UINT16 Attributes;
|
UINT16 Attributes;
|
||||||
} EFI_GUID_DEFINED_SECTION2;
|
UINT32 Reserved;
|
||||||
|
} EFI_GUID_DEFINED_SECTION_APPLE;
|
||||||
|
|
||||||
// Attributes for GUID defined section
|
// Attributes for GUID defined section
|
||||||
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
|
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
|
||||||
@ -453,7 +454,7 @@ const QByteArray EFI_GUIDED_SECTION_TIANO // A31280AD-481E-41B6-95E8-127F4C98477
|
|||||||
const QByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF
|
const QByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF
|
||||||
("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16);
|
("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16);
|
||||||
|
|
||||||
const QByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID //0F9D89E8-9259-4F76-A5AF-0C89E34023DF
|
const QByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID // 0F9D89E8-9259-4F76-A5AF-0C89E34023DF
|
||||||
("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16);
|
("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16);
|
||||||
|
|
||||||
//#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
//#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||||
@ -475,8 +476,6 @@ typedef struct WIN_CERTIFICATE_UEFI_GUID_ {
|
|||||||
// WIN_CERTIFICATE_UEFI_GUID.CertType
|
// WIN_CERTIFICATE_UEFI_GUID.CertType
|
||||||
const QByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID
|
const QByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID
|
||||||
("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF");
|
("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF");
|
||||||
//const QByteArray EFI_CERT_TYPE_PKCS7_GUID
|
|
||||||
//("\x9D\xD2\xAF\x4A\xDF\x68\xEE\x49\x8A\xA9\x34\x7D\x37\x56\x65\xA7");
|
|
||||||
|
|
||||||
// WIN_CERTIFICATE_UEFI_GUID.CertData
|
// WIN_CERTIFICATE_UEFI_GUID.CertData
|
||||||
typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ {
|
typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ {
|
||||||
@ -487,70 +486,19 @@ typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ {
|
|||||||
|
|
||||||
// Version section
|
// Version section
|
||||||
typedef struct EFI_VERSION_SECTION_ {
|
typedef struct EFI_VERSION_SECTION_ {
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT16 BuildNumber;
|
UINT16 BuildNumber;
|
||||||
} EFI_VERSION_SECTION;
|
} EFI_VERSION_SECTION;
|
||||||
|
|
||||||
typedef struct EFI_VERSION_SECTION2_ {
|
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT32 ExtendedSize;
|
|
||||||
UINT16 BuildNumber;
|
|
||||||
} EFI_VERSION_SECTION2;
|
|
||||||
|
|
||||||
// Freeform subtype GUID section
|
// Freeform subtype GUID section
|
||||||
typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION_ {
|
typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION_ {
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
EFI_GUID SubTypeGuid;
|
EFI_GUID SubTypeGuid;
|
||||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
||||||
|
|
||||||
typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION2_ {
|
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT32 ExtendedSize;
|
|
||||||
EFI_GUID SubTypeGuid;
|
|
||||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
|
|
||||||
|
|
||||||
// Phoenix SCT and Insyde postcode section
|
// Phoenix SCT and Insyde postcode section
|
||||||
typedef struct POSTCODE_SECTION_ {
|
typedef struct POSTCODE_SECTION_ {
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT32 Postcode;
|
UINT32 Postcode;
|
||||||
} POSTCODE_SECTION;
|
} POSTCODE_SECTION;
|
||||||
|
|
||||||
typedef struct POSTCODE_SECTION2_ {
|
|
||||||
UINT8 Size[3];
|
|
||||||
UINT8 Type;
|
|
||||||
UINT32 ExtendedSize;
|
|
||||||
UINT32 Postcode;
|
|
||||||
} POSTCODE_SECTION2;
|
|
||||||
|
|
||||||
// Other sections
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
|
|
||||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
|
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
// EFI Dependency Expression
|
// EFI Dependency Expression
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -1870,23 +1870,37 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
|
|||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
UINT32 headerSize;
|
||||||
UINT32 headerSize = sizeof(EFI_COMMON_SECTION_HEADER);
|
UINT8 type;
|
||||||
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED)
|
const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
|
||||||
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2);
|
if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) {
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE);
|
||||||
|
type = appleHeader->Type;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER);
|
||||||
|
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED)
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2);
|
||||||
|
type = sectionHeader->Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check sanity again
|
||||||
|
if ((UINT32)section.size() < headerSize)
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
QByteArray header = section.left(headerSize);
|
QByteArray header = section.left(headerSize);
|
||||||
QByteArray body = section.mid(headerSize);
|
QByteArray body = section.mid(headerSize);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section");
|
QString name = sectionTypeToQString(type) + QObject::tr(" section");
|
||||||
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)")
|
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)")
|
||||||
.hexarg2(sectionHeader->Type, 2)
|
.hexarg2(type, 2)
|
||||||
.hexarg(section.size()).arg(section.size())
|
.hexarg(section.size()).arg(section.size())
|
||||||
.hexarg(headerSize).arg(headerSize)
|
.hexarg(headerSize).arg(headerSize)
|
||||||
.hexarg(body.size()).arg(body.size());
|
.hexarg(body.size()).arg(body.size());
|
||||||
@ -1896,7 +1910,7 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (!preparse) {
|
if (!preparse) {
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, QByteArray(), true, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, type, name, QString(), info, header, body, QByteArray(), true, parsingDataToQByteArray(pdata), parent);
|
||||||
}
|
}
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1904,27 +1918,45 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
|
|||||||
STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMPRESSION_SECTION))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
|
UINT32 headerSize;
|
||||||
|
UINT8 compressionType;
|
||||||
|
UINT32 uncompressedLength;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)sectionHeader;
|
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
|
||||||
UINT32 headerSize = sizeof(EFI_COMPRESSION_SECTION);
|
const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
|
||||||
UINT8 compressionType = compressedSectionHeader->CompressionType;
|
|
||||||
UINT32 uncompressedLength = compressedSectionHeader->UncompressedLength;
|
if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
|
||||||
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) {
|
const EFI_COMPRESSION_SECTION_APPLE* appleSectionHeader = (const EFI_COMPRESSION_SECTION_APPLE*)(appleHeader + 1);
|
||||||
if ((UINT32)section.size() < sizeof(EFI_COMPRESSION_SECTION2))
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_COMPRESSION_SECTION_APPLE);
|
||||||
|
compressionType = (UINT8)appleSectionHeader->CompressionType;
|
||||||
|
uncompressedLength = appleSectionHeader->UncompressedLength;
|
||||||
|
}
|
||||||
|
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
|
||||||
|
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(section2Header + 1);
|
||||||
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
const EFI_COMPRESSION_SECTION2* compressedSectionHeader2 = (const EFI_COMPRESSION_SECTION2*)sectionHeader;
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION);
|
||||||
headerSize = sizeof(EFI_COMPRESSION_SECTION2);
|
compressionType = compressedSectionHeader->CompressionType;
|
||||||
compressionType = compressedSectionHeader2->CompressionType;
|
uncompressedLength = compressedSectionHeader->UncompressedLength;
|
||||||
|
}
|
||||||
|
else { // Normal section
|
||||||
|
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(sectionHeader + 1);
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_COMPRESSION_SECTION);
|
||||||
|
compressionType = compressedSectionHeader->CompressionType;
|
||||||
uncompressedLength = compressedSectionHeader->UncompressedLength;
|
uncompressedLength = compressedSectionHeader->UncompressedLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check sanity again
|
||||||
|
if ((UINT32)section.size() < headerSize)
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
QByteArray header = section.left(headerSize);
|
QByteArray header = section.left(headerSize);
|
||||||
QByteArray body = section.mid(headerSize);
|
QByteArray body = section.mid(headerSize);
|
||||||
|
|
||||||
@ -1953,28 +1985,49 @@ STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const
|
|||||||
STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_GUID_DEFINED_SECTION))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
|
UINT32 headerSize;
|
||||||
|
EFI_GUID guid;
|
||||||
|
UINT16 dataOffset;
|
||||||
|
UINT16 attributes;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)sectionHeader;
|
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
|
||||||
EFI_GUID guid = guidDefinedSectionHeader->SectionDefinitionGuid;
|
const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
|
||||||
UINT16 dataOffset = guidDefinedSectionHeader->DataOffset;
|
|
||||||
UINT16 attributes = guidDefinedSectionHeader->Attributes;
|
if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
|
||||||
UINT32 nextHeaderOffset = sizeof(EFI_GUID_DEFINED_SECTION);
|
const EFI_GUID_DEFINED_SECTION_APPLE* appleSectionHeader = (const EFI_GUID_DEFINED_SECTION_APPLE*)(appleHeader + 1);
|
||||||
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) {
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_GUID_DEFINED_SECTION_APPLE);
|
||||||
if ((UINT32)section.size() < sizeof(EFI_GUID_DEFINED_SECTION2))
|
if ((UINT32)section.size() < headerSize)
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
const EFI_GUID_DEFINED_SECTION2* guidDefinedSectionHeader2 = (const EFI_GUID_DEFINED_SECTION2*)sectionHeader;
|
guid = appleSectionHeader->SectionDefinitionGuid;
|
||||||
guid = guidDefinedSectionHeader2->SectionDefinitionGuid;
|
dataOffset = appleSectionHeader->DataOffset;
|
||||||
dataOffset = guidDefinedSectionHeader2->DataOffset;
|
attributes = appleSectionHeader->Attributes;
|
||||||
attributes = guidDefinedSectionHeader2->Attributes;
|
|
||||||
nextHeaderOffset = sizeof(EFI_GUID_DEFINED_SECTION2);
|
|
||||||
}
|
}
|
||||||
|
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
|
||||||
|
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(section2Header + 1);
|
||||||
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_GUID_DEFINED_SECTION))
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_GUID_DEFINED_SECTION);
|
||||||
|
guid = guidDefinedSectionHeader->SectionDefinitionGuid;
|
||||||
|
dataOffset = guidDefinedSectionHeader->DataOffset;
|
||||||
|
attributes = guidDefinedSectionHeader->Attributes;
|
||||||
|
}
|
||||||
|
else { // Normal section
|
||||||
|
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(sectionHeader + 1);
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_GUID_DEFINED_SECTION);
|
||||||
|
guid = guidDefinedSectionHeader->SectionDefinitionGuid;
|
||||||
|
dataOffset = guidDefinedSectionHeader->DataOffset;
|
||||||
|
attributes = guidDefinedSectionHeader->Attributes;
|
||||||
|
}
|
||||||
|
// Check sanity again
|
||||||
|
if ((UINT32)section.size() < headerSize)
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
// Check for special GUIDed sections
|
// Check for special GUIDed sections
|
||||||
QByteArray additionalInfo;
|
QByteArray additionalInfo;
|
||||||
@ -1991,10 +2044,10 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
|
|||||||
msgNoAuthStatusAttribute = true;
|
msgNoAuthStatusAttribute = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((UINT32)section.size() < nextHeaderOffset + sizeof(UINT32))
|
if ((UINT32)section.size() < headerSize + sizeof(UINT32))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
UINT32 crc = *(UINT32*)(section.constData() + nextHeaderOffset);
|
UINT32 crc = *(UINT32*)(section.constData() + headerSize);
|
||||||
additionalInfo += QObject::tr("\nChecksum type: CRC32");
|
additionalInfo += QObject::tr("\nChecksum type: CRC32");
|
||||||
// Calculate CRC32 of section data
|
// Calculate CRC32 of section data
|
||||||
UINT32 calculated = crc32(0, (const UINT8*)section.constData() + dataOffset, section.size() - dataOffset);
|
UINT32 calculated = crc32(0, (const UINT8*)section.constData() + dataOffset, section.size() - dataOffset);
|
||||||
@ -2019,10 +2072,10 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get certificate type and length
|
// Get certificate type and length
|
||||||
if ((UINT32)section.size() < nextHeaderOffset + sizeof(WIN_CERTIFICATE))
|
if ((UINT32)section.size() < headerSize + sizeof(WIN_CERTIFICATE))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
const WIN_CERTIFICATE* winCertificate = (const WIN_CERTIFICATE*)(section.constData() + nextHeaderOffset);
|
const WIN_CERTIFICATE* winCertificate = (const WIN_CERTIFICATE*)(section.constData() + headerSize);
|
||||||
UINT32 certLength = winCertificate->Length;
|
UINT32 certLength = winCertificate->Length;
|
||||||
UINT16 certType = winCertificate->CertificateType;
|
UINT16 certType = winCertificate->CertificateType;
|
||||||
|
|
||||||
@ -2038,7 +2091,7 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
|
|||||||
additionalInfo += QObject::tr("\nCertificate type: UEFI");
|
additionalInfo += QObject::tr("\nCertificate type: UEFI");
|
||||||
|
|
||||||
// Get certificate GUID
|
// Get certificate GUID
|
||||||
const WIN_CERTIFICATE_UEFI_GUID* winCertificateUefiGuid = (const WIN_CERTIFICATE_UEFI_GUID*)(section.constData() + nextHeaderOffset);
|
const WIN_CERTIFICATE_UEFI_GUID* winCertificateUefiGuid = (const WIN_CERTIFICATE_UEFI_GUID*)(section.constData() + headerSize);
|
||||||
QByteArray certTypeGuid((const char*)&winCertificateUefiGuid->CertType, sizeof(EFI_GUID));
|
QByteArray certTypeGuid((const char*)&winCertificateUefiGuid->CertType, sizeof(EFI_GUID));
|
||||||
|
|
||||||
if (certTypeGuid == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
|
if (certTypeGuid == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
|
||||||
@ -2104,32 +2157,52 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
|
|||||||
STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
|
UINT32 headerSize;
|
||||||
|
EFI_GUID guid;
|
||||||
|
UINT8 type;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)sectionHeader;
|
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
|
||||||
UINT32 headerSize = sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
|
const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
|
||||||
EFI_GUID guid = fsgHeader->SubTypeGuid;
|
|
||||||
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) {
|
if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
|
||||||
if ((UINT32)section.size() < sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION2))
|
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* appleSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(appleHeader + 1);
|
||||||
return ERR_INVALID_SECTION;
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
|
||||||
const EFI_FREEFORM_SUBTYPE_GUID_SECTION2* fsgHeader2 = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION2*)sectionHeader;
|
guid = appleSectionHeader->SubTypeGuid;
|
||||||
headerSize = sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION2);
|
type = appleHeader->Type;
|
||||||
guid = fsgHeader2->SubTypeGuid;
|
|
||||||
}
|
}
|
||||||
|
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
|
||||||
|
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(section2Header + 1);
|
||||||
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION))
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
|
||||||
|
guid = fsgSectionHeader->SubTypeGuid;
|
||||||
|
type = section2Header->Type;
|
||||||
|
}
|
||||||
|
else { // Normal section
|
||||||
|
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(sectionHeader + 1);
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
|
||||||
|
guid = fsgSectionHeader->SubTypeGuid;
|
||||||
|
type = sectionHeader->Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check sanity again
|
||||||
|
if ((UINT32)section.size() < headerSize)
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
QByteArray header = section.left(headerSize);
|
QByteArray header = section.left(headerSize);
|
||||||
QByteArray body = section.mid(headerSize);
|
QByteArray body = section.mid(headerSize);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section");
|
QString name = sectionTypeToQString(type) + QObject::tr(" section");
|
||||||
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nSubtype GUID: %8")
|
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nSubtype GUID: %8")
|
||||||
.hexarg2(fsgHeader->Type, 2)
|
.hexarg2(type, 2)
|
||||||
.hexarg(section.size()).arg(section.size())
|
.hexarg(section.size()).arg(section.size())
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
@ -2141,7 +2214,7 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (!preparse) {
|
if (!preparse) {
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent);
|
||||||
|
|
||||||
// Rename section
|
// Rename section
|
||||||
model->setName(index, guidToQString(guid));
|
model->setName(index, guidToQString(guid));
|
||||||
@ -2152,32 +2225,50 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
|
|||||||
STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(EFI_VERSION_SECTION))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
|
UINT32 headerSize;
|
||||||
|
UINT16 buildNumber;
|
||||||
|
UINT8 type;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)sectionHeader;
|
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
|
||||||
UINT32 headerSize = sizeof(EFI_VERSION_SECTION);
|
const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
|
||||||
UINT16 buildNumber = versionHeader->BuildNumber;
|
|
||||||
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) {
|
if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
|
||||||
if ((UINT32)section.size() < sizeof(EFI_VERSION_SECTION2))
|
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(appleHeader + 1);
|
||||||
return ERR_INVALID_SECTION;
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_VERSION_SECTION);
|
||||||
const EFI_VERSION_SECTION2* versionHeader2 = (const EFI_VERSION_SECTION2*)sectionHeader;
|
buildNumber = versionHeader->BuildNumber;
|
||||||
headerSize = sizeof(EFI_VERSION_SECTION2);
|
type = appleHeader->Type;
|
||||||
buildNumber = versionHeader2->BuildNumber;
|
|
||||||
}
|
}
|
||||||
|
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
|
||||||
|
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(section2Header + 1);
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_VERSION_SECTION);
|
||||||
|
buildNumber = versionHeader->BuildNumber;
|
||||||
|
type = section2Header->Type;
|
||||||
|
}
|
||||||
|
else { // Normal section
|
||||||
|
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(sectionHeader + 1);
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_VERSION_SECTION);
|
||||||
|
buildNumber = versionHeader->BuildNumber;
|
||||||
|
type = sectionHeader->Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check sanity again
|
||||||
|
if ((UINT32)section.size() < headerSize)
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
QByteArray header = section.left(headerSize);
|
QByteArray header = section.left(headerSize);
|
||||||
QByteArray body = section.mid(headerSize);
|
QByteArray body = section.mid(headerSize);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section");
|
QString name = sectionTypeToQString(type) + QObject::tr(" section");
|
||||||
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nBuild number: %8")
|
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nBuild number: %8")
|
||||||
.hexarg2(versionHeader->Type, 2)
|
.hexarg2(type, 2)
|
||||||
.hexarg(section.size()).arg(section.size())
|
.hexarg(section.size()).arg(section.size())
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
@ -2188,7 +2279,7 @@ STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UI
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
if (!preparse) {
|
if (!preparse) {
|
||||||
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent);
|
index = model->addItem(Types::Section, type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent);
|
||||||
}
|
}
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -2196,32 +2287,50 @@ STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UI
|
|||||||
STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
|
||||||
{
|
{
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if ((UINT32)section.size() < sizeof(POSTCODE_SECTION))
|
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
return ERR_INVALID_SECTION;
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
// Get data from parent's parsing data
|
// Get data from parent's parsing data
|
||||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||||
|
|
||||||
// Obtain header fields
|
// Obtain header fields
|
||||||
|
UINT32 headerSize;
|
||||||
|
UINT32 postCode;
|
||||||
|
UINT8 type;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
|
||||||
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)sectionHeader;
|
const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
|
||||||
UINT32 headerSize = sizeof(POSTCODE_SECTION);
|
const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
|
||||||
UINT32 postCode = postcodeHeader->Postcode;
|
|
||||||
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) {
|
if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
|
||||||
if ((UINT32)section.size() < sizeof(POSTCODE_SECTION2))
|
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(appleHeader + 1);
|
||||||
return ERR_INVALID_SECTION;
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(POSTCODE_SECTION);
|
||||||
const POSTCODE_SECTION2* postcodeHeader2 = (const POSTCODE_SECTION2*)sectionHeader;
|
postCode = postcodeHeader->Postcode;
|
||||||
headerSize = sizeof(POSTCODE_SECTION2);
|
type = appleHeader->Type;
|
||||||
postCode = postcodeHeader2->Postcode;
|
|
||||||
}
|
}
|
||||||
|
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
|
||||||
|
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(section2Header + 1);
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(POSTCODE_SECTION);
|
||||||
|
postCode = postcodeHeader->Postcode;
|
||||||
|
type = section2Header->Type;
|
||||||
|
}
|
||||||
|
else { // Normal section
|
||||||
|
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(sectionHeader + 1);
|
||||||
|
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(POSTCODE_SECTION);
|
||||||
|
postCode = postcodeHeader->Postcode;
|
||||||
|
type = sectionHeader->Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check sanity again
|
||||||
|
if ((UINT32)section.size() < headerSize)
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
|
||||||
QByteArray header = section.left(headerSize);
|
QByteArray header = section.left(headerSize);
|
||||||
QByteArray body = section.mid(headerSize);
|
QByteArray body = section.mid(headerSize);
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section");
|
QString name = sectionTypeToQString(type) + QObject::tr(" section");
|
||||||
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nPostcode: %8h")
|
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nPostcode: %8h")
|
||||||
.hexarg2(postcodeHeader->Type, 2)
|
.hexarg2(type, 2)
|
||||||
.hexarg(section.size()).arg(section.size())
|
.hexarg(section.size()).arg(section.size())
|
||||||
.hexarg(header.size()).arg(header.size())
|
.hexarg(header.size()).arg(header.size())
|
||||||
.hexarg(body.size()).arg(body.size())
|
.hexarg(body.size()).arg(body.size())
|
||||||
|
@ -18,16 +18,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
QString machineTypeToQString(UINT16 machineType)
|
QString machineTypeToQString(UINT16 machineType)
|
||||||
{
|
{
|
||||||
switch (machineType) {
|
switch (machineType) {
|
||||||
case EFI_IMAGE_FILE_MACHINE_AMD64: return QObject::tr("x86-64");
|
case EFI_IMAGE_FILE_MACHINE_AMD64: return QObject::tr("x86-64");
|
||||||
case EFI_IMAGE_FILE_MACHINE_ARM: return QObject::tr("ARM");
|
case EFI_IMAGE_FILE_MACHINE_ARM: return QObject::tr("ARM");
|
||||||
case EFI_IMAGE_FILE_MACHINE_ARMNT: return QObject::tr("ARMv7");
|
case EFI_IMAGE_FILE_MACHINE_ARMNT: return QObject::tr("ARMv7");
|
||||||
case EFI_IMAGE_FILE_MACHINE_ARM64: return QObject::tr("ARM64");
|
case EFI_IMAGE_FILE_MACHINE_APPLE_ARM: return QObject::tr("Apple ARM");
|
||||||
case EFI_IMAGE_FILE_MACHINE_EBC: return QObject::tr("EBC");
|
case EFI_IMAGE_FILE_MACHINE_AARCH64: return QObject::tr("AARCH64");
|
||||||
case EFI_IMAGE_FILE_MACHINE_I386: return QObject::tr("x86");
|
case EFI_IMAGE_FILE_MACHINE_EBC: return QObject::tr("EBC");
|
||||||
case EFI_IMAGE_FILE_MACHINE_IA64: return QObject::tr("IA64");
|
case EFI_IMAGE_FILE_MACHINE_I386: return QObject::tr("x86");
|
||||||
case EFI_IMAGE_FILE_MACHINE_POWERPC: return QObject::tr("PowerPC");
|
case EFI_IMAGE_FILE_MACHINE_IA64: return QObject::tr("IA64");
|
||||||
case EFI_IMAGE_FILE_MACHINE_POWERPCFP: return QObject::tr("PowerPC FP");
|
case EFI_IMAGE_FILE_MACHINE_POWERPC: return QObject::tr("PowerPC");
|
||||||
case EFI_IMAGE_FILE_MACHINE_THUMB: return QObject::tr("Thumb");
|
case EFI_IMAGE_FILE_MACHINE_POWERPCFP: return QObject::tr("PowerPC FP");
|
||||||
default: return QObject::tr("Unknown %1h").hexarg2(machineType, 4);
|
case EFI_IMAGE_FILE_MACHINE_THUMB: return QObject::tr("ARM Thumb");
|
||||||
|
case EFI_IMAGE_FILE_MACHINE_RISCV32: return QObject::tr("RISC-V 32-bit");
|
||||||
|
case EFI_IMAGE_FILE_MACHINE_RISCV64: return QObject::tr("RISC-V 64-bit");
|
||||||
|
case EFI_IMAGE_FILE_MACHINE_RISCV128: return QObject::tr("RISC-V 128-bit");
|
||||||
|
default: return QObject::tr("Unknown %1h").hexarg2(machineType, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
1463
common/peimage.h
1463
common/peimage.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user