mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-22 07:58:22 +08:00
UT NE A25.1
- added support for all Phoenix SCT stuff from NVRAM volume: Intel microcodes, CMDB block, SLIC pubkey/marker. - added support for EVSA extended variables (bigger than 0xFFFF) - better EVSA parsing (invalid data vars are shown now) - FlashMap entries now have human-readable types - various small fixes and refactorings
This commit is contained in:
parent
1100cead24
commit
c0a5cd0c0f
@ -13,30 +13,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#include "ffsfinder.h"
|
||||
|
||||
FfsFinder::FfsFinder(const TreeModel* treeModel)
|
||||
: model(treeModel)
|
||||
{
|
||||
}
|
||||
|
||||
FfsFinder::~FfsFinder()
|
||||
{
|
||||
}
|
||||
|
||||
void FfsFinder::msg(const QString & message, const QModelIndex & index)
|
||||
{
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > FfsFinder::getMessages() const
|
||||
{
|
||||
return messagesVector;
|
||||
}
|
||||
|
||||
void FfsFinder::clearMessages()
|
||||
{
|
||||
messagesVector.clear();
|
||||
}
|
||||
|
||||
STATUS FfsFinder::findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode)
|
||||
{
|
||||
if (!index.isValid())
|
||||
|
@ -28,11 +28,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
class FfsFinder
|
||||
{
|
||||
public:
|
||||
explicit FfsFinder(const TreeModel * treeModel);
|
||||
~FfsFinder();
|
||||
FfsFinder(const TreeModel * treeModel) : model(treeModel) {}
|
||||
~FfsFinder() {}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const;
|
||||
void clearMessages();
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
STATUS findHexPattern(const QModelIndex & index, const QByteArray & hexPattern, const UINT8 mode);
|
||||
STATUS findGuidPattern(const QModelIndex & index, const QByteArray & guidPattern, const UINT8 mode);
|
||||
@ -42,7 +42,9 @@ private:
|
||||
const TreeModel* model;
|
||||
std::vector<std::pair<QString, QModelIndex> > messagesVector;
|
||||
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // FFSFINDER_H
|
||||
|
@ -175,7 +175,8 @@ void UEFITool::populateUi(const QModelIndex ¤t)
|
||||
ui->menuVariableActions->setEnabled(type == Types::NvramVariableNvar || type == Types::NvramVariableVss || type == Types::NvramEntryFsys
|
||||
|| type == Types::NvramEntryEvsa || type == Types::NvramEntryFlashMap);
|
||||
ui->menuStoreActions->setEnabled(type == Types::NvramStoreVss || type == Types::NvramStoreFdc || type == Types::NvramStoreFsys
|
||||
|| type == Types::NvramStoreEvsa || type == Types::NvramStoreFtw || type == Types::NvramStoreFlashMap);
|
||||
|| type == Types::NvramStoreEvsa || type == Types::NvramStoreFtw || type == Types::NvramStoreFlashMap || type == Types::NvramStoreCmdb
|
||||
|| type == Types::Microcode || type == Types::SlicPubkey || type == Types::SlicMarker);
|
||||
|
||||
// Enable actions
|
||||
ui->actionExtract->setDisabled(model->hasEmptyHeader(current) && model->hasEmptyBody(current));
|
||||
@ -995,6 +996,10 @@ void UEFITool::contextMenuEvent(QContextMenuEvent* event)
|
||||
case Types::NvramStoreEvsa:
|
||||
case Types::NvramStoreFtw:
|
||||
case Types::NvramStoreFlashMap:
|
||||
case Types::NvramStoreCmdb:
|
||||
case Types::Microcode:
|
||||
case Types::SlicPubkey:
|
||||
case Types::SlicMarker:
|
||||
ui->menuStoreActions->exec(event->globalPos());
|
||||
break;
|
||||
}
|
||||
|
@ -12,30 +12,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
#include "ffsbuilder.h"
|
||||
|
||||
FfsBuilder::FfsBuilder(const TreeModel* treeModel)
|
||||
: model(treeModel)
|
||||
{
|
||||
}
|
||||
|
||||
FfsBuilder::~FfsBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
void FfsBuilder::msg(const QString & message, const QModelIndex & index)
|
||||
{
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > FfsBuilder::getMessages() const
|
||||
{
|
||||
return messagesVector;
|
||||
}
|
||||
|
||||
void FfsBuilder::clearMessages()
|
||||
{
|
||||
messagesVector.clear();
|
||||
}
|
||||
|
||||
STATUS FfsBuilder::erase(const QModelIndex & index, QByteArray & erased)
|
||||
{
|
||||
// Sanity check
|
||||
|
@ -30,18 +30,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
class FfsBuilder
|
||||
{
|
||||
public:
|
||||
explicit FfsBuilder(const TreeModel * treeModel);
|
||||
~FfsBuilder();
|
||||
FfsBuilder(const TreeModel * treeModel) : model(treeModel) {}
|
||||
~FfsBuilder() {}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const;
|
||||
void clearMessages();
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
STATUS build(const QModelIndex & root, QByteArray & image);
|
||||
|
||||
private:
|
||||
const TreeModel* model;
|
||||
std::vector<std::pair<QString, QModelIndex> > messagesVector;
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
}
|
||||
|
||||
STATUS buildCapsule(const QModelIndex & index, QByteArray & capsule);
|
||||
STATUS buildIntelImage(const QModelIndex & index, QByteArray & intelImage);
|
||||
|
@ -24,30 +24,6 @@ struct REGION_INFO {
|
||||
friend bool operator< (const REGION_INFO & lhs, const REGION_INFO & rhs){ return lhs.offset < rhs.offset; }
|
||||
};
|
||||
|
||||
FfsParser::FfsParser(TreeModel* treeModel)
|
||||
: model(treeModel), capsuleOffsetFixup(0)
|
||||
{
|
||||
}
|
||||
|
||||
FfsParser::~FfsParser()
|
||||
{
|
||||
}
|
||||
|
||||
void FfsParser::msg(const QString & message, const QModelIndex & index)
|
||||
{
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > FfsParser::getMessages() const
|
||||
{
|
||||
return messagesVector;
|
||||
}
|
||||
|
||||
void FfsParser::clearMessages()
|
||||
{
|
||||
messagesVector.clear();
|
||||
}
|
||||
|
||||
// Firmware image parsing functions
|
||||
STATUS FfsParser::parse(const QByteArray & buffer)
|
||||
{
|
||||
@ -3370,6 +3346,10 @@ STATUS FfsParser::parseStoreArea(const QByteArray & data, const QModelIndex & in
|
||||
parseFlashMapBody(current);
|
||||
break;
|
||||
case Types::NvramStoreFtw:
|
||||
case Types::NvramStoreCmdb:
|
||||
case Types::Microcode:
|
||||
case Types::SlicPubkey:
|
||||
case Types::SlicMarker:
|
||||
case Types::Padding:
|
||||
// No parsing required
|
||||
break;
|
||||
@ -3423,8 +3403,9 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == NVRAM_EVSA_STORE_SIGNATURE) { //EVSA signature found
|
||||
if (offset < 4)
|
||||
if (offset < sizeof(UINT32))
|
||||
continue;
|
||||
|
||||
const EVSA_STORE_ENTRY* evsaHeader = (const EVSA_STORE_ENTRY*)(currentPos - 1);
|
||||
if (evsaHeader->Header.Type != NVRAM_EVSA_ENTRY_TYPE_STORE) {
|
||||
msg(QObject::tr("findNextStore: EVSA store candidate at offset %1h skipped, has invalid type %2h").hexarg(parentOffset + offset - 4).hexarg2(evsaHeader->Header.Type, 2), index);
|
||||
@ -3435,7 +3416,7 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da
|
||||
continue;
|
||||
}
|
||||
// All checks passed, store found
|
||||
offset -= 4;
|
||||
offset -= sizeof(UINT32);
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == NVRAM_MAIN_STORE_VOLUME_GUID_DATA1 || *currentPos == EDKII_WORKING_BLOCK_SIGNATURE_GUID_DATA1) { //Possible FTW block signature found
|
||||
@ -3460,7 +3441,7 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da
|
||||
}
|
||||
else // Unknown header
|
||||
continue;
|
||||
|
||||
|
||||
// All checks passed, store found
|
||||
break;
|
||||
}
|
||||
@ -3472,6 +3453,68 @@ STATUS FfsParser::findNextStore(const QModelIndex & index, const QByteArray & da
|
||||
// All checks passed, store found
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store
|
||||
const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)currentPos;
|
||||
|
||||
// Check size
|
||||
if (cmdbHeader->HeaderSize != sizeof(PHOENIX_CMDB_HEADER))
|
||||
continue;
|
||||
|
||||
// All checks passed, store found
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == INTEL_MICROCODE_HEADER_VERSION) {// Intel microcode
|
||||
if (!INTEL_MICROCODE_HEADER_SIZES_VALID(currentPos)) // Check header sizes
|
||||
continue;
|
||||
|
||||
// Check reserved bytes
|
||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)currentPos;
|
||||
bool reservedBytesValid = true;
|
||||
for (int 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, store found
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey
|
||||
if (offset < 4 * sizeof(UINT32))
|
||||
continue;
|
||||
|
||||
const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)(currentPos - 4);
|
||||
// Check type
|
||||
if (pubkeyHeader->Type != OEM_ACTIVATION_PUBKEY_TYPE)
|
||||
continue;
|
||||
|
||||
// All checks passed, store found
|
||||
offset -= 4 * sizeof(UINT32);
|
||||
break;
|
||||
}
|
||||
else if (*currentPos == OEM_ACTIVATION_MARKER_WINDOWS_FLAG_PART1) { // SLIC marker
|
||||
if (offset >= dataSize - sizeof(UINT64) ||
|
||||
*(const UINT64*)currentPos != OEM_ACTIVATION_MARKER_WINDOWS_FLAG ||
|
||||
offset < 26) // Check full windows flag and structure size
|
||||
continue;
|
||||
|
||||
const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)(data.constData() + offset - 26);
|
||||
// Check reserved bytes
|
||||
bool reservedBytesValid = true;
|
||||
for (int i = 0; i < sizeof(markerHeader->Reserved); i++)
|
||||
if (markerHeader->Reserved[i] != OEM_ACTIVATION_MARKER_RESERVED_BYTE) {
|
||||
reservedBytesValid = false;
|
||||
break;
|
||||
}
|
||||
if (!reservedBytesValid)
|
||||
continue;
|
||||
|
||||
// All checks passed, store found
|
||||
offset -= 26;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// No more stores found
|
||||
if (offset >= dataSize - sizeof(UINT32))
|
||||
@ -3515,14 +3558,26 @@ STATUS FfsParser::getStoreSize(const QByteArray & data, const UINT32 storeOffset
|
||||
const PHOENIX_FLASH_MAP_HEADER* flashMapHeader = (const PHOENIX_FLASH_MAP_HEADER*)signature;
|
||||
storeSize = sizeof(PHOENIX_FLASH_MAP_HEADER) + sizeof(PHOENIX_FLASH_MAP_ENTRY) * flashMapHeader->NumEntries;
|
||||
}
|
||||
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store
|
||||
storeSize = NVRAM_PHOENIX_CMDB_SIZE; // It's a predefined max size, no need to calculate
|
||||
}
|
||||
else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey
|
||||
const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)signature;
|
||||
storeSize = pubkeyHeader->Size;
|
||||
}
|
||||
else if (*(const UINT64*)(data.constData() + storeOffset + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) { // SLIC marker
|
||||
const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)signature;
|
||||
storeSize = markerHeader->Size;
|
||||
}
|
||||
else if (*signature == INTEL_MICROCODE_HEADER_VERSION) { // Intel microcode, must be checked after SLIC marker because of the same *signature values
|
||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)signature;
|
||||
storeSize = ucodeHeader->TotalSize;
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index)
|
||||
{
|
||||
// Parse VSS volume like raw area
|
||||
//Seen for now: $VSS, $SVS, Fsys, FTW block, _FDC, EVSA, _FLASH_MAP and paddings
|
||||
|
||||
const UINT32 dataSize = (UINT32)store.size();
|
||||
const UINT32* signature = (const UINT32*)store.constData();
|
||||
if (dataSize < sizeof(UINT32)) {
|
||||
@ -3825,7 +3880,7 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
QByteArray body = store.mid(sizeof(PHOENIX_FLASH_MAP_HEADER), flashMapSize - sizeof(PHOENIX_FLASH_MAP_HEADER));
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("Phoenix SCT FlashMap");
|
||||
QString name = QObject::tr("Phoenix SCT flash map");
|
||||
QString info = QObject::tr("Signature: _FLASH_MAP\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)\nNumber of entries: %7")
|
||||
.hexarg(flashMapSize).arg(flashMapSize)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
@ -3838,6 +3893,168 @@ STATUS FfsParser::parseStoreHeader(const QByteArray & store, const UINT32 parent
|
||||
// Add tree item
|
||||
index = model->addItem(Types::NvramStoreFlashMap, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*signature == NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE) { // Phoenix SCT CMDB store
|
||||
if (dataSize < sizeof(PHOENIX_CMDB_HEADER)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for CMDB store header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Check store size
|
||||
UINT32 cmdbSize = NVRAM_PHOENIX_CMDB_SIZE;
|
||||
if (dataSize < cmdbSize) {
|
||||
msg(QObject::tr("parseStoreHeader: CMDB store size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg(cmdbSize).arg(cmdbSize)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get CMBD store header
|
||||
const PHOENIX_CMDB_HEADER* cmdbHeader = (const PHOENIX_CMDB_HEADER*)signature;
|
||||
|
||||
// Get parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||
|
||||
// Construct header and body
|
||||
QByteArray header = store.left(cmdbHeader->TotalSize);
|
||||
QByteArray body = store.mid(cmdbHeader->TotalSize, cmdbSize - cmdbHeader->TotalSize);
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("CMDB store");
|
||||
QString info = QObject::tr("Signature: CMDB\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)")
|
||||
.hexarg(cmdbSize).arg(cmdbSize)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg(body.size()).arg(body.size());
|
||||
|
||||
// Add correct offset
|
||||
pdata.offset = parentOffset;
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(Types::NvramStoreCmdb, 0, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*(signature + 4) == OEM_ACTIVATION_PUBKEY_MAGIC) { // SLIC pubkey
|
||||
if (dataSize < sizeof(OEM_ACTIVATION_PUBKEY)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for SLIC pubkey header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get SLIC pubkey header
|
||||
const OEM_ACTIVATION_PUBKEY* pubkeyHeader = (const OEM_ACTIVATION_PUBKEY*)signature;
|
||||
|
||||
// Check store size
|
||||
if (dataSize < pubkeyHeader->Size) {
|
||||
msg(QObject::tr("parseStoreHeader: SLIC pubkey size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg(pubkeyHeader->Size).arg(pubkeyHeader->Size)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||
|
||||
// Construct header and body
|
||||
QByteArray header = store.left(sizeof(OEM_ACTIVATION_PUBKEY));
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("SLIC pubkey");
|
||||
QString info = QObject::tr("Type: 0h\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: 0h (0)\n"
|
||||
"Key type :%5h\nVersion: %6h\nAlgorithm: %7h\nMagic: RSA1\nBit length: %8h\nExponent:%9h")
|
||||
.hexarg(pubkeyHeader->Size).arg(pubkeyHeader->Size)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg2(pubkeyHeader->KeyType, 2)
|
||||
.hexarg2(pubkeyHeader->Version, 2)
|
||||
.hexarg2(pubkeyHeader->Algorithm, 8)
|
||||
.hexarg2(pubkeyHeader->BitLength, 8)
|
||||
.hexarg2(pubkeyHeader->Exponent, 8);
|
||||
|
||||
// Add correct offset
|
||||
pdata.offset = parentOffset;
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(Types::SlicPubkey, 0, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*(const UINT64*)(store.constData() + 26) == OEM_ACTIVATION_MARKER_WINDOWS_FLAG) { // SLIC marker
|
||||
if (dataSize < sizeof(OEM_ACTIVATION_MARKER)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for SLIC marker header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get SLIC marker header
|
||||
const OEM_ACTIVATION_MARKER* markerHeader = (const OEM_ACTIVATION_MARKER*)signature;
|
||||
|
||||
// Check store size
|
||||
if (dataSize < markerHeader->Size) {
|
||||
msg(QObject::tr("parseStoreHeader: SLIC marker size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg(markerHeader->Size).arg(markerHeader->Size)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||
|
||||
// Construct header and body
|
||||
QByteArray header = store.left(sizeof(OEM_ACTIVATION_MARKER));
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("SLIC marker");
|
||||
QString info = QObject::tr("Type: 1h\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: 0h (0)\n"
|
||||
"Version :%5h\nOEM ID: %6\nOEM table ID: %7\nWindows flag: WINDOWS\nSLIC version: %8h")
|
||||
.hexarg(markerHeader->Size).arg(markerHeader->Size)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg2(markerHeader->Version, 8)
|
||||
.arg(QLatin1String((const char*)&(markerHeader->OemId), sizeof(markerHeader->OemId)))
|
||||
.arg(QLatin1String((const char*)&(markerHeader->OemTableId), sizeof(markerHeader->OemTableId)))
|
||||
.hexarg2(markerHeader->SlicVersion, 8);
|
||||
|
||||
// Add correct offset
|
||||
pdata.offset = parentOffset;
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(Types::SlicMarker, 0, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
else if (*signature == INTEL_MICROCODE_HEADER_VERSION) { // Intel microcode, , must be checked after SLIC marker because of the same *signature values
|
||||
if (dataSize < sizeof(INTEL_MICROCODE_HEADER)) {
|
||||
msg(QObject::tr("parseStoreHeader: volume body is too small even for Intel microcode header"), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get Intel microcode header
|
||||
const INTEL_MICROCODE_HEADER* ucodeHeader = (const INTEL_MICROCODE_HEADER*)signature;
|
||||
|
||||
// Check store size
|
||||
if (dataSize < ucodeHeader->TotalSize) {
|
||||
msg(QObject::tr("parseStoreHeader: Intel microcode size %1h (%2) is greater than volume body size %3h (%4)")
|
||||
.hexarg(ucodeHeader->TotalSize).arg(ucodeHeader->TotalSize)
|
||||
.hexarg(dataSize).arg(dataSize), parent);
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// Get parsing data
|
||||
PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
|
||||
|
||||
// Construct header and body
|
||||
QByteArray header = store.left(sizeof(INTEL_MICROCODE_HEADER));
|
||||
QByteArray body = store.mid(sizeof(INTEL_MICROCODE_HEADER), ucodeHeader->DataSize);
|
||||
|
||||
// Add info
|
||||
QString name = QObject::tr("Intel microcode");
|
||||
QString info = QObject::tr("Revision: 1h\nFull size: %1h (%2)\nHeader size: %3h (%4)\nBody size: %5h (%6)\n"
|
||||
"Date: %7\nCPU signature: %8h\nChecksum: %9h\nLoader revision: %10h\nCPU flags: %11h")
|
||||
.hexarg(ucodeHeader->TotalSize).arg(ucodeHeader->TotalSize)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg(body.size()).arg(body.size())
|
||||
.hexarg2(ucodeHeader->Date, 8)
|
||||
.hexarg2(ucodeHeader->CpuSignature, 8)
|
||||
.hexarg2(ucodeHeader->Checksum, 8)
|
||||
.hexarg2(ucodeHeader->LoaderRevision, 8)
|
||||
.hexarg2(ucodeHeader->CpuFlags, 8);
|
||||
|
||||
// Add correct offset
|
||||
pdata.offset = parentOffset;
|
||||
|
||||
// Add tree item
|
||||
index = model->addItem(Types::Microcode, Subtypes::IntelMicrocode, name, QString(), info, header, body, TRUE, parsingDataToQByteArray(pdata), parent);
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
@ -4187,20 +4404,29 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
||||
// Check variable size
|
||||
variableSize = sizeof(EVSA_ENTRY_HEADER);
|
||||
if (unparsedSize < variableSize || unparsedSize < entryHeader->Size) {
|
||||
// Last variable is bad, add the rest as padding and return
|
||||
QByteArray body = data.mid(offset);
|
||||
QString info = QObject::tr("Full size: %1h (%2)")
|
||||
.hexarg(body.size()).arg(body.size());
|
||||
|
||||
// Check type
|
||||
QString name = QObject::tr("Free space");
|
||||
UINT8 type = Types::FreeSpace;
|
||||
UINT8 subtype = 0;
|
||||
if (getPaddingType(body) == Subtypes::DataPadding) {
|
||||
name = QObject::tr("Padding");
|
||||
type = Types::Padding;
|
||||
subtype = Subtypes::DataPadding;
|
||||
}
|
||||
|
||||
// Add correct offset to parsing data
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Add free space tree item
|
||||
model->addItem(Types::Padding, getPaddingType(body), QObject::tr("Padding"), QString(), info, QByteArray(), body, FALSE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
QModelIndex itemIndex = model->addItem(type, subtype, name, QString(), info, QByteArray(), body, FALSE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
// Show message
|
||||
if (unparsedSize < entryHeader->Size)
|
||||
msg(QObject::tr("parseEvsaStoreBody: next variable appears too big, added as padding"), index);
|
||||
if (type == Types::Padding)
|
||||
msg(QObject::tr("parseEvsaStoreBody: variable parsing failed, rest of unparsed store added as padding"), itemIndex);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -4251,15 +4477,25 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
||||
// Data entry
|
||||
else if (entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_DATA1 ||
|
||||
entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_DATA2 ||
|
||||
entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_DATA3) {
|
||||
entryHeader->Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) {
|
||||
const EVSA_DATA_ENTRY* dataHeader = (const EVSA_DATA_ENTRY*)entryHeader;
|
||||
header = data.mid(offset, sizeof(EVSA_DATA_ENTRY));
|
||||
body = data.mid(offset + sizeof(EVSA_DATA_ENTRY), dataHeader->Header.Size - sizeof(EVSA_DATA_ENTRY));
|
||||
// Check for extended header
|
||||
UINT32 headerSize = sizeof(EVSA_DATA_ENTRY);
|
||||
UINT32 dataSize = dataHeader->Header.Size - sizeof(EVSA_DATA_ENTRY);
|
||||
if (dataHeader->Attributes & NVRAM_EVSA_DATA_ATTRIBUTE_EXTENDED_HEADER) {
|
||||
const EVSA_DATA_ENTRY_EXTENDED* dataHeaderExtended = (const EVSA_DATA_ENTRY_EXTENDED*)entryHeader;
|
||||
headerSize = sizeof(EVSA_DATA_ENTRY_EXTENDED);
|
||||
dataSize = dataHeaderExtended->DataSize;
|
||||
variableSize = headerSize + dataSize;
|
||||
}
|
||||
|
||||
header = data.mid(offset, headerSize);
|
||||
body = data.mid(offset + headerSize, dataSize);
|
||||
name = QObject::tr("Data");
|
||||
info = QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8\nVarId: %9h\nGuidId: %10h\nAttributes: %11h")
|
||||
.hexarg(variableSize).arg(variableSize)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg(body.size()).arg(body.size())
|
||||
.hexarg(headerSize).arg(headerSize)
|
||||
.hexarg(dataSize).arg(dataSize)
|
||||
.hexarg2(dataHeader->Header.Type, 2)
|
||||
.arg(dataHeader->Header.Checksum == calculated ?
|
||||
QObject::tr("%1h, valid").hexarg2(calculated, 2) :
|
||||
@ -4269,20 +4505,32 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
||||
.hexarg2(dataHeader->Attributes, 8);
|
||||
subtype = Subtypes::DataEvsaEntry;
|
||||
}
|
||||
// Unknown entry
|
||||
// Unknown entry or free space
|
||||
else {
|
||||
header = data.mid(offset, sizeof(EVSA_ENTRY_HEADER));
|
||||
body = data.mid(offset + sizeof(EVSA_ENTRY_HEADER), entryHeader->Size - sizeof(EVSA_ENTRY_HEADER));
|
||||
name = QObject::tr("Unknown");
|
||||
info = QObject::tr("Full size: %1h (%2)\nHeader size %3h (%4)\nBody size: %5h (%6)\nType: %7h\nChecksum: %8")
|
||||
.hexarg(variableSize).arg(variableSize)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg(body.size()).arg(body.size())
|
||||
.hexarg2(entryHeader->Type, 2)
|
||||
.arg(entryHeader->Checksum == calculated ?
|
||||
QObject::tr("%1h, valid").hexarg2(calculated, 2) :
|
||||
QObject::tr("%1h, invalid, should be %2h").hexarg2(entryHeader->Checksum, 2).hexarg2(calculated, 2));
|
||||
subtype = Subtypes::UnknownEvsaEntry;
|
||||
QByteArray body = data.mid(offset);
|
||||
QString info = QObject::tr("Full size: %1h (%2)")
|
||||
.hexarg(body.size()).arg(body.size());
|
||||
|
||||
// Check type
|
||||
QString name = QObject::tr("Free space");
|
||||
UINT8 type = Types::FreeSpace;
|
||||
UINT8 subtype = 0;
|
||||
if (getPaddingType(body) == Subtypes::DataPadding) {
|
||||
name = QObject::tr("Padding");
|
||||
type = Types::Padding;
|
||||
subtype = Subtypes::DataPadding;
|
||||
}
|
||||
|
||||
// Add correct offset to parsing data
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Add free space tree item
|
||||
QModelIndex itemIndex = model->addItem(type, subtype, name, QString(), info, QByteArray(), body, FALSE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
// Show message
|
||||
if (type == Types::Padding)
|
||||
msg(QObject::tr("parseEvsaStoreBody: unknown variable of type %1h found at offset %2h, the rest of unparsed store added as padding").hexarg2(entryHeader->Type, 2).hexarg(offset), itemIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Add correct offset to parsing data
|
||||
@ -4326,7 +4574,13 @@ STATUS FfsParser::parseEvsaStoreBody(const QModelIndex & index)
|
||||
msg(QObject::tr("parseEvsaStoreBody: data variable with invalid VarId"), current);
|
||||
}
|
||||
else { // Variable is OK, rename it
|
||||
model->setName(current, guid);
|
||||
if (dataHeader->Header.Type == NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID) {
|
||||
model->setSubtype(current, Subtypes::InvalidEvsaEntry);
|
||||
model->setName(current, QObject::tr("Invalid"));
|
||||
}
|
||||
else {
|
||||
model->setName(current, guid);
|
||||
}
|
||||
model->setText(current, name);
|
||||
}
|
||||
}
|
||||
@ -4381,10 +4635,10 @@ STATUS FfsParser::parseFlashMapBody(const QModelIndex & index)
|
||||
QByteArray header = data.mid(offset, sizeof(PHOENIX_FLASH_MAP_ENTRY));
|
||||
|
||||
// Add info
|
||||
QString info = QObject::tr("Entry GUID: %1\nFull size: 24h (36)\nHeader size %2h (%3)\nBody size: 0h (0)\nType %4h\nMemory address: %5h\nSize: %6h\nOffset: %7h")
|
||||
QString info = QObject::tr("Entry GUID: %1\nFull size: 24h (36)\nHeader size: 24h (36)\nBody size: 0h (0)\nEntry type: %2h\nData type: %3h\nMemory address: %4h\nSize: %5h\nOffset: %6h")
|
||||
.arg(name)
|
||||
.hexarg(header.size()).arg(header.size())
|
||||
.hexarg2(entryHeader->Type, 8)
|
||||
.hexarg2(entryHeader->EntryType, 4)
|
||||
.hexarg2(entryHeader->DataType, 4)
|
||||
.hexarg2(entryHeader->PhysicalAddress, 8)
|
||||
.hexarg2(entryHeader->Size, 8)
|
||||
.hexarg2(entryHeader->Offset, 8);
|
||||
@ -4392,8 +4646,19 @@ STATUS FfsParser::parseFlashMapBody(const QModelIndex & index)
|
||||
// Add correct offset to parsing data
|
||||
pdata.offset = parentOffset + offset;
|
||||
|
||||
// Determine subtype
|
||||
UINT8 subtype = 0;
|
||||
switch (entryHeader->DataType) {
|
||||
case NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_VOLUME:
|
||||
subtype = Subtypes::VolumeFlashMapEntry;
|
||||
break;
|
||||
case NVRAM_PHOENIX_FLASH_MAP_ENTRY_TYPE_DATA_BLOCK:
|
||||
subtype = Subtypes::DataBlockFlashMapEntry;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add tree item
|
||||
model->addItem(Types::NvramEntryFlashMap, 0, name, QString(), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), index);
|
||||
model->addItem(Types::NvramEntryFlashMap, subtype, name, flashMapGuidToQString(entryHeader->Guid), info, header, QByteArray(), TRUE, parsingDataToQByteArray(pdata), index);
|
||||
|
||||
// Move to next variable
|
||||
offset += sizeof(PHOENIX_FLASH_MAP_ENTRY);
|
||||
|
@ -39,13 +39,13 @@ class FfsParser
|
||||
{
|
||||
public:
|
||||
// Default constructor and destructor
|
||||
FfsParser(TreeModel* treeModel);
|
||||
~FfsParser();
|
||||
FfsParser(TreeModel* treeModel) : model(treeModel), capsuleOffsetFixup(0) {}
|
||||
~FfsParser() {}
|
||||
|
||||
// Returns messages
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const;
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; }
|
||||
// Clears messages
|
||||
void clearMessages();
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
// Firmware image parsing
|
||||
STATUS parse(const QByteArray &buffer);
|
||||
@ -119,7 +119,9 @@ private:
|
||||
STATUS parseFlashMapBody(const QModelIndex & index);
|
||||
|
||||
// Message helper
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
};
|
||||
};
|
||||
|
||||
#endif // FFSPARSER_H
|
||||
|
@ -61,6 +61,10 @@ typedef struct INTEL_MICROCODE_HEADER_ {
|
||||
UINT8 Reserved[12];
|
||||
} INTEL_MICROCODE_HEADER;
|
||||
|
||||
#define INTEL_MICROCODE_HEADER_VERSION 0x00000001
|
||||
#define INTEL_MICROCODE_HEADER_RESERVED_BYTE 0x00
|
||||
#define INTEL_MICROCODE_HEADER_SIZES_VALID(ptr) (((INTEL_MICROCODE_HEADER*)ptr)->TotalSize - ((INTEL_MICROCODE_HEADER*)ptr)->DataSize == sizeof(INTEL_MICROCODE_HEADER))
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // FIT_H
|
||||
|
@ -11,31 +11,6 @@ WITHWARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
*/
|
||||
#include "fitparser.h"
|
||||
|
||||
|
||||
FitParser::FitParser(TreeModel* treeModel)
|
||||
: model(treeModel)
|
||||
{
|
||||
}
|
||||
|
||||
FitParser::~FitParser()
|
||||
{
|
||||
}
|
||||
|
||||
void FitParser::msg(const QString & message, const QModelIndex & index)
|
||||
{
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
}
|
||||
|
||||
std::vector<std::pair<QString, QModelIndex> > FitParser::getMessages() const
|
||||
{
|
||||
return messagesVector;
|
||||
}
|
||||
|
||||
void FitParser::clearMessages()
|
||||
{
|
||||
messagesVector.clear();
|
||||
}
|
||||
|
||||
STATUS FitParser::parse(const QModelIndex & index, const QModelIndex & lastVtfIndex)
|
||||
{
|
||||
// Check sanity
|
||||
|
@ -32,13 +32,13 @@ class FitParser
|
||||
{
|
||||
public:
|
||||
// Default constructor and destructor
|
||||
FitParser(TreeModel* treeModel);
|
||||
~FitParser();
|
||||
FitParser(TreeModel* treeModel) : model(treeModel) {}
|
||||
~FitParser() {}
|
||||
|
||||
// Returns messages
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const;
|
||||
std::vector<std::pair<QString, QModelIndex> > getMessages() const { return messagesVector; };
|
||||
// Clears messages
|
||||
void clearMessages();
|
||||
void clearMessages() { messagesVector.clear(); }
|
||||
|
||||
STATUS parse(const QModelIndex & index, const QModelIndex & lastVtf);
|
||||
std::vector<std::vector<QString> > getFitTable() const { return fitTable; }
|
||||
@ -53,7 +53,9 @@ private:
|
||||
QString fitEntryTypeToQString(UINT8 type);
|
||||
|
||||
// Message helper
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex());
|
||||
void msg(const QString & message, const QModelIndex &index = QModelIndex()) {
|
||||
messagesVector.push_back(std::pair<QString, QModelIndex>(message, index));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // FITPARSER_H
|
||||
|
@ -52,3 +52,30 @@ QString efiTimeToQString(const EFI_TIME & time)
|
||||
.arg(time.Second, 2, 10, QLatin1Char('0'))
|
||||
.arg(time.Nanosecond);
|
||||
}
|
||||
|
||||
QString flashMapGuidToQString(const EFI_GUID & guid)
|
||||
{
|
||||
const QByteArray baGuid((const char*)&guid, sizeof(EFI_GUID));
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER)
|
||||
return QObject::tr("Volume header");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID)
|
||||
return QObject::tr("Microcodes");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID)
|
||||
return QObject::tr("CMDB");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID)
|
||||
return QObject::tr("SLIC pubkey");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID || baGuid == NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID)
|
||||
return QObject::tr("SLIC marker");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID ||
|
||||
baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID ||
|
||||
baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA3_GUID ||
|
||||
baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA4_GUID ||
|
||||
baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA5_GUID ||
|
||||
baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID ||
|
||||
baGuid == NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID)
|
||||
return QObject::tr("EVSA store");
|
||||
if (baGuid == NVRAM_PHOENIX_FLASH_MAP_SELF_GUID)
|
||||
return QObject::tr("Flash map");
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
153
common/nvram.h
153
common/nvram.h
@ -19,8 +19,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <QString>
|
||||
#include "basetypes.h"
|
||||
|
||||
// Make sure we use right packing rules
|
||||
#pragma pack(push, 1)
|
||||
|
||||
//
|
||||
// NVAR store
|
||||
// NVAR store and variables
|
||||
//
|
||||
|
||||
// CEF5B9A3-476D-497F-9FDC-E98143E0422C
|
||||
@ -35,9 +38,6 @@ extern QString nvarAttributesToQString(const UINT8 attributes);
|
||||
|
||||
extern QString efiTimeToQString(const EFI_TIME & time);
|
||||
|
||||
// Make sure we use right packing rules
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// Variable header
|
||||
typedef struct NVAR_VARIABLE_HEADER_ {
|
||||
UINT32 Signature; // NVAR
|
||||
@ -67,7 +67,7 @@ typedef struct NVAR_VARIABLE_HEADER_ {
|
||||
|
||||
|
||||
//
|
||||
// TianoCore VSS and it's variations
|
||||
// TianoCore VSS store and variables
|
||||
//
|
||||
|
||||
// FFF12B8D-7696-4C8B-A985-2747075B4F50
|
||||
@ -158,9 +158,10 @@ typedef struct VSS_AUTH_VARIABLE_HEADER_ {
|
||||
#define NVRAM_VSS_VARIABLE_APPEND_WRITE 0x00000040
|
||||
#define NVRAM_VSS_VARIABLE_APPLE_DATA_CHECKSUM 0x80000000
|
||||
|
||||
// FDC region can be found in Insyde VSS volumes
|
||||
// It has another VSS volume inside
|
||||
// _FDC header structure
|
||||
//
|
||||
// FDC region
|
||||
//
|
||||
|
||||
#define NVRAM_FDC_VOLUME_SIGNATURE 0x4344465F
|
||||
|
||||
typedef struct FDC_VOLUME_HEADER_ {
|
||||
@ -171,8 +172,9 @@ typedef struct FDC_VOLUME_HEADER_ {
|
||||
//VSS_VARIABLE_STORE_HEADER VssHeader;
|
||||
} FDC_VOLUME_HEADER;
|
||||
|
||||
//
|
||||
// FTW block
|
||||
// EFI Fault tolerant working block header
|
||||
//
|
||||
#define EFI_FAULT_TOLERANT_WORKING_BLOCK_VALID 0x1
|
||||
#define EFI_FAULT_TOLERANT_WORKING_BLOCK_INVALID 0x2
|
||||
|
||||
@ -202,7 +204,7 @@ typedef struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64_ {
|
||||
} EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64;
|
||||
|
||||
//
|
||||
// Apple Fsys
|
||||
// Apple Fsys store
|
||||
//
|
||||
|
||||
typedef struct APPLE_FSYS_STORE_HEADER_ {
|
||||
@ -221,7 +223,7 @@ typedef struct APPLE_FSYS_STORE_HEADER_ {
|
||||
// Has CRC32 of the whole store without checksum field at the end
|
||||
|
||||
//
|
||||
// EVSA
|
||||
// EVSA store and variables
|
||||
//
|
||||
|
||||
#define NVRAM_EVSA_STORE_SIGNATURE 0x41535645
|
||||
@ -233,7 +235,7 @@ typedef struct APPLE_FSYS_STORE_HEADER_ {
|
||||
#define NVRAM_EVSA_ENTRY_TYPE_NAME2 0xE2
|
||||
#define NVRAM_EVSA_ENTRY_TYPE_DATA1 0xEF
|
||||
#define NVRAM_EVSA_ENTRY_TYPE_DATA2 0xE3
|
||||
#define NVRAM_EVSA_ENTRY_TYPE_DATA3 0x83
|
||||
#define NVRAM_EVSA_ENTRY_TYPE_DATA_INVALID 0x83
|
||||
|
||||
typedef struct EVSA_ENTRY_HEADER_ {
|
||||
UINT8 Type;
|
||||
@ -269,6 +271,16 @@ typedef struct EVSA_DATA_ENTRY_ {
|
||||
//UINT8 Data[];
|
||||
} EVSA_DATA_ENTRY;
|
||||
|
||||
#define NVRAM_EVSA_DATA_ATTRIBUTE_EXTENDED_HEADER 0x10000000
|
||||
|
||||
typedef struct EVSA_DATA_ENTRY_EXTENDED {
|
||||
EVSA_ENTRY_HEADER Header;
|
||||
UINT16 GuidId;
|
||||
UINT16 VarId;
|
||||
UINT32 Attributes;
|
||||
UINT32 DataSize;
|
||||
//UINT8 Data[];
|
||||
} EVSA_DATA_ENTRY_EXTENDED;
|
||||
|
||||
//
|
||||
// Phoenix SCT Flash Map
|
||||
@ -289,15 +301,130 @@ typedef struct PHOENIX_FLASH_MAP_HEADER_ {
|
||||
|
||||
typedef struct PHOENIX_FLASH_MAP_ENTRY_ {
|
||||
EFI_GUID Guid;
|
||||
UINT32 Type;
|
||||
UINT16 DataType;
|
||||
UINT16 EntryType;
|
||||
UINT64 PhysicalAddress;
|
||||
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
|
||||
|
||||
extern QString flashMapGuidToQString(const EFI_GUID & guid);
|
||||
|
||||
// B091E7D2-05A0-4198-94F0-74B7B8C55459
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_VOLUME_HEADER
|
||||
("\xD2\xE7\x91\xB0\xA0\x05\x98\x41\x94\xF0\x74\xB7\xB8\xC5\x54\x59", 16);
|
||||
|
||||
// FD3F690E-B4B0-4D68-89DB-19A1A3318F90
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_MICROCODES_GUID
|
||||
("\x0E\x69\x3F\xFD\xB0\xB4\x68\x4D\x89\xDB\x19\xA1\xA3\x31\x8F\x90", 16);
|
||||
|
||||
// 46310243-7B03-4132-BE44-2243FACA7CDD
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_CMDB_GUID
|
||||
("\x43\x02\x31\x46\x03\x7B\x32\x41\xBE\x44\x22\x43\xFA\xCA\x7C\xDD", 16);
|
||||
|
||||
// 1B2C4952-D778-4B64-BDA1-15A36F5FA545
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY1_GUID
|
||||
("\x52\x49\x2C\x1B\x78\xD7\x64\x4B\xBD\xA1\x15\xA3\x6F\x5F\xA5\x45", 16);
|
||||
|
||||
// 127C1C4E-9135-46E3-B006-F9808B0559A5
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER1_GUID
|
||||
("\x4E\x1C\x7C\x12\x35\x91\xE3\x46\xB0\x06\xF9\x80\x8B\x05\x59\xA5", 16);
|
||||
|
||||
// 7CE75114-8272-45AF-B536-761BD38852CE
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_PUBKEY2_GUID
|
||||
("\x14\x51\xE7\x7C\x72\x82\xAF\x45\xB5\x36\x76\x1B\xD3\x88\x52\xCE", 16);
|
||||
|
||||
// 071A3DBE-CFF4-4B73-83F0-598C13DCFDD5
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_MARKER2_GUID
|
||||
("\xBE\x3D\x1A\x07\xF4\xCF\x73\x4B\x83\xF0\x59\x8C\x13\xDC\xFD\xD5", 16);
|
||||
|
||||
// FACFB110-7BFD-4EFB-873E-88B6B23B97EA
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA1_GUID
|
||||
("\x10\xB1\xCF\xFA\xFD\x7B\xFB\x4E\x87\x3E\x88\xB6\xB2\x3B\x97\xEA", 16);
|
||||
|
||||
// E68DC11A-A5F4-4AC3-AA2E-29E298BFF645
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA2_GUID
|
||||
("\x1A\xC1\x8D\xE6\xF4\xA5\xC3\x4A\xAA\x2E\x29\xE2\x98\xBF\xF6\x45", 16);
|
||||
|
||||
// 4B3828AE-0ACE-45B6-8CDB-DAFC28BBF8C5
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA3_GUID
|
||||
("\xAE\x28\x38\x4B\xCE\x0A\xB6\x45\x8C\xDB\xDA\xFC\x28\xBB\xF8\xC5", 16);
|
||||
|
||||
// C22E6B8A-8159-49A3-B353-E84B79DF19C0
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA4_GUID
|
||||
("\x8A\x6B\x2E\xC2\x59\x81\xA3\x49\xB3\x53\xE8\x4B\x79\xDF\x19\xC0", 16);
|
||||
|
||||
// B6B5FAB9-75C4-4AAE-8314-7FFFA7156EAA
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA5_GUID
|
||||
("\xB9\xFA\xB5\xB6\xC4\x75\xAE\x4A\x83\x14\x7F\xFF\xA7\x15\x6E\xAA", 16);
|
||||
|
||||
// 919B9699-8DD0-4376-AA0B-0E54CCA47D8F
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA6_GUID
|
||||
("\x99\x96\x9B\x91\xD0\x8D\x76\x43\xAA\x0B\x0E\x54\xCC\xA4\x7D\x8F", 16);
|
||||
|
||||
// 58A90A52-929F-44F8-AC35-A7E1AB18AC91
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_EVSA7_GUID
|
||||
("\x52\x0A\xA9\x58\x9F\x92\xF8\x44\xAC\x35\xA7\xE1\xAB\x18\xAC\x91", 16);
|
||||
|
||||
// 8CB71915-531F-4AF5-82BF-A09140817BAA
|
||||
const QByteArray NVRAM_PHOENIX_FLASH_MAP_SELF_GUID
|
||||
("\x15\x19\xB7\x8C\x1F\x53\xF5\x4A\x82\xBF\xA0\x91\x40\x81\x7B\xAA", 16);
|
||||
|
||||
//
|
||||
// SLIC pubkey and marker
|
||||
//
|
||||
|
||||
typedef struct OEM_ACTIVATION_PUBKEY_ {
|
||||
UINT32 Type; // 0
|
||||
UINT32 Size; // 0x9C
|
||||
UINT8 KeyType;
|
||||
UINT8 Version;
|
||||
UINT16 Reserved;
|
||||
UINT32 Algorithm;
|
||||
UINT32 Magic; // RSA1
|
||||
UINT32 BitLength;
|
||||
UINT32 Exponent;
|
||||
UINT8 Modulus[128];
|
||||
} OEM_ACTIVATION_PUBKEY;
|
||||
|
||||
#define OEM_ACTIVATION_PUBKEY_TYPE 0x00000000
|
||||
#define OEM_ACTIVATION_PUBKEY_MAGIC 0x31415352 // RSA1
|
||||
|
||||
typedef struct OEM_ACTIVATION_MARKER_ {
|
||||
UINT32 Type; // 1
|
||||
UINT32 Size; // 0xB6
|
||||
UINT32 Version;
|
||||
UINT8 OemId[6];
|
||||
UINT8 OemTableId[8];
|
||||
UINT64 WindowsFlag;
|
||||
UINT32 SlicVersion;
|
||||
UINT8 Reserved[16];
|
||||
UINT8 Signature[128];
|
||||
} OEM_ACTIVATION_MARKER;
|
||||
|
||||
#define OEM_ACTIVATION_MARKER_TYPE 0x00000001
|
||||
#define OEM_ACTIVATION_MARKER_WINDOWS_FLAG_PART1 0x444E4957
|
||||
#define OEM_ACTIVATION_MARKER_WINDOWS_FLAG 0x2053574F444E4957UL
|
||||
#define OEM_ACTIVATION_MARKER_RESERVED_BYTE 0x00
|
||||
|
||||
//
|
||||
// Phoenix CMDB, no londer used, requires no parsing
|
||||
//
|
||||
|
||||
typedef struct PHOENIX_CMDB_HEADER_ {
|
||||
UINT32 Signature; // CMDB
|
||||
UINT32 HeaderSize; // Size of this header
|
||||
UINT32 TotalSize; // Total size of header and chunks, without strings
|
||||
// UINT8 StartChunk[3];
|
||||
// UINT8 StringChunk[5][x];
|
||||
// C_STR Strings[2*x + 1];
|
||||
} PHOENIX_CMDB_HEADER;
|
||||
|
||||
#define NVRAM_PHOENIX_CMDB_HEADER_SIGNATURE 0x42444D43
|
||||
#define NVRAM_PHOENIX_CMDB_SIZE 0x100;
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
|
122
common/types.cpp
122
common/types.cpp
@ -75,6 +75,8 @@ QString itemTypeToQString(const UINT8 type)
|
||||
return QObject::tr("EVSA store");
|
||||
case Types::NvramStoreFtw:
|
||||
return QObject::tr("FTW store");
|
||||
case Types::NvramStoreCmdb:
|
||||
return QObject::tr("CMDB store");
|
||||
case Types::NvramStoreFlashMap:
|
||||
return QObject::tr("FlashMap store");
|
||||
case Types::NvramVariableNvar:
|
||||
@ -87,6 +89,12 @@ QString itemTypeToQString(const UINT8 type)
|
||||
return QObject::tr("EVSA entry");
|
||||
case Types::NvramEntryFlashMap:
|
||||
return QObject::tr("FlashMap entry");
|
||||
case Types::Microcode:
|
||||
return QObject::tr("Microcode");
|
||||
case Types::SlicPubkey:
|
||||
return QObject::tr("SLIC pubkey");
|
||||
case Types::SlicMarker:
|
||||
return QObject::tr("SLIC marker");
|
||||
default:
|
||||
return QObject::tr("Unknown");
|
||||
}
|
||||
@ -96,61 +104,58 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
||||
{
|
||||
switch (type) {
|
||||
case Types::Root:
|
||||
case Types::Image:
|
||||
if (subtype == Subtypes::IntelImage)
|
||||
return QObject::tr("Intel");
|
||||
else if (Subtypes::UefiImage)
|
||||
return QObject::tr("UEFI");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Padding:
|
||||
if (subtype == Subtypes::ZeroPadding)
|
||||
return QObject::tr("Empty (0x00)");
|
||||
else if (subtype == Subtypes::OnePadding)
|
||||
return QObject::tr("Empty (0xFF)");
|
||||
else if (subtype == Subtypes::DataPadding)
|
||||
return QObject::tr("Non-empty");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Volume:
|
||||
if (subtype == Subtypes::UnknownVolume)
|
||||
return QObject::tr("Unknown");
|
||||
else if (subtype == Subtypes::Ffs2Volume)
|
||||
return QObject::tr("FFSv2");
|
||||
else if (subtype == Subtypes::Ffs3Volume)
|
||||
return QObject::tr("FFSv3");
|
||||
else if (subtype == Subtypes::NvramVolume)
|
||||
return QObject::tr("NVRAM");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Capsule:
|
||||
if (subtype == Subtypes::AptioSignedCapsule)
|
||||
return QObject::tr("Aptio signed");
|
||||
else if (subtype == Subtypes::AptioUnsignedCapsule)
|
||||
return QObject::tr("Aptio unsigned");
|
||||
else if (subtype == Subtypes::UefiCapsule)
|
||||
return QObject::tr("UEFI 2.0");
|
||||
else if (subtype == Subtypes::ToshibaCapsule)
|
||||
return QObject::tr("Toshiba");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
case Types::Region:
|
||||
return regionTypeToQString(subtype);
|
||||
case Types::File:
|
||||
return fileTypeToQString(subtype);
|
||||
case Types::Section:
|
||||
return sectionTypeToQString(subtype);
|
||||
case Types::FreeSpace:
|
||||
return QString();
|
||||
case Types::NvramStoreVss:
|
||||
case Types::NvramStoreFdc:
|
||||
case Types::NvramStoreFsys:
|
||||
case Types::NvramStoreEvsa:
|
||||
case Types::NvramStoreFtw:
|
||||
case Types::NvramStoreFlashMap:
|
||||
case Types::NvramStoreCmdb:
|
||||
case Types::NvramEntryFsys:
|
||||
case Types::NvramEntryFlashMap:
|
||||
case Types::SlicPubkey:
|
||||
case Types::SlicMarker:
|
||||
return QString();
|
||||
case Types::Image:
|
||||
if (subtype == Subtypes::IntelImage)
|
||||
return QObject::tr("Intel");
|
||||
if (Subtypes::UefiImage)
|
||||
return QObject::tr("UEFI");
|
||||
break;
|
||||
case Types::Padding:
|
||||
if (subtype == Subtypes::ZeroPadding)
|
||||
return QObject::tr("Empty (0x00)");
|
||||
if (subtype == Subtypes::OnePadding)
|
||||
return QObject::tr("Empty (0xFF)");
|
||||
if (subtype == Subtypes::DataPadding)
|
||||
return QObject::tr("Non-empty");
|
||||
break;
|
||||
case Types::Volume:
|
||||
if (subtype == Subtypes::UnknownVolume)
|
||||
return QObject::tr("Unknown");
|
||||
if (subtype == Subtypes::Ffs2Volume)
|
||||
return QObject::tr("FFSv2");
|
||||
if (subtype == Subtypes::Ffs3Volume)
|
||||
return QObject::tr("FFSv3");
|
||||
if (subtype == Subtypes::NvramVolume)
|
||||
return QObject::tr("NVRAM");
|
||||
break;
|
||||
case Types::Capsule:
|
||||
if (subtype == Subtypes::AptioSignedCapsule)
|
||||
return QObject::tr("Aptio signed");
|
||||
if (subtype == Subtypes::AptioUnsignedCapsule)
|
||||
return QObject::tr("Aptio unsigned");
|
||||
if (subtype == Subtypes::UefiCapsule)
|
||||
return QObject::tr("UEFI 2.0");
|
||||
if (subtype == Subtypes::ToshibaCapsule)
|
||||
return QObject::tr("Toshiba");
|
||||
break;
|
||||
case Types::Region:
|
||||
return regionTypeToQString(subtype);
|
||||
case Types::File:
|
||||
return fileTypeToQString(subtype);
|
||||
case Types::Section:
|
||||
return sectionTypeToQString(subtype);
|
||||
case Types::NvramVariableNvar:
|
||||
if (subtype == Subtypes::InvalidNvarVariable)
|
||||
return QObject::tr("Invalid");
|
||||
@ -162,8 +167,7 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
||||
return QObject::tr("Data");
|
||||
if (subtype == Subtypes::FullNvarVariable)
|
||||
return QObject::tr("Full");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
break;
|
||||
case Types::NvramVariableVss:
|
||||
if (subtype == Subtypes::InvalidVssVariable)
|
||||
return QObject::tr("Invalid");
|
||||
@ -173,8 +177,7 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
||||
return QObject::tr("Apple CRC32");
|
||||
if (subtype == Subtypes::AuthVssVariable)
|
||||
return QObject::tr("Auth");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
break;
|
||||
case Types::NvramEntryEvsa:
|
||||
if (subtype == Subtypes::InvalidEvsaEntry)
|
||||
return QObject::tr("Invalid");
|
||||
@ -186,11 +189,22 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
||||
return QObject::tr("Name");
|
||||
if (subtype == Subtypes::DataEvsaEntry)
|
||||
return QObject::tr("Data");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
default:
|
||||
return QObject::tr("Unknown subtype");
|
||||
break;
|
||||
case Types::NvramEntryFlashMap:
|
||||
if (subtype == Subtypes::VolumeFlashMapEntry)
|
||||
return QObject::tr("Volume");
|
||||
if (subtype == Subtypes::DataBlockFlashMapEntry)
|
||||
return QObject::tr("Data block");
|
||||
break;
|
||||
case Types::Microcode:
|
||||
if (subtype == Subtypes::IntelMicrocode)
|
||||
return QObject::tr("Intel");
|
||||
if (subtype == Subtypes::AmdMicrocode)
|
||||
return QObject::tr("AMD");
|
||||
break;
|
||||
}
|
||||
|
||||
return QObject::tr("Unknown subtype");
|
||||
}
|
||||
|
||||
QString compressionTypeToQString(const UINT8 algorithm)
|
||||
|
@ -49,11 +49,15 @@ namespace Types {
|
||||
NvramStoreEvsa,
|
||||
NvramStoreFlashMap,
|
||||
NvramStoreFtw,
|
||||
NvramStoreCmdb,
|
||||
NvramVariableNvar,
|
||||
NvramVariableVss,
|
||||
NvramEntryFsys,
|
||||
NvramEntryEvsa,
|
||||
NvramEntryFlashMap,
|
||||
Microcode,
|
||||
SlicPubkey,
|
||||
SlicMarker,
|
||||
};
|
||||
}
|
||||
|
||||
@ -118,6 +122,16 @@ namespace Subtypes {
|
||||
NameEvsaEntry,
|
||||
DataEvsaEntry,
|
||||
};
|
||||
|
||||
enum FlashMapEntrySubtypes {
|
||||
VolumeFlashMapEntry = 160,
|
||||
DataBlockFlashMapEntry
|
||||
};
|
||||
|
||||
enum MicrocodeSubtypes {
|
||||
IntelMicrocode = 170,
|
||||
AmdMicrocode
|
||||
};
|
||||
};
|
||||
|
||||
// *ToQString conversion routines
|
||||
|
Loading…
Reference in New Issue
Block a user