UE 0.10.2

- solved a bug in parsing of signed GUID defined sections
This commit is contained in:
Nikolaj Schlej 2015-07-12 08:15:03 +02:00
parent cb9ecc4b43
commit 48384557a5
4 changed files with 69 additions and 46 deletions

View file

@ -75,7 +75,7 @@ int main(int argc, char *argv[])
} }
} }
else { else {
std::cout << "UEFIExtract 0.10.1" << std::endl << std::endl std::cout << "UEFIExtract 0.10.2" << 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
<< "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl; << "Return value is a bit mask where 0 at position N means that file with GUID_N was found and unpacked, 1 otherwise" << std::endl;
return 1; return 1;

View file

@ -1444,6 +1444,9 @@ STATUS FfsParser::parseSections(QByteArray sections, const QModelIndex & index)
case Types::Padding: case Types::Padding:
// No parsing required // No parsing required
break; break;
case Types::Signature:
// No parsing required
break;
default: default:
return ERR_UNKNOWN_ITEM_TYPE; return ERR_UNKNOWN_ITEM_TYPE;
} }
@ -1622,42 +1625,6 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
QByteArray header = section.left(headerSize); QByteArray header = section.left(headerSize);
QByteArray body = section.mid(headerSize); QByteArray body = section.mid(headerSize);
// Check for signed section
bool msgSigned = false;
bool msgUnknownSignature = false;
bool msgUnknownUefiGuidSignature = false;
QString signInfo;
if (QByteArray((const char*)&guid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
msgSigned = true;
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)model->body(index).constData();
if (certificateHeader->CertificateType == WIN_CERT_TYPE_EFI_GUID) {
signInfo += tr("\nSignature type: UEFI");
const WIN_CERTIFICATE_UEFI_GUID* guidCertificateHeader = (const WIN_CERTIFICATE_UEFI_GUID*)certificateHeader;
if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
signInfo += tr("\nSignature subtype: RSA2048/SHA256");
}
else if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_PKCS7_GUID) {
signInfo += tr("\nSignature subtype: PCKS7");
}
else {
signInfo += tr("\nSignature subtype: unknown");
msgUnknownUefiGuidSignature = true;
}
}
else if (certificateHeader->CertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
signInfo += tr("\nSignature type: PCKS7");
}
else {
signInfo += tr("\nSignature type: unknown");
msgUnknownSignature = true;
}
// Add additional to the header
header.append(body.left(certificateHeader->Length));
// Get new body
body = body.mid(certificateHeader->Length);
}
// Get info // Get info
QString name = sectionTypeToQString(sectionHeader->Type) + tr(" section"); QString name = sectionTypeToQString(sectionHeader->Type) + tr(" section");
QString info = tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nSubtype GUID: %8") QString info = tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nSubtype GUID: %8")
@ -1666,7 +1633,6 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
.hexarg(header.size()).arg(header.size()) .hexarg(header.size()).arg(header.size())
.hexarg(body.size()).arg(body.size()) .hexarg(body.size()).arg(body.size())
.arg(guidToQString(guid)); .arg(guidToQString(guid));
if (!signInfo.isEmpty()) info.append(signInfo);
// Construct parsing data // Construct parsing data
pdata.offset += parentOffset; pdata.offset += parentOffset;
@ -1676,14 +1642,6 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
// Add tree item // Add tree item
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent); index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, parsingDataToQByteArray(pdata), parent);
// Show messages
if (msgSigned)
msg(tr("parseSection: signature may become invalid after any modification"), index);
if (msgUnknownUefiGuidSignature)
msg(tr("parseSection: GUID defined section with unknown signature subtype"), index);
if (msgUnknownSignature)
msg(tr("parseSection: GUID defined section with unknown signature type"), index);
// Rename section // Rename section
model->setName(index, guidToQString(guid)); model->setName(index, guidToQString(guid));
@ -1896,6 +1854,56 @@ STATUS FfsParser::parseGuidedSectionBody(const QModelIndex & index)
else else
info += tr("\nCompression algorithm: unknown"); info += tr("\nCompression algorithm: unknown");
} }
// Signed section
else if (QByteArray((const char*)&guid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
UINT8 subtype = 0;
bool msgUnknownSubtype = false;
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)model->body(index).constData();
QString signInfo = tr("Full Size: %1h (%2)").hexarg2(certificateHeader->Length, 8).arg(certificateHeader->Length);
signInfo += tr("\nType: Signature");
if (certificateHeader->CertificateType == WIN_CERT_TYPE_EFI_GUID) {
const WIN_CERTIFICATE_UEFI_GUID* guidCertificateHeader = (const WIN_CERTIFICATE_UEFI_GUID*)certificateHeader;
if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
signInfo += tr("\nSubtype: RSA2048/SHA256");
subtype = Subtypes::UefiSignature;
}
else if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_PKCS7_GUID) {
signInfo += tr("\nSubtype: PKCS7");
subtype = Subtypes::Pkcs7Signature;
}
else {
signInfo += tr("\nSubtype: unknown");
msgUnknownSubtype = true;
}
}
else if (certificateHeader->CertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
signInfo += tr("\nSubtype: PKCS7");
subtype = Subtypes::Pkcs7Signature;
}
else {
signInfo += tr("\nSubtype: unknown");
msgUnknownSubtype = true;
}
//Get parsing data
PARSING_DATA signPdata = parsingDataFromQModelIndex(index);
signPdata.offset += model->header(index).size();
if (signPdata.isOnFlash) signInfo.prepend(tr("Offset: %1h\n").hexarg(signPdata.offset));
// Add signature data to the tree
QModelIndex signatureIndex = model->addItem(Types::Signature, subtype, tr("Signature"), "", signInfo, QByteArray(), processed.left(certificateHeader->Length), parsingDataToQByteArray(signPdata), index);
// Show messages
msg(tr("parseGuidedSectionBody: signature may become invalid after any modification"), signatureIndex);
if (msgUnknownSubtype)
msg(tr("parseGuidedSectionBody: signature with unknown subtype"), signatureIndex);
// Change offset
pdata.offset += certificateHeader->Length;
// Get new body
processed = processed.mid(certificateHeader->Length);
}
// Unknown GUIDed section // Unknown GUIDed section
else { else {
parseCurrentSection = false; parseCurrentSection = false;

View file

@ -55,6 +55,8 @@ QString itemTypeToQString(const UINT8 type)
return QObject::tr("Section"); return QObject::tr("Section");
case Types::FreeSpace: case Types::FreeSpace:
return QObject::tr("Free space"); return QObject::tr("Free space");
case Types::Signature:
return QObject::tr("Signature");
default: default:
return QObject::tr("Unknown"); return QObject::tr("Unknown");
} }
@ -106,6 +108,13 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
return sectionTypeToQString(subtype); return sectionTypeToQString(subtype);
case Types::FreeSpace: case Types::FreeSpace:
return QString(); return QString();
case Types::Signature:
if (subtype == Subtypes::UefiSignature)
return QObject::tr("UEFI");
else if (subtype == Subtypes::Pkcs7Signature)
return QObject::tr("PKCS#7");
else
return QObject::tr("Unknown subtype");
default: default:
return QObject::tr("Unknown subtype"); return QObject::tr("Unknown subtype");
} }

View file

@ -42,6 +42,7 @@ namespace Types {
Volume, Volume,
File, File,
Section, Section,
Signature,
FreeSpace FreeSpace
}; };
} }
@ -77,6 +78,11 @@ namespace Subtypes {
OnePadding, OnePadding,
DataPadding DataPadding
}; };
enum SignatureSubtypes {
UefiSignature = 120,
Pkcs7Signature
};
}; };
// *ToQString conversion routines // *ToQString conversion routines