Add Insyde Flash Device Map parser

This commit is contained in:
Nikolaj Schlej 2025-03-03 01:27:24 +07:00
parent 0b66c5c7ff
commit b3c68b7006
28 changed files with 1361 additions and 230 deletions

View file

@ -40,7 +40,9 @@ SET(PROJECT_SOURCES
../common/generated/edk2_vss2.cpp ../common/generated/edk2_vss2.cpp
../common/generated/edk2_ftw.cpp ../common/generated/edk2_ftw.cpp
../common/generated/insyde_fdc.cpp ../common/generated/insyde_fdc.cpp
../common/generated/insyde_fdm.cpp
../common/generated/phoenix_flm.cpp ../common/generated/phoenix_flm.cpp
../common/generated/phoenix_evsa.cpp
../common/generated/intel_acbp_v1.cpp ../common/generated/intel_acbp_v1.cpp
../common/generated/intel_acbp_v2.cpp ../common/generated/intel_acbp_v2.cpp
../common/generated/intel_keym_v1.cpp ../common/generated/intel_keym_v1.cpp

View file

@ -37,7 +37,9 @@ SET(PROJECT_SOURCES
../common/generated/edk2_vss2.cpp ../common/generated/edk2_vss2.cpp
../common/generated/edk2_ftw.cpp ../common/generated/edk2_ftw.cpp
../common/generated/insyde_fdc.cpp ../common/generated/insyde_fdc.cpp
../common/generated/insyde_fdm.cpp
../common/generated/phoenix_flm.cpp ../common/generated/phoenix_flm.cpp
../common/generated/phoenix_evsa.cpp
../common/generated/intel_acbp_v1.cpp ../common/generated/intel_acbp_v1.cpp
../common/generated/intel_acbp_v2.cpp ../common/generated/intel_acbp_v2.cpp
../common/generated/intel_keym_v1.cpp ../common/generated/intel_keym_v1.cpp

View file

@ -73,6 +73,8 @@ SET(PROJECT_SOURCES
../common/generated/edk2_vss2.cpp ../common/generated/edk2_vss2.cpp
../common/generated/edk2_ftw.cpp ../common/generated/edk2_ftw.cpp
../common/generated/insyde_fdc.cpp ../common/generated/insyde_fdc.cpp
../common/generated/insyde_fdm.cpp
../common/generated/phoenix_evsa.cpp
../common/generated/phoenix_flm.cpp ../common/generated/phoenix_flm.cpp
../common/generated/intel_acbp_v1.cpp ../common/generated/intel_acbp_v1.cpp
../common/generated/intel_acbp_v2.cpp ../common/generated/intel_acbp_v2.cpp

View file

@ -247,7 +247,8 @@ void UEFITool::populateUi(const QModelIndex &current)
|| type == Types::VssEntry || type == Types::VssEntry
|| type == Types::SysFEntry || type == Types::SysFEntry
|| type == Types::EvsaEntry || type == Types::EvsaEntry
|| type == Types::FlashMapEntry || type == Types::PhoenixFlashMapEntry
|| type == Types::InsydeFlashDeviceMapEntry
|| type == Types::IfwiHeader || type == Types::IfwiHeader
|| type == Types::IfwiPartition || type == Types::IfwiPartition
|| type == Types::FptPartition || type == Types::FptPartition
@ -266,7 +267,8 @@ void UEFITool::populateUi(const QModelIndex &current)
|| type == Types::SysFStore || type == Types::SysFStore
|| type == Types::EvsaStore || type == Types::EvsaStore
|| type == Types::FtwStore || type == Types::FtwStore
|| type == Types::FlashMapStore || type == Types::PhoenixFlashMapStore
|| type == Types::InsydeFlashDeviceMapStore
|| type == Types::NvarGuidStore || type == Types::NvarGuidStore
|| type == Types::CmdbStore || type == Types::CmdbStore
|| type == Types::FptStore || type == Types::FptStore
@ -910,7 +912,8 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
case Types::SysFStore: case Types::SysFStore:
case Types::EvsaStore: case Types::EvsaStore:
case Types::FtwStore: case Types::FtwStore:
case Types::FlashMapStore: case Types::PhoenixFlashMapStore:
case Types::InsydeFlashDeviceMapStore:
case Types::NvarGuidStore: case Types::NvarGuidStore:
case Types::CmdbStore: case Types::CmdbStore:
case Types::FptStore: case Types::FptStore:

View file

@ -56,7 +56,9 @@ HEADERS += uefitool.h \
../common/generated/edk2_vss2.h \ ../common/generated/edk2_vss2.h \
../common/generated/edk2_ftw.h \ ../common/generated/edk2_ftw.h \
../common/generated/insyde_fdc.h \ ../common/generated/insyde_fdc.h \
../common/generated/insyde_fdm.h \
../common/generated/phoenix_flm.h \ ../common/generated/phoenix_flm.h \
../common/generated/phoenix_evsa.h \
../common/generated/intel_acbp_v1.h \ ../common/generated/intel_acbp_v1.h \
../common/generated/intel_acbp_v2.h \ ../common/generated/intel_acbp_v2.h \
../common/generated/intel_keym_v1.h \ ../common/generated/intel_keym_v1.h \
@ -129,7 +131,9 @@ SOURCES += uefitool_main.cpp \
../common/generated/edk2_vss2.cpp \ ../common/generated/edk2_vss2.cpp \
../common/generated/edk2_ftw.cpp \ ../common/generated/edk2_ftw.cpp \
../common/generated/insyde_fdc.cpp \ ../common/generated/insyde_fdc.cpp \
../common/generated/insyde_fdm.cpp \
../common/generated/phoenix_flm.cpp \ ../common/generated/phoenix_flm.cpp \
../common/generated/phoenix_evsa.cpp \
../common/generated/intel_acbp_v1.cpp \ ../common/generated/intel_acbp_v1.cpp \
../common/generated/intel_acbp_v2.cpp \ ../common/generated/intel_acbp_v2.cpp \
../common/generated/intel_keym_v1.cpp \ ../common/generated/intel_keym_v1.cpp \

View file

@ -85,6 +85,48 @@ extern const UByteArray EFI_DXE_CORE_GUID // D6A2CB7F-6A18-4E2F-B43B-9920A733700
extern const UByteArray AMD_COMPRESSED_RAW_FILE_GUID //20BC8AC9-94D1-4208-AB28-5D673FD73487 extern const UByteArray AMD_COMPRESSED_RAW_FILE_GUID //20BC8AC9-94D1-4208-AB28-5D673FD73487
("\xC9\x8A\xBC\x20\xD1\x94\x08\x42\xAB\x28\x5D\x67\x3F\xD7\x34\x87", 16); ("\xC9\x8A\xBC\x20\xD1\x94\x08\x42\xAB\x28\x5D\x67\x3F\xD7\x34\x87", 16);
// Insyde Flash Device Map GUIDs
extern const UByteArray INSYDE_FLASH_MAP_REGION_BOOT_FV_GUID
("\x56\x6d\xd7\xe3\x8a\x98\x6b\x4d\x89\x13\x64\xf2\xdf\x1d\xf6\xa6", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_BVDT_GUID
("\xFC\x5D\x41\x32\x06\xD1\xC7\x48\x9E\xB5\x80\x6C\x11\x4D\xD1\x07", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_EC_GUID
("\xBF\xF3\x3E\xA7\xCC\x33\xA9\x43\xB3\x9C\xA9\x12\xC7\x48\x9A\x57", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_BACKUP_GUID
("\xD3\x15\x8E\xB7\xA5\xF0\x48\x42\x8E\x2F\xD3\x15\x7A\xEF\x88\x36", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_STATE_GUID
("\x04\x6E\x41\xC8\x34\x99\x79\x40\xBE\x9A\x39\xF8\xD6\x02\x84\x98", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_FV_GUID
("\x58\xE7\xE8\xB5\xE6\xA7\x8B\x4C\xAB\x85\xFF\x2A\x95\x9B\x99\xBA", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_FLASH_DEVICE_MAP_GUID
("\xA0\xC1\x78\xF0\x52\xFC\x3F\x4C\xBE\x1F\xD6\x88\x81\x5A\x62\xC0", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_LOGO_GUID
("\x69\xAB\xCF\xDA\x77\xF9\x84\x47\x8A\xD8\x77\x24\xA6\xF4\xB4\x40", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_MICROCODE_GUID
("\xF8\x66\x98\xB4\xD2\x8C\xE4\x49\xA1\x6D\xB6\x0F\xBE\xC3\x1C\x4B", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_MSDM_TABLE_GUID
("\x1A\xEB\x44\xB3\x7E\xF9\x14\x4F\xA1\xE1\x7E\x63\xBC\x40\xC8\xCE", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_MULTI_CONFIG_GUID
("\x92\xB5\x94\x59\x14\x2F\xD5\x48\xBB\x40\xBD\x27\x96\x9C\x77\x80", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_DEFAULT_GUID
("\xA2\xAC\xDD\xD9\x16\x08\xF3\x48\xAD\xED\x6B\x71\x65\x6B\x24\x8A", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_SMBIOS_UPDATE_GUID
("\xDC\xFE\x64\x89\xE7\x6F\x1E\x4E\xA5\x5E\xFF\x82\x1D\x71\xFF\xCF", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_GUID
("\x74\x53\x3C\x77\xD1\x81\x43\x4D\xB2\x93\xF3\xD7\x4F\x18\x1D\x6B", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_UNKNOWN_GUID
("\xE5\x65\x1D\x20\x23\xBE\x75\x48\x80\xF8\xB1\xD4\x79\x5E\x7E\x08", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_UNUSED_GUID
("\x20\xB0\xC8\x13\x27\x4F\x3B\x45\x8F\x80\x1B\xFC\xA1\x87\x38\x0F", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_USB_OPTION_ROM_GUID
("\x0F\xF3\x7B\x60\x2B\x5F\xA2\x4D\xAE\xED\x56\xF9\xBD\xCD\x2D\x21", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_DXE_FV_GUID
("\xCE\xBA\xD0\x1F\x0A\x6F\x85\x40\x90\x1E\xF6\x21\x03\x85\xCB\x6F", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_PEI_FV_GUID
("\xC5\x06\x14\xCF\xEC\x3F\xEB\x47\xA6\xC3\xB7\x1A\x3E\xE0\x0B\x95", 16);
extern const UByteArray INSYDE_FLASH_MAP_REGION_UNSIGNED_FV_GUID
("\xB6\x16\xA0\xF2\x14\xE8\x2E\x40\xA3\x95\x46\xD3\xCF\x75\x26\x4A", 16);
// GUIDs of GUID-defined sections // GUIDs of GUID-defined sections
extern const UByteArray EFI_GUIDED_SECTION_CRC32 // FC1BCDB0-7D31-49AA-936A-A4600D9DD083 extern const UByteArray EFI_GUIDED_SECTION_CRC32 // FC1BCDB0-7D31-49AA-936A-A4600D9DD083
("\xB0\xCD\x1B\xFC\x31\x7D\xAA\x49\x93\x6A\xA4\x60\x0D\x9D\xD0\x83", 16); ("\xB0\xCD\x1B\xFC\x31\x7D\xAA\x49\x93\x6A\xA4\x60\x0D\x9D\xD0\x83", 16);

View file

@ -862,6 +862,67 @@ extern const UByteArray AMI_ROM_HOLE_FILE_GUID_13; //05CA0209-0FC1-11DC-9011-001
extern const UByteArray AMI_ROM_HOLE_FILE_GUID_14; // 05CA020A-0FC1-11DC-9011-00173153EBA8 extern const UByteArray AMI_ROM_HOLE_FILE_GUID_14; // 05CA020A-0FC1-11DC-9011-00173153EBA8
extern const UByteArray AMI_ROM_HOLE_FILE_GUID_15; // 05CA020B-0FC1-11DC-9011-00173153EBA8 extern const UByteArray AMI_ROM_HOLE_FILE_GUID_15; // 05CA020B-0FC1-11DC-9011-00173153EBA8
//
// Insyde Flash Device Map
//
#define INSYDE_FLASH_DEVICE_MAP_SIGNATURE 0x4D444648 // HFDM
typedef struct _INSYDE_FLASH_DEVICE_MAP_HEADER {
UINT32 Signature;
UINT32 Size;
UINT32 DataOffset;
UINT32 EntrySize;
UINT8 EntryFormat;
UINT8 Revision;
UINT8 ExtensionCount;
UINT8 Checksum;
UINT64 FdBaseAddress;
//INSYDE_FLASH_DEVICE_MAP_EXTENSION Extensions[ExtensionCount];
} INSYDE_FLASH_DEVICE_MAP_HEADER;
typedef struct _INSYDE_FLASH_DEVICE_MAP_EXTENSION {
UINT16 EntryOffset;
UINT16 EntryCount;
} INSYDE_FLASH_DEVICE_MAP_EXTENSION;
typedef struct _INSYDE_FLASH_DEVICE_MAP_ENTRY {
EFI_GUID RegionTypeGuid;
UINT8 RegionId[16];
UINT64 RegionOffset;
UINT64 RegionSize;
UINT32 Attributes;
//UINT8 Hash[]; // Size depends on EntryFormat and EntrySize of the header
} INSYDE_FLASH_DEVICE_MAP_ENTRY;
typedef struct _INSYDE_FLASH_DEVICE_MAP_BOARD_ID_MAP {
UINT32 BoardIdIndex;
UINT32 BoardIdCount;
//UINT64 BoardIds[Count];
} INSYDE_FLASH_DEVICE_MAP_BOARD_ID_MAP;
#define INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE 0x00000001
extern const UByteArray INSYDE_FLASH_MAP_REGION_BOOT_FV_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_BVDT_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_EC_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_BACKUP_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_FTW_STATE_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_FV_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_FLASH_DEVICE_MAP_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_LOGO_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_MICROCODE_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_MSDM_TABLE_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_MULTI_CONFIG_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_DEFAULT_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_SMBIOS_UPDATE_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_VAR_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_UNKNOWN_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_UNUSED_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_USB_OPTION_ROM_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_DXE_FV_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_PEI_FV_GUID;
extern const UByteArray INSYDE_FLASH_MAP_REGION_UNSIGNED_FV_GUID;
// Restore previous packing rules // Restore previous packing rules
#pragma pack(pop) #pragma pack(pop)

View file

@ -35,6 +35,10 @@
#include "digest/sha2.h" #include "digest/sha2.h"
#include "digest/sm3.h" #include "digest/sm3.h"
#include "umemstream.h"
#include "kaitai/kaitaistream.h"
#include "generated/insyde_fdm.h"
// Constructor // Constructor
FfsParser::FfsParser(TreeModel* treeModel) : model(treeModel), FfsParser::FfsParser(TreeModel* treeModel) : model(treeModel),
imageBase(0), addressDiff(0x100000000ULL), protectedRegionsBase(0) { imageBase(0), addressDiff(0x100000000ULL), protectedRegionsBase(0) {
@ -948,6 +952,114 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
msg(usprintf("%s: BPDT store parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index); msg(usprintf("%s: BPDT store parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
} }
} }
else if (itemType == Types::InsydeFlashDeviceMapStore) {
UByteArray fdm = data.mid(itemOffset, itemSize);
umemstream is(fdm.constData(), fdm.size());
kaitai::kstream ks(&is);
insyde_fdm_t parsed(&ks);
UINT32 storeSize = (UINT32)fdm.size();
// Construct header and body
UByteArray header = fdm.left(parsed.data_offset());
UByteArray body = fdm.mid(header.size(), storeSize - header.size());
// Add info
UString name = UString("Insyde H2O FlashDeviceMap");
UString info = usprintf("Signature: HFDM\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nData offset: %Xh\nEntry size: %Xh (%u)\nEntry format: %02Xh\nRevision: %02Xh\nExtension count: %u\nFlash descriptor base address: %08Xh\nChecksum: %02Xh",
storeSize, storeSize,
(UINT32)header.size(), (UINT32)header.size(),
(UINT32)body.size(), (UINT32)body.size(),
parsed.data_offset(),
parsed.entry_size(), parsed.entry_size(),
parsed.entry_format(),
parsed.revision(),
parsed.num_extensions(),
(UINT32)parsed.fd_base_address(),
parsed.checksum());
// Check header checksum
{
UByteArray tempHeader = data.mid(itemOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_HEADER));
INSYDE_FLASH_DEVICE_MAP_HEADER* tempFdmHeader = (INSYDE_FLASH_DEVICE_MAP_HEADER*)tempHeader.data();
tempFdmHeader->Checksum = 0;
UINT8 calculated = calculateChecksum8((const UINT8*)tempFdmHeader, (UINT32)tempHeader.size());
if (calculated == parsed.checksum()) {
info += UString(", valid");
}
else {
info += usprintf(", invalid, should be %02Xh", calculated);
}
}
// Add board IDs
if (parsed.revision() == 3) {
info += usprintf("\nRegion index: %Xh\nBoardId Count: %u",
parsed.board_ids()->region_index(),
parsed.board_ids()->num_board_ids());
UINT32 i = 0;
for (const auto & boardId : *parsed.board_ids()->board_ids()) {
info += usprintf("\nBoardId #%u: %" PRIX64 "\n", i++, boardId);
}
}
// Add header tree item
UModelIndex headerIndex = model->addItem(headerSize + itemOffset, Types::InsydeFlashDeviceMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
// Add entries
UINT32 entryOffset = parsed.data_offset();
bool protectedRangeFound = false;
for (const auto & entry : *parsed.entries()->entries()) {
const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str());
name = insydeFlashDeviceMapEntryTypeGuidToUString(guid);
UString text;
header = data.mid(itemOffset + entryOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_ENTRY));
body = data.mid(itemOffset + entryOffset + header.size(), parsed.entry_size() - header.size());
// Add info
UINT32 entrySize = (UINT32)header.size() + (UINT32)body.size();
info = UString("Region type: ") + guidToUString(guid, false) + "\n";
info += UString("Region id: ");
for (UINT8 i = 0; i < 16; i++) {
info += usprintf("%02X", *(const UINT8*)(entry->region_id().c_str() + i));
}
info += usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nRegion address: %08Xh\nRegion size: %08Xh\nAttributes: %08Xh",
entrySize, entrySize,
(UINT32)header.size(), (UINT32)header.size(),
(UINT32)body.size(), (UINT32)body.size(),
(UINT32)entry->region_base(),
(UINT32)entry->region_size(),
entry->attributes());
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) {
if (!protectedRangeFound) {
securityInfo += usprintf("Insyde Flash Device Map found at base %08Xh\nProtected ranges:\n", model->base(headerIndex));
protectedRangeFound = true;
}
// TODO: make sure that the only hash possible here is SHA256
// Add this region to the list of Insyde protected regions
PROTECTED_RANGE range = {};
range.Offset = (UINT32)entry->region_base();
range.Size = (UINT32)entry->region_size();
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
range.Type = PROTECTED_RANGE_VENDOR_HASH_INSYDE;
range.Hash = body;
protectedRanges.push_back(range);
securityInfo += usprintf("Address: %08Xh Size: %Xh\nHash: ", range.Offset, range.Size) + UString(body.toHex().constData()) + "\n";
}
// Add tree item
model->addItem(entryOffset, Types::InsydeFlashDeviceMapEntry, 0, name, text, info, header, body, UByteArray(), Fixed, headerIndex);
entryOffset += entrySize;
}
if (protectedRangeFound) {
securityInfo += "\n";
}
}
else { else {
return U_UNKNOWN_ITEM_TYPE; return U_UNKNOWN_ITEM_TYPE;
} }
@ -992,6 +1104,9 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
case Types::BpdtPartition: case Types::BpdtPartition:
// Parsing already done // Parsing already done
break; break;
case Types::InsydeFlashDeviceMapStore:
// Parsing already done
break;
case Types::Padding: case Types::Padding:
// No parsing required // No parsing required
break; break;
@ -1415,6 +1530,28 @@ continue_searching: {}
nextItemOffset = offset; nextItemOffset = offset;
break; break;
} }
else if (readUnaligned(currentPos) == INSYDE_FLASH_DEVICE_MAP_SIGNATURE) {
// Check data size
if (restSize < sizeof(INSYDE_FLASH_DEVICE_MAP_HEADER))
continue;
const INSYDE_FLASH_DEVICE_MAP_HEADER *fdmHeader = (const INSYDE_FLASH_DEVICE_MAP_HEADER *)currentPos;
if (restSize < fdmHeader->Size)
continue;
if (fdmHeader->Revision > 3) {
msg(usprintf("%s: Insyde Flash Device Map candidate with unknown revision %u", __FUNCTION__, fdmHeader->Revision), index);
continue;
}
// All checks passed, FDM found
nextItemType = Types::InsydeFlashDeviceMapStore;
nextItemSize = fdmHeader->Size;
nextItemAlternativeSize = fdmHeader->Size;
nextItemOffset = offset;
break;
}
} }
// No more stores found // No more stores found
@ -3764,6 +3901,26 @@ USTATUS FfsParser::checkProtectedRanges(const UModelIndex & index)
// Do nothing, this range is likely not found in the image // Do nothing, this range is likely not found in the image
} }
} }
else if (protectedRanges[i].Type == PROTECTED_RANGE_VENDOR_HASH_INSYDE) {
try {
protectedRanges[i].Offset -= (UINT32)addressDiff;
protectedParts = openedImage.mid(protectedRanges[i].Offset, protectedRanges[i].Size);
UByteArray digest(SHA256_HASH_SIZE, '\x00');
sha256(protectedParts.constData(), protectedParts.size(), digest.data());
if (digest != protectedRanges[i].Hash) {
msg(usprintf("%s: Insyde protected range [%Xh:%Xh] hash mismatch, opened image may refuse to boot", __FUNCTION__,
protectedRanges[i].Offset, protectedRanges[i].Offset + protectedRanges[i].Size),
model->findByBase(protectedRanges[i].Offset));
}
markProtectedRangeRecursive(index, protectedRanges[i]);
}
catch(...) {
// Do nothing, this range is likely not found in the image
}
}
} }
return U_SUCCESS; return U_SUCCESS;

View file

@ -67,6 +67,7 @@ typedef struct PROTECTED_RANGE_ {
#define PROTECTED_RANGE_VENDOR_HASH_AMI_V2 0x06 #define PROTECTED_RANGE_VENDOR_HASH_AMI_V2 0x06
#define PROTECTED_RANGE_VENDOR_HASH_AMI_V3 0x07 #define PROTECTED_RANGE_VENDOR_HASH_AMI_V3 0x07
#define PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA 0x08 #define PROTECTED_RANGE_VENDOR_HASH_MICROSOFT_PMDA 0x08
#define PROTECTED_RANGE_VENDOR_HASH_INSYDE 0x09
class FitParser; class FitParser;
class NvramParser; class NvramParser;

View file

@ -12,35 +12,11 @@ edk2_ftw_t::edk2_ftw_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, edk2_
} }
void edk2_ftw_t::_read() { void edk2_ftw_t::_read() {
m_signature = m__io->read_u4le(); m_signature = m__io->read_bytes(16);
{ {
uint32_t _ = signature(); std::string _ = signature();
if (!( ((_ == 4293995405UL) || (_ == 2656577835UL)) )) { if (!( ((_ == std::string("\x8D\x2B\xF1\xFF\x96\x76\x8B\x4C\xA9\x85\x27\x47\x07\x5B\x4F\x50", 16)) || (_ == std::string("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\x0A\xCE\x65\x00\xFD\x9F\x1B\x95", 16)) || (_ == std::string("\x2B\x29\x58\x9E\x68\x7C\x7D\x49\xA0\xCE\x65\x00\xFD\x9F\x1B\x95", 16))) )) {
throw kaitai::validation_expr_error<uint32_t>(signature(), _io(), std::string("/seq/0")); throw kaitai::validation_expr_error<std::string>(signature(), _io(), std::string("/seq/0"));
}
}
n_signature_main = true;
if (signature() == 4293995405UL) {
n_signature_main = false;
m_signature_main = m__io->read_bytes(12);
if (!(signature_main() == std::string("\x96\x76\x8B\x4C\xA9\x85\x27\x47\x07\x5B\x4F\x50", 12))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x96\x76\x8B\x4C\xA9\x85\x27\x47\x07\x5B\x4F\x50", 12), signature_main(), _io(), std::string("/seq/1"));
}
}
n_signature_edk2_working_block = true;
if (signature() == 2656577835UL) {
n_signature_edk2_working_block = false;
m_signature_edk2_working_block = m__io->read_bytes(12);
if (!(signature_edk2_working_block() == std::string("\x68\x7C\x7D\x49\x0A\xCE\x65\x00\xFD\x9F\x1B\x95", 12))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x68\x7C\x7D\x49\x0A\xCE\x65\x00\xFD\x9F\x1B\x95", 12), signature_edk2_working_block(), _io(), std::string("/seq/2"));
}
}
n_signature_vss2_working_block = true;
if (signature() == 2656577835UL) {
n_signature_vss2_working_block = false;
m_signature_vss2_working_block = m__io->read_bytes(12);
if (!(signature_vss2_working_block() == std::string("\x68\x7C\x7D\x49\xA0\xCE\x65\x00\xFD\x9F\x1B\x95", 12))) {
throw kaitai::validation_not_equal_error<std::string>(std::string("\x68\x7C\x7D\x49\xA0\xCE\x65\x00\xFD\x9F\x1B\x95", 12), signature_vss2_working_block(), _io(), std::string("/seq/3"));
} }
} }
m_crc = m__io->read_u4le(); m_crc = m__io->read_u4le();
@ -69,12 +45,6 @@ edk2_ftw_t::~edk2_ftw_t() {
} }
void edk2_ftw_t::_clean_up() { void edk2_ftw_t::_clean_up() {
if (!n_signature_main) {
}
if (!n_signature_edk2_working_block) {
}
if (!n_signature_vss2_working_block) {
}
if (!n_len_write_queue_64) { if (!n_len_write_queue_64) {
} }
if (!n_write_queue_32) { if (!n_write_queue_32) {

View file

@ -38,28 +38,7 @@ public:
int8_t len_ftw_store_header_64(); int8_t len_ftw_store_header_64();
private: private:
uint32_t m_signature; std::string m_signature;
std::string m_signature_main;
bool n_signature_main;
public:
bool _is_null_signature_main() { signature_main(); return n_signature_main; };
private:
std::string m_signature_edk2_working_block;
bool n_signature_edk2_working_block;
public:
bool _is_null_signature_edk2_working_block() { signature_edk2_working_block(); return n_signature_edk2_working_block; };
private:
std::string m_signature_vss2_working_block;
bool n_signature_vss2_working_block;
public:
bool _is_null_signature_vss2_working_block() { signature_vss2_working_block(); return n_signature_vss2_working_block; };
private:
uint32_t m_crc; uint32_t m_crc;
uint8_t m_state; uint8_t m_state;
std::string m_reserved; std::string m_reserved;
@ -89,10 +68,7 @@ private:
kaitai::kstruct* m__parent; kaitai::kstruct* m__parent;
public: public:
uint32_t signature() const { return m_signature; } std::string signature() const { return m_signature; }
std::string signature_main() const { return m_signature_main; }
std::string signature_edk2_working_block() const { return m_signature_edk2_working_block; }
std::string signature_vss2_working_block() const { return m_signature_vss2_working_block; }
uint32_t crc() const { return m_crc; } uint32_t crc() const { return m_crc; }
uint8_t state() const { return m_state; } uint8_t state() const { return m_state; }
std::string reserved() const { return m_reserved; } std::string reserved() const { return m_reserved; }

View file

@ -354,7 +354,7 @@ int32_t edk2_vss2_t::vss2_variable_t::end_offset() {
int32_t edk2_vss2_t::vss2_variable_t::len_alignment_padding_auth() { int32_t edk2_vss2_t::vss2_variable_t::len_alignment_padding_auth() {
if (f_len_alignment_padding_auth) if (f_len_alignment_padding_auth)
return m_len_alignment_padding_auth; return m_len_alignment_padding_auth;
m_len_alignment_padding_auth = ((((end_offset_auth() - offset()) + 3) & ~3) - (end_offset() - offset())); m_len_alignment_padding_auth = ((((end_offset_auth() - offset()) + 3) & ~3) - (end_offset_auth() - offset()));
f_len_alignment_padding_auth = true; f_len_alignment_padding_auth = true;
return m_len_alignment_padding_auth; return m_len_alignment_padding_auth;
} }

View file

@ -0,0 +1,179 @@
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "insyde_fdm.h"
#include "../kaitai/exceptions.h"
insyde_fdm_t::insyde_fdm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = this; (void)p__root;
m_extensions = nullptr;
m__io__raw_extensions = nullptr;
m_board_ids = nullptr;
m_entries = nullptr;
m__io__raw_entries = nullptr;
_read();
}
void insyde_fdm_t::_read() {
m_signature = m__io->read_u4le();
if (!(signature() == 1296320072)) {
throw kaitai::validation_not_equal_error<uint32_t>(1296320072, signature(), _io(), std::string("/seq/0"));
}
m_store_size = m__io->read_u4le();
m_data_offset = m__io->read_u4le();
m_entry_size = m__io->read_u4le();
m_entry_format = m__io->read_u1();
m_revision = m__io->read_u1();
m_num_extensions = m__io->read_u1();
m_checksum = m__io->read_u1();
m_fd_base_address = m__io->read_u8le();
n_extensions = true;
if (revision() == 3) {
n_extensions = false;
m__raw_extensions = m__io->read_bytes((num_extensions() * 4));
m__io__raw_extensions = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_extensions));
m_extensions = std::unique_ptr<fdm_extensions_t>(new fdm_extensions_t(m__io__raw_extensions.get(), this, m__root));
}
n_board_ids = true;
if (revision() == 3) {
n_board_ids = false;
m_board_ids = std::unique_ptr<fdm_board_ids_t>(new fdm_board_ids_t(m__io, this, m__root));
}
m__raw_entries = m__io->read_bytes((store_size() - data_offset()));
m__io__raw_entries = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_entries));
m_entries = std::unique_ptr<fdm_entries_t>(new fdm_entries_t(m__io__raw_entries.get(), this, m__root));
}
insyde_fdm_t::~insyde_fdm_t() {
_clean_up();
}
void insyde_fdm_t::_clean_up() {
if (!n_extensions) {
}
if (!n_board_ids) {
}
}
insyde_fdm_t::fdm_entries_t::fdm_entries_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_entries = nullptr;
_read();
}
void insyde_fdm_t::fdm_entries_t::_read() {
m_entries = std::unique_ptr<std::vector<std::unique_ptr<fdm_entry_t>>>(new std::vector<std::unique_ptr<fdm_entry_t>>());
{
int i = 0;
while (!m__io->is_eof()) {
m_entries->push_back(std::move(std::unique_ptr<fdm_entry_t>(new fdm_entry_t(m__io, this, m__root))));
i++;
}
}
}
insyde_fdm_t::fdm_entries_t::~fdm_entries_t() {
_clean_up();
}
void insyde_fdm_t::fdm_entries_t::_clean_up() {
}
insyde_fdm_t::fdm_extension_t::fdm_extension_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_extensions_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void insyde_fdm_t::fdm_extension_t::_read() {
m_offset = m__io->read_u2le();
m_count = m__io->read_u2le();
}
insyde_fdm_t::fdm_extension_t::~fdm_extension_t() {
_clean_up();
}
void insyde_fdm_t::fdm_extension_t::_clean_up() {
}
insyde_fdm_t::fdm_board_ids_t::fdm_board_ids_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_board_ids = nullptr;
_read();
}
void insyde_fdm_t::fdm_board_ids_t::_read() {
m_region_index = m__io->read_u4le();
m_num_board_ids = m__io->read_u4le();
m_board_ids = std::unique_ptr<std::vector<uint64_t>>(new std::vector<uint64_t>());
const int l_board_ids = num_board_ids();
for (int i = 0; i < l_board_ids; i++) {
m_board_ids->push_back(std::move(m__io->read_u8le()));
}
}
insyde_fdm_t::fdm_board_ids_t::~fdm_board_ids_t() {
_clean_up();
}
void insyde_fdm_t::fdm_board_ids_t::_clean_up() {
}
insyde_fdm_t::fdm_extensions_t::fdm_extensions_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
m_extensions = nullptr;
_read();
}
void insyde_fdm_t::fdm_extensions_t::_read() {
m_extensions = std::unique_ptr<std::vector<std::unique_ptr<fdm_extension_t>>>(new std::vector<std::unique_ptr<fdm_extension_t>>());
{
int i = 0;
while (!m__io->is_eof()) {
m_extensions->push_back(std::move(std::unique_ptr<fdm_extension_t>(new fdm_extension_t(m__io, this, m__root))));
i++;
}
}
}
insyde_fdm_t::fdm_extensions_t::~fdm_extensions_t() {
_clean_up();
}
void insyde_fdm_t::fdm_extensions_t::_clean_up() {
}
insyde_fdm_t::fdm_entry_t::fdm_entry_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_entries_t* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
f_region_base = false;
_read();
}
void insyde_fdm_t::fdm_entry_t::_read() {
m_guid = m__io->read_bytes(16);
m_region_id = m__io->read_bytes(16);
m_region_offset = m__io->read_u8le();
m_region_size = m__io->read_u8le();
m_attributes = m__io->read_u4le();
m_hash = m__io->read_bytes((((((_parent()->_parent()->entry_size() - 16) - 16) - 8) - 8) - 4));
}
insyde_fdm_t::fdm_entry_t::~fdm_entry_t() {
_clean_up();
}
void insyde_fdm_t::fdm_entry_t::_clean_up() {
}
int32_t insyde_fdm_t::fdm_entry_t::region_base() {
if (f_region_base)
return m_region_base;
m_region_base = (static_cast<uint32_t>(_root()->fd_base_address()) + static_cast<uint32_t>(region_offset()));
f_region_base = true;
return m_region_base;
}

View file

@ -0,0 +1,232 @@
#pragma once
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
#include "../kaitai/kaitaistruct.h"
#include <stdint.h>
#include <memory>
#include <vector>
#if KAITAI_STRUCT_VERSION < 9000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.9 or later is required"
#endif
class insyde_fdm_t : public kaitai::kstruct {
public:
class fdm_entries_t;
class fdm_extension_t;
class fdm_board_ids_t;
class fdm_extensions_t;
class fdm_entry_t;
insyde_fdm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, insyde_fdm_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~insyde_fdm_t();
class fdm_entries_t : public kaitai::kstruct {
public:
fdm_entries_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~fdm_entries_t();
private:
std::unique_ptr<std::vector<std::unique_ptr<fdm_entry_t>>> m_entries;
insyde_fdm_t* m__root;
insyde_fdm_t* m__parent;
public:
std::vector<std::unique_ptr<fdm_entry_t>>* entries() const { return m_entries.get(); }
insyde_fdm_t* _root() const { return m__root; }
insyde_fdm_t* _parent() const { return m__parent; }
};
class fdm_extension_t : public kaitai::kstruct {
public:
fdm_extension_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_extensions_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~fdm_extension_t();
private:
uint16_t m_offset;
uint16_t m_count;
insyde_fdm_t* m__root;
insyde_fdm_t::fdm_extensions_t* m__parent;
public:
uint16_t offset() const { return m_offset; }
uint16_t count() const { return m_count; }
insyde_fdm_t* _root() const { return m__root; }
insyde_fdm_t::fdm_extensions_t* _parent() const { return m__parent; }
};
class fdm_board_ids_t : public kaitai::kstruct {
public:
fdm_board_ids_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~fdm_board_ids_t();
private:
uint32_t m_region_index;
uint32_t m_num_board_ids;
std::unique_ptr<std::vector<uint64_t>> m_board_ids;
insyde_fdm_t* m__root;
insyde_fdm_t* m__parent;
public:
uint32_t region_index() const { return m_region_index; }
uint32_t num_board_ids() const { return m_num_board_ids; }
std::vector<uint64_t>* board_ids() const { return m_board_ids.get(); }
insyde_fdm_t* _root() const { return m__root; }
insyde_fdm_t* _parent() const { return m__parent; }
};
class fdm_extensions_t : public kaitai::kstruct {
public:
fdm_extensions_t(kaitai::kstream* p__io, insyde_fdm_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~fdm_extensions_t();
private:
std::unique_ptr<std::vector<std::unique_ptr<fdm_extension_t>>> m_extensions;
insyde_fdm_t* m__root;
insyde_fdm_t* m__parent;
public:
std::vector<std::unique_ptr<fdm_extension_t>>* extensions() const { return m_extensions.get(); }
insyde_fdm_t* _root() const { return m__root; }
insyde_fdm_t* _parent() const { return m__parent; }
};
class fdm_entry_t : public kaitai::kstruct {
public:
fdm_entry_t(kaitai::kstream* p__io, insyde_fdm_t::fdm_entries_t* p__parent = nullptr, insyde_fdm_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~fdm_entry_t();
private:
bool f_region_base;
int32_t m_region_base;
public:
int32_t region_base();
private:
std::string m_guid;
std::string m_region_id;
uint64_t m_region_offset;
uint64_t m_region_size;
uint32_t m_attributes;
std::string m_hash;
insyde_fdm_t* m__root;
insyde_fdm_t::fdm_entries_t* m__parent;
public:
std::string guid() const { return m_guid; }
std::string region_id() const { return m_region_id; }
uint64_t region_offset() const { return m_region_offset; }
uint64_t region_size() const { return m_region_size; }
uint32_t attributes() const { return m_attributes; }
std::string hash() const { return m_hash; }
insyde_fdm_t* _root() const { return m__root; }
insyde_fdm_t::fdm_entries_t* _parent() const { return m__parent; }
};
private:
uint32_t m_signature;
uint32_t m_store_size;
uint32_t m_data_offset;
uint32_t m_entry_size;
uint8_t m_entry_format;
uint8_t m_revision;
uint8_t m_num_extensions;
uint8_t m_checksum;
uint64_t m_fd_base_address;
std::unique_ptr<fdm_extensions_t> m_extensions;
bool n_extensions;
public:
bool _is_null_extensions() { extensions(); return n_extensions; };
private:
std::unique_ptr<fdm_board_ids_t> m_board_ids;
bool n_board_ids;
public:
bool _is_null_board_ids() { board_ids(); return n_board_ids; };
private:
std::unique_ptr<fdm_entries_t> m_entries;
insyde_fdm_t* m__root;
kaitai::kstruct* m__parent;
std::string m__raw_extensions;
bool n__raw_extensions;
public:
bool _is_null__raw_extensions() { _raw_extensions(); return n__raw_extensions; };
private:
std::unique_ptr<kaitai::kstream> m__io__raw_extensions;
std::string m__raw_entries;
std::unique_ptr<kaitai::kstream> m__io__raw_entries;
public:
uint32_t signature() const { return m_signature; }
uint32_t store_size() const { return m_store_size; }
uint32_t data_offset() const { return m_data_offset; }
uint32_t entry_size() const { return m_entry_size; }
uint8_t entry_format() const { return m_entry_format; }
uint8_t revision() const { return m_revision; }
uint8_t num_extensions() const { return m_num_extensions; }
uint8_t checksum() const { return m_checksum; }
uint64_t fd_base_address() const { return m_fd_base_address; }
fdm_extensions_t* extensions() const { return m_extensions.get(); }
fdm_board_ids_t* board_ids() const { return m_board_ids.get(); }
fdm_entries_t* entries() const { return m_entries.get(); }
insyde_fdm_t* _root() const { return m__root; }
kaitai::kstruct* _parent() const { return m__parent; }
std::string _raw_extensions() const { return m__raw_extensions; }
kaitai::kstream* _io__raw_extensions() const { return m__io__raw_extensions.get(); }
std::string _raw_entries() const { return m__raw_entries; }
kaitai::kstream* _io__raw_entries() const { return m__io__raw_entries.get(); }
};

View file

@ -17,18 +17,18 @@ void phoenix_evsa_t::_read() {
throw kaitai::validation_not_equal_error<uint8_t>(236, type(), _io(), std::string("/seq/0")); throw kaitai::validation_not_equal_error<uint8_t>(236, type(), _io(), std::string("/seq/0"));
} }
m_checksum = m__io->read_u1(); m_checksum = m__io->read_u1();
m_size = m__io->read_u2le(); m_len_evsa_store_header = m__io->read_u2le();
if (!(size() == 20)) { if (!(len_evsa_store_header() == 20)) {
throw kaitai::validation_not_equal_error<uint16_t>(20, size(), _io(), std::string("/seq/2")); throw kaitai::validation_not_equal_error<uint16_t>(20, len_evsa_store_header(), _io(), std::string("/seq/2"));
} }
m_signature = m__io->read_u4le(); m_signature = m__io->read_u4le();
if (!(signature() == 1095980613)) { if (!(signature() == 1095980613)) {
throw kaitai::validation_not_equal_error<uint32_t>(1095980613, signature(), _io(), std::string("/seq/3")); throw kaitai::validation_not_equal_error<uint32_t>(1095980613, signature(), _io(), std::string("/seq/3"));
} }
m_attributes = m__io->read_u4le(); m_attributes = m__io->read_u4le();
m_store_size = m__io->read_u4le(); m_len_evsa_store = m__io->read_u4le();
m_reserved = m__io->read_u4le(); m_reserved = m__io->read_u4le();
m__raw_body = m__io->read_bytes((store_size() - 20)); m__raw_body = m__io->read_bytes((len_evsa_store() - len_evsa_store_header()));
m__io__raw_body = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_body)); m__io__raw_body = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_body));
m_body = std::unique_ptr<evsa_body_t>(new evsa_body_t(m__io__raw_body.get(), this, m__root)); m_body = std::unique_ptr<evsa_body_t>(new evsa_body_t(m__io__raw_body.get(), this, m__root));
} }
@ -47,10 +47,18 @@ phoenix_evsa_t::evsa_entry_t::evsa_entry_t(kaitai::kstream* p__io, phoenix_evsa_
} }
void phoenix_evsa_t::evsa_entry_t::_read() { void phoenix_evsa_t::evsa_entry_t::_read() {
m_type = m__io->read_u1(); m_entry_type = m__io->read_u1();
n_checksum = true;
if ( ((entry_type() == 225) || (entry_type() == 226) || (entry_type() == 227) || (entry_type() == 237) || (entry_type() == 238) || (entry_type() == 239) || (entry_type() == 131)) ) {
n_checksum = false;
m_checksum = m__io->read_u1(); m_checksum = m__io->read_u1();
m_size = m__io->read_u2le(); }
switch (type()) { n_len_evsa_entry = true;
if ( ((entry_type() == 225) || (entry_type() == 226) || (entry_type() == 227) || (entry_type() == 237) || (entry_type() == 238) || (entry_type() == 239) || (entry_type() == 131)) ) {
n_len_evsa_entry = false;
m_len_evsa_entry = m__io->read_u2le();
}
switch (entry_type()) {
case 239: { case 239: {
m_body = std::unique_ptr<evsa_data_t>(new evsa_data_t(m__io, this, m__root)); m_body = std::unique_ptr<evsa_data_t>(new evsa_data_t(m__io, this, m__root));
break; break;
@ -91,6 +99,10 @@ phoenix_evsa_t::evsa_entry_t::~evsa_entry_t() {
} }
void phoenix_evsa_t::evsa_entry_t::_clean_up() { void phoenix_evsa_t::evsa_entry_t::_clean_up() {
if (!n_checksum) {
}
if (!n_len_evsa_entry) {
}
} }
phoenix_evsa_t::evsa_unknown_t::evsa_unknown_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { phoenix_evsa_t::evsa_unknown_t::evsa_unknown_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
@ -114,15 +126,26 @@ phoenix_evsa_t::evsa_body_t::evsa_body_t(kaitai::kstream* p__io, phoenix_evsa_t*
m__parent = p__parent; m__parent = p__parent;
m__root = p__root; m__root = p__root;
m_entries = nullptr; m_entries = nullptr;
m_free_space = nullptr;
_read(); _read();
} }
void phoenix_evsa_t::evsa_body_t::_read() { void phoenix_evsa_t::evsa_body_t::_read() {
m_entries = std::unique_ptr<std::vector<std::unique_ptr<evsa_entry_t>>>(new std::vector<std::unique_ptr<evsa_entry_t>>()); m_entries = std::unique_ptr<std::vector<std::unique_ptr<evsa_entry_t>>>(new std::vector<std::unique_ptr<evsa_entry_t>>());
{
int i = 0;
evsa_entry_t* _;
do {
_ = new evsa_entry_t(m__io, this, m__root);
m_entries->push_back(std::move(std::unique_ptr<evsa_entry_t>(_)));
i++;
} while (!( (( ((_->entry_type() != 237) && (_->entry_type() != 238) && (_->entry_type() != 239) && (_->entry_type() != 225) && (_->entry_type() != 226) && (_->entry_type() != 227) && (_->entry_type() != 131)) ) || (_io()->is_eof())) ));
}
m_free_space = std::unique_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>());
{ {
int i = 0; int i = 0;
while (!m__io->is_eof()) { while (!m__io->is_eof()) {
m_entries->push_back(std::move(std::unique_ptr<evsa_entry_t>(new evsa_entry_t(m__io, this, m__root)))); m_free_space->push_back(std::move(m__io->read_u1()));
i++; i++;
} }
} }
@ -143,7 +166,7 @@ phoenix_evsa_t::evsa_name_t::evsa_name_t(kaitai::kstream* p__io, phoenix_evsa_t:
void phoenix_evsa_t::evsa_name_t::_read() { void phoenix_evsa_t::evsa_name_t::_read() {
m_var_id = m__io->read_u2le(); m_var_id = m__io->read_u2le();
m_name = m__io->read_bytes((_parent()->size() - 6)); m_name = m__io->read_bytes((_parent()->len_evsa_entry() - 6));
} }
phoenix_evsa_t::evsa_name_t::~evsa_name_t() { phoenix_evsa_t::evsa_name_t::~evsa_name_t() {
@ -162,6 +185,12 @@ phoenix_evsa_t::evsa_guid_t::evsa_guid_t(kaitai::kstream* p__io, phoenix_evsa_t:
void phoenix_evsa_t::evsa_guid_t::_read() { void phoenix_evsa_t::evsa_guid_t::_read() {
m_guid_id = m__io->read_u2le(); m_guid_id = m__io->read_u2le();
m_guid = m__io->read_bytes(16); m_guid = m__io->read_bytes(16);
{
std::string _ = guid();
if (!(_parent()->len_evsa_entry() == 22)) {
throw kaitai::validation_expr_error<std::string>(guid(), _io(), std::string("/types/evsa_guid/seq/1"));
}
}
} }
phoenix_evsa_t::evsa_guid_t::~evsa_guid_t() { phoenix_evsa_t::evsa_guid_t::~evsa_guid_t() {
@ -171,30 +200,57 @@ phoenix_evsa_t::evsa_guid_t::~evsa_guid_t() {
void phoenix_evsa_t::evsa_guid_t::_clean_up() { void phoenix_evsa_t::evsa_guid_t::_clean_up() {
} }
phoenix_evsa_t::evsa_variable_attributes_t::evsa_variable_attributes_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_data_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent;
m__root = p__root;
_read();
}
void phoenix_evsa_t::evsa_variable_attributes_t::_read() {
m_non_volatile = m__io->read_bits_int_le(1);
m_boot_service = m__io->read_bits_int_le(1);
m_runtime = m__io->read_bits_int_le(1);
m_hw_error_record = m__io->read_bits_int_le(1);
m_auth_write = m__io->read_bits_int_le(1);
m_time_based_auth = m__io->read_bits_int_le(1);
m_append_write = m__io->read_bits_int_le(1);
m_reserved = m__io->read_bits_int_le(21);
m_extended_header = m__io->read_bits_int_le(1);
m_reserved1 = m__io->read_bits_int_le(3);
}
phoenix_evsa_t::evsa_variable_attributes_t::~evsa_variable_attributes_t() {
_clean_up();
}
void phoenix_evsa_t::evsa_variable_attributes_t::_clean_up() {
}
phoenix_evsa_t::evsa_data_t::evsa_data_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) { phoenix_evsa_t::evsa_data_t::evsa_data_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_entry_t* p__parent, phoenix_evsa_t* p__root) : kaitai::kstruct(p__io) {
m__parent = p__parent; m__parent = p__parent;
m__root = p__root; m__root = p__root;
m_attributes = nullptr;
_read(); _read();
} }
void phoenix_evsa_t::evsa_data_t::_read() { void phoenix_evsa_t::evsa_data_t::_read() {
m_guid_id = m__io->read_u2le(); m_guid_id = m__io->read_u2le();
m_var_id = m__io->read_u2le(); m_var_id = m__io->read_u2le();
m_attributes = m__io->read_u4le(); m_attributes = std::unique_ptr<evsa_variable_attributes_t>(new evsa_variable_attributes_t(m__io, this, m__root));
n_data_size = true; n_len_data_ext = true;
if ((attributes() & 268435456) != 268435456) { if (attributes()->extended_header()) {
n_data_size = false; n_len_data_ext = false;
m_data_size = m__io->read_u4le(); m_len_data_ext = m__io->read_u4le();
} }
n_data = true; n_data = true;
if ((attributes() & 268435456) == 268435456) { if (!(attributes()->extended_header())) {
n_data = false; n_data = false;
m_data = m__io->read_bytes((_parent()->size() - 12)); m_data = m__io->read_bytes((_parent()->len_evsa_entry() - 12));
} }
n_data_ext = true; n_data_ext = true;
if ((attributes() & 268435456) != 268435456) { if (attributes()->extended_header()) {
n_data_ext = false; n_data_ext = false;
m_data_ext = m__io->read_bytes(data_size()); m_data_ext = m__io->read_bytes(len_data_ext());
} }
} }
@ -203,7 +259,7 @@ phoenix_evsa_t::evsa_data_t::~evsa_data_t() {
} }
void phoenix_evsa_t::evsa_data_t::_clean_up() { void phoenix_evsa_t::evsa_data_t::_clean_up() {
if (!n_data_size) { if (!n_len_data_ext) {
} }
if (!n_data) { if (!n_data) {
} }

View file

@ -19,6 +19,7 @@ public:
class evsa_body_t; class evsa_body_t;
class evsa_name_t; class evsa_name_t;
class evsa_guid_t; class evsa_guid_t;
class evsa_variable_attributes_t;
class evsa_data_t; class evsa_data_t;
phoenix_evsa_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr); phoenix_evsa_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
@ -44,17 +45,29 @@ public:
~evsa_entry_t(); ~evsa_entry_t();
private: private:
uint8_t m_type; uint8_t m_entry_type;
uint8_t m_checksum; uint8_t m_checksum;
uint16_t m_size; bool n_checksum;
public:
bool _is_null_checksum() { checksum(); return n_checksum; };
private:
uint16_t m_len_evsa_entry;
bool n_len_evsa_entry;
public:
bool _is_null_len_evsa_entry() { len_evsa_entry(); return n_len_evsa_entry; };
private:
std::unique_ptr<kaitai::kstruct> m_body; std::unique_ptr<kaitai::kstruct> m_body;
phoenix_evsa_t* m__root; phoenix_evsa_t* m__root;
phoenix_evsa_t::evsa_body_t* m__parent; phoenix_evsa_t::evsa_body_t* m__parent;
public: public:
uint8_t type() const { return m_type; } uint8_t entry_type() const { return m_entry_type; }
uint8_t checksum() const { return m_checksum; } uint8_t checksum() const { return m_checksum; }
uint16_t size() const { return m_size; } uint16_t len_evsa_entry() const { return m_len_evsa_entry; }
kaitai::kstruct* body() const { return m_body.get(); } kaitai::kstruct* body() const { return m_body.get(); }
phoenix_evsa_t* _root() const { return m__root; } phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t::evsa_body_t* _parent() const { return m__parent; } phoenix_evsa_t::evsa_body_t* _parent() const { return m__parent; }
@ -99,11 +112,13 @@ public:
private: private:
std::unique_ptr<std::vector<std::unique_ptr<evsa_entry_t>>> m_entries; std::unique_ptr<std::vector<std::unique_ptr<evsa_entry_t>>> m_entries;
std::unique_ptr<std::vector<uint8_t>> m_free_space;
phoenix_evsa_t* m__root; phoenix_evsa_t* m__root;
phoenix_evsa_t* m__parent; phoenix_evsa_t* m__parent;
public: public:
std::vector<std::unique_ptr<evsa_entry_t>>* entries() const { return m_entries.get(); } std::vector<std::unique_ptr<evsa_entry_t>>* entries() const { return m_entries.get(); }
std::vector<uint8_t>* free_space() const { return m_free_space.get(); }
phoenix_evsa_t* _root() const { return m__root; } phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t* _parent() const { return m__parent; } phoenix_evsa_t* _parent() const { return m__parent; }
}; };
@ -160,6 +175,48 @@ public:
phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; } phoenix_evsa_t::evsa_entry_t* _parent() const { return m__parent; }
}; };
class evsa_variable_attributes_t : public kaitai::kstruct {
public:
evsa_variable_attributes_t(kaitai::kstream* p__io, phoenix_evsa_t::evsa_data_t* p__parent = nullptr, phoenix_evsa_t* p__root = nullptr);
private:
void _read();
void _clean_up();
public:
~evsa_variable_attributes_t();
private:
bool m_non_volatile;
bool m_boot_service;
bool m_runtime;
bool m_hw_error_record;
bool m_auth_write;
bool m_time_based_auth;
bool m_append_write;
uint64_t m_reserved;
bool m_extended_header;
uint64_t m_reserved1;
phoenix_evsa_t* m__root;
phoenix_evsa_t::evsa_data_t* m__parent;
public:
bool non_volatile() const { return m_non_volatile; }
bool boot_service() const { return m_boot_service; }
bool runtime() const { return m_runtime; }
bool hw_error_record() const { return m_hw_error_record; }
bool auth_write() const { return m_auth_write; }
bool time_based_auth() const { return m_time_based_auth; }
bool append_write() const { return m_append_write; }
uint64_t reserved() const { return m_reserved; }
bool extended_header() const { return m_extended_header; }
uint64_t reserved1() const { return m_reserved1; }
phoenix_evsa_t* _root() const { return m__root; }
phoenix_evsa_t::evsa_data_t* _parent() const { return m__parent; }
};
class evsa_data_t : public kaitai::kstruct { class evsa_data_t : public kaitai::kstruct {
public: public:
@ -176,12 +233,12 @@ public:
private: private:
uint16_t m_guid_id; uint16_t m_guid_id;
uint16_t m_var_id; uint16_t m_var_id;
uint32_t m_attributes; std::unique_ptr<evsa_variable_attributes_t> m_attributes;
uint32_t m_data_size; uint32_t m_len_data_ext;
bool n_data_size; bool n_len_data_ext;
public: public:
bool _is_null_data_size() { data_size(); return n_data_size; }; bool _is_null_len_data_ext() { len_data_ext(); return n_len_data_ext; };
private: private:
std::string m_data; std::string m_data;
@ -204,8 +261,8 @@ public:
public: public:
uint16_t guid_id() const { return m_guid_id; } uint16_t guid_id() const { return m_guid_id; }
uint16_t var_id() const { return m_var_id; } uint16_t var_id() const { return m_var_id; }
uint32_t attributes() const { return m_attributes; } evsa_variable_attributes_t* attributes() const { return m_attributes.get(); }
uint32_t data_size() const { return m_data_size; } uint32_t len_data_ext() const { return m_len_data_ext; }
std::string data() const { return m_data; } std::string data() const { return m_data; }
std::string data_ext() const { return m_data_ext; } std::string data_ext() const { return m_data_ext; }
phoenix_evsa_t* _root() const { return m__root; } phoenix_evsa_t* _root() const { return m__root; }
@ -215,10 +272,10 @@ public:
private: private:
uint8_t m_type; uint8_t m_type;
uint8_t m_checksum; uint8_t m_checksum;
uint16_t m_size; uint16_t m_len_evsa_store_header;
uint32_t m_signature; uint32_t m_signature;
uint32_t m_attributes; uint32_t m_attributes;
uint32_t m_store_size; uint32_t m_len_evsa_store;
uint32_t m_reserved; uint32_t m_reserved;
std::unique_ptr<evsa_body_t> m_body; std::unique_ptr<evsa_body_t> m_body;
phoenix_evsa_t* m__root; phoenix_evsa_t* m__root;
@ -229,10 +286,10 @@ private:
public: public:
uint8_t type() const { return m_type; } uint8_t type() const { return m_type; }
uint8_t checksum() const { return m_checksum; } uint8_t checksum() const { return m_checksum; }
uint16_t size() const { return m_size; } uint16_t len_evsa_store_header() const { return m_len_evsa_store_header; }
uint32_t signature() const { return m_signature; } uint32_t signature() const { return m_signature; }
uint32_t attributes() const { return m_attributes; } uint32_t attributes() const { return m_attributes; }
uint32_t store_size() const { return m_store_size; } uint32_t len_evsa_store() const { return m_len_evsa_store; }
uint32_t reserved() const { return m_reserved; } uint32_t reserved() const { return m_reserved; }
evsa_body_t* body() const { return m_body.get(); } evsa_body_t* body() const { return m_body.get(); }
phoenix_evsa_t* _root() const { return m__root; } phoenix_evsa_t* _root() const { return m__root; }

View file

@ -11,18 +11,11 @@ meta:
seq: seq:
- id: signature - id: signature
type: u4 size: 16
valid: valid:
expr: _ == 0xFFF12B8D or _ == 0x9E58292B expr: _ == [0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50]
- id: signature_main or _ == [0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49, 0x0A, 0xCE, 0x65, 0x00, 0xFD, 0x9F, 0x1B, 0x95]
contents: [0x96, 0x76, 0x8B, 0x4C, 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50] # FF12B8D-7696-4C8B-A985-2747075B4F50 or _ == [0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49, 0xA0, 0xCE, 0x65, 0x00, 0xFD, 0x9F, 0x1B, 0x95]
if: signature == 0xFFF12B8D
- id: signature_edk2_working_block
contents: [0x68, 0x7C, 0x7D, 0x49, 0x0A, 0xCE, 0x65, 0x00, 0xFD, 0x9F, 0x1B, 0x95] # 9E58292B-7C68-497D-0ACE-6500FD9F1B95
if: signature == 0x9E58292B
- id: signature_vss2_working_block
contents: [0x68, 0x7C, 0x7D, 0x49, 0xA0, 0xCE, 0x65, 0x00, 0xFD, 0x9F, 0x1B, 0x95] # 9E58292B-7C68-497D-A0CE-6500FD9F1B95
if: signature == 0x9E58292B
- id: crc - id: crc
type: u4 type: u4
- id: state - id: state

View file

@ -40,6 +40,7 @@ seq:
- id: body - id: body
type: vss2_store_body type: vss2_store_body
size: vss2_size - len_vss2_store_header size: vss2_size - len_vss2_store_header
instances: instances:
len_vss2_store_header: len_vss2_store_header:
value: 7 * sizeof<u4> value: 7 * sizeof<u4>
@ -71,7 +72,6 @@ types:
- id: reserved - id: reserved
type: b25le type: b25le
# TODO: check if VSS2 stores can have standard VSS variables
vss2_variable: vss2_variable:
seq: seq:
- id: invoke_offset - id: invoke_offset
@ -152,7 +152,7 @@ types:
len_alignment_padding: len_alignment_padding:
value: (((end_offset - offset)+3) & ~3) - (end_offset - offset) value: (((end_offset - offset)+3) & ~3) - (end_offset - offset)
len_alignment_padding_auth: len_alignment_padding_auth:
value: (((end_offset_auth - offset)+3) & ~3) - (end_offset - offset) value: (((end_offset_auth - offset)+3) & ~3) - (end_offset_auth - offset)
is_valid: is_valid:
value: state == 0x7F or state == 0x3F value: state == 0x7F or state == 0x3F
is_auth: is_auth:

91
common/ksy/insyde_fdm.ksy Normal file
View file

@ -0,0 +1,91 @@
meta:
id: insyde_fdm
title: Insyde Flash Device
application: Insyde-based UEFI firmware
file-extension: fdm
tags:
- firmware
license: CC0-1.0
ks-version: 0.9
endian: le
seq:
- id: signature
type: u4
valid: 0x4D444648 # HFDM
- id: store_size
type: u4
- id: data_offset
type: u4
- id: entry_size
type: u4
- id: entry_format
type: u1
- id: revision
type: u1
- id: num_extensions
type: u1
- id: checksum
type: u1
- id: fd_base_address
type: u8
- id: extensions
type: fdm_extensions
size: num_extensions * sizeof<fdm_extension>
if: revision == 3
- id: board_ids
type: fdm_board_ids
if: revision == 3
- id: entries
type: fdm_entries
size: store_size - data_offset
types:
fdm_extensions:
seq:
- id: extensions
type: fdm_extension
repeat: eos
fdm_extension:
seq:
- id: offset
type: u2
- id: count
type: u2
fdm_board_ids:
seq:
- id: region_index
type: u4
- id: num_board_ids
type: u4
- id: board_ids
type: u8
repeat: expr
repeat-expr: num_board_ids
fdm_entries:
seq:
- id: entries
type: fdm_entry
repeat: eos
fdm_entry:
seq:
- id: guid
size: 16
- id: region_id
size: 16
- id: region_offset
type: u8
- id: region_size
type: u8
- id: attributes
type: u4
- id: hash
size: _parent._parent.entry_size - 16 - 16 - 8 - 8 - 4
instances:
region_base:
value: _root.fd_base_address.as<u4> + region_offset.as<u4>

View file

@ -15,21 +15,21 @@ seq:
valid: 0xEC valid: 0xEC
- id: checksum - id: checksum
type: u1 type: u1
- id: size - id: len_evsa_store_header
type: u2 type: u2
valid: 20 valid: 20
- id: signature - id: signature
type: u4 type: u4
valid: 0x41535645 valid: 0x41535645 #EVSA
- id: attributes - id: attributes
type: u4 type: u4
- id: store_size - id: len_evsa_store
type: u4 type: u4
- id: reserved - id: reserved
type: u4 type: u4
- id: body - id: body
type: evsa_body type: evsa_body
size: store_size - 20 size: len_evsa_store - len_evsa_store_header
types: types:
evsa_guid: evsa_guid:
@ -38,13 +38,38 @@ types:
type: u2 type: u2
- id: guid - id: guid
size: 16 size: 16
valid:
expr: _parent.len_evsa_entry == 22
evsa_name: evsa_name:
seq: seq:
- id: var_id - id: var_id
type: u2 type: u2
- id: name - id: name
size: _parent.size - 6 size: _parent.len_evsa_entry - 6
evsa_variable_attributes:
seq:
- id: non_volatile
type: b1le
- id: boot_service
type: b1le
- id: runtime
type: b1le
- id: hw_error_record
type: b1le
- id: auth_write
type: b1le
- id: time_based_auth
type: b1le
- id: append_write
type: b1le
- id: reserved
type: b21le
- id: extended_header
type: b1le
- id: reserved1
type: b3le
evsa_data: evsa_data:
seq: seq:
@ -53,16 +78,16 @@ types:
- id: var_id - id: var_id
type: u2 type: u2
- id: attributes - id: attributes
type: evsa_variable_attributes
- id: len_data_ext
type: u4 type: u4
- id: data_size if: attributes.extended_header
type: u4
if: (attributes & 0x10000000) != 0x10000000
- id: data - id: data
size: _parent.size - 12 size: _parent.len_evsa_entry - 12
if: (attributes & 0x10000000) == 0x10000000 if: not attributes.extended_header
- id: data_ext - id: data_ext
size: data_size size: len_data_ext
if: (attributes & 0x10000000) != 0x10000000 if: attributes.extended_header
evsa_unknown: evsa_unknown:
seq: seq:
@ -71,15 +96,29 @@ types:
evsa_entry: evsa_entry:
seq: seq:
- id: type - id: entry_type
type: u1 type: u1
- id: checksum - id: checksum
type: u1 type: u1
- id: size if: entry_type == 0xE1
or entry_type == 0xE2
or entry_type == 0xE3
or entry_type == 0xED
or entry_type == 0xEE
or entry_type == 0xEF
or entry_type == 0x83
- id: len_evsa_entry
type: u2 type: u2
if: entry_type == 0xE1
or entry_type == 0xE2
or entry_type == 0xE3
or entry_type == 0xED
or entry_type == 0xEE
or entry_type == 0xEF
or entry_type == 0x83
- id: body - id: body
type: type:
switch-on: type switch-on: entry_type
cases: cases:
0xED: evsa_guid 0xED: evsa_guid
0xE1: evsa_guid 0xE1: evsa_guid
@ -94,6 +133,15 @@ types:
seq: seq:
- id: entries - id: entries
type: evsa_entry type: evsa_entry
repeat: until
repeat-until: (_.entry_type != 0xED
and _.entry_type != 0xEE
and _.entry_type != 0xEF
and _.entry_type != 0xE1
and _.entry_type != 0xE2
and _.entry_type != 0xE3
and _.entry_type != 0x83)
or _io.eof
- id: free_space
type: u1
repeat: eos repeat: eos

View file

@ -38,7 +38,9 @@ uefitoolcommon = static_library('uefitoolcommon',
'generated/edk2_vss2.cpp', 'generated/edk2_vss2.cpp',
'generated/edk2_ftw.cpp', 'generated/edk2_ftw.cpp',
'generated/insyde_fdc.cpp', 'generated/insyde_fdc.cpp',
'generated/insyde_fdm.cpp',
'generated/phoenix_flm.cpp', 'generated/phoenix_flm.cpp',
'generated/phoenix_evsa.cpp',
'generated/intel_acbp_v1.cpp', 'generated/intel_acbp_v1.cpp',
'generated/intel_acbp_v2.cpp', 'generated/intel_acbp_v2.cpp',
'generated/intel_keym_v1.cpp', 'generated/intel_keym_v1.cpp',

View file

@ -152,7 +152,7 @@ UString efiTimeToUString(const EFI_TIME & time)
time.Nanosecond); time.Nanosecond);
} }
UString flashMapGuidToUString(const EFI_GUID & guid) UString phoenixFlashMapGuidToUString(const EFI_GUID & guid)
{ {
const UByteArray baGuid((const char*)&guid, sizeof(EFI_GUID)); const UByteArray baGuid((const char*)&guid, sizeof(EFI_GUID));
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER) return UString("Volume header"); if (baGuid == NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER) return UString("Volume header");

View file

@ -274,7 +274,7 @@ typedef struct EVSA_STORE_ENTRY_ {
UINT32 Signature; // EVSA signature UINT32 Signature; // EVSA signature
UINT32 Attributes; UINT32 Attributes;
UINT32 StoreSize; UINT32 StoreSize;
UINT32 : 32; UINT32 Reserved;
} EVSA_STORE_ENTRY; } EVSA_STORE_ENTRY;
typedef struct EVSA_GUID_ENTRY_ { typedef struct EVSA_GUID_ENTRY_ {
@ -347,7 +347,7 @@ typedef struct PHOENIX_FLASH_MAP_ENTRY_ {
#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_VOLUME 0x0000 #define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_VOLUME 0x0000
#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_DATA_BLOCK 0x0001 #define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_DATA_BLOCK 0x0001
extern UString flashMapGuidToUString(const EFI_GUID & guid); extern UString phoenixFlashMapGuidToUString(const EFI_GUID & guid);
extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER; // B091E7D2-05A0-4198-94F0-74B7B8C55459 extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER; // B091E7D2-05A0-4198-94F0-74B7B8C55459
extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID; // FD3F690E-B4B0-4D68-89DB-19A1A3318F90 extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID; // FD3F690E-B4B0-4D68-89DB-19A1A3318F90

View file

@ -32,6 +32,7 @@
#include "generated/edk2_ftw.h" #include "generated/edk2_ftw.h"
#include "generated/insyde_fdc.h" #include "generated/insyde_fdc.h"
#include "generated/phoenix_flm.h" #include "generated/phoenix_flm.h"
#include "generated/phoenix_evsa.h"
USTATUS NvramParser::parseNvarStore(const UModelIndex & index) USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
{ {
@ -387,16 +388,15 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::VssStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
// Add variables // Add variables
UINT32 vssVariableOffset = storeOffset + parsed.len_vss_store_header(); UINT32 vssVariableOffset = parsed.len_vss_store_header();
for (const auto & variable : *parsed.body()->variables()) { for (const auto & variable : *parsed.body()->variables()) {
UINT8 subtype; UINT8 subtype;
// This is the terminating entry, needs special processing // This is the terminating entry, needs special processing
if (variable->_is_null_signature_last()) { if (variable->_is_null_signature_last()) {
// Add free space or padding after all variables, if needed // Add free space or padding after all variables, if needed
UINT32 freeSpaceOffset = vssVariableOffset - storeOffset; if (vssVariableOffset < storeSize) {
if (freeSpaceOffset < storeSize) { UByteArray freeSpace = vss.mid(vssVariableOffset, storeSize - vssVariableOffset);
UByteArray freeSpace = volumeBody.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
// Add info // Add info
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
@ -425,7 +425,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
variableSize = (UINT32)(header.size() + body.size()); variableSize = (UINT32)(header.size() + body.size());
const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str()));
name = guidToUString(variableGuid); name = guidToUString(variableGuid);
info += UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n";
} }
else if (variable->is_auth()) { // Authenticated else if (variable->is_auth()) { // Authenticated
subtype = Subtypes::AuthVssEntry; subtype = Subtypes::AuthVssEntry;
@ -435,7 +435,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str()));
name = guidToUString(variableGuid); name = guidToUString(variableGuid);
text = uFromUcs2(variable->name_auth().c_str()); text = uFromUcs2(variable->name_auth().c_str());
info += UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n";
} }
else if (!variable->_is_null_apple_data_crc32()) { // Apple CRC32 else if (!variable->_is_null_apple_data_crc32()) { // Apple CRC32
subtype = Subtypes::AppleVssEntry; subtype = Subtypes::AppleVssEntry;
@ -445,7 +445,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str()));
name = guidToUString(variableGuid); name = guidToUString(variableGuid);
text = uFromUcs2(variable->name().c_str()); text = uFromUcs2(variable->name().c_str());
info += UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n";
} }
else { // Standard else { // Standard
subtype = Subtypes::StandardVssEntry; subtype = Subtypes::StandardVssEntry;
@ -455,7 +455,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str()));
name = guidToUString(variableGuid); name = guidToUString(variableGuid);
text = uFromUcs2(variable->name().c_str()); text = uFromUcs2(variable->name().c_str());
info += UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n";
} }
// Override variable type to Invalid if needed // Override variable type to Invalid if needed
@ -472,6 +472,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
+ (variable->attributes()->auth_write() << 4) + (variable->attributes()->auth_write() << 4)
+ (variable->attributes()->time_based_auth() << 5) + (variable->attributes()->time_based_auth() << 5)
+ (variable->attributes()->append_write() << 6) + (variable->attributes()->append_write() << 6)
+ (UINT32)(variable->attributes()->reserved() << 7)
+ (variable->attributes()->apple_data_checksum() << 31); + (variable->attributes()->apple_data_checksum() << 31);
// Add generic info // Add generic info
@ -518,6 +519,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
} }
UByteArray vss2 = volumeBody.mid(storeOffset); UByteArray vss2 = volumeBody.mid(storeOffset);
// Check if we are here to parse a special case of FDC store with size override // Check if we are here to parse a special case of FDC store with size override
UINT32 originalStoreSize = 0; UINT32 originalStoreSize = 0;
VSS2_VARIABLE_STORE_HEADER* vss2Header = (VSS2_VARIABLE_STORE_HEADER*)vss2.data(); VSS2_VARIABLE_STORE_HEADER* vss2Header = (VSS2_VARIABLE_STORE_HEADER*)vss2.data();
@ -527,10 +529,12 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
originalStoreSize = vss2Header->Size; originalStoreSize = vss2Header->Size;
vss2Header->Size = fdcStoreSizeOverride; vss2Header->Size = fdcStoreSizeOverride;
} }
umemstream is(vss2.constData(), vss2.size()); umemstream is(vss2.constData(), vss2.size());
kaitai::kstream ks(&is); kaitai::kstream ks(&is);
edk2_vss2_t parsed(&ks); edk2_vss2_t parsed(&ks);
UINT32 storeSize = parsed.vss2_size(); UINT32 storeSize = parsed.vss2_size();
// Restore original store size, if needed // Restore original store size, if needed
if (fdcHeaderSizeOverrideRequired) { if (fdcHeaderSizeOverrideRequired) {
vss2Header->Size = originalStoreSize; vss2Header->Size = originalStoreSize;
@ -573,16 +577,15 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::Vss2Store, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::Vss2Store, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
// Add variables // Add variables
UINT32 vss2VariableOffset = storeOffset + parsed.len_vss2_store_header(); UINT32 vss2VariableOffset = parsed.len_vss2_store_header();
for (const auto & variable : *parsed.body()->variables()) { for (const auto & variable : *parsed.body()->variables()) {
UINT8 subtype; UINT8 subtype;
// This is the terminating entry, needs special processing // This is the terminating entry, needs special processing
if (variable->_is_null_signature_last()) { if (variable->_is_null_signature_last()) {
// Add free space or padding after all variables, if needed // Add free space or padding after all variables, if needed
UINT32 freeSpaceOffset = vss2VariableOffset - storeOffset; if (vss2VariableOffset < storeSize) {
if (freeSpaceOffset < storeSize) { UByteArray freeSpace = vss2.mid(vss2VariableOffset, storeSize - vss2VariableOffset);
UByteArray freeSpace = volumeBody.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
// Add info // Add info
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
@ -601,25 +604,28 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
// This is a normal entry // This is a normal entry
UINT32 variableSize; UINT32 variableSize;
UINT32 alignmentSize;
if (variable->is_auth()) { // Authenticated if (variable->is_auth()) { // Authenticated
subtype = Subtypes::AuthVssEntry; subtype = Subtypes::AuthVssEntry;
header = vss2.mid(vss2VariableOffset, variable->len_auth_header() + variable->len_name_auth()); header = vss2.mid(vss2VariableOffset, variable->len_auth_header() + variable->len_name_auth());
body = vss2.mid(vss2VariableOffset + header.size(), variable->len_data_auth()); body = vss2.mid(vss2VariableOffset + header.size(), variable->len_data_auth());
variableSize = (UINT32)(header.size() + body.size()); variableSize = (UINT32)(header.size() + body.size());
alignmentSize = variable->len_alignment_padding_auth();
const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str()));
name = guidToUString(variableGuid); name = guidToUString(variableGuid);
text = uFromUcs2(variable->name_auth().c_str()); text = uFromUcs2(variable->name_auth().c_str());
info += UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n";
} }
else { // Standard else { // Standard
subtype = Subtypes::StandardVssEntry; subtype = Subtypes::StandardVssEntry;
header = vss2.mid(vss2VariableOffset, variable->len_standard_header() + variable->len_name()); header = vss2.mid(vss2VariableOffset, variable->len_standard_header() + variable->len_name());
body = vss2.mid(vss2VariableOffset + header.size(), variable->len_data()); body = vss2.mid(vss2VariableOffset + header.size(), variable->len_data());
variableSize = (UINT32)(header.size() + body.size()); variableSize = (UINT32)(header.size() + body.size());
alignmentSize = variable->len_alignment_padding();
const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str())); const EFI_GUID variableGuid = readUnaligned((const EFI_GUID*)(variable->vendor_guid().c_str()));
name = guidToUString(variableGuid); name = guidToUString(variableGuid);
text = uFromUcs2(variable->name().c_str()); text = uFromUcs2(variable->name().c_str());
info += UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n"; info = UString("Variable GUID: ") + guidToUString(variableGuid, false) + "\n";
} }
// Override variable type to Invalid if needed // Override variable type to Invalid if needed
@ -635,7 +641,8 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
+ (variable->attributes()->hw_error_record() << 3) + (variable->attributes()->hw_error_record() << 3)
+ (variable->attributes()->auth_write() << 4) + (variable->attributes()->auth_write() << 4)
+ (variable->attributes()->time_based_auth() << 5) + (variable->attributes()->time_based_auth() << 5)
+ (variable->attributes()->append_write() << 6); + (variable->attributes()->append_write() << 6)
+ (UINT32)(variable->attributes()->reserved() << 7);
// Add generic info // Add generic info
info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nReserved: %02Xh\nAttributes: %08Xh (", info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nReserved: %02Xh\nAttributes: %08Xh (",
@ -656,7 +663,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
// Add tree item // Add tree item
model->addItem(vss2VariableOffset, Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), Fixed, headerIndex); model->addItem(vss2VariableOffset, Types::VssEntry, subtype, name, text, info, header, body, UByteArray(), Fixed, headerIndex);
vss2VariableOffset += variableSize; vss2VariableOffset += (variableSize + alignmentSize);
} }
storeOffset += storeSize - 1; storeOffset += storeSize - 1;
@ -836,7 +843,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::SysFStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::SysFStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
// Add variables // Add variables
UINT32 sysfVariableOffset = storeOffset + parsed.len_sysf_store_header(); UINT32 sysfVariableOffset = parsed.len_sysf_store_header();
for (const auto & variable : *parsed.body()->variables()) { for (const auto & variable : *parsed.body()->variables()) {
UINT8 subtype; UINT8 subtype;
@ -850,11 +857,11 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
} }
if (variable->len_name() == 3 && variable->name() == "EOF") { if (variable->len_name() == 3 && variable->name() == "EOF") {
header = volumeBody.mid(sysfVariableOffset, 4); header = sysf.mid(sysfVariableOffset, 4);
} }
else { else {
header = volumeBody.mid(sysfVariableOffset, sizeof(UINT8) + (UINT32)variable->len_name() + sizeof(UINT16)); header = sysf.mid(sysfVariableOffset, sizeof(UINT8) + (UINT32)variable->len_name() + sizeof(UINT16));
body = volumeBody.mid(sysfVariableOffset + header.size(), (UINT32)variable->len_data()); body = sysf.mid(sysfVariableOffset + header.size(), (UINT32)variable->len_data());
} }
// Add generic info // Add generic info
UINT32 variableSize = (UINT32)header.size() + (UINT32)body.size(); UINT32 variableSize = (UINT32)header.size() + (UINT32)body.size();
@ -870,9 +877,8 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
} }
// Add free space or padding after all variables, if needed // Add free space or padding after all variables, if needed
UINT32 freeSpaceOffset = sysfVariableOffset - storeOffset; if (sysfVariableOffset < storeSize) {
if (freeSpaceOffset < storeSize) { UByteArray freeSpace = sysf.mid(sysfVariableOffset, storeSize - sysfVariableOffset);
UByteArray freeSpace = volumeBody.mid(freeSpaceOffset, storeSize - freeSpaceOffset);
// Add info // Add info
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size()); info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
@ -894,7 +900,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
// Parsing failed, try something else // Parsing failed, try something else
} }
// Phoenix FlashMap // Phoenix SCT FlashMap
try { try {
if (volumeBodySize - storeOffset < NVRAM_PHOENIX_FLASH_MAP_TOTAL_SIZE) { if (volumeBodySize - storeOffset < NVRAM_PHOENIX_FLASH_MAP_TOTAL_SIZE) {
// No need to parse further, the rest of the volume is too small // No need to parse further, the rest of the volume is too small
@ -920,7 +926,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
body = flm.mid(header.size(), storeSize - header.size()); body = flm.mid(header.size(), storeSize - header.size());
// Add info // Add info
name = UString("FlashMap"); name = UString("Phoenix SCT FlashMap");
info = usprintf("Signature: _FLASH_MAP\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nEntries: %u\nReserved: %08Xh", info = usprintf("Signature: _FLASH_MAP\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nEntries: %u\nReserved: %08Xh",
storeSize, storeSize, storeSize, storeSize,
(UINT32)header.size(), (UINT32)header.size(), (UINT32)header.size(), (UINT32)header.size(),
@ -929,10 +935,10 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
parsed.reserved()); parsed.reserved());
// Add header tree item // Add header tree item
UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::FlashMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index); UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::PhoenixFlashMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
// Add entries // Add entries
UINT32 entryOffset = storeOffset + parsed.len_flm_store_header(); UINT32 entryOffset = parsed.len_flm_store_header();
for (const auto & entry : *parsed.entries()) { for (const auto & entry : *parsed.entries()) {
UINT8 subtype; UINT8 subtype;
@ -948,8 +954,8 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str()); const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str());
name = guidToUString(guid); name = guidToUString(guid);
text = flashMapGuidToUString(guid); text = phoenixFlashMapGuidToUString(guid);
header = volumeBody.mid(entryOffset, parsed.len_flm_entry()); header = flm.mid(entryOffset, parsed.len_flm_entry());
// Add info // Add info
UINT32 entrySize = (UINT32)header.size(); UINT32 entrySize = (UINT32)header.size();
@ -963,7 +969,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
entry->physical_address()); entry->physical_address());
// Add tree item // Add tree item
model->addItem(entryOffset, Types::FlashMapEntry, subtype, name, text, info, header, UByteArray(), UByteArray(), Fixed, headerIndex); model->addItem(entryOffset, Types::PhoenixFlashMapEntry, subtype, name, text, info, header, UByteArray(), UByteArray(), Fixed, headerIndex);
entryOffset += entrySize; entryOffset += entrySize;
} }
@ -996,7 +1002,220 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
} }
// Phoenix EVSA // Phoenix EVSA
try {
if (volumeBodySize - storeOffset < sizeof(EVSA_STORE_ENTRY)) {
// No need to parse further, the rest of the volume is too small
throw 0;
}
UByteArray evsa = volumeBody.mid(storeOffset);
umemstream is(evsa.constData(), evsa.size());
kaitai::kstream ks(&is);
phoenix_evsa_t parsed(&ks);
UINT32 storeSize = parsed.len_evsa_store();
// Phoenix EVSA store at current offset parsed correctly
// Check if we need to add a padding before it
if (!outerPadding.isEmpty()) {
info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size());
model->addItem(previousStoreEndOffset, Types::Padding, getPaddingType(outerPadding), UString("Padding"), UString(), info, UByteArray(), outerPadding, UByteArray(), Fixed, index);
outerPadding.clear();
}
// Construct header and body
header = evsa.left(parsed.len_evsa_store_header());
body = evsa.mid(header.size(), storeSize - header.size());
const EVSA_STORE_ENTRY* evsaStoreHeader = (const EVSA_STORE_ENTRY*)header.constData();
UINT8 calculated = calculateChecksum8(((const UINT8*)evsaStoreHeader) + 2, evsaStoreHeader->Header.Size - 2);
// Add info
name = UString("EVSA Store");
info = usprintf("Signature: EVSA\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nAttributes: %08Xh\nReserved: %08Xh\nChecksum: %02Xh",
storeSize, storeSize,
(UINT32)header.size(), (UINT32)header.size(),
(UINT32)body.size(), (UINT32)body.size(),
parsed.attributes(),
parsed.reserved(),
parsed.checksum())
+ (parsed.checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid"));
// Add header tree item
UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::EvsaStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
// Add entries
std::map<UINT16, EFI_GUID> guidMap;
std::map<UINT16, UString> nameMap;
UINT32 entryOffset = parsed.len_evsa_store_header();
for (const auto & entry : *parsed.body()->entries()) {
UINT8 subtype;
UINT32 entrySize;
// This is the terminating entry, needs special processing
if (entry->_is_null_checksum()) {
// Add free space or padding after all variables, if needed
if (entryOffset < storeSize) {
UByteArray freeSpace = evsa.mid(entryOffset, storeSize - entryOffset);
// Add info
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
// Check that remaining unparsed bytes are actually empty
if (freeSpace.count(emptyByte) == freeSpace.size()) { // Free space
// Add tree item
model->addItem(entryOffset, Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
}
else {
// Add tree item
model->addItem(entryOffset, Types::Padding, getPaddingType(freeSpace), UString("Padding"), UString(), info, UByteArray(), freeSpace, UByteArray(), Fixed, headerIndex);
}
}
break;
}
const EVSA_ENTRY_HEADER* entryHeader = (const EVSA_ENTRY_HEADER*)(evsa.constData() + entryOffset);
calculated = calculateChecksum8(((const UINT8*)entryHeader) + 2, entryHeader->Size - 2);
// GUID entry
if (entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_GUID1 || entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_GUID2) {
const phoenix_evsa_t::evsa_guid_t* guidEntry = (const phoenix_evsa_t::evsa_guid_t*)(entry->body());
header = evsa.mid(entryOffset, sizeof(EVSA_GUID_ENTRY));
body = evsa.mid(entryOffset + sizeof(EVSA_GUID_ENTRY), entry->len_evsa_entry() - header.size());
entrySize = (UINT32)(header.size() + body.size());
EFI_GUID guid = *(const EFI_GUID*)(guidEntry->guid().c_str());
name = guidToUString(guid);
info = UString("GUID: ") + guidToUString(guid, false)
+ usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
entrySize, entrySize,
(UINT32)header.size(), (UINT32)header.size(),
(UINT32)body.size(), (UINT32)body.size(),
entry->entry_type(),
entry->checksum())
+ (entry->checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid"))
+ usprintf("\nGuidId: %04Xh", guidEntry->guid_id());
subtype = Subtypes::GuidEvsaEntry;
guidMap.insert(std::pair<UINT16, EFI_GUID>(guidEntry->guid_id(), guid));
}
// Name entry
else if (entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_NAME1 || entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_NAME2) {
const phoenix_evsa_t::evsa_name_t* nameEntry = (const phoenix_evsa_t::evsa_name_t*)(entry->body());
header = evsa.mid(entryOffset, sizeof(EVSA_NAME_ENTRY));
body = evsa.mid(entryOffset + sizeof(EVSA_NAME_ENTRY), entry->len_evsa_entry() - header.size());
entrySize = (UINT32)(header.size() + body.size());
name = uFromUcs2(body.constData());
info = UString("Name: ") + name
+ usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
entrySize, entrySize,
(UINT32)header.size(), (UINT32)header.size(),
(UINT32)body.size(), (UINT32)body.size(),
entry->entry_type(),
entry->checksum())
+ (entry->checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid"))
+ usprintf("\nVarId: %04Xh", nameEntry->var_id());
subtype = Subtypes::NameEvsaEntry;
nameMap.insert(std::pair<UINT16, UString>(nameEntry->var_id(), name));
}
// Data entry
else if (entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_DATA1
|| entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_DATA2
|| entry->entry_type() == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) {
phoenix_evsa_t::evsa_data_t* dataEntry = (phoenix_evsa_t::evsa_data_t*)(entry->body());
if (dataEntry->_is_null_len_data_ext()) {
header = evsa.mid(entryOffset, sizeof(EVSA_DATA_ENTRY));
body = evsa.mid(entryOffset + sizeof(EVSA_DATA_ENTRY), entry->len_evsa_entry() - header.size());
}
else {
header = evsa.mid(entryOffset, sizeof(EVSA_DATA_ENTRY_EXTENDED));
body = evsa.mid(entryOffset + sizeof(EVSA_DATA_ENTRY_EXTENDED), dataEntry->len_data_ext());
}
entrySize = (UINT32)(header.size() + body.size());
name = UString("Data");
subtype = Subtypes::DataEvsaEntry;
const UINT32 attributes = dataEntry->attributes()->non_volatile()
+ (dataEntry->attributes()->boot_service() << 1)
+ (dataEntry->attributes()->runtime() << 2)
+ (dataEntry->attributes()->hw_error_record() << 3)
+ (dataEntry->attributes()->auth_write() << 4)
+ (dataEntry->attributes()->time_based_auth() << 5)
+ (dataEntry->attributes()->append_write() << 6)
+ (UINT32)(dataEntry->attributes()->reserved() << 7)
+ (dataEntry->attributes()->extended_header() << 28)
+ (UINT32)(dataEntry->attributes()->reserved1() << 29);
info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nType: %02Xh\nChecksum: %02Xh",
entrySize, entrySize,
(UINT32)header.size(), (UINT32)header.size(),
(UINT32)body.size(), (UINT32)body.size(),
entry->entry_type(),
entry->checksum())
+ (entry->checksum() != calculated ? usprintf(", invalid, should be %02Xh", calculated) : UString(", valid"))
+ usprintf("\nVarId: %04Xh\nGuidId: %04Xh\nAttributes: %08Xh (",
dataEntry->var_id(),
dataEntry->guid_id(),
attributes)
+ evsaAttributesToUString(attributes) + UString(")");
}
// Add tree item
model->addItem(entryOffset, Types::EvsaEntry, subtype, name, text, info, header, body, UByteArray(), Fixed, headerIndex);
entryOffset += entrySize;
}
// Reparse all data variables to detect invalid ones and assign name and test to valid ones
for (int i = 0; i < model->rowCount(headerIndex); i++) {
UModelIndex current = headerIndex.model()->index(i, 0, headerIndex);
if (model->subtype(current) == Subtypes::DataEvsaEntry) {
UByteArray header = model->header(current);
const EVSA_DATA_ENTRY* dataHeader = (const EVSA_DATA_ENTRY*)header.constData();
UString guid;
if (guidMap.count(dataHeader->GuidId))
guid = guidToUString(guidMap[dataHeader->GuidId], false);
UString name;
if (nameMap.count(dataHeader->VarId))
name = nameMap[dataHeader->VarId];
// Check for variable validity
if (guid.isEmpty() && name.isEmpty()) { // Both name and guid aren't found
model->setSubtype(current, Subtypes::InvalidEvsaEntry);
model->setName(current, UString("Invalid"));
model->setText(current, UString());
msg(usprintf("%s: data variable with invalid GuidId and invalid VarId", __FUNCTION__), current);
}
else if (guid.isEmpty()) { // Guid not found
model->setSubtype(current, Subtypes::InvalidEvsaEntry);
model->setName(current, UString("Invalid"));
model->setText(current, UString());
msg(usprintf("%s: data variable with invalid GuidId", __FUNCTION__), current);
}
else if (name.isEmpty()) { // Name not found
model->setSubtype(current, Subtypes::InvalidEvsaEntry);
model->setName(current, UString("Invalid"));
model->setText(current, UString());
msg(usprintf("%s: data variable with invalid VarId", __FUNCTION__), current);
}
else { // Variable is OK, rename it
if (dataHeader->Header.Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) {
model->setSubtype(current, Subtypes::InvalidEvsaEntry);
model->setName(current, UString("Invalid"));
model->setText(current, UString());
}
else {
model->setName(current, guid);
model->setText(current, name);
model->addInfo(current, UString("GUID: ") + guid + UString("\nName: ") + name + "\n", false);
}
}
}
}
storeOffset += storeSize - 1;
previousStoreEndOffset = storeOffset + 1;
continue;
} catch (...) {
// Parsing failed, try something else
}
// Phoenix CMDB // Phoenix CMDB
// Phoenix SLIC Pubkey/Marker // Phoenix SLIC Pubkey/Marker

