Skip to content

Commit 0446201

Browse files
committed
Simplify Insyde FDM parsing by skipping optional header extensions
1 parent c4649f3 commit 0446201

6 files changed

Lines changed: 141 additions & 297 deletions

File tree

UEFITool/ffsfinder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ USTATUS FfsFinder::findTextPattern(const UModelIndex & index, const UString & pa
245245
name = model->name(parentFileIndex) + UString("/.../") + name;
246246
}
247247

248-
msg(UString("Text \"") + UString(pattern) + UString("\" found in ") + name + UString(" information"), index);
248+
msg((unicode ? UString("Unicode") : UString("ASCII")) + UString(" text \"") + UString(pattern) + UString("\" found in ") + name + UString(" information"), index);
249249
ret = U_SUCCESS;
250250
}
251251
if (mode == SEARCH_MODE_INFO)

common/ffs.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -910,13 +910,8 @@ typedef struct _INSYDE_FLASH_DEVICE_MAP_ENTRY {
910910
//UINT8 Hash[]; // Size depends on EntryFormat and EntrySize of the header
911911
} INSYDE_FLASH_DEVICE_MAP_ENTRY;
912912

913-
typedef struct _INSYDE_FLASH_DEVICE_MAP_BOARD_ID_MAP {
914-
UINT32 BoardIdIndex;
915-
UINT32 BoardIdCount;
916-
//UINT64 BoardIds[Count];
917-
} INSYDE_FLASH_DEVICE_MAP_BOARD_ID_MAP;
918-
919913
#define INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE 0x00000001
914+
#define INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_IGNORED 0x00000002
920915

921916
extern const UByteArray INSYDE_FLASH_MAP_REGION_AUX_FV_GUID;
922917
extern const UByteArray INSYDE_FLASH_MAP_REGION_BOOT_FV_GUID;

common/ffsparser.cpp

Lines changed: 77 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,6 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
976976
parsed.num_extensions(),
977977
(UINT32)parsed.fd_base_address(),
978978
parsed.checksum());
979-
980979
// Check header checksum
981980
{
982981
UByteArray tempHeader = data.mid(itemOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_HEADER));
@@ -991,89 +990,92 @@ USTATUS FfsParser::parseRawArea(const UModelIndex & index)
991990
}
992991
}
993992

