mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 16:08:23 +08:00
Fix #246
- fixed CPLD extension area parser hang - added some definitions for CSME types obtained from MEParser
This commit is contained in:
parent
963671a73e
commit
1f488862c6
@ -175,6 +175,8 @@ UString bpdtEntryTypeToUString(const UINT16 type)
|
|||||||
case BPDT_ENTRY_TYPE_TCSS_FW_IOM: return UString("TCSS FW IOM");
|
case BPDT_ENTRY_TYPE_TCSS_FW_IOM: return UString("TCSS FW IOM");
|
||||||
case BPDT_ENTRY_TYPE_TCSS_FW_PHY: return UString("TCSS FW PHY");
|
case BPDT_ENTRY_TYPE_TCSS_FW_PHY: return UString("TCSS FW PHY");
|
||||||
case BPDT_ENTRY_TYPE_TBT: return UString("TCSS TBT");
|
case BPDT_ENTRY_TYPE_TBT: return UString("TCSS TBT");
|
||||||
|
case BPDT_ENTRY_TYPE_SAMF: return UString("SAMF");
|
||||||
|
case BPDT_ENTRY_TYPE_PPHY: return UString("PPHY");
|
||||||
default: return usprintf("Unknown %u", type);
|
default: return usprintf("Unknown %u", type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,6 +211,11 @@ UString cpdExtensionTypeToUstring(const UINT32 type)
|
|||||||
case CPD_EXT_TYPE_IOM_METADATA: return UString("IOM Metadata");
|
case CPD_EXT_TYPE_IOM_METADATA: return UString("IOM Metadata");
|
||||||
case CPD_EXT_TYPE_MGP_METADATA: return UString("MGP Metadata");
|
case CPD_EXT_TYPE_MGP_METADATA: return UString("MGP Metadata");
|
||||||
case CPD_EXT_TYPE_TBT_METADATA: return UString("TBT Metadata");
|
case CPD_EXT_TYPE_TBT_METADATA: return UString("TBT Metadata");
|
||||||
|
case CPD_EXT_TYPE_GMF_CERTIFICATE: return UString("Golden Measurement File Certificate");
|
||||||
|
case CPD_EXT_TYPE_GMF_BODY: return UString("Golden Measurement File Body");
|
||||||
|
case CPD_EXT_TYPE_KEY_MANIFEST_EXT: return UString("Extended Key Manifest");
|
||||||
|
case CPD_EXT_TYPE_SIGNED_PACKAGE_INFO_EXT: return UString("Extended Signed Package Info");
|
||||||
|
case CPD_EXT_TYPE_SPS_PLATFORM_ID: return UString("SPS Platform ID");
|
||||||
default: return usprintf("Unknown %u", type);
|
default: return usprintf("Unknown %u", type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
common/ffs.h
20
common/ffs.h
@ -648,7 +648,8 @@ typedef struct BPDT_ENTRY_ {
|
|||||||
#define BPDT_ENTRY_TYPE_TCSS_FW_IOM 23
|
#define BPDT_ENTRY_TYPE_TCSS_FW_IOM 23
|
||||||
#define BPDT_ENTRY_TYPE_TCSS_FW_PHY 24
|
#define BPDT_ENTRY_TYPE_TCSS_FW_PHY 24
|
||||||
#define BPDT_ENTRY_TYPE_TBT 25
|
#define BPDT_ENTRY_TYPE_TBT 25
|
||||||
#define BPDT_LAST_KNOWN_ENTRY_TYPE BPDT_ENTRY_TYPE_TBT
|
#define BPDT_ENTRY_TYPE_SAMF 41
|
||||||
|
#define BPDT_ENTRY_TYPE_PPHY 42
|
||||||
|
|
||||||
// CPD
|
// CPD
|
||||||
#define CPD_SIGNATURE 0x44504324 //$CPD
|
#define CPD_SIGNATURE 0x44504324 //$CPD
|
||||||
@ -740,7 +741,11 @@ typedef struct CPD_EXTENTION_HEADER_ {
|
|||||||
#define CPD_EXT_TYPE_IOM_METADATA 24
|
#define CPD_EXT_TYPE_IOM_METADATA 24
|
||||||
#define CPD_EXT_TYPE_MGP_METADATA 25
|
#define CPD_EXT_TYPE_MGP_METADATA 25
|
||||||
#define CPD_EXT_TYPE_TBT_METADATA 26
|
#define CPD_EXT_TYPE_TBT_METADATA 26
|
||||||
#define CPD_LAST_KNOWN_EXT_TYPE CPD_EXT_TYPE_TBT_METADATA
|
#define CPD_EXT_TYPE_GMF_CERTIFICATE 30
|
||||||
|
#define CPD_EXT_TYPE_GMF_BODY 31
|
||||||
|
#define CPD_EXT_TYPE_KEY_MANIFEST_EXT 34
|
||||||
|
#define CPD_EXT_TYPE_SIGNED_PACKAGE_INFO_EXT 35
|
||||||
|
#define CPD_EXT_TYPE_SPS_PLATFORM_ID 50
|
||||||
|
|
||||||
typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_MODULE_ {
|
typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_MODULE_ {
|
||||||
UINT8 Name[12];
|
UINT8 Name[12];
|
||||||
@ -748,7 +753,7 @@ typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_MODULE_ {
|
|||||||
UINT8 HashAlgorithm;
|
UINT8 HashAlgorithm;
|
||||||
UINT16 HashSize;
|
UINT16 HashSize;
|
||||||
UINT32 MetadataSize;
|
UINT32 MetadataSize;
|
||||||
UINT8 MetadataHash[32];
|
UINT8 MetadataHash[1]; // Can be 32 or 48 bit
|
||||||
} CPD_EXT_SIGNED_PACKAGE_INFO_MODULE;
|
} CPD_EXT_SIGNED_PACKAGE_INFO_MODULE;
|
||||||
|
|
||||||
typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_ {
|
typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_ {
|
||||||
@ -765,12 +770,11 @@ typedef struct CPD_EXT_SIGNED_PACKAGE_INFO_ {
|
|||||||
typedef struct CPD_EXT_MODULE_ATTRIBUTES_ {
|
typedef struct CPD_EXT_MODULE_ATTRIBUTES_ {
|
||||||
UINT32 ExtensionType;
|
UINT32 ExtensionType;
|
||||||
UINT32 ExtensionLength;
|
UINT32 ExtensionLength;
|
||||||
UINT8 CompressionType;
|
UINT32 CompressionType;
|
||||||
UINT8 Reserved[3];
|
|
||||||
UINT32 UncompressedSize;
|
UINT32 UncompressedSize;
|
||||||
UINT32 CompressedSize;
|
UINT32 CompressedSize;
|
||||||
UINT32 GlobalModuleId;
|
UINT32 GlobalModuleId;
|
||||||
UINT8 ImageHash[32];
|
UINT8 ImageHash[1]; // The actual hash size is 32 or 48 bytes
|
||||||
} CPD_EXT_MODULE_ATTRIBUTES;
|
} CPD_EXT_MODULE_ATTRIBUTES;
|
||||||
|
|
||||||
#define CPD_EXT_MODULE_COMPRESSION_TYPE_UNCOMPRESSED 0
|
#define CPD_EXT_MODULE_COMPRESSION_TYPE_UNCOMPRESSED 0
|
||||||
@ -797,8 +801,8 @@ typedef struct CPD_EXT_IFWI_PARTITION_MANIFEST_ {
|
|||||||
UINT32 ReservedFlags : 23;
|
UINT32 ReservedFlags : 23;
|
||||||
UINT32 HashAlgorithm : 8;
|
UINT32 HashAlgorithm : 8;
|
||||||
UINT32 HashSize : 24;
|
UINT32 HashSize : 24;
|
||||||
UINT8 CompletePartitionHash[32];
|
UINT8 CompletePartitionHash[48];
|
||||||
UINT8 Reserved[20];
|
UINT8 Reserved[4];
|
||||||
} CPD_EXT_IFWI_PARTITION_MANIFEST;
|
} CPD_EXT_IFWI_PARTITION_MANIFEST;
|
||||||
|
|
||||||
// Restore previous packing rules
|
// Restore previous packing rules
|
||||||
|
@ -3871,10 +3871,10 @@ USTATUS FfsParser::parseFit(const UModelIndex & index)
|
|||||||
// Perform validation of BootGuard stuff
|
// Perform validation of BootGuard stuff
|
||||||
if (bgAcmFound) {
|
if (bgAcmFound) {
|
||||||
if (!bgKeyManifestFound) {
|
if (!bgKeyManifestFound) {
|
||||||
msg(usprintf("%s: ACM found, but KeyManifest isn't", __FUNCTION__), acmIndex);
|
msg(usprintf("%s: ACM found, but KeyManifest is not", __FUNCTION__), acmIndex);
|
||||||
}
|
}
|
||||||
else if (!bgBootPolicyFound) {
|
else if (!bgBootPolicyFound) {
|
||||||
msg(usprintf("%s: ACM and KeyManifest found, BootPolicy isn't", __FUNCTION__), kmIndex);
|
msg(usprintf("%s: ACM and KeyManifest found, BootPolicy is not", __FUNCTION__), kmIndex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Check key hashes
|
// Check key hashes
|
||||||
@ -4693,10 +4693,13 @@ make_partition_table_consistent:
|
|||||||
if (readUnaligned((const UINT32*)partition.constData()) == CPD_SIGNATURE) {
|
if (readUnaligned((const UINT32*)partition.constData()) == CPD_SIGNATURE) {
|
||||||
// Parse code partition contents
|
// Parse code partition contents
|
||||||
UModelIndex cpdIndex;
|
UModelIndex cpdIndex;
|
||||||
parseCpdRegion(partition, localOffset, partitionIndex, cpdIndex);
|
parseCpdRegion(partition, 0, partitionIndex, cpdIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (partitions[i].ptEntry.Type > BPDT_LAST_KNOWN_ENTRY_TYPE) {
|
// TODO: make this generic again
|
||||||
|
if (partitions[i].ptEntry.Type > BPDT_ENTRY_TYPE_TBT
|
||||||
|
&& partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_SAMF
|
||||||
|
&& partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_PPHY) {
|
||||||
msg(usprintf("%s: BPDT entry of unknown type found", __FUNCTION__), partitionIndex);
|
msg(usprintf("%s: BPDT entry of unknown type found", __FUNCTION__), partitionIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4765,11 +4768,11 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
|
|||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
UByteArray header = region.left(ptHeaderSize);
|
UByteArray header = region.left(ptHeaderSize);
|
||||||
UByteArray body = region.mid(ptHeaderSize);
|
UByteArray body = region.mid(ptHeaderSize, ptBodySize);
|
||||||
UString name = usprintf("CPD partition table");
|
UString name = usprintf("CPD partition table");
|
||||||
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nNumber of entries: %u\n"
|
UString info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")\nNumber of entries: %u\n"
|
||||||
"Header version: %02X\nEntry version: %02X",
|
"Header version: %u\nEntry version: %u",
|
||||||
region.size(), region.size(),
|
ptSize, ptSize,
|
||||||
header.size(), header.size(),
|
header.size(), header.size(),
|
||||||
body.size(), body.size(),
|
body.size(), body.size(),
|
||||||
cpdHeader->NumEntries,
|
cpdHeader->NumEntries,
|
||||||
@ -4832,8 +4835,8 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
|
|||||||
std::sort(partitions.begin(), partitions.end());
|
std::sort(partitions.begin(), partitions.end());
|
||||||
|
|
||||||
// Because lenghts for all Huffmann-compressed partitions mean nothing at all, we need to split all partitions into 2 classes:
|
// Because lenghts for all Huffmann-compressed partitions mean nothing at all, we need to split all partitions into 2 classes:
|
||||||
// 1. CPD manifest (should be the first)
|
// 1. CPD manifest
|
||||||
// 2. Metadata entries (should begin right after partition manifest and end before any code partition)
|
// 2. Metadata entries
|
||||||
UINT32 i = 1; // manifest is index 0, .met partitions start at index 1
|
UINT32 i = 1; // manifest is index 0, .met partitions start at index 1
|
||||||
while (i < partitions.size()) {
|
while (i < partitions.size()) {
|
||||||
name = usprintf("%.12s", partitions[i].ptEntry.EntryName);
|
name = usprintf("%.12s", partitions[i].ptEntry.EntryName);
|
||||||
@ -4866,7 +4869,7 @@ USTATUS FfsParser::parseCpdRegion(const UByteArray & region, const UINT32 localO
|
|||||||
|
|
||||||
// Search
|
// Search
|
||||||
bool found = false;
|
bool found = false;
|
||||||
UINT32 j = i + 1;
|
UINT32 j = 1;
|
||||||
while (j < partitions.size()) {
|
while (j < partitions.size()) {
|
||||||
UString namej = usprintf("%.12s", partitions[j].ptEntry.EntryName);
|
UString namej = usprintf("%.12s", partitions[j].ptEntry.EntryName);
|
||||||
|
|
||||||
@ -4991,17 +4994,20 @@ make_partition_table_consistent:
|
|||||||
name = usprintf("%.12s", partitions[i].ptEntry.EntryName);
|
name = usprintf("%.12s", partitions[i].ptEntry.EntryName);
|
||||||
|
|
||||||
// It's a manifest
|
// It's a manifest
|
||||||
if (name.contains(".man")) {
|
if (name.endsWith(".man")) {
|
||||||
if (!partitions[i].ptEntry.Offset.HuffmanCompressed
|
if (!partitions[i].ptEntry.Offset.HuffmanCompressed
|
||||||
&& partitions[i].ptEntry.Length >= sizeof(CPD_MANIFEST_HEADER)) {
|
&& partitions[i].ptEntry.Length >= sizeof(CPD_MANIFEST_HEADER)) {
|
||||||
const CPD_MANIFEST_HEADER* manifestHeader = (const CPD_MANIFEST_HEADER*) partition.constData();
|
const CPD_MANIFEST_HEADER* manifestHeader = (const CPD_MANIFEST_HEADER*) partition.constData();
|
||||||
if (manifestHeader->HeaderId == ME_MANIFEST_HEADER_ID) {
|
if (manifestHeader->HeaderId == ME_MANIFEST_HEADER_ID) {
|
||||||
UByteArray header = partition.left(manifestHeader->HeaderLength * sizeof(UINT32));
|
UByteArray header = partition.left(manifestHeader->HeaderLength * sizeof(UINT32));
|
||||||
UByteArray body = partition.mid(header.size());
|
UByteArray body = partition.mid(manifestHeader->HeaderLength * sizeof(UINT32));
|
||||||
|
|
||||||
info += usprintf(
|
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHeader size: %" PRIXQ "h (%" PRIuQ ")\nBody size: %" PRIXQ "h (%" PRIuQ ")"
|
||||||
"\nHeader type: %u\nHeader length: %lXh (%lu)\nHeader version: %Xh\nFlags: %08Xh\nVendor: %Xh\n"
|
"\nHeader type: %u\nHeader length: %lXh (%lu)\nHeader version: %Xh\nFlags: %08Xh\nVendor: %Xh\n"
|
||||||
"Date: %Xh\nSize: %lXh (%lu)\nVersion: %u.%u.%u.%u\nSecurity version number: %u\nModulus size: %lXh (%lu)\nExponent size: %lXh (%lu)",
|
"Date: %Xh\nSize: %lXh (%lu)\nVersion: %u.%u.%u.%u\nSecurity version number: %u\nModulus size: %lXh (%lu)\nExponent size: %lXh (%lu)",
|
||||||
|
partition.size(), partition.size(),
|
||||||
|
header.size(), header.size(),
|
||||||
|
body.size(), body.size(),
|
||||||
manifestHeader->HeaderType,
|
manifestHeader->HeaderType,
|
||||||
manifestHeader->HeaderLength * sizeof(UINT32), manifestHeader->HeaderLength * sizeof(UINT32),
|
manifestHeader->HeaderLength * sizeof(UINT32), manifestHeader->HeaderLength * sizeof(UINT32),
|
||||||
manifestHeader->HeaderVersion,
|
manifestHeader->HeaderVersion,
|
||||||
@ -5023,11 +5029,9 @@ make_partition_table_consistent:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// It's a metadata
|
// It's a metadata
|
||||||
else if (name.contains(".met")) {
|
else if (name.endsWith(".met")) {
|
||||||
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
|
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHuffman compressed: ",
|
||||||
partition.size(), partition.size(),
|
partition.size(), partition.size())
|
||||||
partitions[i].ptEntry.Offset.Offset,
|
|
||||||
partitions[i].ptEntry.Length)
|
|
||||||
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
|
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
|
||||||
|
|
||||||
// Calculate SHA256 hash over the metadata and add it to its info
|
// Calculate SHA256 hash over the metadata and add it to its info
|
||||||
@ -5041,31 +5045,10 @@ make_partition_table_consistent:
|
|||||||
// Parse data as extensions area
|
// Parse data as extensions area
|
||||||
parseCpdExtensionsArea(partitionIndex);
|
parseCpdExtensionsArea(partitionIndex);
|
||||||
}
|
}
|
||||||
// It's a key
|
|
||||||
else if (name.contains(".key")) {
|
|
||||||
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
|
|
||||||
partition.size(), partition.size(),
|
|
||||||
partitions[i].ptEntry.Offset.Offset,
|
|
||||||
partitions[i].ptEntry.Length)
|
|
||||||
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
|
|
||||||
|
|
||||||
// Calculate SHA256 hash over the key and add it to its info
|
|
||||||
UByteArray hash(SHA256_DIGEST_SIZE, '\x00');
|
|
||||||
sha256(partition.constData(), partition.size(), hash.data());
|
|
||||||
info += UString("\nHash: ") + UString(hash.toHex().constData());
|
|
||||||
|
|
||||||
// Add three item
|
|
||||||
UModelIndex partitionIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset.Offset, Types::CpdPartition, Subtypes::KeyCpdPartition, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent);
|
|
||||||
|
|
||||||
// Parse data as extensions area
|
|
||||||
parseCpdExtensionsArea(partitionIndex);
|
|
||||||
}
|
|
||||||
// It's a code
|
// It's a code
|
||||||
else {
|
else {
|
||||||
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nEntry offset: %Xh\nEntry length: %Xh\nHuffman compressed: ",
|
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nHuffman compressed: ",
|
||||||
partition.size(), partition.size(),
|
partition.size(), partition.size())
|
||||||
partitions[i].ptEntry.Offset.Offset,
|
|
||||||
partitions[i].ptEntry.Length)
|
|
||||||
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
|
+ (partitions[i].ptEntry.Offset.HuffmanCompressed ? "Yes" : "No");
|
||||||
|
|
||||||
// Calculate SHA256 hash over the code and add it to its info
|
// Calculate SHA256 hash over the code and add it to its info
|
||||||
@ -5106,7 +5089,7 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
|
|||||||
UINT32 offset = 0;
|
UINT32 offset = 0;
|
||||||
while (offset < (UINT32)body.size()) {
|
while (offset < (UINT32)body.size()) {
|
||||||
const CPD_EXTENTION_HEADER* extHeader = (const CPD_EXTENTION_HEADER*) (body.constData() + offset);
|
const CPD_EXTENTION_HEADER* extHeader = (const CPD_EXTENTION_HEADER*) (body.constData() + offset);
|
||||||
if (extHeader->Length <= ((UINT32)body.size() - offset)) {
|
if (extHeader->Length > 0 && extHeader->Length <= ((UINT32)body.size() - offset)) {
|
||||||
UByteArray partition = body.mid(offset, extHeader->Length);
|
UByteArray partition = body.mid(offset, extHeader->Length);
|
||||||
|
|
||||||
UString name = cpdExtensionTypeToUstring(extHeader->Type);
|
UString name = cpdExtensionTypeToUstring(extHeader->Type);
|
||||||
@ -5143,9 +5126,17 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
|
|||||||
else if (extHeader->Type == CPD_EXT_TYPE_IFWI_PARTITION_MANIFEST) {
|
else if (extHeader->Type == CPD_EXT_TYPE_IFWI_PARTITION_MANIFEST) {
|
||||||
const CPD_EXT_IFWI_PARTITION_MANIFEST* attrHeader = (const CPD_EXT_IFWI_PARTITION_MANIFEST*)partition.constData();
|
const CPD_EXT_IFWI_PARTITION_MANIFEST* attrHeader = (const CPD_EXT_IFWI_PARTITION_MANIFEST*)partition.constData();
|
||||||
|
|
||||||
|
// Check HashSize to be sane.
|
||||||
|
UINT32 hashSize = attrHeader->HashSize;
|
||||||
|
bool msgHashSizeMismatch = false;
|
||||||
|
if (hashSize > sizeof(attrHeader->CompletePartitionHash)) {
|
||||||
|
hashSize = sizeof(attrHeader->CompletePartitionHash);
|
||||||
|
msgHashSizeMismatch = true;
|
||||||
|
}
|
||||||
|
|
||||||
// This hash is stored reversed
|
// This hash is stored reversed
|
||||||
// Need to reverse it back to normal
|
// Need to reverse it back to normal
|
||||||
UByteArray hash((const char*)&attrHeader->CompletePartitionHash, attrHeader->HashSize);
|
UByteArray hash((const char*)&attrHeader->CompletePartitionHash, hashSize);
|
||||||
std::reverse(hash.begin(), hash.end());
|
std::reverse(hash.begin(), hash.end());
|
||||||
|
|
||||||
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh\n"
|
info = usprintf("Full size: %" PRIXQ "h (%" PRIuQ ")\nType: %Xh\n"
|
||||||
@ -5172,14 +5163,13 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
|
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
|
||||||
if (sizeof (attrHeader->CompletePartitionHash) != attrHeader->HashSize) {
|
if (msgHashSizeMismatch) {
|
||||||
msg(usprintf("%s: IFWI Partition Manifest hash size is %d, expected %lu", __FUNCTION__, attrHeader->HashSize, sizeof (attrHeader->CompletePartitionHash)), extIndex);
|
msg(usprintf("%s: IFWI Partition Manifest hash size is %u, maximum allowed is %lu, truncated", __FUNCTION__, attrHeader->HashSize, sizeof(attrHeader->CompletePartitionHash)), extIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Parse Module Attributes a bit further
|
// Parse Module Attributes a bit further
|
||||||
else if (extHeader->Type == CPD_EXT_TYPE_MODULE_ATTRIBUTES) {
|
else if (extHeader->Type == CPD_EXT_TYPE_MODULE_ATTRIBUTES) {
|
||||||
const CPD_EXT_MODULE_ATTRIBUTES* attrHeader = (const CPD_EXT_MODULE_ATTRIBUTES*)partition.constData();
|
const CPD_EXT_MODULE_ATTRIBUTES* attrHeader = (const CPD_EXT_MODULE_ATTRIBUTES*)partition.constData();
|
||||||
|
|
||||||
int hashSize = partition.size() - offsetof(CPD_EXT_MODULE_ATTRIBUTES, ImageHash);
|
int hashSize = partition.size() - offsetof(CPD_EXT_MODULE_ATTRIBUTES, ImageHash);
|
||||||
|
|
||||||
// This hash is stored reversed
|
// This hash is stored reversed
|
||||||
@ -5198,9 +5188,6 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
|
|||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
|
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
|
||||||
if (hashSize != sizeof (attrHeader->ImageHash)) {
|
|
||||||
msg(usprintf("%s: Module Attributes hash size is %d, expected %lu", __FUNCTION__, hashSize, sizeof (attrHeader->ImageHash)), extIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Parse everything else
|
// Parse everything else
|
||||||
else {
|
else {
|
||||||
@ -5208,7 +5195,13 @@ USTATUS FfsParser::parseCpdExtensionsArea(const UModelIndex & index)
|
|||||||
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
|
extIndex = model->addItem(offset, Types::CpdExtension, 0, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extHeader->Type > CPD_LAST_KNOWN_EXT_TYPE) {
|
// TODO: make this generic again
|
||||||
|
if (extHeader->Type > CPD_EXT_TYPE_TBT_METADATA
|
||||||
|
&& extHeader->Type != CPD_EXT_TYPE_GMF_CERTIFICATE
|
||||||
|
&& extHeader->Type != CPD_EXT_TYPE_GMF_BODY
|
||||||
|
&& extHeader->Type != CPD_EXT_TYPE_KEY_MANIFEST_EXT
|
||||||
|
&& extHeader->Type != CPD_EXT_TYPE_SIGNED_PACKAGE_INFO_EXT
|
||||||
|
&& extHeader->Type != CPD_EXT_TYPE_SPS_PLATFORM_ID) {
|
||||||
msg(usprintf("%s: CPD extention of unknown type found", __FUNCTION__), extIndex);
|
msg(usprintf("%s: CPD extention of unknown type found", __FUNCTION__), extIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5232,8 +5225,8 @@ USTATUS FfsParser::parseSignedPackageInfoData(const UModelIndex & index)
|
|||||||
while (offset < (UINT32)body.size()) {
|
while (offset < (UINT32)body.size()) {
|
||||||
const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE* moduleHeader = (const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE*)(body.constData() + offset);
|
const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE* moduleHeader = (const CPD_EXT_SIGNED_PACKAGE_INFO_MODULE*)(body.constData() + offset);
|
||||||
if (sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE) <= ((UINT32)body.size() - offset)) {
|
if (sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE) <= ((UINT32)body.size() - offset)) {
|
||||||
|
// TODO: check sanity of moduleHeader->HashSize
|
||||||
UByteArray module((const char*)moduleHeader, sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE) - sizeof(moduleHeader->MetadataHash) + moduleHeader->HashSize);
|
UByteArray module((const char*)moduleHeader, sizeof(CPD_EXT_SIGNED_PACKAGE_INFO_MODULE) - sizeof(moduleHeader->MetadataHash) + moduleHeader->HashSize);
|
||||||
|
|
||||||
UString name = usprintf("%.12s", moduleHeader->Name);
|
UString name = usprintf("%.12s", moduleHeader->Name);
|
||||||
|
|
||||||
// This hash is stored reversed
|
// This hash is stored reversed
|
||||||
@ -5249,10 +5242,6 @@ USTATUS FfsParser::parseSignedPackageInfoData(const UModelIndex & index)
|
|||||||
moduleHeader->MetadataSize, moduleHeader->MetadataSize) + UString(hash.toHex().constData());
|
moduleHeader->MetadataSize, moduleHeader->MetadataSize) + UString(hash.toHex().constData());
|
||||||
// Add tree otem
|
// Add tree otem
|
||||||
UModelIndex extIndex = model->addItem(offset, Types::CpdSpiEntry, 0, name, UString(), info, UByteArray(), module, UByteArray(), Fixed, index);
|
UModelIndex extIndex = model->addItem(offset, Types::CpdSpiEntry, 0, name, UString(), info, UByteArray(), module, UByteArray(), Fixed, index);
|
||||||
if (sizeof (moduleHeader->MetadataHash) != moduleHeader->HashSize) {
|
|
||||||
msg(usprintf("%s: CPD Signed Package Info hash size is %d, expected %lu", __FUNCTION__, moduleHeader->HashSize, sizeof (moduleHeader->MetadataHash)), extIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += module.size();
|
offset += module.size();
|
||||||
}
|
}
|
||||||
else break;
|
else break;
|
||||||
|
@ -126,13 +126,6 @@ USTATUS MeParser::parseFptRegion(const UByteArray & region, const UModelIndex &
|
|||||||
return U_INVALID_ME_PARTITION_TABLE;
|
return U_INVALID_ME_PARTITION_TABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate checksum
|
|
||||||
UByteArray tempHeader = UByteArray((const char*)region.constData(), romBypassVectorSize + sizeof(FPT_HEADER));
|
|
||||||
FPT_HEADER* tempPtHeader = (FPT_HEADER*)(tempHeader.data() + romBypassVectorSize);
|
|
||||||
tempPtHeader->Checksum = 0;
|
|
||||||
UINT8 calculated = calculateChecksum8((const UINT8*)tempHeader.data(), romBypassVectorSize + sizeof(FPT_HEADER));
|
|
||||||
bool msgInvalidPtHeaderChecksum = (calculated != ptHeader->Checksum);
|
|
||||||
|
|
||||||
// Get info
|
// Get info
|
||||||
UByteArray header = region.left(romBypassVectorSize + sizeof(FPT_HEADER));
|
UByteArray header = region.left(romBypassVectorSize + sizeof(FPT_HEADER));
|
||||||
UByteArray body = region.mid(header.size(), ptBodySize);
|
UByteArray body = region.mid(header.size(), ptBodySize);
|
||||||
@ -153,16 +146,11 @@ USTATUS MeParser::parseFptRegion(const UByteArray & region, const UModelIndex &
|
|||||||
ptHeader->UmaSize,
|
ptHeader->UmaSize,
|
||||||
ptHeader->FlashLayout,
|
ptHeader->FlashLayout,
|
||||||
ptHeader->FitcMajor, ptHeader->FitcMinor, ptHeader->FitcHotfix, ptHeader->FitcBuild,
|
ptHeader->FitcMajor, ptHeader->FitcMinor, ptHeader->FitcHotfix, ptHeader->FitcBuild,
|
||||||
ptHeader->Checksum) + (ptHeader->Checksum == calculated ? UString("valid\n") : usprintf("invalid, should be %02Xh\n", calculated));
|
ptHeader->Checksum);
|
||||||
|
|
||||||
// Add tree item
|
// Add tree item
|
||||||
index = model->addItem(0, Types::FptStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
index = model->addItem(0, Types::FptStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, parent);
|
||||||
|
|
||||||
// Show messages
|
|
||||||
if (msgInvalidPtHeaderChecksum) {
|
|
||||||
msg(usprintf("%s: FPT partition table header checksum is invalid", __FUNCTION__), index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add partition table entries
|
// Add partition table entries
|
||||||
std::vector<FPT_PARTITION_INFO> partitions;
|
std::vector<FPT_PARTITION_INFO> partitions;
|
||||||
UINT32 offset = (UINT32)header.size();
|
UINT32 offset = (UINT32)header.size();
|
||||||
|
@ -33,7 +33,20 @@ UString visibleAsciiOrHex(UINT8* bytes, UINT32 length)
|
|||||||
for (UINT32 i = 0; i < length; i++) {
|
for (UINT32 i = 0; i < length; i++) {
|
||||||
hexString += usprintf("%02X", bytes[i]);
|
hexString += usprintf("%02X", bytes[i]);
|
||||||
|
|
||||||
if (bytes[i] < '\x20' || bytes[i] > '\x7E') { // Explicit ascii codes to avoid locale dependency
|
if (bytes[i] == '\x00') { // Check for the rest of the buffer being zeroes, and make the whole previous string visible, if so
|
||||||
|
for (UINT32 j = i + 1; j < length; j++) {
|
||||||
|
if (bytes[j] != '\x00') {
|
||||||
|
ascii = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ascii) {
|
||||||
|
// No need to continue iterating over every symbol, we did it already
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bytes[i] < '\x20' || bytes[i] > '\x7E') { // Explicit ascii codes to avoid locale dependency
|
||||||
ascii = false;
|
ascii = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user