View file

@ -58,13 +58,15 @@ UString itemTypeToUString(const UINT8 type)
case Types::SysFStore: return UString("SysF store"); case Types::SysFStore: return UString("SysF store");
case Types::EvsaStore: return UString("EVSA store"); case Types::EvsaStore: return UString("EVSA store");
case Types::CmdbStore: return UString("CMDB store"); case Types::CmdbStore: return UString("CMDB store");
case Types::FlashMapStore: return UString("FlashMap store"); case Types::PhoenixFlashMapStore: return UString("FlashMap store");
case Types::InsydeFlashDeviceMapStore: return UString("FlashDeviceMap store");
case Types::NvarGuidStore: return UString("NVAR GUID store"); case Types::NvarGuidStore: return UString("NVAR GUID store");
case Types::NvarEntry: return UString("NVAR entry"); case Types::NvarEntry: return UString("NVAR entry");
case Types::VssEntry: return UString("VSS entry"); case Types::VssEntry: return UString("VSS entry");
case Types::SysFEntry: return UString("SysF entry"); case Types::SysFEntry: return UString("SysF entry");
case Types::EvsaEntry: return UString("EVSA entry"); case Types::EvsaEntry: return UString("EVSA entry");
case Types::FlashMapEntry: return UString("FlashMap entry"); case Types::PhoenixFlashMapEntry: return UString("FlashMap entry");
case Types::InsydeFlashDeviceMapEntry: return UString("FlashDeviceMap entry");
case Types::Microcode: return UString("Microcode"); case Types::Microcode: return UString("Microcode");
case Types::SlicData: return UString("SLIC data"); case Types::SlicData: return UString("SLIC data");
case Types::FptStore: return UString("FPT store"); case Types::FptStore: return UString("FPT store");
@ -139,7 +141,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
else if (subtype == Subtypes::NameEvsaEntry) return UString("Name"); else if (subtype == Subtypes::NameEvsaEntry) return UString("Name");
else if (subtype == Subtypes::DataEvsaEntry) return UString("Data"); else if (subtype == Subtypes::DataEvsaEntry) return UString("Data");
break; break;
case Types::FlashMapEntry: case Types::PhoenixFlashMapEntry:
if (subtype == Subtypes::VolumeFlashMapEntry) return UString("Volume"); if (subtype == Subtypes::VolumeFlashMapEntry) return UString("Volume");
else if (subtype == Subtypes::DataFlashMapEntry) return UString("Data"); else if (subtype == Subtypes::DataFlashMapEntry) return UString("Data");
else if (subtype == Subtypes::UnknownFlashMapEntry) return UString("Unknown"); else if (subtype == Subtypes::UnknownFlashMapEntry) return UString("Unknown");
@ -250,3 +252,29 @@ UString hashTypeToUString(const UINT16 algorithm_id)
return usprintf("Unknown %04Xh", algorithm_id); return usprintf("Unknown %04Xh", algorithm_id);
} }
UString insydeFlashDeviceMapEntryTypeGuidToUString(const EFI_GUID & guid)
{
const UByteArray baGuid((const char*)&guid, sizeof(EFI_GUID));
if (baGuid == INSYDE_FLASH_MAP_REGION_BOOT_FV_GUID) return UString("Boot Firmare Volume");
if (baGuid == INSYDE_FLASH_MAP_REGION_BVDT_GUID) return UString("BIOS Version Data Table");
if (baGuid == INSYDE_FLASH_MAP_REGION_EC_GUID) return UString("EC Firmware");
if (baGuid == INSYDE_FLASH_MAP_REGION_FTW_BACKUP_GUID) return UString("FTW Backup");
if (baGuid == INSYDE_FLASH_MAP_REGION_FTW_STATE_GUID) return UString("FTW State");
if (baGuid == INSYDE_FLASH_MAP_REGION_FV_GUID) return UString("Firmare Volume");
if (baGuid == INSYDE_FLASH_MAP_REGION_FLASH_DEVICE_MAP_GUID) return UString("Flash Device Map");
if (baGuid == INSYDE_FLASH_MAP_REGION_LOGO_GUID) return UString("Logo");
if (baGuid == INSYDE_FLASH_MAP_REGION_MICROCODE_GUID) return UString("Microcode");
if (baGuid == INSYDE_FLASH_MAP_REGION_MSDM_TABLE_GUID) return UString("MSDM Table");
if (baGuid == INSYDE_FLASH_MAP_REGION_MULTI_CONFIG_GUID) return UString("MultiConfig");
if (baGuid == INSYDE_FLASH_MAP_REGION_VAR_DEFAULT_GUID) return UString("Variable Defaults");
if (baGuid == INSYDE_FLASH_MAP_REGION_SMBIOS_UPDATE_GUID) return UString("SMBIOS Update");
if (baGuid == INSYDE_FLASH_MAP_REGION_VAR_GUID) return UString("Variables");
if (baGuid == INSYDE_FLASH_MAP_REGION_UNKNOWN_GUID) return UString("Unknown");
if (baGuid == INSYDE_FLASH_MAP_REGION_UNUSED_GUID) return UString("Unused");
if (baGuid == INSYDE_FLASH_MAP_REGION_USB_OPTION_ROM_GUID) return UString("USB Option ROM");
if (baGuid == INSYDE_FLASH_MAP_REGION_DXE_FV_GUID) return UString("DXE Firmare Volume");
if (baGuid == INSYDE_FLASH_MAP_REGION_PEI_FV_GUID) return UString("PEI Firmare Volume");
if (baGuid == INSYDE_FLASH_MAP_REGION_UNSIGNED_FV_GUID) return UString("Unsigned Firmare Volume");
return guidToUString(guid);
}

View file

@ -49,14 +49,16 @@ namespace Types {
FdcStore, FdcStore,
SysFStore, SysFStore,
EvsaStore, EvsaStore,
FlashMapStore, PhoenixFlashMapStore,
InsydeFlashDeviceMapStore,
CmdbStore, CmdbStore,
NvarGuidStore, NvarGuidStore,
NvarEntry, NvarEntry,
VssEntry, VssEntry,
SysFEntry, SysFEntry,
EvsaEntry, EvsaEntry,
FlashMapEntry, PhoenixFlashMapEntry,
InsydeFlashDeviceMapEntry,
Microcode, Microcode,
SlicData, SlicData,
IfwiHeader, IfwiHeader,
@ -204,5 +206,6 @@ extern UString compressionTypeToUString(const UINT8 algorithm);
extern UString regionTypeToUString(const UINT8 type); extern UString regionTypeToUString(const UINT8 type);
extern UString fitEntryTypeToUString(const UINT8 type); extern UString fitEntryTypeToUString(const UINT8 type);
extern UString hashTypeToUString(const UINT16 digest_agorithm_id); extern UString hashTypeToUString(const UINT16 digest_agorithm_id);
extern UString insydeFlashDeviceMapEntryTypeGuidToUString(const EFI_GUID & guid);
#endif // TYPES_H #endif // TYPES_H

View file

@ -83,7 +83,8 @@ UString uniqueItemName(const UModelIndex & index)
case Types::VssEntry: case Types::VssEntry:
case Types::SysFEntry: case Types::SysFEntry:
case Types::EvsaEntry: case Types::EvsaEntry:
case Types::FlashMapEntry: case Types::PhoenixFlashMapEntry:
case Types::InsydeFlashDeviceMapEntry:
case Types::File: case Types::File:
name = itemText.isEmpty() ? itemName : itemName + '_' + itemText; name = itemText.isEmpty() ? itemName : itemName + '_' + itemText;
break; break;

View file

@ -37,7 +37,9 @@ SET(PROJECT_SOURCES
../common/generated/edk2_vss2.cpp ../common/generated/edk2_vss2.cpp
../common/generated/edk2_ftw.cpp ../common/generated/edk2_ftw.cpp
../common/generated/insyde_fdc.cpp ../common/generated/insyde_fdc.cpp
../common/generated/insyde_fdm.cpp
../common/generated/phoenix_flm.cpp ../common/generated/phoenix_flm.cpp
../common/generated/phoenix_evsa.cpp
../common/generated/intel_acbp_v1.cpp ../common/generated/intel_acbp_v1.cpp
../common/generated/intel_acbp_v2.cpp ../common/generated/intel_acbp_v2.cpp
../common/generated/intel_keym_v1.cpp ../common/generated/intel_keym_v1.cpp