994-
// Add board IDs
995-
if (!parsed._is_null_board_ids()) {
996-
info += usprintf("\nRegion index: %Xh\nBoardId Count: %u",
997-
parsed.board_ids()->region_index(),
998-
parsed.board_ids()->num_board_ids());
999-
UINT32 i = 0;
1000-
for (const auto & boardId : *parsed.board_ids()->board_ids()) {
1001-
info += usprintf("\nBoardId #%u: %" PRIX64 "\n", i++, boardId);
1002-
}
1003-
}
1004-
1005993
// Add header tree item
1006994
UModelIndex headerIndex = model->addItem(headerSize + itemOffset, Types::InsydeFlashDeviceMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
1007995

1008-
// Add entries
1009-
UINT32 entryOffset = parsed.data_offset();
1010-
bool protectedRangeFound = false;
1011-
for (const auto & entry : *parsed.entries()->entries()) {
1012-
const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str());
1013-
name = insydeFlashDeviceMapEntryTypeGuidToUString(guid);
1014-
UString text;
1015-
header = data.mid(itemOffset + entryOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_ENTRY));
1016-
body = data.mid(itemOffset + entryOffset + header.size(), parsed.entry_size() - header.size());
1017-
1018-
// Add info
1019-
UINT32 entrySize = (UINT32)header.size() + (UINT32)body.size();
1020-
info = UString("Region type: ") + guidToUString(guid, false) + "\n";
1021-
info += UString("Region id: ");
1022-
for (UINT8 i = 0; i < 16; i++) {
1023-
info += usprintf("%02X", *(const UINT8*)(entry->region_id().c_str() + i));
1024-
}
1025-
info += usprintf("\nRegion address: %08Xh\nRegion size: %08Xh\nAttributes: %08Xh (",
1026-
(UINT32)entry->region_base(),
1027-
(UINT32)entry->region_size(),
1028-
entry->attributes());
1029-
1030-
// Add atributes
1031-
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) {
1032-
info += UString("HashVerified");
1033-
}
1034-
else if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) {
1035-
info += UString("HashIgnored");
1036-
}
1037-
else if (entry->attributes() > INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) {
1038-
info += usprintf(", Unknown %08X", entry->attributes() - INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE);
1039-
msg(usprintf("%s: FlashDeviceMap entry with unknown attributes %08X", __FUNCTION__, entry->attributes()), headerIndex);
1040-
}
1041-
info += UString(")");
1042-
1043-
// Add hash
1044-
info += UString("\nSHA256: ");
1045-
for (UINT16 j = 0; j < (UINT16)body.size(); j++) {
1046-
info += usprintf("%02X", (UINT8)body.constData()[j]);
1047-
}
1048-
1049-
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) {
1050-
if (!protectedRangeFound) {
1051-
securityInfo += usprintf("Insyde Flash Device Map found at base %08Xh\nProtected ranges:\n", model->base(headerIndex));
1052-
protectedRangeFound = true;
996+
// Check if we can add entries
997+
if (parsed._is_null_entries()) {
998+
msg(usprintf("%s: FDM store with unknown entry format or size", __FUNCTION__), headerIndex);
999+
}
1000+
else {
1001+
// Add entries
1002+
UINT32 entryOffset = parsed.data_offset();
1003+
bool protectedRangeFound = false;
1004+
for (const auto & entry : *parsed.entries()->entries()) {
1005+
const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str());
1006+
name = insydeFlashDeviceMapEntryTypeGuidToUString(guid);
1007+
UString text;
1008+
header = data.mid(itemOffset + entryOffset, sizeof(INSYDE_FLASH_DEVICE_MAP_ENTRY));
1009+
body = data.mid(itemOffset + entryOffset + header.size(), parsed.entry_size() - header.size());
1010+
1011+
// Add info
1012+
UINT32 entrySize = (UINT32)header.size() + (UINT32)body.size();
1013+
info = UString("Region type: ") + guidToUString(guid, false) + "\n";
1014+
info += UString("Region id: ");
1015+
for (UINT8 i = 0; i < 16; i++) {
1016+
info += usprintf("%02X", *(const UINT8*)(entry->region_id().c_str() + i));
10531017
}
1018+
info += usprintf("\nRegion address: %08Xh\nRegion size: %08Xh\nAttributes: %08Xh (",
1019+
(UINT32)entry->region_base(),
1020+
(UINT32)entry->region_size(),
1021+
entry->attributes());
10541022

1055-
// TODO: make sure that the only hash possible here is SHA256
1023+
// Add atributes
1024+
// Ignored or Valid
1025+
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_IGNORED) == 0) {
1026+
info += UString("EntryValid");
1027+
}
1028+
else if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_IGNORED) == INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_IGNORED) {
1029+
info += UString("EntryIgnored");
1030+
}
1031+
// HashIgnored or HashVerified
1032+
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) {
1033+
info += UString(", HashVerified");
1034+
}
1035+
else if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) {
1036+
info += UString(", HashIgnored");
1037+
}
1038+
// Unknown atributes other than the two known above
1039+
if (entry->attributes() > INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_IGNORED + INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) {
1040+
UINT32 unknown_attributes = entry->attributes() & ((UINT32)(0xFFFFFFFFC));
1041+
info += usprintf(", Unknown %08Xh", unknown_attributes);
1042+
msg(usprintf("%s: FlashDeviceMap entry with unknown attributes %08Xh", __FUNCTION__, unknown_attributes), headerIndex);
1043+
}
1044+
info += UString(")");
10561045

1057-
// Add this region to the list of Insyde protected regions
1058-
PROTECTED_RANGE range = {};
1059-
range.Offset = (UINT32)entry->region_base();
1060-
range.Size = (UINT32)entry->region_size();
1061-
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
1062-
range.Type = PROTECTED_RANGE_VENDOR_HASH_INSYDE;
1063-
range.Hash = body;
1064-
protectedRanges.push_back(range);
1046+
// Add hash
1047+
info += UString("\nSHA256: ");
1048+
for (UINT16 j = 0; j < (UINT16)body.size(); j++) {
1049+
info += usprintf("%02X", (UINT8)body.constData()[j]);
1050+
}
10651051

1066-
securityInfo += usprintf("Address: %08Xh Size: %Xh\nHash: ", range.Offset, range.Size) + UString(body.toHex().constData()) + "\n";
1052+
if ((entry->attributes() & INSYDE_FLASH_DEVICE_MAP_ENTRY_ATTRIBUTE_MODIFIABLE) == 0) {
1053+
if (!protectedRangeFound) {
1054+
securityInfo += usprintf("Insyde Flash Device Map found at base %08Xh\nProtected ranges:\n", model->base(headerIndex));
1055+
protectedRangeFound = true;
1056+
}
1057+
1058+
// Add this region to the list of Insyde protected regions
1059+
PROTECTED_RANGE range = {};
1060+
range.Offset = (UINT32)entry->region_base();
1061+
range.Size = (UINT32)entry->region_size();
1062+
range.AlgorithmId = TCG_HASH_ALGORITHM_ID_SHA256;
1063+
range.Type = PROTECTED_RANGE_VENDOR_HASH_INSYDE;
1064+
range.Hash = body;
1065+
protectedRanges.push_back(range);
1066+
1067+
securityInfo += usprintf("Address: %08Xh Size: %Xh\nHash: ", range.Offset, range.Size) + UString(body.toHex().constData()) + "\n";
1068+
}
1069+
1070+
// Add tree item
1071+
model->addItem(entryOffset, Types::InsydeFlashDeviceMapEntry, 0, name, text, info, header, body, UByteArray(), Fixed, headerIndex);
1072+
1073+
entryOffset += entrySize;
10671074
}
10681075

1069-
// Add tree item
1070-
model->addItem(entryOffset, Types::InsydeFlashDeviceMapEntry, 0, name, text, info, header, body, UByteArray(), Fixed, headerIndex);
1071-
1072-
entryOffset += entrySize;
1073-
}
1074-
1075-
if (protectedRangeFound) {
1076-
securityInfo += "\n";
1076+
if (protectedRangeFound) {
1077+
securityInfo += "\n";
1078+
}
10771079
}
10781080
}
10791081
catch (...) {

common/generated/insyde_fdm.cpp

Lines changed: 31 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
insyde_fdm_t::insyde_fdm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, insyde_fdm_t* p__root) : kaitai::kstruct(p__io) {
66
m__parent = p__parent;
77
m__root = p__root ? p__root : this;
8-
m_extensions = nullptr;
9-
m__io__raw_extensions = nullptr;
10-
m_board_ids = nullptr;
118
m_entries = nullptr;
129
m__io__raw_entries = nullptr;
10+
f_entries = false;
11+
f_valid_entry_format = false;
12+
f_valid_entry_size = false;
1313
_read();
1414
}
1515

@@ -23,58 +23,17 @@ void insyde_fdm_t::_read() {
2323
m_num_extensions = m__io->read_u1();
2424
m_checksum = m__io->read_u1();
2525
m_fd_base_address = m__io->read_u8le();
26-
n_extensions = true;
27-
if (revision() > 2) {
28-
n_extensions = false;
29-
m__raw_extensions = m__io->read_bytes(num_extensions() * 4);
30-
m__io__raw_extensions = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_extensions));
31-
m_extensions = std::unique_ptr<fdm_extensions_t>(new fdm_extensions_t(m__io__raw_extensions.get(), this, m__root));
32-
}
33-
n_board_ids = true;
34-
if ( ((revision() > 2) && (extensions()->extensions()->at(1)->count() > 0)) ) {
35-
n_board_ids = false;
36-
m_board_ids = std::unique_ptr<fdm_board_ids_t>(new fdm_board_ids_t(m__io, this, m__root));
37-
}
38-
m__raw_entries = m__io->read_bytes(store_size() - data_offset());
39-
m__io__raw_entries = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_entries));
40-
m_entries = std::unique_ptr<fdm_entries_t>(new fdm_entries_t(m__io__raw_entries.get(), this, m__root));
4126
}
4227

4328
insyde_fdm_t::~insyde_fdm_t() {
4429
_clean_up();
4530
}
4631

