mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-05-09 13:52:01 -04:00
Add Phoenix FlashMap parser
This commit is contained in:
parent
4e600eb986
commit
f989fdfea1
20 changed files with 412 additions and 39 deletions
|
@ -40,6 +40,7 @@ SET(PROJECT_SOURCES
|
|||
../common/generated/edk2_vss2.cpp
|
||||
../common/generated/edk2_ftw.cpp
|
||||
../common/generated/insyde_fdc.cpp
|
||||
../common/generated/phoenix_flm.cpp
|
||||
../common/generated/intel_acbp_v1.cpp
|
||||
../common/generated/intel_acbp_v2.cpp
|
||||
../common/generated/intel_keym_v1.cpp
|
||||
|
|
|
@ -37,6 +37,7 @@ SET(PROJECT_SOURCES
|
|||
../common/generated/edk2_vss2.cpp
|
||||
../common/generated/edk2_ftw.cpp
|
||||
../common/generated/insyde_fdc.cpp
|
||||
../common/generated/phoenix_flm.cpp
|
||||
../common/generated/intel_acbp_v1.cpp
|
||||
../common/generated/intel_acbp_v2.cpp
|
||||
../common/generated/intel_keym_v1.cpp
|
||||
|
|
|
@ -73,6 +73,7 @@ SET(PROJECT_SOURCES
|
|||
../common/generated/edk2_vss2.cpp
|
||||
../common/generated/edk2_ftw.cpp
|
||||
../common/generated/insyde_fdc.cpp
|
||||
../common/generated/phoenix_flm.cpp
|
||||
../common/generated/intel_acbp_v1.cpp
|
||||
../common/generated/intel_acbp_v2.cpp
|
||||
../common/generated/intel_keym_v1.cpp
|
||||
|
|
|
@ -56,6 +56,7 @@ HEADERS += uefitool.h \
|
|||
../common/generated/edk2_vss2.h \
|
||||
../common/generated/edk2_ftw.h \
|
||||
../common/generated/insyde_fdc.h \
|
||||
../common/generated/phoenix_flm.h \
|
||||
../common/generated/intel_acbp_v1.h \
|
||||
../common/generated/intel_acbp_v2.h \
|
||||
../common/generated/intel_keym_v1.h \
|
||||
|
@ -128,6 +129,7 @@ SOURCES += uefitool_main.cpp \
|
|||
../common/generated/edk2_vss2.cpp \
|
||||
../common/generated/edk2_ftw.cpp \
|
||||
../common/generated/insyde_fdc.cpp \
|
||||
../common/generated/phoenix_flm.cpp \
|
||||
../common/generated/intel_acbp_v1.cpp \
|
||||
../common/generated/intel_acbp_v2.cpp \
|
||||
../common/generated/intel_keym_v1.cpp \
|
||||
|
|
|
@ -23,7 +23,7 @@ void edk2_vss_t::_read() {
|
|||
m_vss_size = m__io->read_u4le();
|
||||
{
|
||||
uint32_t _ = vss_size();
|
||||
if (!( ((_ > len_vss_store_header()) && (_ < 4294967295UL)) )) {
|
||||
if (!( ((_ > static_cast<uint32_t>(len_vss_store_header())) && (_ < 4294967295UL)) )) {
|
||||
throw kaitai::validation_expr_error<uint32_t>(vss_size(), _io(), std::string("/seq/1"));
|
||||
}
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ void edk2_vss_t::vss_variable_t::_read() {
|
|||
m_len_total = m__io->read_u4le();
|
||||
{
|
||||
uint32_t _ = len_total();
|
||||
if (!(_ >= ((len_intel_legacy_header() + 4) + 1))) {
|
||||
if (!(_ >= ((static_cast<uint32_t>(len_intel_legacy_header()) + 4) + 1))) {
|
||||
throw kaitai::validation_expr_error<uint32_t>(len_total(), _io(), std::string("/types/vss_variable/seq/5"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ void edk2_vss2_t::_read() {
|
|||
m_vss2_size = m__io->read_u4le();
|
||||
{
|
||||
uint32_t _ = vss2_size();
|
||||
if (!( ((_ > len_vss2_store_header()) && (_ < 4294967295UL)) )) {
|
||||
if (!( ((_ > static_cast<uint32_t>(len_vss2_store_header())) && (_ < 4294967295UL)) )) {
|
||||
throw kaitai::validation_expr_error<uint32_t>(vss2_size(), _io(), std::string("/seq/4"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ void insyde_fdc_t::_read() {
|
|||
m_fdc_size = m__io->read_u4le();
|
||||
{
|
||||
uint32_t _ = fdc_size();
|
||||
if (!( ((_ > len_fdc_store_header()) && (_ < 4294967295UL)) )) {
|
||||
if (!( ((_ > static_cast<uint32_t>(len_fdc_store_header())) && (_ < 4294967295UL)) )) {
|
||||
throw kaitai::validation_expr_error<uint32_t>(fdc_size(), _io(), std::string("/seq/1"));
|
||||
}
|
||||
}
|
||||
|
|
93
common/generated/phoenix_flm.cpp
Normal file
93
common/generated/phoenix_flm.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
|
||||
|
||||
#include "phoenix_flm.h"
|
||||
#include "../kaitai/exceptions.h"
|
||||
|
||||
phoenix_flm_t::phoenix_flm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, phoenix_flm_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = this; (void)p__root;
|
||||
m_entries = nullptr;
|
||||
m_free_space = nullptr;
|
||||
f_len_flm_store = false;
|
||||
f_len_flm_store_header = false;
|
||||
f_len_flm_entry = false;
|
||||
_read();
|
||||
}
|
||||
|
||||
void phoenix_flm_t::_read() {
|
||||
m_signature = m__io->read_bytes(10);
|
||||
if (!(signature() == std::string("\x5F\x46\x4C\x41\x53\x48\x5F\x4D\x41\x50", 10))) {
|
||||
throw kaitai::validation_not_equal_error<std::string>(std::string("\x5F\x46\x4C\x41\x53\x48\x5F\x4D\x41\x50", 10), signature(), _io(), std::string("/seq/0"));
|
||||
}
|
||||
m_num_entries = m__io->read_u2le();
|
||||
{
|
||||
uint16_t _ = num_entries();
|
||||
if (!(_ <= 113)) {
|
||||
throw kaitai::validation_expr_error<uint16_t>(num_entries(), _io(), std::string("/seq/1"));
|
||||
}
|
||||
}
|
||||
m_reserved = m__io->read_u4le();
|
||||
m_entries = std::unique_ptr<std::vector<std::unique_ptr<flm_entry_t>>>(new std::vector<std::unique_ptr<flm_entry_t>>());
|
||||
const int l_entries = num_entries();
|
||||
for (int i = 0; i < l_entries; i++) {
|
||||
m_entries->push_back(std::move(std::unique_ptr<flm_entry_t>(new flm_entry_t(m__io, this, m__root))));
|
||||
}
|
||||
m_free_space = std::unique_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>());
|
||||
const int l_free_space = ((len_flm_store() - len_flm_store_header()) - (len_flm_entry() * num_entries()));
|
||||
for (int i = 0; i < l_free_space; i++) {
|
||||
m_free_space->push_back(std::move(m__io->read_u1()));
|
||||
}
|
||||
}
|
||||
|
||||
phoenix_flm_t::~phoenix_flm_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void phoenix_flm_t::_clean_up() {
|
||||
}
|
||||
|
||||
phoenix_flm_t::flm_entry_t::flm_entry_t(kaitai::kstream* p__io, phoenix_flm_t* p__parent, phoenix_flm_t* p__root) : kaitai::kstruct(p__io) {
|
||||
m__parent = p__parent;
|
||||
m__root = p__root;
|
||||
_read();
|
||||
}
|
||||
|
||||
void phoenix_flm_t::flm_entry_t::_read() {
|
||||
m_guid = m__io->read_bytes(16);
|
||||
m_data_type = m__io->read_u2le();
|
||||
m_entry_type = m__io->read_u2le();
|
||||
m_physical_address = m__io->read_u8le();
|
||||
m_size = m__io->read_u4le();
|
||||
m_offset = m__io->read_u4le();
|
||||
}
|
||||
|
||||
phoenix_flm_t::flm_entry_t::~flm_entry_t() {
|
||||
_clean_up();
|
||||
}
|
||||
|
||||
void phoenix_flm_t::flm_entry_t::_clean_up() {
|
||||
}
|
||||
|
||||
int32_t phoenix_flm_t::len_flm_store() {
|
||||
if (f_len_flm_store)
|
||||
return m_len_flm_store;
|
||||
m_len_flm_store = 4096;
|
||||
f_len_flm_store = true;
|
||||
return m_len_flm_store;
|
||||
}
|
||||
|
||||
int8_t phoenix_flm_t::len_flm_store_header() {
|
||||
if (f_len_flm_store_header)
|
||||
return m_len_flm_store_header;
|
||||
m_len_flm_store_header = 16;
|
||||
f_len_flm_store_header = true;
|
||||
return m_len_flm_store_header;
|
||||
}
|
||||
|
||||
int8_t phoenix_flm_t::len_flm_entry() {
|
||||
if (f_len_flm_entry)
|
||||
return m_len_flm_entry;
|
||||
m_len_flm_entry = 36;
|
||||
f_len_flm_entry = true;
|
||||
return m_len_flm_entry;
|
||||
}
|
100
common/generated/phoenix_flm.h
Normal file
100
common/generated/phoenix_flm.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
#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 phoenix_flm_t : public kaitai::kstruct {
|
||||
|
||||
public:
|
||||
class flm_entry_t;
|
||||
|
||||
phoenix_flm_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = nullptr, phoenix_flm_t* p__root = nullptr);
|
||||
|
||||
private:
|
||||
void _read();
|
||||
void _clean_up();
|
||||
|
||||
public:
|
||||
~phoenix_flm_t();
|
||||
|
||||
class flm_entry_t : public kaitai::kstruct {
|
||||
|
||||
public:
|
||||
|
||||
flm_entry_t(kaitai::kstream* p__io, phoenix_flm_t* p__parent = nullptr, phoenix_flm_t* p__root = nullptr);
|
||||
|
||||
private:
|
||||
void _read();
|
||||
void _clean_up();
|
||||
|
||||
public:
|
||||
~flm_entry_t();
|
||||
|
||||
private:
|
||||
std::string m_guid;
|
||||
uint16_t m_data_type;
|
||||
uint16_t m_entry_type;
|
||||
uint64_t m_physical_address;
|
||||
uint32_t m_size;
|
||||
uint32_t m_offset;
|
||||
phoenix_flm_t* m__root;
|
||||
phoenix_flm_t* m__parent;
|
||||
|
||||
public:
|
||||
std::string guid() const { return m_guid; }
|
||||
uint16_t data_type() const { return m_data_type; }
|
||||
uint16_t entry_type() const { return m_entry_type; }
|
||||
uint64_t physical_address() const { return m_physical_address; }
|
||||
uint32_t size() const { return m_size; }
|
||||
uint32_t offset() const { return m_offset; }
|
||||
phoenix_flm_t* _root() const { return m__root; }
|
||||
phoenix_flm_t* _parent() const { return m__parent; }
|
||||
};
|
||||
|
||||
private:
|
||||
bool f_len_flm_store;
|
||||
int32_t m_len_flm_store;
|
||||
|
||||
public:
|
||||
int32_t len_flm_store();
|
||||
|
||||
private:
|
||||
bool f_len_flm_store_header;
|
||||
int8_t m_len_flm_store_header;
|
||||
|
||||
public:
|
||||
int8_t len_flm_store_header();
|
||||
|
||||
private:
|
||||
bool f_len_flm_entry;
|
||||
int8_t m_len_flm_entry;
|
||||
|
||||
public:
|
||||
int8_t len_flm_entry();
|
||||
|
||||
private:
|
||||
std::string m_signature;
|
||||
uint16_t m_num_entries;
|
||||
uint32_t m_reserved;
|
||||
std::unique_ptr<std::vector<std::unique_ptr<flm_entry_t>>> m_entries;
|
||||
std::unique_ptr<std::vector<uint8_t>> m_free_space;
|
||||
phoenix_flm_t* m__root;
|
||||
kaitai::kstruct* m__parent;
|
||||
|
||||
public:
|
||||
std::string signature() const { return m_signature; }
|
||||
uint16_t num_entries() const { return m_num_entries; }
|
||||
uint32_t reserved() const { return m_reserved; }
|
||||
std::vector<std::unique_ptr<flm_entry_t>>* entries() const { return m_entries.get(); }
|
||||
std::vector<uint8_t>* free_space() const { return m_free_space.get(); }
|
||||
phoenix_flm_t* _root() const { return m__root; }
|
||||
kaitai::kstruct* _parent() const { return m__parent; }
|
||||
};
|
|
@ -17,7 +17,7 @@ seq:
|
|||
- id: vss_size
|
||||
type: u4
|
||||
valid:
|
||||
expr: _ > len_vss_store_header and _ < 0xFFFFFFFF
|
||||
expr: _ > len_vss_store_header.as<u4> and _ < 0xFFFFFFFF
|
||||
- id: format
|
||||
type: u1
|
||||
valid:
|
||||
|
@ -87,7 +87,7 @@ types:
|
|||
type: u4
|
||||
if: signature_first == 0xAA and is_intel_legacy
|
||||
valid:
|
||||
expr: _ >= len_intel_legacy_header + 4 + 1 # Header size + at least one UCS2 character for the name + UCS2 null terminator + at least one byte of data
|
||||
expr: _ >= len_intel_legacy_header.as<u4> + 4 + 1 # Header size + at least one UCS2 character for the name + UCS2 null terminator + at least one byte of data
|
||||
# ^^^ Intel legacy
|
||||
# Next 2 fields can be of any value for an authenticated variable due to them being a combined value of MonothonicCounter
|
||||
- id: len_name
|
||||
|
|
|
@ -26,7 +26,7 @@ seq:
|
|||
- id: vss2_size
|
||||
type: u4
|
||||
valid:
|
||||
expr: _ > len_vss2_store_header and _ < 0xFFFFFFFF
|
||||
expr: _ > len_vss2_store_header.as<u4> and _ < 0xFFFFFFFF
|
||||
- id: format
|
||||
type: u1
|
||||
valid:
|
||||
|
|
|
@ -17,7 +17,7 @@ seq:
|
|||
- id: fdc_size
|
||||
type: u4
|
||||
valid:
|
||||
expr: _ > len_fdc_store_header and _ < 0xFFFFFFFF
|
||||
expr: _ > len_fdc_store_header.as<u4> and _ < 0xFFFFFFFF
|
||||
- id: body
|
||||
size: fdc_size - len_fdc_store_header
|
||||
instances:
|
||||
|
|
54
common/ksy/phoenix_flm.ksy
Normal file
54
common/ksy/phoenix_flm.ksy
Normal file
|
@ -0,0 +1,54 @@
|
|||
meta:
|
||||
id: phoenix_flm
|
||||
title: Phoenix flash map
|
||||
application: Phoenix-based UEFI firmware
|
||||
file-extension: flm
|
||||
tags:
|
||||
- firmware
|
||||
license: CC0-1.0
|
||||
ks-version: 0.9
|
||||
endian: le
|
||||
|
||||
seq:
|
||||
- id: signature
|
||||
contents: [0x5F, 0x46, 0x4C, 0x41, 0x53, 0x48, 0x5F, 0x4D, 0x41, 0x50] # _FLASH_MAP
|
||||
- id: num_entries
|
||||
type: u2
|
||||
valid:
|
||||
expr: _ <= 113 # Needs to fit into the last 0x1000 bytes of the NVRAM volume
|
||||
- id: reserved
|
||||
type: u4
|
||||
- id: entries
|
||||
type: flm_entry
|
||||
repeat: expr
|
||||
repeat-expr: num_entries
|
||||
- id: free_space
|
||||
type: u1
|
||||
repeat: expr
|
||||
repeat-expr: len_flm_store - len_flm_store_header - len_flm_entry * num_entries
|
||||
|
||||
instances:
|
||||
len_flm_store:
|
||||
value: 0x1000
|
||||
len_flm_store_header:
|
||||
value: 16
|
||||
len_flm_entry:
|
||||
value: 36
|
||||
|
||||
types:
|
||||
flm_entry:
|
||||
seq:
|
||||
- id: guid
|
||||
size: 16
|
||||
- id: data_type
|
||||
type: u2
|
||||
- id: entry_type
|
||||
type: u2
|
||||
- id: physical_address
|
||||
type: u8
|
||||
- id: size
|
||||
type: u4
|
||||
- id: offset
|
||||
type: u4
|
||||
|
||||
|
|
@ -38,6 +38,7 @@ uefitoolcommon = static_library('uefitoolcommon',
|
|||
'generated/edk2_vss2.cpp',
|
||||
'generated/edk2_ftw.cpp',
|
||||
'generated/insyde_fdc.cpp',
|
||||
'generated/phoenix_flm.cpp',
|
||||
'generated/intel_acbp_v1.cpp',
|
||||
'generated/intel_acbp_v2.cpp',
|
||||
'generated/intel_keym_v1.cpp',
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
//
|
||||
// GUIDs mentioned in by nvram.h
|
||||
//
|
||||
extern const UByteArray ZERO_GUID // 00000000-0000-0000-0000-000000000000
|
||||
("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16);
|
||||
extern const UByteArray NVRAM_NVAR_STORE_FILE_GUID // CEF5B9A3-476D-497F-9FDC-E98143E0422C
|
||||
("\xA3\xB9\xF5\xCE\x6D\x47\x7F\x49\x9F\xDC\xE9\x81\x43\xE0\x42\x2C", 16);
|
||||
extern const UByteArray NVRAM_NVAR_EXTERNAL_DEFAULTS_FILE_GUID // 9221315B-30BB-46B5-813E-1B1BF4712BD3
|
||||
|
@ -168,6 +170,7 @@ 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");
|
||||
if (baGuid == ZERO_GUID) return UString();
|
||||
return UString("Unknown");
|
||||
}
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ extern const UByteArray NVRAM_PHOENIX_FLASH_MAP_SIGNATURE;
|
|||
typedef struct PHOENIX_FLASH_MAP_HEADER_ {
|
||||
UINT8 Signature[10]; // _FLASH_MAP signature
|
||||
UINT16 NumEntries; // Number of entries in the map
|
||||
UINT32 : 32; // Reserved field
|
||||
UINT32 Reserved; // Reserved field
|
||||
} PHOENIX_FLASH_MAP_HEADER;
|
||||
|
||||
typedef struct PHOENIX_FLASH_MAP_ENTRY_ {
|
||||
|
@ -343,9 +343,9 @@ typedef struct PHOENIX_FLASH_MAP_ENTRY_ {
|
|||
UINT32 Size;
|
||||
UINT32 Offset;
|
||||
} PHOENIX_FLASH_MAP_ENTRY;
|
||||
|
||||
#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_VOLUME 0x0000
|
||||
#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_DATA_BLOCK 0x0001
|
||||
#define NVRAM_PHOENIX_FLASH_MAP_TOTAL_SIZE 0x1000
|
||||
#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_VOLUME 0x0000
|
||||
#define NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_DATA_BLOCK 0x0001
|
||||
|
||||
extern UString flashMapGuidToUString(const EFI_GUID & guid);
|
||||
|
||||
|
@ -416,6 +416,9 @@ typedef struct PHOENIX_CMDB_HEADER_ {
|
|||
#define NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE 0x42444D43
|
||||
#define NVRAM_PHOENIX_CMDB_SIZE 0x100;
|
||||
|
||||
// Zero GUID
|
||||
extern const UByteArray ZERO_GUID;
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "generated/edk2_vss2.h"
|
||||
#include "generated/edk2_ftw.h"
|
||||
#include "generated/insyde_fdc.h"
|
||||
#include "generated/phoenix_flm.h"
|
||||
|
||||
USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
||||
{
|
||||
|
@ -44,6 +45,14 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
|||
if (nvar.isEmpty())
|
||||
return U_SUCCESS;
|
||||
|
||||
// Obtain required fields from parsing data
|
||||
UINT8 emptyByte = 0xFF;
|
||||
if (model->hasEmptyParsingData(index) == false) {
|
||||
UByteArray data = model->parsingData(index);
|
||||
const VOLUME_PARSING_DATA* pdata = (const VOLUME_PARSING_DATA*)data.constData();
|
||||
emptyByte = pdata->emptyByte;
|
||||
}
|
||||
|
||||
try {
|
||||
const UINT32 localOffset = (UINT32)model->header(index).size();
|
||||
umemstream is(nvar.constData(), nvar.size());
|
||||
|
@ -73,7 +82,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
|||
// Get info
|
||||
UString info = usprintf("Full size: %Xh (%u)", (UINT32)padding.size(), (UINT32)padding.size());
|
||||
|
||||
if ((UINT32)padding.count('\'xFF') == unparsedSize) { // Free space
|
||||
if ((UINT32)padding.count(emptyByte) == unparsedSize) { // Free space
|
||||
// Add tree item
|
||||
model->addItem(localOffset + entry->offset(), Types::FreeSpace, 0, UString("Free space"), UString(), info, UByteArray(), padding, UByteArray(), Fixed, index);
|
||||
}
|
||||
|
@ -106,7 +115,7 @@ USTATUS NvramParser::parseNvarStore(const UModelIndex & index)
|
|||
|
||||
// Set default next to predefined last value
|
||||
NVAR_ENTRY_PARSING_DATA pdata = {};
|
||||
pdata.emptyByte = 0xFF;
|
||||
pdata.emptyByte = emptyByte;
|
||||
pdata.next = 0xFFFFFF;
|
||||
pdata.isValid = TRUE;
|
||||
|
||||
|
@ -313,6 +322,9 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
for (UINT32 storeOffset = 0;
|
||||
storeOffset < volumeBodySize;
|
||||
storeOffset++) {
|
||||
UString name, text, info;
|
||||
UByteArray header, body;
|
||||
|
||||
// VSS
|
||||
try {
|
||||
if (volumeBodySize - storeOffset < sizeof(VSS_VARIABLE_STORE_HEADER)) {
|
||||
|
@ -347,11 +359,10 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
}
|
||||
|
||||
// Construct header and body
|
||||
UByteArray header = vss.left(parsed.len_vss_store_header());
|
||||
UByteArray body = vss.mid(header.size(), storeSize - header.size());
|
||||
header = vss.left(parsed.len_vss_store_header());
|
||||
body = vss.mid(header.size(), storeSize - header.size());
|
||||
|
||||
// Add info
|
||||
UString name;
|
||||
if (parsed.signature() == NVRAM_APPLE_SVS_STORE_SIGNATURE) {
|
||||
name = UString("SVS store");
|
||||
}
|
||||
|
@ -361,7 +372,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
else {
|
||||
name = UString("VSS store");
|
||||
}
|
||||
UString info = usprintf("Signature: %Xh (", parsed.signature()) + fourCC(parsed.signature()) + UString(")\n");
|
||||
info = usprintf("Signature: %Xh (", parsed.signature()) + fourCC(parsed.signature()) + UString(")\n");
|
||||
|
||||
info += usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nFormat: %02Xh\nState: %02Xh\nReserved: %02Xh\nReserved1: %04Xh",
|
||||
storeSize , storeSize,
|
||||
|
@ -379,7 +390,6 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
UINT32 vssVariableOffset = storeOffset + parsed.len_vss_store_header();
|
||||
for (const auto & variable : *parsed.body()->variables()) {
|
||||
UINT8 subtype;
|
||||
UString text;
|
||||
|
||||
// This is the terminating entry, needs special processing
|
||||
if (variable->_is_null_signature_last()) {
|
||||
|
@ -529,18 +539,17 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
// VSS2 store at current offset parsed correctly
|
||||
// Check if we need to add a padding before it
|
||||
if (!outerPadding.isEmpty()) {
|
||||
UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size());
|
||||
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
|
||||
UByteArray header = vss2.left(parsed.len_vss2_store_header());
|
||||
UByteArray body = vss2.mid(header.size(), storeSize - header.size());
|
||||
header = vss2.left(parsed.len_vss2_store_header());
|
||||
body = vss2.mid(header.size(), storeSize - header.size());
|
||||
|
||||
// Add info
|
||||
UString name = UString("VSS2 store");
|
||||
UString info;
|
||||
name = UString("VSS2 store");
|
||||
if (parsed.signature() == NVRAM_VSS2_AUTH_VAR_KEY_DATABASE_GUID_PART1) {
|
||||
info = UString("Signature: AAF32C78-947B-439A-A180-2E144EC37792\n");
|
||||
}
|
||||
|
@ -567,7 +576,6 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
UINT32 vss2VariableOffset = storeOffset + parsed.len_vss2_store_header();
|
||||
for (const auto & variable : *parsed.body()->variables()) {
|
||||
UINT8 subtype;
|
||||
UString text;
|
||||
|
||||
// This is the terminating entry, needs special processing
|
||||
if (variable->_is_null_signature_last()) {
|
||||
|
@ -662,6 +670,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
if (fdcStoreSizeOverride != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// FTW
|
||||
try {
|
||||
if (volumeBodySize - storeOffset < sizeof(EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32)) {
|
||||
|
@ -676,7 +685,6 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
UINT64 storeSize;
|
||||
UINT64 headerSize;
|
||||
UINT32 calculatedCrc;
|
||||
UByteArray header;
|
||||
if (parsed._is_null_len_write_queue_64()) {
|
||||
headerSize = parsed.len_ftw_store_header_32();
|
||||
storeSize = headerSize + parsed.len_write_queue_32();
|
||||
|
@ -711,12 +719,12 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
}
|
||||
|
||||
// Construct header and body
|
||||
UByteArray body = ftw.mid(header.size(), storeSize - header.size());
|
||||
body = ftw.mid(header.size(), storeSize - header.size());
|
||||
|
||||
// Add info
|
||||
const EFI_GUID* guid = (const EFI_GUID*)header.constData();
|
||||
UString name = UString("FTW store");
|
||||
UString info = UString("Signature: ") + guidToUString(*guid, false);
|
||||
name = UString("FTW store");
|
||||
info = UString("Signature: ") + guidToUString(*guid, false);
|
||||
info += usprintf("\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nState: %02Xh\nHeader CRC32: %08Xh",
|
||||
(UINT32)storeSize, (UINT32)storeSize,
|
||||
(UINT32)header.size(), (UINT32)header.size(),
|
||||
|
@ -733,6 +741,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
} catch (...) {
|
||||
// Parsing failed, try something else
|
||||
}
|
||||
|
||||
// Insyde FDC
|
||||
try {
|
||||
if (volumeBodySize - storeOffset < sizeof(FDC_VOLUME_HEADER)) {
|
||||
|
@ -755,12 +764,12 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
}
|
||||
|
||||
// Construct header and body
|
||||
UByteArray header = fdc.left(parsed.len_fdc_store_header());
|
||||
UByteArray body = fdc.mid(header.size(),storeSize - header.size());
|
||||
header = fdc.left(parsed.len_fdc_store_header());
|
||||
body = fdc.mid(header.size(),storeSize - header.size());
|
||||
|
||||
// Add info
|
||||
UString name = UString("FDC store");
|
||||
UString info = usprintf("Signature: _FDC\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)",
|
||||
name = UString("FDC store");
|
||||
info = usprintf("Signature: _FDC\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)",
|
||||
storeSize, storeSize,
|
||||
(UINT32)header.size(), (UINT32)header.size(),
|
||||
(UINT32)body.size(), (UINT32)body.size());
|
||||
|
@ -794,21 +803,19 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
// Apple SysF store at current offset parsed correctly
|
||||
// Check if we need to add a padding before it
|
||||
if (!outerPadding.isEmpty()) {
|
||||
UString info = usprintf("Full size: %Xh (%u)", (UINT32)outerPadding.size(), (UINT32)outerPadding.size());
|
||||
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
|
||||
UByteArray header = sysf.left(parsed.len_sysf_store_header());
|
||||
UByteArray body = sysf.mid(header.size(), storeSize - header.size());
|
||||
header = sysf.left(parsed.len_sysf_store_header());
|
||||
body = sysf.mid(header.size(), storeSize - header.size());
|
||||
|
||||
// Check store checksum
|
||||
UINT32 calculatedCrc = (UINT32)crc32(0, (const UINT8*)sysf.constData(), storeSize - sizeof(UINT32));
|
||||
|
||||
// Add info
|
||||
UString name;
|
||||
UString info;
|
||||
if (parsed.signature() == NVRAM_APPLE_SYSF_STORE_SIGNATURE) {
|
||||
name = UString("SysF store");
|
||||
info = UString("Signature: Fsys\n");
|
||||
|
@ -841,6 +848,7 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
subtype = Subtypes::NormalSysFEntry;
|
||||
name = usprintf("%s", variable->name().c_str());
|
||||
}
|
||||
|
||||
if (variable->len_name() == 3 && variable->name() == "EOF") {
|
||||
header = volumeBody.mid(sysfVariableOffset, 4);
|
||||
}
|
||||
|
@ -886,10 +894,113 @@ USTATUS NvramParser::parseNvramVolumeBody(const UModelIndex & index,const UINT32
|
|||
// Parsing failed, try something else
|
||||
}
|
||||
|
||||
// Phoenix EVSA
|
||||
// Phoenix FlashMap
|
||||
try {
|
||||
if (volumeBodySize - storeOffset < NVRAM_PHOENIX_FLASH_MAP_TOTAL_SIZE) {
|
||||
// No need to parse further, the rest of the volume is too small
|
||||
throw 0;
|
||||
}
|
||||
|
||||
UByteArray flm = volumeBody.mid(storeOffset);
|
||||
umemstream is(flm.constData(), flm.size());
|
||||
kaitai::kstream ks(&is);
|
||||
phoenix_flm_t parsed(&ks);
|
||||
UINT32 storeSize = parsed.len_flm_store();
|
||||
|
||||
// Phoenix FlashMap 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 = flm.left(parsed.len_flm_store_header());
|
||||
body = flm.mid(header.size(), storeSize - header.size());
|
||||
|
||||
// Add info
|
||||
name = UString("FlashMap");
|
||||
info = usprintf("Signature: _FLASH_MAP\nFull size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: %Xh (%u)\nEntries: %u\nReserved: %08Xh",
|
||||
storeSize, storeSize,
|
||||
(UINT32)header.size(), (UINT32)header.size(),
|
||||
(UINT32)body.size(), (UINT32)body.size(),
|
||||
parsed.num_entries(),
|
||||
parsed.reserved());
|
||||
|
||||
// Add header tree item
|
||||
UModelIndex headerIndex = model->addItem(localOffset + storeOffset, Types::FlashMapStore, 0, name, UString(), info, header, body, UByteArray(), Fixed, index);
|
||||
|
||||
// Add entries
|
||||
UINT32 entryOffset = storeOffset + parsed.len_flm_store_header();
|
||||
for (const auto & entry : *parsed.entries()) {
|
||||
UINT8 subtype;
|
||||
|
||||
if (entry->data_type() == NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_VOLUME) {
|
||||
subtype = Subtypes::VolumeFlashMapEntry;
|
||||
}
|
||||
else if (entry->data_type() == NVRAM_PHOENIX_FLASH_MAP_ENTRY_DATA_TYPE_DATA_BLOCK) {
|
||||
subtype = Subtypes::DataFlashMapEntry;
|
||||
}
|
||||
else {
|
||||
subtype = Subtypes::UnknownFlashMapEntry;
|
||||
}
|
||||
|
||||
const EFI_GUID guid = readUnaligned((const EFI_GUID*)entry->guid().c_str());
|
||||
name = guidToUString(guid);
|
||||
text = flashMapGuidToUString(guid);
|
||||
header = volumeBody.mid(entryOffset, parsed.len_flm_entry());
|
||||
|
||||
// Add info
|
||||
UINT32 entrySize = (UINT32)header.size();
|
||||
info = usprintf("Full size: %Xh (%u)\nHeader size: %Xh (%u)\nBody size: 0h (0)\nData type: %04Xh\nEntry type: %04Xh\nSize: %08Xh\nOffset: %08Xh\nPhysical address: %" PRIX64 "h",
|
||||
entrySize, entrySize,
|
||||
(UINT32)header.size(), (UINT32)header.size(),
|
||||
entry->data_type(),
|
||||
entry->entry_type(),
|
||||
entry->size(),
|
||||
entry->offset(),
|
||||
entry->physical_address());
|
||||
|
||||
// Add tree item
|
||||
model->addItem(entryOffset, Types::FlashMapEntry, subtype, name, text, info, header, UByteArray(), UByteArray(), Fixed, headerIndex);
|
||||
|
||||
entryOffset += entrySize;
|
||||
}
|
||||
|
||||
// Add free space, if needed
|
||||
UByteArray freeSpace;
|
||||
for (const auto & byte : *parsed.free_space()) {
|
||||
freeSpace += (const char)byte;
|
||||
}
|
||||
if (freeSpace.size() > 0) {
|
||||
// Add info
|
||||
info = usprintf("Full size: %Xh (%u)", (UINT32)freeSpace.size(), (UINT32)freeSpace.size());
|
||||
|
||||
// Check that remaining unparsed bytes are actually zeroes
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
storeOffset += storeSize - 1;
|
||||
previousStoreEndOffset = storeOffset + 1;
|
||||
continue;
|
||||
} catch (...) {
|
||||
// Parsing failed, try something else
|
||||
}
|
||||
|
||||
// Phoenix EVSA
|
||||
|
||||
// Phoenix CMDB
|
||||
|
||||
// Phoenix SLIC Pubkey/Marker
|
||||
|
||||
// Intel uCode
|
||||
|
||||
// Padding
|
||||
|
|
|
@ -142,6 +142,7 @@ UString itemSubtypeToUString(const UINT8 type, const UINT8 subtype)
|
|||
case Types::FlashMapEntry:
|
||||
if (subtype == Subtypes::VolumeFlashMapEntry) return UString("Volume");
|
||||
else if (subtype == Subtypes::DataFlashMapEntry) return UString("Data");
|
||||
else if (subtype == Subtypes::UnknownFlashMapEntry) return UString("Unknown");
|
||||
break;
|
||||
case Types::Microcode:
|
||||
if (subtype == Subtypes::IntelMicrocode) return UString("Intel");
|
||||
|
|
|
@ -154,6 +154,7 @@ namespace Subtypes {
|
|||
enum FlashMapEntrySubtypes {
|
||||
VolumeFlashMapEntry = 170,
|
||||
DataFlashMapEntry,
|
||||
UnknownFlashMapEntry,
|
||||
};
|
||||
|
||||
enum MicrocodeSubtypes {
|
||||
|
|
|
@ -37,6 +37,7 @@ SET(PROJECT_SOURCES
|
|||
../common/generated/edk2_vss2.cpp
|
||||
../common/generated/edk2_ftw.cpp
|
||||
../common/generated/insyde_fdc.cpp
|
||||
../common/generated/phoenix_flm.cpp
|
||||
../common/generated/intel_acbp_v1.cpp
|
||||
../common/generated/intel_acbp_v2.cpp
|
||||
../common/generated/intel_keym_v1.cpp
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue