Display microcode in the tree

This commit is contained in:
vit9696 2018-09-01 08:17:17 +03:00
parent 717821de2b
commit 2d02eeab6d
21 changed files with 369 additions and 8270 deletions

View file

@ -17,8 +17,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
const UByteArray FFSv2VolumesInt[] = {
EFI_FIRMWARE_FILE_SYSTEM_GUID,
EFI_FIRMWARE_FILE_SYSTEM2_GUID,
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID,
EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID,
EFI_APPLE_AUTHENTICATION_FV_GUID,
EFI_APPLE_IMMUTABLE_FV_GUID,
EFI_INTEL_FILE_SYSTEM_GUID,
EFI_INTEL_FILE_SYSTEM2_GUID,
EFI_SONY_FILE_SYSTEM_GUID

View file

@ -114,38 +114,43 @@ typedef struct EFI_FIRMWARE_VOLUME_HEADER_ {
} EFI_FIRMWARE_VOLUME_HEADER;
// Standard file system GUIDs
const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID
const UByteArray EFI_FIRMWARE_FILE_SYSTEM_GUID // 7A9354D9-0468-444A-81CE-0BF617D890DF
("\xD9\x54\x93\x7A\x68\x04\x4A\x44\x81\xCE\x0B\xF6\x17\xD8\x90\xDF", 16);
const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID
const UByteArray EFI_FIRMWARE_FILE_SYSTEM2_GUID // 8C8CE578-8A3D-4F1C-9935-896185C32DD3
("\x78\xE5\x8C\x8C\x3D\x8A\x1C\x4F\x99\x35\x89\x61\x85\xC3\x2D\xD3", 16);
// Vendor-specific file system GUIDs
const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM_GUID
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
const UByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
// AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 // Intel 1
const UByteArray EFI_INTEL_FILE_SYSTEM_GUID
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
// D6A1CD70-4B33-4994-A6EA-375F2CCC5437 // Intel 2
const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1
const UByteArray EFI_SONY_FILE_SYSTEM_GUID
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
// Vector of volume GUIDs with FFSv2-compatible files
extern const std::vector<UByteArray> FFSv2Volumes;
const UByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A
("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16);
// Vendor-specific file system GUIDs
const UByteArray EFI_APPLE_IMMUTABLE_FV_GUID // 04ADEEAD-61FF-4D31-B6BA-64F8BF901F5A
("\xAD\xEE\xAD\x04\xFF\x61\x31\x4D\xB6\xBA\x64\xF8\xBF\x90\x1F\x5A", 16);
const UByteArray EFI_APPLE_AUTHENTICATION_FV_GUID // BD001B8C-6A71-487B-A14F-0C2A2DCF7A5D
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
const UByteArray EFI_APPLE_MICROCODE_VOLUME_GUID // 153D2197-29BD-44DC-AC59-887F70E41A6B
("\x97\x21\x3D\x15\xBD\x29\xDC\x44\xAC\x59\x88\x7F\x70\xE4\x1A\x6B", 16);
#define EFI_APPLE_MICROCODE_VOLUME_HEADER_SIZE 0x100
const UByteArray EFI_INTEL_FILE_SYSTEM_GUID // AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
const UByteArray EFI_INTEL_FILE_SYSTEM2_GUID // D6A1CD70-4B33-4994-A6EA-375F2CCC5437
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
const UByteArray EFI_SONY_FILE_SYSTEM_GUID // 4F494156-AED6-4D64-A537-B8A5557BCEEC
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
// Vector of volume GUIDs with FFSv2-compatible files
extern const std::vector<UByteArray> FFSv2Volumes;
// Vector of volume GUIDs with FFSv3-compatible files
extern const std::vector<UByteArray> FFSv3Volumes;
// Firmware volume signature
const UByteArray EFI_FV_SIGNATURE("_FVH", 4);
#define EFI_FV_SIGNATURE 0x4856465F // _FVH
#define EFI_FV_SIGNATURE_OFFSET 0x28
// Firmware volume attributes

View file

@ -104,13 +104,15 @@ USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & ind
peiCoreEntryPoint = 0;
newPeiCoreEntryPoint = 0;
// Sanity check
// Sanity check
if (buffer.isEmpty()) {
return EFI_INVALID_PARAMETER;
}
USTATUS result;
// Try parsing as UEFI Capsule
USTATUS result = parseCapsule(buffer, index);
result = parseCapsule(buffer, 0, UModelIndex(), index);;
if (result != U_ITEM_NOT_FOUND) {
return result;
}
@ -122,6 +124,7 @@ USTATUS FfsParser::performFirstPass(const UByteArray & buffer, UModelIndex & ind
}
// Parse as generic image
imageBase = 0;
return parseGenericImage(buffer, 0, UModelIndex(), index);
}
@ -138,7 +141,7 @@ USTATUS FfsParser::parseGenericImage(const UByteArray & buffer, const UINT32 loc
return parseRawArea(index);
}
USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
USTATUS FfsParser::parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index)
{
// Check buffer size to be more than or equal to size of EFI_CAPSULE_HEADER
if ((UINT32)capsule.size() < sizeof(EFI_CAPSULE_HEADER)) {
@ -181,7 +184,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
capsuleHeader->Flags);
// Add tree item
index = model->addItem(0, Types::Capsule, Subtypes::UefiCapsule, name, UString(), info, header, body, UByteArray(), Fixed);
index = model->addItem(model->offset(parent) + localOffset, Types::Capsule, Subtypes::UefiCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent);
}
// Check buffer for being Toshiba capsule header
else if (capsule.startsWith(TOSHIBA_CAPSULE_GUID)) {
@ -213,7 +216,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
capsuleHeader->Flags);
// Add tree item
index = model->addItem(0, Types::Capsule, Subtypes::ToshibaCapsule, name, UString(), info, header, body, UByteArray(), Fixed);
index = model->addItem(model->offset(parent) + localOffset, Types::Capsule, Subtypes::ToshibaCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent);
}
// Check buffer for being extended Aptio capsule header
else if (capsule.startsWith(APTIO_SIGNED_CAPSULE_GUID)
@ -255,7 +258,7 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
capsuleHeader->CapsuleHeader.Flags);
// Add tree item
index = model->addItem(0, Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, UString(), info, header, body, UByteArray(), Fixed);
index = model->addItem(model->offset(parent) + localOffset, Types::Capsule, signedCapsule ? Subtypes::AptioSignedCapsule : Subtypes::AptioUnsignedCapsule, name, UString(), info, header, body, UByteArray(), Fixed, parent);
// Show message about possible Aptio signature break
if (signedCapsule) {
@ -265,9 +268,6 @@ USTATUS FfsParser::parseCapsule(const UByteArray & capsule, UModelIndex & index)
// Capsule present
if (capsuleHeaderSize > 0) {
// Set imageBase for proper alignment calculation
imageBase = capsuleHeaderSize;
UByteArray image = capsule.mid(capsuleHeaderSize);
UModelIndex imageIndex;
@ -574,6 +574,9 @@ USTATUS FfsParser::parseIntelImage(const UByteArray & intelImage, const UINT32 l
// Add descriptor tree item
UModelIndex regionIndex = model->addItem(model->offset(parent) + localOffset, Types::Region, Subtypes::DescriptorRegion, name, UString(), info, UByteArray(), body, UByteArray(), Fixed, index);
// Set image base
imageBase = model->offset(parent) + localOffset;
// Parse regions
USTATUS result = U_SUCCESS;
USTATUS parseResult = U_SUCCESS;
@ -697,10 +700,10 @@ USTATUS FfsParser::parseMeRegion(const UByteArray & me, const UINT32 localOffset
if (versionFound) {
const ME_VERSION* version = (const ME_VERSION*)(me.constData() + versionOffset);
info += usprintf("\nVersion: %u.%u.%u.%u",
version->major,
version->minor,
version->bugfix,
version->build);
version->Major,
version->Minor,
version->Bugfix,
version->Build);
}
}
@ -780,30 +783,32 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
if (!index.isValid())
return U_INVALID_PARAMETER;
// Get parsing data
// Get item data
UByteArray data = model->body(index);
UINT32 headerSize = model->header(index).size();
UINT32 offset = model->offset(index) + headerSize;
// Get item data
UByteArray data = model->body(index);
// Search for first volume
USTATUS result;
UINT32 prevVolumeOffset;
UString name;
UString info;
result = findNextVolume(index, data, offset, 0, prevVolumeOffset);
// Search for the first item
UINT8 prevItemType;
UINT32 prevItemOffset;
UINT32 prevItemSize;
UINT32 prevItemAltSize;
result = findNextRawAreaItem(index, 0, prevItemType, prevItemOffset, prevItemSize, prevItemAltSize);
if (result)
return result;
if (bgFirstVolumeOffset == 0x100000000ULL)
bgFirstVolumeOffset = model->offset(index) + prevVolumeOffset;
bgFirstVolumeOffset = model->offset(index) + prevItemOffset;
// First volume is not at the beginning of RAW area
UString name;
UString info;
if (prevVolumeOffset > 0) {
// First item is not at the beginning of this raw area
if (prevItemOffset > 0) {
// Get info
UByteArray padding = data.left(prevVolumeOffset);
UByteArray padding = data.left(prevItemOffset);
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
@ -811,16 +816,17 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
model->addItem(offset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
}
// Search for and parse all volumes
UINT32 volumeOffset = prevVolumeOffset;
UINT32 prevVolumeSize = 0;
// Search for and parse all items
UINT8 itemType = prevItemType;
UINT32 itemOffset = prevItemOffset;
UINT32 itemSize = prevItemSize;
UINT32 itemAltSize = prevItemAltSize;
while (!result)
{
// Padding between volumes
if (volumeOffset > prevVolumeOffset + prevVolumeSize) {
UINT32 paddingOffset = prevVolumeOffset + prevVolumeSize;
UINT32 paddingSize = volumeOffset - paddingOffset;
while (!result) {
// Padding between items
if (itemOffset > prevItemOffset + prevItemSize) {
UINT32 paddingOffset = prevItemOffset + prevItemSize;
UINT32 paddingSize = itemOffset - paddingOffset;
UByteArray padding = data.mid(paddingOffset, paddingSize);
// Get info
@ -830,66 +836,74 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
// Add tree item
model->addItem(offset + paddingOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
}
// Get volume size
UINT32 volumeSize = 0;
UINT32 bmVolumeSize = 0;
result = getVolumeSize(data, volumeOffset, volumeSize, bmVolumeSize);
if (result) {
msg(usprintf("%s: getVolumeSize failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
return result;
}
// Check that volume is fully present in input
if (volumeSize > (UINT32)data.size() || volumeOffset + volumeSize > (UINT32)data.size()) {
// Mark the rest as padding and finish the parsing
UByteArray padding = data.mid(volumeOffset);
// Check that item is fully present in input
if (itemSize > (UINT32)data.size() || itemOffset + itemSize > (UINT32)data.size()) {
// Mark the rest as padding and finish parsing
UByteArray padding = data.mid(itemOffset);
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Add tree item
UModelIndex paddingIndex = model->addItem(offset + volumeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
UModelIndex paddingIndex = model->addItem(offset + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
msg(usprintf("%s: one of volumes inside overlaps the end of data", __FUNCTION__), paddingIndex);
// Update variables
prevVolumeOffset = volumeOffset;
prevVolumeSize = padding.size();
prevItemOffset = itemOffset;
prevItemSize = padding.size();
break;
}
// Parse current volume's header
UModelIndex volumeIndex;
UByteArray volume = data.mid(volumeOffset, volumeSize);
result = parseVolumeHeader(volume, headerSize + volumeOffset, index, volumeIndex);
if (result) {
msg(usprintf("%s: volume header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
} else {
// Show messages
if (volumeSize != bmVolumeSize)
msg(usprintf("%s: volume size stored in header %Xh differs from calculated using block map %Xh", __FUNCTION__,
volumeSize, bmVolumeSize),
volumeIndex);
if (itemType == Types::Volume) {
UModelIndex volumeIndex;
UByteArray volume = data.mid(itemOffset, itemSize);
result = parseVolumeHeader(volume, headerSize + itemOffset, index, volumeIndex);
if (result) {
msg(usprintf("%s: volume header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
} else {
// Show messages
if (itemSize != itemAltSize)
msg(usprintf("%s: volume size stored in header %Xh differs from calculated using block map %Xh", __FUNCTION__,
itemSize, itemAltSize),
volumeIndex);
}
}
else if (itemType == Types::Microcode) {
UModelIndex microcodeIndex;
UByteArray microcode = data.mid(itemOffset, itemSize);
result = parseIntelMicrocodeHeader(microcode, headerSize + itemOffset, index, microcodeIndex);
if (result) {
msg(usprintf("%s: microcode header parsing failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
}
}
else {
return U_UNKNOWN_ITEM_TYPE;
}
// Go to next volume
prevVolumeOffset = volumeOffset;
prevVolumeSize = volumeSize;
result = findNextVolume(index, data, offset, volumeOffset + prevVolumeSize, volumeOffset);
// Go to next item
prevItemOffset = itemOffset;
prevItemSize = itemSize;
prevItemType = itemType;
result = findNextRawAreaItem(index, itemOffset + prevItemSize, itemType, itemOffset, itemSize, itemAltSize);
}
// Fixes clang analyzer warning
(void)prevItemType;
// Padding at the end of RAW area
volumeOffset = prevVolumeOffset + prevVolumeSize;
if ((UINT32)data.size() > volumeOffset) {
UByteArray padding = data.mid(volumeOffset);
itemOffset = prevItemOffset + prevItemSize;
if ((UINT32)data.size() > itemOffset) {
UByteArray padding = data.mid(itemOffset);
// Get info
name = UString("Padding");
info = usprintf("Full size: %Xh (%u)", padding.size(), padding.size());
// Add tree item
model->addItem(offset + volumeOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
model->addItem(offset + itemOffset, Types::Padding, getPaddingType(padding), name, UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
}
// Parse bodies
@ -899,6 +913,9 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
case Types::Volume:
parseVolumeBody(current);
break;
case Types::Microcode:
// Parsing already done
break;
case Types::Padding:
// No parsing required
break;
@ -947,8 +964,9 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
headerSize = volumeHeader->ExtHeaderOffset + extendedHeader->ExtHeaderSize;
extendedHeaderGuid = extendedHeader->FvName;
}
else
else {
headerSize = volumeHeader->HeaderLength;
}
// Extended header end can be unaligned
headerSize = ALIGN8(headerSize);
@ -956,6 +974,7 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
// Check for volume structure to be known
bool isUnknown = true;
bool isNvramVolume = false;
bool isMicrocodeVolume = false;
UINT8 ffsVersion = 0;
// Check for FFS v2 volume
@ -977,6 +996,13 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
isNvramVolume = true;
}
// Check for Microcode volume
if (guid == EFI_APPLE_MICROCODE_VOLUME_GUID) {
isUnknown = false;
isMicrocodeVolume = true;
headerSize = EFI_APPLE_MICROCODE_VOLUME_HEADER_SIZE;
}
// Check volume revision and alignment
bool msgAlignmentBitsSet = false;
bool msgUnaligned = false;
@ -1071,6 +1097,8 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
subtype = Subtypes::Ffs3Volume;
else if (isNvramVolume)
subtype = Subtypes::NvramVolume;
else if (isMicrocodeVolume)
subtype = Subtypes::MicrocodeVolume;
}
index = model->addItem(model->offset(parent) + localOffset, Types::Volume, subtype, name, text, info, header, body, UByteArray(), Fixed, parent, mode);
@ -1103,67 +1131,82 @@ USTATUS FfsParser::parseVolumeHeader(const UByteArray & volume, const UINT32 loc
return U_SUCCESS;
}
USTATUS FfsParser::findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset)
USTATUS FfsParser::findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset, UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize)
{
int nextIndex = bios.indexOf(EFI_FV_SIGNATURE, volumeOffset);
if (nextIndex < EFI_FV_SIGNATURE_OFFSET)
return U_VOLUMES_NOT_FOUND;
UByteArray data = model->body(index);
UINT32 dataSize = data.size();
// Check volume header to be sane
for (; nextIndex > 0; nextIndex = bios.indexOf(EFI_FV_SIGNATURE, nextIndex + 1)) {
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + nextIndex - EFI_FV_SIGNATURE_OFFSET);
if (volumeHeader->FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY) || volumeHeader->FvLength >= 0xFFFFFFFFUL) {
msg(usprintf("%s: volume candidate at offset %Xh skipped, has invalid FvLength %" PRIX64 "h", __FUNCTION__,
globalOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET),
volumeHeader->FvLength), index);
continue;
if (dataSize < sizeof(UINT32))
return U_STORES_NOT_FOUND;
UINT32 offset = localOffset;
for (; offset < dataSize - sizeof(UINT32); offset++) {
const UINT32* currentPos = (const UINT32*)(data.constData() + offset);
const UINT32 restSize = dataSize - offset;
UINT32 magic;
memcpy(&magic, currentPos, sizeof(UINT32));
if (magic == INTEL_MICROCODE_HEADER_VERSION) {// Intel microcode
// Check data size
if (restSize < sizeof(INTEL_MICROCODE_HEADER))
continue;
// Check microcode size
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos;
if (!INTEL_MICROCODE_HEADER_SIZES_VALID(currentPos) || restSize < ucodeHeader->TotalSize) //TODO: needs a separate checking function
continue;
// Check reserved bytes
bool reservedBytesValid = true;
for (UINT32 i = 0; i < sizeof(ucodeHeader->Reserved); i++)
if (ucodeHeader->Reserved[i] != INTEL_MICROCODE_HEADER_RESERVED_BYTE) {
reservedBytesValid = false;
break;
}
if (!reservedBytesValid)
continue;
// All checks passed, microcode found
nextItemType = Types::Microcode;
nextItemSize = ucodeHeader->TotalSize;
nextItemAlternativeSize = ucodeHeader->TotalSize;
nextItemOffset = offset;
break;
}
if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) {
msg(usprintf("%s: volume candidate at offset %Xh skipped, has invalid Revision byte value %02Xh", __FUNCTION__,
globalOffset + (nextIndex - EFI_FV_SIGNATURE_OFFSET),
volumeHeader->Revision), index);
continue;
else if (magic == EFI_FV_SIGNATURE) {
if (offset < EFI_FV_SIGNATURE_OFFSET)
continue;
offset -= EFI_FV_SIGNATURE_OFFSET;
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(data.constData() + offset);
if (volumeHeader->FvLength < sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY) || volumeHeader->FvLength >= 0xFFFFFFFFUL) {
continue;
}
if (volumeHeader->Revision != 1 && volumeHeader->Revision != 2) {
continue;
}
// Calculate alternative volume size using it's BlockMap
nextItemAlternativeSize = 0;
const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(data.constData() + offset + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
while (entry->NumBlocks != 0 && entry->Length != 0) {
if ((void*)entry >= data.constData() + data.size()) {
continue;
}
nextItemAlternativeSize += entry->NumBlocks * entry->Length;
entry += 1;
}
// All checks passed, volume found
nextItemType = Types::Volume;
nextItemSize = volumeHeader->FvLength;
nextItemOffset = offset;
break;
}
// All checks passed, volume found
break;
}
// No more volumes found
if (nextIndex < EFI_FV_SIGNATURE_OFFSET)
return U_VOLUMES_NOT_FOUND;
nextVolumeOffset = nextIndex - EFI_FV_SIGNATURE_OFFSET;
return U_SUCCESS;
}
USTATUS FfsParser::getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize)
{
// Check that there is space for the volume header and at least two block map entries.
if ((UINT32)bios.size() < volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY))
return U_INVALID_VOLUME;
// Populate volume header
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + volumeOffset);
// Check volume signature
if (UByteArray((const char*)&volumeHeader->Signature, sizeof(volumeHeader->Signature)) != EFI_FV_SIGNATURE)
return U_INVALID_VOLUME;
// Calculate volume size using BlockMap
const EFI_FV_BLOCK_MAP_ENTRY* entry = (const EFI_FV_BLOCK_MAP_ENTRY*)(bios.constData() + volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
UINT32 calcVolumeSize = 0;
while (entry->NumBlocks != 0 && entry->Length != 0) {
if ((void*)entry > bios.constData() + bios.size())
return U_INVALID_VOLUME;
calcVolumeSize += entry->NumBlocks * entry->Length;
entry += 1;
}
volumeSize = (UINT32)volumeHeader->FvLength;
bmVolumeSize = calcVolumeSize;
if (volumeSize == 0)
return U_INVALID_VOLUME;
// No more stores found
if (offset >= dataSize - sizeof(UINT32))
return U_STORES_NOT_FOUND;
return U_SUCCESS;
}
@ -1199,6 +1242,10 @@ USTATUS FfsParser::parseVolumeBody(const UModelIndex & index)
if (model->subtype(index) == Subtypes::NvramVolume)
return nvramParser->parseNvramVolumeBody(index);
// Parse Microcode volume with a dedicated function
if (model->subtype(index) == Subtypes::MicrocodeVolume)
return parseMicrocodeVolumeBody(index);
// Get required values from parsing data
UINT8 emptyByte = 0xFF;
UINT8 ffsVersion = 2;
@ -1732,7 +1779,8 @@ USTATUS FfsParser::parsePadFileBody(const UModelIndex & index)
// Rename the file
model->setName(index, UString("Non-empty pad-file"));
return U_SUCCESS;
// Parse contents as RAW area
return parseRawArea(dataIndex);
}
USTATUS FfsParser::parseSections(const UByteArray & sections, const UModelIndex & index, const bool insertIntoTree)
@ -3484,7 +3532,7 @@ USTATUS FfsParser::parseFit(const UModelIndex & index)
}
if (currentEntry->Type == FIT_TYPE_TXT_CONF_POLICY)
parseTxtConfigurationPolicy(currentEntry, info);
parseFitEntryTxtConfigurationPolicy(currentEntry, info);
// Set item index
if (currentEntry->Address > addressDiff && currentEntry->Address < 0xFFFFFFFFUL) { // Only elements in the image need to be parsed
@ -3497,21 +3545,21 @@ USTATUS FfsParser::parseFit(const UModelIndex & index)
switch (currentEntry->Type) {
case FIT_TYPE_MICROCODE:
status = parseIntelMicrocode(item, localOffset, itemIndex, info, currentEntrySize);
status = parseFitEntryMicrocode(item, localOffset, itemIndex, info, currentEntrySize);
break;
case FIT_TYPE_BIOS_AC_MODULE:
status = parseIntelAcm(item, localOffset, itemIndex, info, currentEntrySize);
status = parseFitEntryAcm(item, localOffset, itemIndex, info, currentEntrySize);
acmIndex = itemIndex;
break;
case FIT_TYPE_AC_KEY_MANIFEST:
status = parseIntelBootGuardKeyManifest(item, localOffset, itemIndex, info, currentEntrySize);
status = parseFitEntryBootGuardKeyManifest(item, localOffset, itemIndex, info, currentEntrySize);
kmIndex = itemIndex;
break;
case FIT_TYPE_AC_BOOT_POLICY:
status = parseIntelBootGuardBootPolicy(item, localOffset, itemIndex, info, currentEntrySize);
status = parseFitEntryBootGuardBootPolicy(item, localOffset, itemIndex, info, currentEntrySize);
bpIndex = itemIndex;
break;
@ -3596,7 +3644,7 @@ USTATUS FfsParser::findFitRecursive(const UModelIndex & index, UModelIndex & fou
return U_SUCCESS;
}
USTATUS FfsParser::parseIntelMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
USTATUS FfsParser::parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
{
U_UNUSED_PARAMETER(parent);
if ((UINT32)microcode.size() < localOffset + sizeof(INTEL_MICROCODE_HEADER)) {
@ -3633,33 +3681,10 @@ USTATUS FfsParser::parseIntelMicrocode(const UByteArray & microcode, const UINT3
header->DateYear
);
realSize = mcSize;
// Add Microcode header info
microcodeInfo += usprintf(
"Microcode Update Capsule found at offset %Xh\n"
"Checksum: %08Xh CPU Flags: %08Xh CPU Signature: %08Xh\n"
"Data Size: %08Xh Date: %02X.%02X.%04X Loader Revision: %08Xh\n"
"Date: %02X.%02X.%04X ModuleSize: %08Xh EntryPoint: %08Xh\n"
"Reserved: %02Xh Revision: %08Xh TotalSize: %08Xh\n"
"Version: %08Xh"
"\n------------------------------------------------------------------------\n\n",
model->offset(parent) + localOffset,
header->Checksum,
header->CpuFlags,
header->CpuSignature,
header->DataSize,
header->DateDay, header->DateMonth, header->DateYear,
header->LoaderRevision,
header->Reserved,
header->Revision,
header->TotalSize,
header->Version
);
return U_SUCCESS;
}
USTATUS FfsParser::parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info)
USTATUS FfsParser::parseFitEntryTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info)
{
U_UNUSED_PARAMETER(info);
const TXT_CONFIG_POLICY* txtCfg = (const TXT_CONFIG_POLICY*)entry;
@ -3694,7 +3719,7 @@ USTATUS FfsParser::parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString &
return U_SUCCESS;
}
USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
USTATUS FfsParser::parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
{
if ((UINT32)acm.size() < localOffset + sizeof(INTEL_ACM_HEADER)) {
return U_INVALID_ACM;
@ -3778,7 +3803,7 @@ USTATUS FfsParser::parseIntelAcm(const UByteArray & acm, const UINT32 localOffse
return U_SUCCESS;
}
USTATUS FfsParser::parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
USTATUS FfsParser::parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
{
U_UNUSED_PARAMETER(realSize);
if ((UINT32)keyManifest.size() < localOffset + sizeof(BG_KEY_MANIFEST)) {
@ -3844,7 +3869,7 @@ USTATUS FfsParser::parseIntelBootGuardKeyManifest(const UByteArray & keyManifest
return U_SUCCESS;
}
USTATUS FfsParser::findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize)
USTATUS FfsParser::findNextBootGuardBootPolicyElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize)
{
UINT32 dataSize = bootPolicy.size();
if (dataSize < sizeof(UINT64)) {
@ -3882,7 +3907,7 @@ USTATUS FfsParser::findNextElement(const UByteArray & bootPolicy, const UINT32 e
return U_ELEMENTS_NOT_FOUND;
}
USTATUS FfsParser::parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
USTATUS FfsParser::parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize)
{
U_UNUSED_PARAMETER(realSize);
if ((UINT32)bootPolicy.size() < localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER)) {
@ -3923,7 +3948,7 @@ USTATUS FfsParser::parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy,
// Iterate over elements to get them all
UINT32 elementOffset = 0;
UINT32 elementSize = 0;
USTATUS status = findNextElement(bootPolicy, localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER), elementOffset, elementSize);
USTATUS status = findNextBootGuardBootPolicyElement(bootPolicy, localOffset + sizeof(BG_BOOT_POLICY_MANIFEST_HEADER), elementOffset, elementSize);
while (status == U_SUCCESS) {
const UINT64* currentPos = (const UINT64*)(bootPolicy.constData() + elementOffset);
if (*currentPos == BG_BOOT_POLICY_MANIFEST_IBB_ELEMENT_TAG) {
@ -4062,13 +4087,119 @@ USTATUS FfsParser::parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy,
bootGuardInfo += usprintf("%02X", elementHeader->KeySignature.Signature.Signature[i]);
}
}
status = findNextElement(bootPolicy, elementOffset + elementSize, elementOffset, elementSize);
status = findNextBootGuardBootPolicyElement(bootPolicy, elementOffset + elementSize, elementOffset, elementSize);
}
bootGuardInfo += UString("\n------------------------------------------------------------------------\n\n");
bgBootPolicyFound = true;
return U_SUCCESS;
}
#endif
USTATUS FfsParser::parseMicrocodeVolumeBody(const UModelIndex & index)
{
const UINT32 headerSize = (UINT32)model->header(index).size();
const UINT32 bodySize = (UINT32)model->body(index).size();
UINT32 offset = 0;
USTATUS result = U_SUCCESS;
while(true) {
// Parse current microcode
UModelIndex currentMicrocode;
UByteArray ucode = model->body(index).mid(offset);
// Check for empty area
if (ucode.size() == ucode.count('\xFF') || ucode.size() == ucode.count('\x00')) {
result = U_INVALID_MICROCODE;
}
else {
result = parseIntelMicrocodeHeader(ucode, headerSize + offset, index, currentMicrocode);
}
// Add the rest as padding
if (result) {
if (offset < bodySize) {
// Get info
UString name = UString("Padding");
UString info = usprintf("Full size: %Xh (%u)", ucode.size(), ucode.size());
// Add tree item
model->addItem(model->offset(index) + headerSize + offset, Types::Padding, getPaddingType(ucode), name, UString(), info, UByteArray(), ucode, UByteArray(), Fixed, index);
}
return U_SUCCESS;
}
// Get to next candidate
offset += model->header(currentMicrocode).size() + model->body(currentMicrocode).size() + model->tail(currentMicrocode).size();
if (offset >= bodySize)
break;
}
return U_SUCCESS;
}
USTATUS FfsParser::parseIntelMicrocodeHeader(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, UINT8 mode)
{
const UINT32 dataSize = (const UINT32)microcode.size();
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
//msg(usprintf("%s: input is too small even for Intel microcode header", __FUNCTION__), parent);
return U_INVALID_MICROCODE;
}
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)microcode.constData();
if (ucodeHeader->Version != INTEL_MICROCODE_HEADER_VERSION) {
//msg(usprintf("%s: input has invalid Intel microcode header", __FUNCTION__), parent);
return U_INVALID_MICROCODE;
}
if (!INTEL_MICROCODE_HEADER_SIZES_VALID(ucodeHeader)) {
//msg(usprintf("%s: input has invalid Intel microcode header", __FUNCTION__), parent);
return U_INVALID_MICROCODE;
}
bool reservedBytesValid = true;
for (UINT8 i = 0; i < sizeof(ucodeHeader->Reserved); i++)
if (ucodeHeader->Reserved[i] != INTEL_MICROCODE_HEADER_RESERVED_BYTE) {
reservedBytesValid = false;
break;
}
if (!reservedBytesValid) {
//msg(usprintf("%s: input has invalid Intel microcode header", __FUNCTION__), parent);
return U_INVALID_MICROCODE;
}
if (dataSize < ucodeHeader->TotalSize) {
//msg(usprintf("%s: input is too small for the whole Intel microcode", __FUNCTION__), parent);
return U_INVALID_MICROCODE;
}
// Valid microcode found
// Construct header and body
UByteArray header = microcode.left(sizeof(INTEL_MICROCODE_HEADER));
UByteArray body = microcode.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
//TODO: recalculate microcode checksum
// Add info
UString name("Intel microcode");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n"
"Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh",
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
header.size(), header.size(),
body.size(), body.size(),
ucodeHeader->DateDay,
ucodeHeader->DateMonth,
ucodeHeader->DateYear,
ucodeHeader->CpuSignature,
ucodeHeader->Revision,
ucodeHeader->Checksum,
ucodeHeader->LoaderRevision,
ucodeHeader->CpuFlags);
// Add tree item
index = model->addItem(model->offset(parent) + localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
// No need to parse body further for now
return U_SUCCESS;
}

View file

@ -64,9 +64,6 @@ public:
// Obtain TXT ACM Info
UString getTxtInfo() const { return txtInfo; }
// Obtain Microcode Info
UString getMicrocodeInfo() const { return microcodeInfo; }
// Obtain offset/address difference
UINT64 getAddressDiff() { return addressDiff; }
@ -102,18 +99,18 @@ private:
UModelIndex bgDxeCoreIndex;
UString txtInfo;
UString microcodeInfo;
// First pass
USTATUS performFirstPass(const UByteArray & imageFile, UModelIndex & index);
USTATUS parseCapsule(const UByteArray & capsule, UModelIndex & index);
USTATUS parseCapsule(const UByteArray & capsule, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseIntelImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseGenericImage(const UByteArray & intelImage, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index);
USTATUS parseRawArea(const UModelIndex & index);
USTATUS parseVolumeHeader(const UByteArray & volume, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
USTATUS parseVolumeBody(const UModelIndex & index);
USTATUS parseMicrocodeVolumeBody(const UModelIndex & index);
USTATUS parseFileHeader(const UByteArray & file, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
USTATUS parseFileBody(const UModelIndex & index);
USTATUS parseSectionHeader(const UByteArray & section, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const bool insertIntoTree, const UINT8 mode = CREATE_MODE_APPEND);
@ -146,8 +143,8 @@ private:
USTATUS parseTeImageSectionBody(const UModelIndex & index);
USTATUS parseAprioriRawSection(const UByteArray & body, UString & parsed);
USTATUS findNextVolume(const UModelIndex & index, const UByteArray & bios, const UINT32 globalOffset, const UINT32 volumeOffset, UINT32 & nextVolumeOffset);
USTATUS getVolumeSize(const UByteArray & bios, const UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize);
USTATUS findNextRawAreaItem(const UModelIndex & index, const UINT32 localOffset,
UINT8 & nextItemType, UINT32 & nextItemOffset, UINT32 & nextItemSize, UINT32 & nextItemAlternativeSize);
UINT32 getFileSize(const UByteArray & volume, const UINT32 fileOffset, const UINT8 ffsVersion);
UINT32 getSectionSize(const UByteArray & file, const UINT32 sectionOffset, const UINT8 ffsVersion);
@ -161,17 +158,18 @@ private:
USTATUS parseFit(const UModelIndex & index);
USTATUS parseVendorHashFile(const UByteArray & fileGuid, const UModelIndex & index);
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, UINT8 mode = CREATE_MODE_APPEND);
#ifdef U_ENABLE_FIT_PARSING_SUPPORT
USTATUS findFitRecursive(const UModelIndex & index, UModelIndex & found, UINT32 & fitOffset);
// FIT entries
USTATUS parseIntelMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseIntelAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseIntelBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseIntelBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info);
USTATUS findNextElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
USTATUS parseFitEntryMicrocode(const UByteArray & microcode, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseFitEntryAcm(const UByteArray & acm, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseFitEntryBootGuardKeyManifest(const UByteArray & keyManifest, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseFitEntryBootGuardBootPolicy(const UByteArray & bootPolicy, const UINT32 localOffset, const UModelIndex & parent, UString & info, UINT32 &realSize);
USTATUS parseFitEntryTxtConfigurationPolicy(const FIT_ENTRY* entry, UString & info);
USTATUS findNextBootGuardBootPolicyElement(const UByteArray & bootPolicy, const UINT32 elementOffset, UINT32 & nextElementOffset, UINT32 & nextElementSize);
#endif
#ifdef U_ENABLE_NVRAM_PARSING_SUPPORT

View file

@ -18,8 +18,8 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <fstream>
#include <sstream>
#include <string>
#include <cstdio>
#include <vector>
#include <cstdio>
struct OperatorLessForGuids : public std::binary_function<EFI_GUID, EFI_GUID, bool>
{

View file

@ -22,12 +22,12 @@ const UByteArray ME_VERSION_SIGNATURE("\x24\x4D\x41\x4E", 4); //$MAN
const UByteArray ME_VERSION_SIGNATURE2("\x24\x4D\x4E\x32", 4); //$MN2
typedef struct ME_VERSION_ {
UINT32 signature;
UINT32 reserved;
UINT16 major;
UINT16 minor;
UINT16 bugfix;
UINT16 build;
UINT32 Signature;
UINT32 Reserved;
UINT16 Major;
UINT16 Minor;
UINT16 Bugfix;
UINT16 Build;
} ME_VERSION;
// Restore previous packing rules

View file

@ -108,6 +108,6 @@ UString flashMapGuidToUString(const EFI_GUID & guid)
|| baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID
|| baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID) return UString("EVSA store");
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_SELF_GUID) return UString("Flash map");
return UString();
return UString("Unknown");
}

View file

@ -1225,55 +1225,6 @@ USTATUS NvramParser::parseSlicMarkerHeader(const UByteArray & store, const UINT3
return U_SUCCESS;
}
USTATUS NvramParser::parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
{
const UINT32 dataSize = (const UINT32)store.size();
// Check data size
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
msg(usprintf("%s: volume body is too small even for Intel microcode header", __FUNCTION__), parent);
return U_SUCCESS;
}
// Get Intel microcode header
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)store.constData();
// Check store size
if (dataSize < ucodeHeader->TotalSize) {
msg(usprintf("%s: Intel microcode size %Xh (%u) is greater than volume body size %Xh (%u)", __FUNCTION__,
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
dataSize, dataSize), parent);
return U_SUCCESS;
}
// Construct header and body
UByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER));
UByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
//TODO: recalculate microcode checksum
// Add info
UString name("Intel microcode");
UString info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\n"
"Date: %02X.%02X.%04x\nCPU signature: %08Xh\nRevision: %08Xh\nChecksum: %08Xh\nLoader revision: %08Xh\nCPU flags: %08Xh",
ucodeHeader->TotalSize, ucodeHeader->TotalSize,
header.size(), header.size(),
body.size(), body.size(),
ucodeHeader->DateDay,
ucodeHeader->DateMonth,
ucodeHeader->DateYear,
ucodeHeader->CpuSignature,
ucodeHeader->Revision,
ucodeHeader->Checksum,
ucodeHeader->LoaderRevision,
ucodeHeader->CpuFlags);
// Add tree item
index = model->addItem(localOffset, Types::Microcode, Subtypes::IntelMicrocode, name, UString(), info, header, body, UByteArray(), Fixed, parent, mode);
return U_SUCCESS;
}
USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode)
{
const UINT32 dataSize = (const UINT32)store.size();
@ -1318,7 +1269,7 @@ USTATUS NvramParser::parseStoreHeader(const UByteArray & store, const UINT32 loc
// Intel microcode
// Must be checked after SLIC marker because of the same *signature values
else if (*signature == INTEL_MICROCODE_HEADER_VERSION)
return parseIntelMicrocodeHeader(store, localOffset, parent, index, mode);
return ffsParser->parseIntelMicrocodeHeader(store, localOffset, parent, index, mode);
msg(usprintf("parseStoreHeader: don't know how to parse a header with signature %08Xh", *signature), parent);
return U_SUCCESS;

View file

@ -62,7 +62,6 @@ private:
USTATUS parseCmdbStoreHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
USTATUS parseSlicPubkeyHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
USTATUS parseSlicMarkerHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
USTATUS parseIntelMicrocodeHeader(const UByteArray & store, const UINT32 localOffset, const UModelIndex & parent, UModelIndex & index, const UINT8 mode = CREATE_MODE_APPEND);
USTATUS parseFdcStoreBody(const UModelIndex & index);
USTATUS parseVssStoreBody(const UModelIndex & index, const UINT8 alignment);

View file

@ -74,17 +74,6 @@ UString itemTypeToUString(const UINT8 type)
UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
{
switch (type) {
case Types::Root:
case Types::FreeSpace:
case Types::VssStore:
case Types::Vss2Store:
case Types::FdcStore:
case Types::FsysStore:
case Types::EvsaStore:
case Types::FtwStore:
case Types::FlashMapStore:
case Types::CmdbStore:
case Types::SlicData: return UString();
case Types::Image:
if (subtype == Subtypes::IntelImage) return UString("Intel");
if (subtype == Subtypes::UefiImage) return UString("UEFI");
@ -99,6 +88,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
if (subtype == Subtypes::Ffs2Volume) return UString("FFSv2");
if (subtype == Subtypes::Ffs3Volume) return UString("FFSv3");
if (subtype == Subtypes::NvramVolume) return UString("NVRAM");
if (subtype == Subtypes::MicrocodeVolume) return UString("Microcode");
break;
case Types::Capsule:
if (subtype == Subtypes::AptioSignedCapsule) return UString("Aptio signed");
@ -144,7 +134,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
break;
}
return UString("Unknown");
return UString();
}
UString compressionTypeToUString(const UINT8 algorithm)

View file

@ -78,7 +78,8 @@ namespace Subtypes {
UnknownVolume = 110,
Ffs2Volume,
Ffs3Volume,
NvramVolume
NvramVolume,
MicrocodeVolume
};
enum RegionSubtypes {