mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-25 09:28:22 +08:00
Engine update 0.20.2
- Intel signed section identified as EFI_FIRMWARE_CONTENTS_SIGNED GUIDed section - solved a bug with no element for "Non-UEFI data inside pad-file" message - HP postcode section renamed to Insyde postcode (found in non-HP images) - various small fixes - this is the latest release without FFSv3 support, which requires massive refactoring round and can possibly last long
This commit is contained in:
parent
39ab1e5f06
commit
df03531ca7
@ -1,6 +1,6 @@
|
||||
/* uefiextract_main.cpp
|
||||
|
||||
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
}
|
||||
else {
|
||||
std::cout << "UEFIExtract 0.4.1" << std::endl << std::endl <<
|
||||
std::cout << "UEFIExtract 0.4.2" << std::endl << std::endl <<
|
||||
"Usage: uefiextract imagefile [FileGUID_1 FileGUID_2 ... FileGUID_31]" << std::endl <<
|
||||
"Returned value is a bit mask where 0 on position N meant File with GUID_N was found and unpacked, 1 otherwise" << std::endl;
|
||||
return 1;
|
||||
|
@ -53,10 +53,28 @@ UINT8 UEFIFind::init(const QString & path)
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
QString UEFIFind::guidToQString(const UINT8* guid)
|
||||
{
|
||||
const UINT32 u32 = *(const UINT32*)guid;
|
||||
const UINT16 u16_1 = *(const UINT16*)(guid + 4);
|
||||
const UINT16 u16_2 = *(const UINT16*)(guid + 6);
|
||||
const UINT8 u8_1 = *(const UINT8*)(guid + 8);
|
||||
const UINT8 u8_2 = *(const UINT8*)(guid + 9);
|
||||
const UINT8 u8_3 = *(const UINT8*)(guid + 10);
|
||||
const UINT8 u8_4 = *(const UINT8*)(guid + 11);
|
||||
const UINT8 u8_5 = *(const UINT8*)(guid + 12);
|
||||
const UINT8 u8_6 = *(const UINT8*)(guid + 13);
|
||||
const UINT8 u8_7 = *(const UINT8*)(guid + 14);
|
||||
const UINT8 u8_8 = *(const UINT8*)(guid + 15);
|
||||
|
||||
return QString("%1-%2-%3-%4%5-%6%7%8%9%10%11").hexarg2(u32, 8).hexarg2(u16_1, 4).hexarg2(u16_2, 4).hexarg2(u8_1, 2).hexarg2(u8_2, 2)
|
||||
.hexarg2(u8_3, 2).hexarg2(u8_4, 2).hexarg2(u8_5, 2).hexarg2(u8_6, 2).hexarg2(u8_7, 2).hexarg2(u8_8, 2);
|
||||
}
|
||||
|
||||
UINT8 UEFIFind::find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result)
|
||||
{
|
||||
QModelIndex root = model->index(0, 0);
|
||||
QSet<QModelIndex> files;
|
||||
QSet<QPair<QModelIndex, QModelIndex> > files;
|
||||
|
||||
result.clear();
|
||||
|
||||
@ -70,31 +88,24 @@ UINT8 UEFIFind::find(const UINT8 mode, const bool count, const QString & hexPatt
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
QModelIndex index;
|
||||
Q_FOREACH(index, files) {
|
||||
QByteArray data = model->header(index).left(16);
|
||||
QPair<QModelIndex, QModelIndex> indexes;
|
||||
Q_FOREACH(indexes, files) {
|
||||
QByteArray data = model->header(indexes.first).left(16);
|
||||
result.append(guidToQString((const UINT8*)data.constData()));
|
||||
|
||||
UINT32 u32 = *(UINT32*)data.constData();
|
||||
UINT16 u16_1 = *(UINT16*)(data.constData() + 4);
|
||||
UINT16 u16_2 = *(UINT16*)(data.constData() + 6);
|
||||
UINT8 u8_1 = *(UINT8*)(data.constData() + 8);
|
||||
UINT8 u8_2 = *(UINT8*)(data.constData() + 9);
|
||||
UINT8 u8_3 = *(UINT8*)(data.constData() + 10);
|
||||
UINT8 u8_4 = *(UINT8*)(data.constData() + 11);
|
||||
UINT8 u8_5 = *(UINT8*)(data.constData() + 12);
|
||||
UINT8 u8_6 = *(UINT8*)(data.constData() + 13);
|
||||
UINT8 u8_7 = *(UINT8*)(data.constData() + 14);
|
||||
UINT8 u8_8 = *(UINT8*)(data.constData() + 15);
|
||||
// Special case of freeform subtype GUID files
|
||||
if (indexes.second.isValid() && model->subtype(indexes.second) == EFI_SECTION_FREEFORM_SUBTYPE_GUID) {
|
||||
data = model->header(indexes.second).left(sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION));
|
||||
result.append(" ").append(guidToQString((const UINT8*)data.constData() + sizeof(EFI_COMMON_SECTION_HEADER)));
|
||||
}
|
||||
|
||||
result.append("\n");
|
||||
|
||||
QString guid = QString("%1-%2-%3-%4%5-%6%7%8%9%10%11\n").hexarg2(u32, 8).hexarg2(u16_1, 4).hexarg2(u16_2, 4).hexarg2(u8_1, 2).hexarg2(u8_2, 2)
|
||||
.hexarg2(u8_3, 2).hexarg2(u8_4, 2).hexarg2(u8_5, 2).hexarg2(u8_6, 2).hexarg2(u8_7, 2).hexarg2(u8_8, 2);
|
||||
|
||||
result.append(guid);
|
||||
}
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT8 UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QModelIndex> & files)
|
||||
UINT8 UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QPair<QModelIndex, QModelIndex> > & files)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return ERR_SUCCESS;
|
||||
@ -132,10 +143,13 @@ UINT8 UEFIFind::findFileRecursive(const QModelIndex index, const QString & hexPa
|
||||
if (offset % 2 == 0) {
|
||||
if (model->type(index) != Types::File) {
|
||||
QModelIndex ffs = model->findParentOfType(index, Types::File);
|
||||
files.insert(ffs);
|
||||
if (model->type(index) == Types::Section && model->subtype(index) == EFI_SECTION_FREEFORM_SUBTYPE_GUID)
|
||||
files.insert(QPair<QModelIndex, QModelIndex>(ffs, index));
|
||||
else
|
||||
files.insert(QPair<QModelIndex, QModelIndex>(ffs, QModelIndex()));
|
||||
}
|
||||
else
|
||||
files.insert(index);
|
||||
files.insert(QPair<QModelIndex, QModelIndex>(index, QModelIndex()));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -19,12 +19,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QPair>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QUuid>
|
||||
|
||||
#include "../basetypes.h"
|
||||
#include "../ffsengine.h"
|
||||
#include "../ffs.h"
|
||||
|
||||
class UEFIFind : public QObject
|
||||
{
|
||||
@ -38,7 +40,8 @@ public:
|
||||
UINT8 find(const UINT8 mode, const bool count, const QString & hexPattern, QString & result);
|
||||
|
||||
private:
|
||||
UINT8 findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QModelIndex> & files);
|
||||
UINT8 findFileRecursive(const QModelIndex index, const QString & hexPattern, const UINT8 mode, QSet<QPair<QModelIndex, QModelIndex> > & files);
|
||||
QString UEFIFind::guidToQString(const UINT8* guid);
|
||||
|
||||
FfsEngine* ffsEngine;
|
||||
TreeModel* model;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* uefifind_main.cpp
|
||||
|
||||
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -64,7 +64,7 @@ int main(int argc, char *argv[])
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
else {
|
||||
std::cout << "UEFIFind 0.2.0" << std::endl << std::endl <<
|
||||
std::cout << "UEFIFind 0.3.0" << std::endl << std::endl <<
|
||||
"Usage: uefifind {header | body | all} {list | count} pattern imagefile\n";
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* uefipatch_main.cpp
|
||||
|
||||
Copyright (c) 2014, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
@ -31,7 +31,7 @@ int main(int argc, char *argv[])
|
||||
result = w.patchFromFile(a.arguments().at(1));
|
||||
}
|
||||
else {
|
||||
std::cout << "UEFIPatch 0.3.1 - UEFI image file patching utility" << std::endl << std::endl <<
|
||||
std::cout << "UEFIPatch 0.3.2 - UEFI image file patching utility" << std::endl << std::endl <<
|
||||
"Usage: UEFIPatch image_file" << std::endl << std::endl <<
|
||||
"Patches will be read from patches.txt file\n";
|
||||
return ERR_SUCCESS;
|
||||
|
64
ffs.cpp
64
ffs.cpp
@ -23,6 +23,10 @@ const QVector<QByteArray> FFSv2Volumes =
|
||||
<< EFI_INTEL_FILE_SYSTEM2_GUID
|
||||
<< EFI_SONY_FILE_SYSTEM_GUID;
|
||||
|
||||
const QVector<QByteArray> FFSv3Volumes =
|
||||
QVector<QByteArray>()
|
||||
<< EFI_FIRMWARE_FILE_SYSTEM3_GUID;
|
||||
|
||||
const UINT8 ffsAlignmentTable[] =
|
||||
{ 0, 4, 7, 9, 10, 12, 15, 16 };
|
||||
|
||||
@ -140,7 +144,7 @@ QString sectionTypeToQString(const UINT8 type)
|
||||
case EFI_SECTION_RAW: return QObject::tr("Raw");
|
||||
case EFI_SECTION_PEI_DEPEX: return QObject::tr("PEI dependency");
|
||||
case EFI_SECTION_SMM_DEPEX: return QObject::tr("SMM dependency");
|
||||
case HP_SECTION_POSTCODE: return QObject::tr("HP postcode");
|
||||
case INSYDE_SECTION_POSTCODE: return QObject::tr("Insyde postcode");
|
||||
case SCT_SECTION_POSTCODE: return QObject::tr("SCT postcode");
|
||||
default: return QObject::tr("Unknown");
|
||||
}
|
||||
@ -151,27 +155,47 @@ UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header)
|
||||
if (!header)
|
||||
return 0;
|
||||
|
||||
bool extended = false;
|
||||
/*if (uint24ToUint32(header->Size) == EFI_SECTION2_IS_USED) {
|
||||
extended = true;
|
||||
}*/
|
||||
|
||||
switch (header->Type)
|
||||
{
|
||||
case EFI_SECTION_GUID_DEFINED: {
|
||||
const EFI_GUID_DEFINED_SECTION* gdsHeader = (const EFI_GUID_DEFINED_SECTION*)header;
|
||||
return gdsHeader->DataOffset; }
|
||||
case EFI_SECTION_COMPRESSION: return sizeof(EFI_COMPRESSION_SECTION);
|
||||
case EFI_SECTION_DISPOSABLE: return sizeof(EFI_DISPOSABLE_SECTION);
|
||||
case EFI_SECTION_PE32: return sizeof(EFI_PE32_SECTION);
|
||||
case EFI_SECTION_PIC: return sizeof(EFI_PIC_SECTION);
|
||||
case EFI_SECTION_TE: return sizeof(EFI_TE_SECTION);
|
||||
case EFI_SECTION_DXE_DEPEX: return sizeof(EFI_DXE_DEPEX_SECTION);
|
||||
case EFI_SECTION_VERSION: return sizeof(EFI_VERSION_SECTION);
|
||||
case EFI_SECTION_USER_INTERFACE: return sizeof(EFI_USER_INTERFACE_SECTION);
|
||||
case EFI_SECTION_COMPATIBILITY16: return sizeof(EFI_COMPATIBILITY16_SECTION);
|
||||
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION);
|
||||
case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
|
||||
case EFI_SECTION_RAW: return sizeof(EFI_RAW_SECTION);
|
||||
case EFI_SECTION_PEI_DEPEX: return sizeof(EFI_PEI_DEPEX_SECTION);
|
||||
case EFI_SECTION_SMM_DEPEX: return sizeof(EFI_SMM_DEPEX_SECTION);
|
||||
case HP_SECTION_POSTCODE: return sizeof(POSTCODE_SECTION);
|
||||
case SCT_SECTION_POSTCODE: return sizeof(POSTCODE_SECTION);
|
||||
default: return sizeof(EFI_COMMON_SECTION_HEADER);
|
||||
if (!extended) {
|
||||
const EFI_GUID_DEFINED_SECTION* gdsHeader = (const EFI_GUID_DEFINED_SECTION*)header;
|
||||
if (QByteArray((const char*)&gdsHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)(gdsHeader + 1);
|
||||
return gdsHeader->DataOffset + certificateHeader->Length;
|
||||
}
|
||||
return gdsHeader->DataOffset;
|
||||
}
|
||||
else {
|
||||
const EFI_GUID_DEFINED_SECTION2* gdsHeader = (const EFI_GUID_DEFINED_SECTION2*)header;
|
||||
if (QByteArray((const char*)&gdsHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)(gdsHeader + 1);
|
||||
return gdsHeader->DataOffset + certificateHeader->Length;
|
||||
}
|
||||
return gdsHeader->DataOffset;
|
||||
}
|
||||
}
|
||||
case EFI_SECTION_COMPRESSION: return extended ? sizeof(EFI_COMPRESSION_SECTION2) : sizeof(EFI_COMPRESSION_SECTION);
|
||||
case EFI_SECTION_DISPOSABLE: return extended ? sizeof(EFI_DISPOSABLE_SECTION2) : sizeof(EFI_DISPOSABLE_SECTION);
|
||||
case EFI_SECTION_PE32: return extended ? sizeof(EFI_PE32_SECTION2) : sizeof(EFI_PE32_SECTION);
|
||||
case EFI_SECTION_PIC: return extended ? sizeof(EFI_PIC_SECTION2) : sizeof(EFI_PIC_SECTION);
|
||||
case EFI_SECTION_TE: return extended ? sizeof(EFI_TE_SECTION2) : sizeof(EFI_TE_SECTION);
|
||||
case EFI_SECTION_DXE_DEPEX: return extended ? sizeof(EFI_DXE_DEPEX_SECTION2) : sizeof(EFI_DXE_DEPEX_SECTION);
|
||||
case EFI_SECTION_VERSION: return extended ? sizeof(EFI_VERSION_SECTION2) : sizeof(EFI_VERSION_SECTION);
|
||||
case EFI_SECTION_USER_INTERFACE: return extended ? sizeof(EFI_USER_INTERFACE_SECTION2) : sizeof(EFI_USER_INTERFACE_SECTION);
|
||||
case EFI_SECTION_COMPATIBILITY16: return extended ? sizeof(EFI_COMPATIBILITY16_SECTION2) : sizeof(EFI_COMPATIBILITY16_SECTION);
|
||||
case EFI_SECTION_FIRMWARE_VOLUME_IMAGE: return extended ? sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION2) : sizeof(EFI_FIRMWARE_VOLUME_IMAGE_SECTION);
|
||||
case EFI_SECTION_FREEFORM_SUBTYPE_GUID: return extended ? sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION2) : sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
|
||||
case EFI_SECTION_RAW: return extended ? sizeof(EFI_RAW_SECTION2) : sizeof(EFI_RAW_SECTION);
|
||||
case EFI_SECTION_PEI_DEPEX: return extended ? sizeof(EFI_PEI_DEPEX_SECTION2) : sizeof(EFI_PEI_DEPEX_SECTION);
|
||||
case EFI_SECTION_SMM_DEPEX: return extended ? sizeof(EFI_SMM_DEPEX_SECTION2) : sizeof(EFI_SMM_DEPEX_SECTION);
|
||||
case INSYDE_SECTION_POSTCODE: return extended ? sizeof(POSTCODE_SECTION2) : sizeof(POSTCODE_SECTION);
|
||||
case SCT_SECTION_POSTCODE: return extended ? sizeof(POSTCODE_SECTION2) : sizeof(POSTCODE_SECTION);
|
||||
default: return extended ? sizeof(EFI_COMMON_SECTION_HEADER2) : sizeof(EFI_COMMON_SECTION_HEADER);
|
||||
}
|
||||
}
|
||||
|
139
ffs.h
139
ffs.h
@ -108,18 +108,23 @@ const QByteArray EFI_APPLE_BOOT_VOLUME_FILE_SYSTEM2_GUID
|
||||
("\x8C\x1B\x00\xBD\x71\x6A\x7B\x48\xA1\x4F\x0C\x2A\x2D\xCF\x7A\x5D", 16);
|
||||
const QByteArray EFI_INTEL_FILE_SYSTEM_GUID
|
||||
("\xFF\xFF\x3F\xAD\x8B\xD2\xC4\x44\x9F\x13\x9E\xA9\x8A\x97\xF9\xF0", 16);
|
||||
//AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 //Intel 1
|
||||
// AD3FFFFF-D28B-44C4-9F13-9EA98A97F9F0 // Intel 1
|
||||
const QByteArray EFI_INTEL_FILE_SYSTEM2_GUID
|
||||
("\x70\xCD\xA1\xD6\x33\x4B\x94\x49\xA6\xEA\x37\x5F\x2C\xCC\x54\x37", 16);
|
||||
//D6A1CD70-4B33-4994-A6EA-375F2CCC5437 //Intel 2
|
||||
// D6A1CD70-4B33-4994-A6EA-375F2CCC5437 // Intel 2
|
||||
const QByteArray EFI_SONY_FILE_SYSTEM_GUID
|
||||
("\x56\x41\x49\x4F\xD6\xAE\x64\x4D\xA5\x37\xB8\xA5\x55\x7B\xCE\xEC", 16);
|
||||
//4F494156-AED6-4D64-A537-B8A5557BCEEC //Sony 1
|
||||
// 4F494156-AED6-4D64-A537-B8A5557BCEEC // Sony 1
|
||||
|
||||
|
||||
//Vector of volume GUIDs with FFSv2-compatible files
|
||||
// Vector of volume GUIDs with FFSv2-compatible files
|
||||
extern const QVector<QByteArray> FFSv2Volumes;
|
||||
|
||||
const QByteArray EFI_FIRMWARE_FILE_SYSTEM3_GUID // 5473C07A-3DCB-4dca-BD6F-1E9689E7349A
|
||||
("\x7A\xC0\x73\x54\xCB\x3D\xCA\x4D\xBD\x6F\x1E\x96\x89\xE7\x34\x9A", 16);
|
||||
|
||||
// Vector of volume GUIDs with FFSv3-compatible files
|
||||
extern const QVector<QByteArray> FFSv3Volumes;
|
||||
|
||||
// Firmware volume signature
|
||||
const QByteArray EFI_FV_SIGNATURE("_FVH", 4);
|
||||
#define EFI_FV_SIGNATURE_OFFSET 0x28
|
||||
@ -214,21 +219,21 @@ typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER {
|
||||
// Extended header entry
|
||||
// The extended header entries follow each other and are
|
||||
// terminated by ExtHeaderType EFI_FV_EXT_TYPE_END
|
||||
#define EFI_FV_EXT_TYPE_END 0x00
|
||||
#define EFI_FV_EXT_TYPE_END 0x0000
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY {
|
||||
UINT16 ExtEntrySize;
|
||||
UINT16 ExtEntryType;
|
||||
} EFI_FIRMWARE_VOLUME_EXT_ENTRY;
|
||||
|
||||
// GUID that maps OEM file types to GUIDs
|
||||
#define EFI_FV_EXT_TYPE_OEM_TYPE 0x01
|
||||
#define EFI_FV_EXT_TYPE_OEM_TYPE 0x0001
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE {
|
||||
EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
|
||||
UINT32 TypeMask;
|
||||
//EFI_GUID Types[1];
|
||||
} EFI_FIRMWARE_VOLUME_EXT_HEADER_OEM_TYPE;
|
||||
|
||||
#define EFI_FV_EXT_TYPE_GUID_TYPE 0x02
|
||||
#define EFI_FV_EXT_TYPE_GUID_TYPE 0x0002
|
||||
typedef struct _EFI_FIRMWARE_VOLUME_EXT_ENTRY_GUID_TYPE {
|
||||
EFI_FIRMWARE_VOLUME_EXT_ENTRY Header;
|
||||
EFI_GUID FormatType;
|
||||
@ -269,7 +274,7 @@ EFI_GUID Name;
|
||||
EFI_FFS_INTEGRITY_CHECK IntegrityCheck;
|
||||
UINT8 Type;
|
||||
UINT8 Attributes;
|
||||
UINT8 Size[3];
|
||||
UINT8 Size[3]; // Set to 0xFFFFFF
|
||||
UINT8 State;
|
||||
UINT32 ExtendedSize;
|
||||
} EFI_FFS_FILE_HEADER2;
|
||||
@ -302,8 +307,9 @@ UINT32 ExtendedSize;
|
||||
#define EFI_FV_FILETYPE_FFS_MAX 0xFF
|
||||
|
||||
// File attributes
|
||||
#define FFS_ATTRIB_TAIL_PRESENT 0x01
|
||||
#define FFS_ATTRIB_RECOVERY 0x02
|
||||
#define FFS_ATTRIB_TAIL_PRESENT 0x01 // Valid only for revision 1 volumes
|
||||
#define FFS_ATTRIB_RECOVERY 0x02 // Valid only for revision 1 volumes
|
||||
#define FFS_ATTRIB_LARGE_FILE 0x01 // Valid only for FFSv3 volumes
|
||||
#define FFS_ATTRIB_FIXED 0x04
|
||||
#define FFS_ATTRIB_DATA_ALIGNMENT 0x38
|
||||
#define FFS_ATTRIB_CHECKSUM 0x40
|
||||
@ -357,6 +363,9 @@ typedef struct _EFI_COMMON_SECTION_HEADER2 {
|
||||
UINT32 ExtendedSize;
|
||||
} EFI_COMMON_SECTION_HEADER2;
|
||||
|
||||
// Section2 usage indicator
|
||||
#define EFI_SECTION2_IS_USED 0xFFFFFF
|
||||
|
||||
// File section types
|
||||
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
|
||||
|
||||
@ -379,7 +388,7 @@ typedef struct _EFI_COMMON_SECTION_HEADER2 {
|
||||
#define EFI_SECTION_PEI_DEPEX 0x1B
|
||||
#define EFI_SECTION_SMM_DEPEX 0x1C
|
||||
#define SCT_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
|
||||
#define HP_SECTION_POSTCODE 0x20 // Specific to HP images
|
||||
#define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde images
|
||||
|
||||
// Compression section
|
||||
typedef struct _EFI_COMPRESSION_SECTION {
|
||||
@ -389,6 +398,14 @@ typedef struct _EFI_COMPRESSION_SECTION {
|
||||
UINT8 CompressionType;
|
||||
} EFI_COMPRESSION_SECTION;
|
||||
|
||||
typedef struct _EFI_COMPRESSION_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
UINT32 UncompressedLength;
|
||||
UINT8 CompressionType;
|
||||
} EFI_COMPRESSION_SECTION2;
|
||||
|
||||
// Compression types
|
||||
#define EFI_NOT_COMPRESSED 0x00
|
||||
#define EFI_STANDARD_COMPRESSION 0x01
|
||||
@ -403,6 +420,15 @@ typedef struct _EFI_GUID_DEFINED_SECTION {
|
||||
UINT16 Attributes;
|
||||
} EFI_GUID_DEFINED_SECTION;
|
||||
|
||||
typedef struct _EFI_GUID_DEFINED_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
EFI_GUID SectionDefinitionGuid;
|
||||
UINT16 DataOffset;
|
||||
UINT16 Attributes;
|
||||
} EFI_GUID_DEFINED_SECTION2;
|
||||
|
||||
// Attributes for GUID defined section
|
||||
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
|
||||
#define EFI_GUIDED_SECTION_AUTH_STATUS_VALID 0x02
|
||||
@ -417,7 +443,7 @@ const QByteArray EFI_GUIDED_SECTION_TIANO // A31280AD-481E-41B6-95E8-127F4C98477
|
||||
const QByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF
|
||||
("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16);
|
||||
|
||||
const QByteArray EFI_GUIDED_SECTION_INTEL_SIGNED //0F9D89E8-9259-4F76-A5AF-0C89E34023DF
|
||||
const QByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID //0F9D89E8-9259-4F76-A5AF-0C89E34023DF
|
||||
("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16);
|
||||
|
||||
// Version section
|
||||
@ -427,6 +453,13 @@ typedef struct _EFI_VERSION_SECTION {
|
||||
UINT16 BuildNumber;
|
||||
} EFI_VERSION_SECTION;
|
||||
|
||||
typedef struct _EFI_VERSION_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
UINT16 BuildNumber;
|
||||
} EFI_VERSION_SECTION2;
|
||||
|
||||
// Freeform subtype GUID section
|
||||
typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION {
|
||||
UINT8 Size[3];
|
||||
@ -434,6 +467,13 @@ typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION {
|
||||
EFI_GUID SubTypeGuid;
|
||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION;
|
||||
|
||||
typedef struct _EFI_FREEFORM_SUBTYPE_GUID_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
EFI_GUID SubTypeGuid;
|
||||
} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
|
||||
|
||||
// Phoenix SCT and HP postcode section
|
||||
typedef struct _POSTCODE_SECTION {
|
||||
UINT8 Size[3];
|
||||
@ -441,18 +481,36 @@ typedef struct _POSTCODE_SECTION {
|
||||
UINT32 Postcode;
|
||||
} POSTCODE_SECTION;
|
||||
|
||||
typedef struct _POSTCODE_SECTION2 {
|
||||
UINT8 Size[3];
|
||||
UINT8 Type;
|
||||
UINT32 ExtendedSize;
|
||||
UINT32 Postcode;
|
||||
} POSTCODE_SECTION2;
|
||||
|
||||
// Other sections
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
|
||||
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
|
||||
typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
|
||||
|
||||
//Section routines
|
||||
extern UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header);
|
||||
@ -490,6 +548,39 @@ extern UINT32 sizeOfSectionHeader(const EFI_COMMON_SECTION_HEADER* header);
|
||||
///
|
||||
#define EFI_DEP_SOR 0x09
|
||||
|
||||
//*****************************************************************************
|
||||
// UEFI Crypto-signed Stuff
|
||||
//*****************************************************************************
|
||||
|
||||
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
|
||||
#define WIN_CERT_TYPE_EFI_GUID 0x0EF1
|
||||
|
||||
typedef struct _WIN_CERTIFICATE {
|
||||
UINT32 Length;
|
||||
UINT16 Revision;
|
||||
UINT16 CertificateType;
|
||||
//UINT8 CertData[];
|
||||
} WIN_CERTIFICATE;
|
||||
|
||||
typedef struct _WIN_CERTIFICATE_UEFI_GUID {
|
||||
WIN_CERTIFICATE Header; // Standard WIN_CERTIFICATE
|
||||
EFI_GUID CertType; // Determines format of CertData
|
||||
// UINT8 CertData[]; // Certificate data follows
|
||||
} WIN_CERTIFICATE_UEFI_GUID;
|
||||
|
||||
// WIN_CERTIFICATE_UEFI_GUID.CertType
|
||||
const QByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID
|
||||
("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF");
|
||||
const QByteArray EFI_CERT_TYPE_PKCS7_GUID
|
||||
("\x9D\xD2\xAF\x4A\xDF\x68\xEE\x49\x8A\xA9\x34\x7D\x37\x56\x65\xA7");
|
||||
|
||||
// WIN_CERTIFICATE_UEFI_GUID.CertData
|
||||
typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {
|
||||
UINT32 HashType;
|
||||
UINT8 PublicKey[256];
|
||||
UINT8 Signature[256];
|
||||
} EFI_CERT_BLOCK_RSA_2048_SHA256;
|
||||
|
||||
// Restore previous packing rules
|
||||
#pragma pack(pop)
|
||||
|
||||
|
@ -784,8 +784,12 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
|
||||
volumeFfsVersion = 2;
|
||||
}
|
||||
|
||||
//!TODO:Check for FFS v3 volume
|
||||
|
||||
// Check for FFS v3 volume
|
||||
/*if (FFSv3Volumes.contains(QByteArray::fromRawData((const char*)volumeHeader->FileSystemGuid.Data, sizeof(EFI_GUID)))) {
|
||||
volumeIsUnknown = false;
|
||||
volumeFfsVersion = 3;
|
||||
}*/
|
||||
|
||||
// Check attributes
|
||||
// Determine value of empty byte
|
||||
char empty = volumeHeader->Attributes & EFI_FVB_ERASE_POLARITY ? '\xFF' : '\x00';
|
||||
@ -896,7 +900,7 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
|
||||
// Check free space to be actually free
|
||||
QByteArray freeSpace = volume.mid(fileOffset);
|
||||
if (freeSpace.count(empty) != freeSpace.count()) {
|
||||
msg(tr("parseVolume: non-standard data found in volume's free space"), index);
|
||||
msg(tr("parseVolume: non-UEFI data found in volume's free space"), index);
|
||||
|
||||
// Search for the first non-empty byte
|
||||
UINT32 i;
|
||||
@ -1085,7 +1089,6 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, QModelIndex & index, const U
|
||||
// Check for non-empty pad file
|
||||
else if (fileHeader->Type == EFI_FV_FILETYPE_PAD) {
|
||||
parseAsNonEmptyPadFile = true;
|
||||
msg(tr("parseFile: non-empty pad-file contents will be destroyed after volume modifications"), index);
|
||||
}
|
||||
|
||||
// Get info
|
||||
@ -1139,7 +1142,11 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, QModelIndex & index, const U
|
||||
}
|
||||
// ... and all bytes after as a padding
|
||||
QByteArray padding = body.mid(i);
|
||||
model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Non-UEFI data"), "", tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size()), QByteArray(), padding, QByteArray(), index, mode);
|
||||
QModelIndex dataIndex = model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Non-UEFI data"), "", tr("Full size: %1h (%2)").hexarg(padding.size()).arg(padding.size()), QByteArray(), padding, QByteArray(), index, mode);
|
||||
|
||||
// Show message
|
||||
msg(tr("parseFile: non-empty pad-file contents will be destroyed after volume modifications"), dataIndex);
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1360,6 +1367,9 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
||||
bool msgUnknownGuid = false;
|
||||
bool msgInvalidCrc = false;
|
||||
bool msgUnknownAuth = false;
|
||||
bool msgSigned = false;
|
||||
bool msgUnknownSignature = false;
|
||||
bool msgUnknownUefiGuidSignature = false;
|
||||
|
||||
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader;
|
||||
header = section.left(sizeof(EFI_GUID_DEFINED_SECTION));
|
||||
@ -1368,7 +1378,6 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
||||
guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(header.constData());
|
||||
body = section.mid(guidDefinedSectionHeader->DataOffset, sectionSize - guidDefinedSectionHeader->DataOffset);
|
||||
QByteArray processed = body;
|
||||
QByteArray signature;
|
||||
|
||||
// Get info
|
||||
name = guidToQString(guidDefinedSectionHeader->SectionDefinitionGuid);
|
||||
@ -1418,11 +1427,39 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
||||
else
|
||||
info += tr("\nCompression type: unknown");
|
||||
}
|
||||
// Intel signed section
|
||||
else if (QByteArray((const char*)&guidDefinedSectionHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_INTEL_SIGNED) {
|
||||
UINT32 signatureSize = *(const UINT32*)body.constData();
|
||||
signature = body.left(signatureSize);
|
||||
processed = body.mid(signatureSize);
|
||||
// Signed section
|
||||
else if (QByteArray((const char*)&guidDefinedSectionHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||
msgSigned = true;
|
||||
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)body.constData();
|
||||
if (certificateHeader->CertificateType == WIN_CERT_TYPE_EFI_GUID) {
|
||||
info += tr("\nSignature type: UEFI");
|
||||
const WIN_CERTIFICATE_UEFI_GUID* guidCertificateHeader = (const WIN_CERTIFICATE_UEFI_GUID*)certificateHeader;
|
||||
if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
|
||||
info += tr("\nSignature subtype: RSA2048/SHA256");
|
||||
// TODO: show signature info in Information panel
|
||||
}
|
||||
else if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_PKCS7_GUID) {
|
||||
info += tr("\nSignature subtype: PCKS7");
|
||||
// TODO: show signature info in Information panel
|
||||
}
|
||||
else {
|
||||
info += tr("\nSignature subtype: unknown");
|
||||
msgUnknownUefiGuidSignature = true;
|
||||
}
|
||||
}
|
||||
else if (certificateHeader->CertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
|
||||
info += tr("\nSignature type: PCKS7");
|
||||
// TODO: show signature info in Information panel
|
||||
}
|
||||
else {
|
||||
info += tr("\nSignature type: unknown");
|
||||
msgUnknownSignature = true;
|
||||
}
|
||||
|
||||
// Add additional to the header
|
||||
header.append(body.left(certificateHeader->Length));
|
||||
// Get new body
|
||||
processed = body = body.mid(certificateHeader->Length);
|
||||
}
|
||||
// Unknown GUIDed section
|
||||
else {
|
||||
@ -1461,18 +1498,17 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
||||
msg(tr("parseSection: GUID defined section with unknown authentication method"), index);
|
||||
if (msgInvalidCrc)
|
||||
msg(tr("parseSection: GUID defined section with invalid CRC32"), index);
|
||||
if (msgSigned)
|
||||
msg(tr("parseSection: signature may become invalid after any modification"), index);
|
||||
if (msgUnknownUefiGuidSignature)
|
||||
msg(tr("parseSection: GUID defined section with unknown signature subtype"), index);
|
||||
if (msgUnknownSignature)
|
||||
msg(tr("parseSection: GUID defined section with unknown signature type"), index);
|
||||
|
||||
if (!parseCurrentSection) {
|
||||
msg(tr("parseSection: GUID defined section can not be processed"), index);
|
||||
}
|
||||
else { // Parse processed data
|
||||
if (!signature.isEmpty()) {
|
||||
// Add Intel signature padding to the tree
|
||||
QModelIndex signatureIndex = model->addItem(Types::Padding, Subtypes::DataPadding, COMPRESSION_ALGORITHM_NONE, tr("Intel signature"), "", tr("Full size: %1h (%2)").hexarg(signature.size()).arg(signature.size()), QByteArray(), signature, QByteArray(), index, mode);
|
||||
// Show message
|
||||
msg(tr("parseSection: Intel signature may become invalid after any modification of the following sections"), signatureIndex);
|
||||
}
|
||||
|
||||
result = parseSections(processed, index);
|
||||
if (result)
|
||||
return result;
|
||||
@ -1824,7 +1860,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
||||
} break;
|
||||
|
||||
case SCT_SECTION_POSTCODE:
|
||||
case HP_SECTION_POSTCODE: {
|
||||
case INSYDE_SECTION_POSTCODE: {
|
||||
header = section.left(sizeof(POSTCODE_SECTION));
|
||||
body = section.mid(sizeof(POSTCODE_SECTION), sectionSize - sizeof(POSTCODE_SECTION));
|
||||
|
||||
@ -3358,7 +3394,7 @@ UINT8 FfsEngine::reconstructSection(const QModelIndex& index, const UINT32 base,
|
||||
}
|
||||
// Check for Intel signed section
|
||||
if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED
|
||||
&& QByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_INTEL_SIGNED) {
|
||||
&& QByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||
msg(tr("reconstructSection: GUID defined section signature can become invalid")
|
||||
.arg(guidToQString(guidDefinedHeader->SectionDefinitionGuid)), index);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
UEFITool::UEFITool(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::UEFITool),
|
||||
version(tr("0.20.1"))
|
||||
version(tr("0.20.2"))
|
||||
{
|
||||
clipboard = QApplication::clipboard();
|
||||
|
||||
@ -349,7 +349,7 @@ void UEFITool::replace(const UINT8 mode)
|
||||
}
|
||||
else if (model->type(index) == Types::Section) {
|
||||
if (mode == REPLACE_MODE_AS_IS) {
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sec *.bin);;All files (*)");
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select section file to replace selected object"), currentDir, "Section files (*.sct *.bin);;All files (*)");
|
||||
}
|
||||
else if (mode == REPLACE_MODE_BODY) {
|
||||
if (model->subtype(index) == EFI_SECTION_COMPRESSION || model->subtype(index) == EFI_SECTION_GUID_DEFINED || model->subtype(index) == EFI_SECTION_DISPOSABLE)
|
||||
|
Loading…
Reference in New Issue
Block a user