4732
void insyde_fdm_t::_clean_up() {
48-
if (!n_extensions) {
49-
}
50-
if (!n_board_ids) {
51-
}
52-
}
53-
54-
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) {
55-
m__parent = p__parent;
56-
m__root = p__root;
57-
m_board_ids = nullptr;
58-
_read();
59-
}
60-
61-
void insyde_fdm_t::fdm_board_ids_t::_read() {
62-
m_region_index = m__io->read_u4le();
63-
m_num_board_ids = m__io->read_u4le();
64-
m_board_ids = std::unique_ptr<std::vector<uint64_t>>(new std::vector<uint64_t>());
65-
const int l_board_ids = num_board_ids();
66-
for (int i = 0; i < l_board_ids; i++) {
67-
m_board_ids->push_back(std::move(m__io->read_u8le()));
33+
if (f_entries && !n_entries) {
6834
}
6935
}
7036

71-
insyde_fdm_t::fdm_board_ids_t::~fdm_board_ids_t() {
72-
_clean_up();
73-
}
74-
75-
void insyde_fdm_t::fdm_board_ids_t::_clean_up() {
76-
}
77-
7837
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) {
7938
m__parent = p__parent;
8039
m__root = p__root;
@@ -113,7 +72,7 @@ void insyde_fdm_t::fdm_entry_t::_read() {
11372
m_region_offset = m__io->read_u8le();
11473
m_region_size = m__io->read_u8le();
11574
m_attributes = m__io->read_u4le();
116-
m_hash = m__io->read_bytes(((((_parent()->_parent()->entry_size() - 16) - 16) - 8) - 8) - 4);
75+
m_hash = m__io->read_bytes(32);
11776
}
11877

11978
insyde_fdm_t::fdm_entry_t::~fdm_entry_t() {
@@ -131,45 +90,35 @@ int32_t insyde_fdm_t::fdm_entry_t::region_base() {
13190
return m_region_base;
13291
}
13392

134-
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) {
135-
m__parent = p__parent;
136-
m__root = p__root;
137-
_read();
138-
}
139-
140-
void insyde_fdm_t::fdm_extension_t::_read() {
141-
m_offset = m__io->read_u2le();
142-
m_count = m__io->read_u2le();
143-
}
144-
145-
insyde_fdm_t::fdm_extension_t::~fdm_extension_t() {
146-
_clean_up();
147-
}
148-
149-
void insyde_fdm_t::fdm_extension_t::_clean_up() {
150-
}
151-
152-
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) {
153-
m__parent = p__parent;
154-
m__root = p__root;
155-
m_extensions = nullptr;
156-
_read();
157-
}
158-
159-
void insyde_fdm_t::fdm_extensions_t::_read() {
160-
m_extensions = std::unique_ptr<std::vector<std::unique_ptr<fdm_extension_t>>>(new std::vector<std::unique_ptr<fdm_extension_t>>());
161-
{
162-
int i = 0;
163-
while (!m__io->is_eof()) {
164-
m_extensions->push_back(std::move(std::unique_ptr<fdm_extension_t>(new fdm_extension_t(m__io, this, m__root))));
165-
i++;
166-
}
93+
insyde_fdm_t::fdm_entries_t* insyde_fdm_t::entries() {
94+
if (f_entries)
95+
return m_entries.get();
96+
f_entries = true;
97+
n_entries = true;
98+
if ( ((entry_size() == valid_entry_size()) && (entry_format() == valid_entry_format())) ) {
99+
n_entries = false;
100+
std::streampos _pos = m__io->pos();
101+
m__io->seek(data_offset());
102+
m__raw_entries = m__io->read_bytes(store_size() - data_offset());
103+
m__io__raw_entries = std::unique_ptr<kaitai::kstream>(new kaitai::kstream(m__raw_entries));
104+
m_entries = std::unique_ptr<fdm_entries_t>(new fdm_entries_t(m__io__raw_entries.get(), this, m__root));
105+
m__io->seek(_pos);
167106
}
107+
return m_entries.get();
168108
}
169109

170-
insyde_fdm_t::fdm_extensions_t::~fdm_extensions_t() {
171-
_clean_up();
110+
int8_t insyde_fdm_t::valid_entry_format() {
111+
if (f_valid_entry_format)
112+
return m_valid_entry_format;
113+
f_valid_entry_format = true;
114+
m_valid_entry_format = 0;
115+
return m_valid_entry_format;
172116
}
173117

174-
void insyde_fdm_t::fdm_extensions_t::_clean_up() {
118+
int8_t insyde_fdm_t::valid_entry_size() {
119+
if (f_valid_entry_size)
120+
return m_valid_entry_size;
121+
f_valid_entry_size = true;
122+
m_valid_entry_size = 84;
123+
return m_valid_entry_size;
175124
}

0 commit comments

Comments
 (0)