From 7e5e02b4b4ae93bbd488a6596a9474afe31c78fa Mon Sep 17 00:00:00 2001 From: Nikolaj Schlej Date: Sun, 9 Oct 2022 07:18:28 +0200 Subject: [PATCH] Improve detection of BPDT partition tables in raw areas, update the list of known BPDT entry types --- common/ffs.cpp | 76 +++++++++++++++++++++++++----------------- common/ffs.h | 79 +++++++++++++++++++++++++++----------------- common/ffsparser.cpp | 29 ++++++++++------ 3 files changed, 112 insertions(+), 72 deletions(-) diff --git a/common/ffs.cpp b/common/ffs.cpp index d1d6f96..ae8709c 100644 --- a/common/ffs.cpp +++ b/common/ffs.cpp @@ -274,36 +274,52 @@ UString sectionTypeToUString(const UINT8 type) UString bpdtEntryTypeToUString(const UINT16 type) { switch (type) { - case BPDT_ENTRY_TYPE_OEM_SMIP: return UString("OEM SMIP"); - case BPDT_ENTRY_TYPE_OEM_RBE: return UString("CSE RBE"); - case BPDT_ENTRY_TYPE_CSE_BUP: return UString("CSE BUP"); - case BPDT_ENTRY_TYPE_UCODE: return UString("uCode"); - case BPDT_ENTRY_TYPE_IBB: return UString("IBB"); - case BPDT_ENTRY_TYPE_SBPDT: return UString("S-BPDT"); - case BPDT_ENTRY_TYPE_OBB: return UString("OBB"); - case BPDT_ENTRY_TYPE_CSE_MAIN: return UString("CSE Main"); - case BPDT_ENTRY_TYPE_ISH: return UString("ISH"); - case BPDT_ENTRY_TYPE_CSE_IDLM: return UString("CSE IDLM"); - case BPDT_ENTRY_TYPE_IFP_OVERRIDE: return UString("IFP Override"); - case BPDT_ENTRY_TYPE_DEBUG_TOKENS: return UString("Debug Tokens"); - case BPDT_ENTRY_TYPE_USF_PHY_CONFIG: return UString("USF Phy Config"); - case BPDT_ENTRY_TYPE_USF_GPP_LUN_ID: return UString("USF GPP LUN ID"); - case BPDT_ENTRY_TYPE_PMC: return UString("PMC"); - case BPDT_ENTRY_TYPE_IUNIT: return UString("iUnit"); - case BPDT_ENTRY_TYPE_NVM_CONFIG: return UString("NVM Config"); - case BPDT_ENTRY_TYPE_UEP: return UString("UEP"); - case BPDT_ENTRY_TYPE_WLAN_UCODE: return UString("WLAN uCode"); - case BPDT_ENTRY_TYPE_LOCL_SPRITES: return UString("LOCL Sprites"); - case BPDT_ENTRY_TYPE_OEM_KEY_MANIFEST: return UString("OEM Key Manifest"); - case BPDT_ENTRY_TYPE_DEFAULTS: return UString("Defaults"); - case BPDT_ENTRY_TYPE_PAVP: return UString("PAVP"); - 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_TBT: return UString("TCSS TBT"); - case BPDT_ENTRY_TYPE_USB_PHY: return UString("USB PHY"); - case BPDT_ENTRY_TYPE_PCHC: return UString("PCHC"); - case BPDT_ENTRY_TYPE_SAMF: return UString("SAMF"); - case BPDT_ENTRY_TYPE_PPHY: return UString("PPHY"); + case BPDT_ENTRY_TYPE_SMIP: return UString("OEM SMIP"); + case BPDT_ENTRY_TYPE_RBEP: return UString("ROM Boot Extensions"); + case BPDT_ENTRY_TYPE_FTPR: return UString("Bring Up"); + case BPDT_ENTRY_TYPE_UCOD: return UString("Microcode"); + case BPDT_ENTRY_TYPE_IBBP: return UString("IBB"); + case BPDT_ENTRY_TYPE_S_BPDT: return UString("Secondary BPDT"); + case BPDT_ENTRY_TYPE_OBBP: return UString("OBB"); + case BPDT_ENTRY_TYPE_NFTP: return UString("Main"); + case BPDT_ENTRY_TYPE_ISHC: return UString("ISH"); + case BPDT_ENTRY_TYPE_DLMP: return UString("Debug Launch Module"); + case BPDT_ENTRY_TYPE_UEBP: return UString("IFP Bypass"); + case BPDT_ENTRY_TYPE_UTOK: return UString("Debug Tokens"); + case BPDT_ENTRY_TYPE_UFS_PHY: return UString("UFS PHY Config"); + case BPDT_ENTRY_TYPE_UFS_GPP_LUN: return UString("UFS GPP LUN"); + case BPDT_ENTRY_TYPE_PMCP: return UString("PMC"); + case BPDT_ENTRY_TYPE_IUNP: return UString("iUnit"); + case BPDT_ENTRY_TYPE_NVMC: return UString("NVM Config"); + case BPDT_ENTRY_TYPE_UEP: return UString("Unified Emulation"); + case BPDT_ENTRY_TYPE_WCOD: return UString("WLAN Microcode"); + case BPDT_ENTRY_TYPE_LOCL: return UString("LOCL Sprites"); + case BPDT_ENTRY_TYPE_OEMP: return UString("OEM Key Manifest"); + case BPDT_ENTRY_TYPE_FITC: return UString("fitc.cfg"); + case BPDT_ENTRY_TYPE_PAVP: return UString("PAVP"); + case BPDT_ENTRY_TYPE_IOMP: return UString("TCSS FW IOM"); + case BPDT_ENTRY_TYPE_XPHY: return UString("TCSS FW PHY"); + case BPDT_ENTRY_TYPE_TBTP: return UString("TCSS TBT"); + case BPDT_ENTRY_TYPE_PLTS: return UString("Platform Settings"); + case BPDT_ENTRY_TYPE_RES27: return UString("Reserved 27"); + case BPDT_ENTRY_TYPE_RES28: return UString("Reserved 28"); + case BPDT_ENTRY_TYPE_RES29: return UString("Reserved 29"); + case BPDT_ENTRY_TYPE_RES30: return UString("Reserved 30"); + case BPDT_ENTRY_TYPE_DPHY: return UString("Dekel PHY"); + case BPDT_ENTRY_TYPE_PCHC: return UString("PCH Config"); + case BPDT_ENTRY_TYPE_ISIF: return UString("ISI FW"); + case BPDT_ENTRY_TYPE_ISIC: return UString("ISI Config"); + case BPDT_ENTRY_TYPE_HBMI: return UString("HBM IO"); + case BPDT_ENTRY_TYPE_OMSM: return UString("OOB MSM"); + case BPDT_ENTRY_TYPE_GTGP: return UString("GT-GPU"); + case BPDT_ENTRY_TYPE_MDFI: return UString("MDF IO"); + case BPDT_ENTRY_TYPE_PUNP: return UString("PUnit"); + case BPDT_ENTRY_TYPE_PHYP: return UString("GSC PHY"); + case BPDT_ENTRY_TYPE_SAMF: return UString("SAM FW"); + case BPDT_ENTRY_TYPE_PPHY: return UString("PPHY"); + case BPDT_ENTRY_TYPE_GBST: return UString("GBST"); + case BPDT_ENTRY_TYPE_TCCP: return UString("TCC"); + case BPDT_ENTRY_TYPE_PSEP: return UString("PSE"); } return usprintf("Unknown %04Xh", type); } diff --git a/common/ffs.h b/common/ffs.h index 8612241..037be44 100644 --- a/common/ffs.h +++ b/common/ffs.h @@ -286,7 +286,7 @@ UINT64 ExtendedSize; } EFI_FFS_FILE_HEADER2; // Lenovo large file header -typedef struct EFI_FFS_FILE_HEADER_LENOVO_ { +typedef struct EFI_FFS_FILE_HEADER2_LENOVO_ { EFI_GUID Name; EFI_FFS_INTEGRITY_CHECK IntegrityCheck; UINT8 Type; @@ -579,36 +579,53 @@ typedef struct BPDT_ENTRY_ { UINT32 Size; } BPDT_ENTRY; -#define BPDT_ENTRY_TYPE_OEM_SMIP 0 -#define BPDT_ENTRY_TYPE_OEM_RBE 1 -#define BPDT_ENTRY_TYPE_CSE_BUP 2 -#define BPDT_ENTRY_TYPE_UCODE 3 -#define BPDT_ENTRY_TYPE_IBB 4 -#define BPDT_ENTRY_TYPE_SBPDT 5 -#define BPDT_ENTRY_TYPE_OBB 6 -#define BPDT_ENTRY_TYPE_CSE_MAIN 7 -#define BPDT_ENTRY_TYPE_ISH 8 -#define BPDT_ENTRY_TYPE_CSE_IDLM 9 -#define BPDT_ENTRY_TYPE_IFP_OVERRIDE 10 -#define BPDT_ENTRY_TYPE_DEBUG_TOKENS 11 -#define BPDT_ENTRY_TYPE_USF_PHY_CONFIG 12 -#define BPDT_ENTRY_TYPE_USF_GPP_LUN_ID 13 -#define BPDT_ENTRY_TYPE_PMC 14 -#define BPDT_ENTRY_TYPE_IUNIT 15 -#define BPDT_ENTRY_TYPE_NVM_CONFIG 16 -#define BPDT_ENTRY_TYPE_UEP 17 -#define BPDT_ENTRY_TYPE_WLAN_UCODE 18 -#define BPDT_ENTRY_TYPE_LOCL_SPRITES 19 -#define BPDT_ENTRY_TYPE_OEM_KEY_MANIFEST 20 -#define BPDT_ENTRY_TYPE_DEFAULTS 21 -#define BPDT_ENTRY_TYPE_PAVP 22 -#define BPDT_ENTRY_TYPE_TCSS_FW_IOM 23 -#define BPDT_ENTRY_TYPE_TCSS_FW_PHY 24 -#define BPDT_ENTRY_TYPE_TBT 25 -#define BPDT_ENTRY_TYPE_USB_PHY 31 -#define BPDT_ENTRY_TYPE_PCHC 32 -#define BPDT_ENTRY_TYPE_SAMF 41 -#define BPDT_ENTRY_TYPE_PPHY 42 +// https://github.com/platomav/MEAnalyzer/blob/master/MEA.py#L10595 +#define BPDT_ENTRY_TYPE_SMIP 0 +#define BPDT_ENTRY_TYPE_RBEP 1 +#define BPDT_ENTRY_TYPE_FTPR 2 +#define BPDT_ENTRY_TYPE_UCOD 3 +#define BPDT_ENTRY_TYPE_IBBP 4 +#define BPDT_ENTRY_TYPE_S_BPDT 5 +#define BPDT_ENTRY_TYPE_OBBP 6 +#define BPDT_ENTRY_TYPE_NFTP 7 +#define BPDT_ENTRY_TYPE_ISHC 8 +#define BPDT_ENTRY_TYPE_DLMP 9 +#define BPDT_ENTRY_TYPE_UEBP 10 +#define BPDT_ENTRY_TYPE_UTOK 11 +#define BPDT_ENTRY_TYPE_UFS_PHY 12 +#define BPDT_ENTRY_TYPE_UFS_GPP_LUN 13 +#define BPDT_ENTRY_TYPE_PMCP 14 +#define BPDT_ENTRY_TYPE_IUNP 15 +#define BPDT_ENTRY_TYPE_NVMC 16 +#define BPDT_ENTRY_TYPE_UEP 17 +#define BPDT_ENTRY_TYPE_WCOD 18 +#define BPDT_ENTRY_TYPE_LOCL 19 +#define BPDT_ENTRY_TYPE_OEMP 20 +#define BPDT_ENTRY_TYPE_FITC 21 +#define BPDT_ENTRY_TYPE_PAVP 22 +#define BPDT_ENTRY_TYPE_IOMP 23 +#define BPDT_ENTRY_TYPE_XPHY 24 +#define BPDT_ENTRY_TYPE_TBTP 25 +#define BPDT_ENTRY_TYPE_PLTS 26 +#define BPDT_ENTRY_TYPE_RES27 27 +#define BPDT_ENTRY_TYPE_RES28 28 +#define BPDT_ENTRY_TYPE_RES29 29 +#define BPDT_ENTRY_TYPE_RES30 30 +#define BPDT_ENTRY_TYPE_DPHY 31 +#define BPDT_ENTRY_TYPE_PCHC 32 +#define BPDT_ENTRY_TYPE_ISIF 33 +#define BPDT_ENTRY_TYPE_ISIC 34 +#define BPDT_ENTRY_TYPE_HBMI 35 +#define BPDT_ENTRY_TYPE_OMSM 36 +#define BPDT_ENTRY_TYPE_GTGP 37 +#define BPDT_ENTRY_TYPE_MDFI 38 +#define BPDT_ENTRY_TYPE_PUNP 39 +#define BPDT_ENTRY_TYPE_PHYP 40 +#define BPDT_ENTRY_TYPE_SAMF 41 +#define BPDT_ENTRY_TYPE_PPHY 42 +#define BPDT_ENTRY_TYPE_GBST 43 +#define BPDT_ENTRY_TYPE_TCCP 44 +#define BPDT_ENTRY_TYPE_PSEP 45 // CPD #define CPD_SIGNATURE 0x44504324 //$CPD diff --git a/common/ffsparser.cpp b/common/ffsparser.cpp index f8f949c..c842aa7 100644 --- a/common/ffsparser.cpp +++ b/common/ffsparser.cpp @@ -929,7 +929,7 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index) // Add tree item UModelIndex paddingIndex = model->addItem(headerSize + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index); - msg(usprintf("%s: one of volumes inside overlaps the end of data", __FUNCTION__), paddingIndex); + msg(usprintf("%s: one of objects inside overlaps the end of data", __FUNCTION__), paddingIndex); // Update variables prevItemOffset = itemOffset; @@ -1381,8 +1381,17 @@ USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 l continue; const BPDT_HEADER *bpdtHeader = (const BPDT_HEADER *)currentPos; - // Check version - if (bpdtHeader->HeaderVersion != BPDT_HEADER_VERSION_1) // IFWI 2.0 only for now + + // Check NumEntries to be sane + if (bpdtHeader->NumEntries > 0x100) + continue; + + // Check HeaderVersion to be 1 + if (bpdtHeader->HeaderVersion != BPDT_HEADER_VERSION_1) // Check only for IFWI 2.0 headers in raw areas + continue; + + // Check RedundancyFlag to be 0 or 1 + if (bpdtHeader->RedundancyFlag != 0 && bpdtHeader->RedundancyFlag != 1) // Check only for IFWI 2.0 headers in raw areas continue; UINT32 ptBodySize = bpdtHeader->NumEntries * sizeof(BPDT_ENTRY); @@ -4053,13 +4062,15 @@ USTATUS FfsParser::parseBpdtRegion(const UByteArray & region, const UINT32 local UByteArray body = region.mid(sizeof(BPDT_HEADER), ptBodySize); UString name = UString("BPDT partition table"); - UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nNumber of entries: %u\nVersion: %2Xh\n" + UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n" + "Number of entries: %u\nVersion: %02Xh\nRedundancyFlag: %Xh\n" "IFWI version: %Xh\nFITC version: %u.%u.%u.%u", ptSize, ptSize, (UINT32)header.size(), (UINT32)header.size(), ptBodySize, ptBodySize, ptHeader->NumEntries, ptHeader->HeaderVersion, + ptHeader->RedundancyFlag, ptHeader->IfwiVersion, ptHeader->FitcMajor, ptHeader->FitcMinor, ptHeader->FitcHotfix, ptHeader->FitcBuild); @@ -4204,7 +4215,7 @@ make_partition_table_consistent: UModelIndex partitionIndex = model->addItem(localOffset + partitions[i].ptEntry.Offset, Types::BpdtPartition, 0, name, text, info, UByteArray(), partition, UByteArray(), Fixed, parent); // Special case of S-BPDT - if (partitions[i].ptEntry.Type == BPDT_ENTRY_TYPE_SBPDT) { + if (partitions[i].ptEntry.Type == BPDT_ENTRY_TYPE_S_BPDT) { UModelIndex sbpdtIndex; parseBpdtRegion(partition, 0, partitions[i].ptEntry.Offset, partitionIndex, sbpdtIndex); // Third parameter is a fixup for S-BPDT offset entries, because they are calculated from the start of BIOS region } @@ -4216,12 +4227,8 @@ make_partition_table_consistent: parseCpdRegion(partition, 0, partitionIndex, cpdIndex); } - // There needs to be a more generic way to do it, but it is fine for now - if (partitions[i].ptEntry.Type > BPDT_ENTRY_TYPE_TBT - && partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_USB_PHY - && partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_PCHC - && partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_SAMF - && partitions[i].ptEntry.Type != BPDT_ENTRY_TYPE_PPHY) { + // Check for entry type to be known + if (partitions[i].ptEntry.Type > BPDT_ENTRY_TYPE_PSEP) { msg(usprintf("%s: BPDT entry of unknown type found", __FUNCTION__), partitionIndex); } }