mirror of
https://github.com/LongSoft/UEFITool.git
synced 2024-11-23 00:18:23 +08:00
UT 0.21.5 /UP 0.3.9 untested
- fixed various crashes reported in #39 - changes aren't tested yet, please don't use until #39 is fixed
This commit is contained in:
parent
7ebbc58b9b
commit
19cc031244
@ -86,6 +86,7 @@ typedef unsigned int UINTN;
|
|||||||
#define ERR_NOTHING_TO_PATCH 41
|
#define ERR_NOTHING_TO_PATCH 41
|
||||||
#define ERR_DEPEX_PARSE_FAILED 42
|
#define ERR_DEPEX_PARSE_FAILED 42
|
||||||
#define ERR_TRUNCATED_IMAGE 43
|
#define ERR_TRUNCATED_IMAGE 43
|
||||||
|
#define ERR_BAD_RELOCATION_ENTRY 44
|
||||||
#define ERR_NOT_IMPLEMENTED 0xFF
|
#define ERR_NOT_IMPLEMENTED 0xFF
|
||||||
|
|
||||||
// UDK porting definitions
|
// UDK porting definitions
|
||||||
|
@ -53,6 +53,8 @@ typedef struct _FLASH_DESCRIPTOR_MAP {
|
|||||||
UINT32: 16;
|
UINT32: 16;
|
||||||
} FLASH_DESCRIPTOR_MAP;
|
} FLASH_DESCRIPTOR_MAP;
|
||||||
|
|
||||||
|
#define FLASH_DESCRIPTOR_MAX_BASE 0xE0
|
||||||
|
|
||||||
// Component section
|
// Component section
|
||||||
// Flash parameters DWORD structure
|
// Flash parameters DWORD structure
|
||||||
typedef struct _FLASH_PARAMETERS {
|
typedef struct _FLASH_PARAMETERS {
|
||||||
|
2
ffs.h
2
ffs.h
@ -109,7 +109,7 @@ typedef struct _EFI_FIRMWARE_VOLUME_HEADER {
|
|||||||
UINT16 ExtHeaderOffset; //Reserved in Revision 1
|
UINT16 ExtHeaderOffset; //Reserved in Revision 1
|
||||||
UINT8 Reserved;
|
UINT8 Reserved;
|
||||||
UINT8 Revision;
|
UINT8 Revision;
|
||||||
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[1];
|
//EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2];
|
||||||
} EFI_FIRMWARE_VOLUME_HEADER;
|
} EFI_FIRMWARE_VOLUME_HEADER;
|
||||||
|
|
||||||
// Standard file system GUIDs
|
// Standard file system GUIDs
|
||||||
|
183
ffsengine.cpp
183
ffsengine.cpp
@ -76,6 +76,7 @@ QString errorMessage(UINT8 errorCode)
|
|||||||
case ERR_NOTHING_TO_PATCH: return QObject::tr("Nothing to patch");
|
case ERR_NOTHING_TO_PATCH: return QObject::tr("Nothing to patch");
|
||||||
case ERR_DEPEX_PARSE_FAILED: return QObject::tr("Dependency expression parsing failed");
|
case ERR_DEPEX_PARSE_FAILED: return QObject::tr("Dependency expression parsing failed");
|
||||||
case ERR_TRUNCATED_IMAGE: return QObject::tr("Image is truncated");
|
case ERR_TRUNCATED_IMAGE: return QObject::tr("Image is truncated");
|
||||||
|
case ERR_BAD_RELOCATION_ENTRY: return QObject::tr("Bad image relocation entry");
|
||||||
default: return QObject::tr("Unknown error %1").arg(errorCode);
|
default: return QObject::tr("Unknown error %1").arg(errorCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,13 +258,31 @@ UINT8 FfsEngine::parseIntelImage(const QByteArray & intelImage, QModelIndex & in
|
|||||||
|
|
||||||
// Check for buffer size to be greater or equal to descriptor region size
|
// Check for buffer size to be greater or equal to descriptor region size
|
||||||
if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) {
|
if (intelImage.size() < FLASH_DESCRIPTOR_SIZE) {
|
||||||
msg(tr("parseIntelImage: input file is smaller then minimum descriptor size of %1h (%2) bytes").hexarg(FLASH_DESCRIPTOR_SIZE).arg(FLASH_DESCRIPTOR_SIZE));
|
msg(tr("parseIntelImage: input file is smaller than minimum descriptor size of 1000h (4096) bytes"));
|
||||||
return ERR_INVALID_FLASH_DESCRIPTOR;
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse descriptor map
|
// Parse descriptor map
|
||||||
const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor + sizeof(FLASH_DESCRIPTOR_HEADER));
|
const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor + sizeof(FLASH_DESCRIPTOR_HEADER));
|
||||||
const FLASH_DESCRIPTOR_UPPER_MAP* upperMap = (const FLASH_DESCRIPTOR_UPPER_MAP*)(descriptor + FLASH_DESCRIPTOR_UPPER_MAP_BASE);
|
const FLASH_DESCRIPTOR_UPPER_MAP* upperMap = (const FLASH_DESCRIPTOR_UPPER_MAP*)(descriptor + FLASH_DESCRIPTOR_UPPER_MAP_BASE);
|
||||||
|
|
||||||
|
// Check sanity of base values
|
||||||
|
if (descriptorMap->MasterBase > FLASH_DESCRIPTOR_MAX_BASE
|
||||||
|
|| descriptorMap->MasterBase == descriptorMap->RegionBase
|
||||||
|
|| descriptorMap->MasterBase == descriptorMap->ComponentBase) {
|
||||||
|
msg(tr("parseIntelImage: invalid descriptor master base %1h").hexarg2(descriptorMap->MasterBase, 2));
|
||||||
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
if (descriptorMap->RegionBase > FLASH_DESCRIPTOR_MAX_BASE
|
||||||
|
|| descriptorMap->RegionBase == descriptorMap->ComponentBase) {
|
||||||
|
msg(tr("parseIntelImage: invalid descriptor region base %1h").hexarg2(descriptorMap->RegionBase, 2));
|
||||||
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
if (descriptorMap->ComponentBase > FLASH_DESCRIPTOR_MAX_BASE) {
|
||||||
|
msg(tr("parseIntelImage: invalid descriptor component base %1h").hexarg2(descriptorMap->ComponentBase, 2));
|
||||||
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
|
||||||
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8(descriptor, descriptorMap->RegionBase);
|
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8(descriptor, descriptorMap->RegionBase);
|
||||||
const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8(descriptor, descriptorMap->ComponentBase);
|
const FLASH_DESCRIPTOR_COMPONENT_SECTION* componentSection = (const FLASH_DESCRIPTOR_COMPONENT_SECTION*)calculateAddress8(descriptor, descriptorMap->ComponentBase);
|
||||||
|
|
||||||
@ -807,19 +826,21 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
|
|||||||
|
|
||||||
// Get volume size
|
// Get volume size
|
||||||
result = getVolumeSize(bios, volumeOffset, volumeSize, bmVolumeSize);
|
result = getVolumeSize(bios, volumeOffset, volumeSize, bmVolumeSize);
|
||||||
if (result)
|
if (result) {
|
||||||
|
msg(tr("parseBios: getVolumeSize failed with error \"%1\"").arg(errorMessage(result)), parent);
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Check reported size
|
// Check that volume is fully present in input
|
||||||
if (volumeSize != bmVolumeSize)
|
if (volumeSize > (UINT32)bios.size() || volumeOffset + volumeSize > (UINT32)bios.size()) {
|
||||||
msgSizeMismach = true;
|
|
||||||
|
|
||||||
//Check that volume is fully present in input
|
|
||||||
if (volumeOffset + volumeSize > (UINT32)bios.size()) {
|
|
||||||
msg(tr("parseBios: one of volumes inside overlaps the end of data"), parent);
|
msg(tr("parseBios: one of volumes inside overlaps the end of data"), parent);
|
||||||
return ERR_INVALID_VOLUME;
|
return ERR_INVALID_VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check reported size against a size calculated using block map
|
||||||
|
if (volumeSize != bmVolumeSize)
|
||||||
|
msgSizeMismach = true;
|
||||||
|
|
||||||
// Check volume revision and alignment
|
// Check volume revision and alignment
|
||||||
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + volumeOffset);
|
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + volumeOffset);
|
||||||
UINT32 alignment;
|
UINT32 alignment;
|
||||||
@ -898,6 +919,10 @@ UINT8 FfsEngine::findNextVolume(const QByteArray & bios, UINT32 volumeOffset, UI
|
|||||||
|
|
||||||
UINT8 FfsEngine::getVolumeSize(const QByteArray & bios, UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize)
|
UINT8 FfsEngine::getVolumeSize(const QByteArray & bios, UINT32 volumeOffset, UINT32 & volumeSize, UINT32 & bmVolumeSize)
|
||||||
{
|
{
|
||||||
|
// Check that there is space for the volume header and at least two block map entries.
|
||||||
|
if ((UINT32)bios.size() < volumeOffset + sizeof(EFI_FIRMWARE_VOLUME_HEADER) + 2 * sizeof(EFI_FV_BLOCK_MAP_ENTRY))
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
|
|
||||||
// Populate volume header
|
// Populate volume header
|
||||||
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + volumeOffset);
|
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(bios.constData() + volumeOffset);
|
||||||
|
|
||||||
@ -918,14 +943,37 @@ UINT8 FfsEngine::getVolumeSize(const QByteArray & bios, UINT32 volumeOffset, UIN
|
|||||||
|
|
||||||
volumeSize = volumeHeader->FvLength;
|
volumeSize = volumeHeader->FvLength;
|
||||||
bmVolumeSize = calcVolumeSize;
|
bmVolumeSize = calcVolumeSize;
|
||||||
|
|
||||||
|
if (volumeSize == 0)
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
|
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, const QModelIndex & parent, const UINT8 mode)
|
UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, const QModelIndex & parent, const UINT8 mode)
|
||||||
{
|
{
|
||||||
|
// Check that there is space for the volume header
|
||||||
|
if ((UINT32)volume.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER)) {
|
||||||
|
msg(tr("parseVolume: input volume size %1h (%2) is smaller than volume header size 40h (64)").hexarg(volume.size()).arg(volume.size()));
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
// Populate volume header
|
// Populate volume header
|
||||||
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(volume.constData());
|
const EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (const EFI_FIRMWARE_VOLUME_HEADER*)(volume.constData());
|
||||||
|
|
||||||
|
// Check sanity of HeaderLength value
|
||||||
|
if (ALIGN8(volumeHeader->HeaderLength) > volume.size()) {
|
||||||
|
msg(tr("parseVolume: volume header overlaps the end of data"));
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check sanity of ExtHeaderOffset value
|
||||||
|
if (volumeHeader->ExtHeaderOffset > 0
|
||||||
|
&& (UINT32)volume.size() < ALIGN8(volumeHeader->ExtHeaderOffset + sizeof(EFI_FIRMWARE_VOLUME_EXT_HEADER))) {
|
||||||
|
msg(tr("parseVolume: extended volume header overlaps the end of data"));
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate volume header size
|
// Calculate volume header size
|
||||||
UINT32 headerSize;
|
UINT32 headerSize;
|
||||||
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
|
if (volumeHeader->Revision > 1 && volumeHeader->ExtHeaderOffset) {
|
||||||
@ -940,12 +988,10 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
|
|||||||
|
|
||||||
// Check for volume structure to be known
|
// Check for volume structure to be known
|
||||||
bool volumeIsUnknown = true;
|
bool volumeIsUnknown = true;
|
||||||
/*UINT8 volumeFfsVersion = 0;*/
|
|
||||||
|
|
||||||
// Check for FFS v2 volume
|
// Check for FFS v2 volume
|
||||||
if (FFSv2Volumes.contains(QByteArray::fromRawData((const char*)volumeHeader->FileSystemGuid.Data, sizeof(EFI_GUID)))) {
|
if (FFSv2Volumes.contains(QByteArray::fromRawData((const char*)volumeHeader->FileSystemGuid.Data, sizeof(EFI_GUID)))) {
|
||||||
volumeIsUnknown = false;
|
volumeIsUnknown = false;
|
||||||
/*volumeFfsVersion = 2;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check attributes
|
// Check attributes
|
||||||
@ -1139,6 +1185,8 @@ UINT8 FfsEngine::parseVolume(const QByteArray & volume, QModelIndex & index, co
|
|||||||
|
|
||||||
UINT8 FfsEngine::getFileSize(const QByteArray & volume, const UINT32 fileOffset, UINT32 & fileSize)
|
UINT8 FfsEngine::getFileSize(const QByteArray & volume, const UINT32 fileOffset, UINT32 & fileSize)
|
||||||
{
|
{
|
||||||
|
if ((UINT32)volume.size() < fileOffset + sizeof(EFI_FFS_FILE_HEADER))
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)(volume.constData() + fileOffset);
|
const EFI_FFS_FILE_HEADER* fileHeader = (const EFI_FFS_FILE_HEADER*)(volume.constData() + fileOffset);
|
||||||
fileSize = uint24ToUint32(fileHeader->Size);
|
fileSize = uint24ToUint32(fileHeader->Size);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -1332,6 +1380,8 @@ UINT8 FfsEngine::parseFile(const QByteArray & file, QModelIndex & index, const U
|
|||||||
|
|
||||||
UINT8 FfsEngine::getSectionSize(const QByteArray & file, const UINT32 sectionOffset, UINT32 & sectionSize)
|
UINT8 FfsEngine::getSectionSize(const QByteArray & file, const UINT32 sectionOffset, UINT32 & sectionSize)
|
||||||
{
|
{
|
||||||
|
if ((UINT32)file.size() < sectionOffset + sizeof(EFI_COMMON_SECTION_HEADER))
|
||||||
|
return ERR_INVALID_FILE;
|
||||||
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(file.constData() + sectionOffset);
|
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(file.constData() + sectionOffset);
|
||||||
sectionSize = uint24ToUint32(sectionHeader->Size);
|
sectionSize = uint24ToUint32(sectionHeader->Size);
|
||||||
return ERR_SUCCESS;
|
return ERR_SUCCESS;
|
||||||
@ -1350,6 +1400,9 @@ UINT8 FfsEngine::parseSections(const QByteArray & body, const QModelIndex & pare
|
|||||||
result = getSectionSize(body, sectionOffset, sectionSize);
|
result = getSectionSize(body, sectionOffset, sectionSize);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
// Exit from loop if no sections left
|
||||||
|
if (sectionSize == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
// Parse section
|
// Parse section
|
||||||
QModelIndex sectionIndex;
|
QModelIndex sectionIndex;
|
||||||
@ -1531,6 +1584,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
bool msgInvalidCrc = false;
|
bool msgInvalidCrc = false;
|
||||||
bool msgUnknownAuth = false;
|
bool msgUnknownAuth = false;
|
||||||
bool msgSigned = false;
|
bool msgSigned = false;
|
||||||
|
bool msgInvalidSignatureLength = false;
|
||||||
bool msgUnknownSignature = false;
|
bool msgUnknownSignature = false;
|
||||||
bool msgUnknownUefiGuidSignature = false;
|
bool msgUnknownUefiGuidSignature = false;
|
||||||
|
|
||||||
@ -1594,7 +1648,12 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
else if (QByteArray((const char*)&guidDefinedSectionHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
else if (QByteArray((const char*)&guidDefinedSectionHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_FIRMWARE_CONTENTS_SIGNED_GUID) {
|
||||||
msgSigned = true;
|
msgSigned = true;
|
||||||
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)body.constData();
|
const WIN_CERTIFICATE* certificateHeader = (const WIN_CERTIFICATE*)body.constData();
|
||||||
if (certificateHeader->CertificateType == WIN_CERT_TYPE_EFI_GUID) {
|
if ((UINT32)body.size() < sizeof(WIN_CERTIFICATE)) {
|
||||||
|
info += tr("\nSignature type: invalid, wrong length");
|
||||||
|
msgInvalidSignatureLength = true;
|
||||||
|
parseCurrentSection = false;
|
||||||
|
}
|
||||||
|
else if (certificateHeader->CertificateType == WIN_CERT_TYPE_EFI_GUID) {
|
||||||
info += tr("\nSignature type: UEFI");
|
info += tr("\nSignature type: UEFI");
|
||||||
const WIN_CERTIFICATE_UEFI_GUID* guidCertificateHeader = (const WIN_CERTIFICATE_UEFI_GUID*)certificateHeader;
|
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) {
|
if (QByteArray((const char*)&guidCertificateHeader->CertType, sizeof(EFI_GUID)) == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
|
||||||
@ -1619,11 +1678,18 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
msgUnknownSignature = true;
|
msgUnknownSignature = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add additional to the header
|
if ((UINT32)body.size() < certificateHeader->Length) {
|
||||||
|
info += tr("\nSignature type: invalid, wrong length");
|
||||||
|
msgInvalidSignatureLength = true;
|
||||||
|
parseCurrentSection = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Add additional data to the header
|
||||||
header.append(body.left(certificateHeader->Length));
|
header.append(body.left(certificateHeader->Length));
|
||||||
// Get new body
|
// Get new body
|
||||||
processed = body = body.mid(certificateHeader->Length);
|
processed = body = body.mid(certificateHeader->Length);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Unknown GUIDed section
|
// Unknown GUIDed section
|
||||||
else {
|
else {
|
||||||
msgUnknownGuid = true;
|
msgUnknownGuid = true;
|
||||||
@ -1665,6 +1731,8 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
msg(tr("parseSection: signature may become invalid after any modification"), index);
|
msg(tr("parseSection: signature may become invalid after any modification"), index);
|
||||||
if (msgUnknownUefiGuidSignature)
|
if (msgUnknownUefiGuidSignature)
|
||||||
msg(tr("parseSection: GUID defined section with unknown signature subtype"), index);
|
msg(tr("parseSection: GUID defined section with unknown signature subtype"), index);
|
||||||
|
if (msgInvalidSignatureLength)
|
||||||
|
msg(tr("parseSection: GUID defined section with invalid signature length"), index);
|
||||||
if (msgUnknownSignature)
|
if (msgUnknownSignature)
|
||||||
msg(tr("parseSection: GUID defined section with unknown signature type"), index);
|
msg(tr("parseSection: GUID defined section with unknown signature type"), index);
|
||||||
|
|
||||||
@ -1796,6 +1864,7 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
|
|
||||||
// Get PE info
|
// Get PE info
|
||||||
bool msgInvalidDosSignature = false;
|
bool msgInvalidDosSignature = false;
|
||||||
|
bool msgInvalidDosHeader = false;
|
||||||
bool msgInvalidPeSignature = false;
|
bool msgInvalidPeSignature = false;
|
||||||
bool msgUnknownOptionalHeaderSignature = false;
|
bool msgUnknownOptionalHeaderSignature = false;
|
||||||
|
|
||||||
@ -1806,7 +1875,11 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const EFI_IMAGE_PE_HEADER* peHeader = (EFI_IMAGE_PE_HEADER*)(body.constData() + dosHeader->e_lfanew);
|
const EFI_IMAGE_PE_HEADER* peHeader = (EFI_IMAGE_PE_HEADER*)(body.constData() + dosHeader->e_lfanew);
|
||||||
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE) {
|
if ((UINT32)body.size() < dosHeader->e_lfanew + sizeof(EFI_IMAGE_PE_HEADER)) {
|
||||||
|
info += tr("\nDOS lfanew: %1h, invalid").hexarg2(dosHeader->e_lfanew, 8);
|
||||||
|
msgInvalidDosHeader = true;
|
||||||
|
}
|
||||||
|
else if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE) {
|
||||||
info += tr("\nPE signature: %1h, invalid").hexarg2(peHeader->Signature, 8);
|
info += tr("\nPE signature: %1h, invalid").hexarg2(peHeader->Signature, 8);
|
||||||
msgInvalidPeSignature = true;
|
msgInvalidPeSignature = true;
|
||||||
}
|
}
|
||||||
@ -1853,6 +1926,9 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||||||
if (msgInvalidDosSignature) {
|
if (msgInvalidDosSignature) {
|
||||||
msg("parseSection: PE32 image with invalid DOS signature", index);
|
msg("parseSection: PE32 image with invalid DOS signature", index);
|
||||||
}
|
}
|
||||||
|
if (msgInvalidDosHeader) {
|
||||||
|
msg("parseSection: PE32 image with invalid DOS header", index);
|
||||||
|
}
|
||||||
if (msgInvalidPeSignature) {
|
if (msgInvalidPeSignature) {
|
||||||
msg("parseSection: PE32 image with invalid PE signature", index);
|
msg("parseSection: PE32 image with invalid PE signature", index);
|
||||||
}
|
}
|
||||||
@ -2845,7 +2921,31 @@ UINT8 FfsEngine::reconstructIntelImage(const QModelIndex& index, QByteArray& rec
|
|||||||
return result;
|
return result;
|
||||||
reconstructed.append(descriptor);
|
reconstructed.append(descriptor);
|
||||||
|
|
||||||
|
// Check descriptor size
|
||||||
|
if ((UINT32)descriptor.size() < FLASH_DESCRIPTOR_SIZE) {
|
||||||
|
msg(tr("reconstructIntelImage: descriptor is smaller than minimum size of 1000h (4096) bytes"));
|
||||||
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
|
||||||
const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor.constData() + sizeof(FLASH_DESCRIPTOR_HEADER));
|
const FLASH_DESCRIPTOR_MAP* descriptorMap = (const FLASH_DESCRIPTOR_MAP*)(descriptor.constData() + sizeof(FLASH_DESCRIPTOR_HEADER));
|
||||||
|
// Check sanity of base values
|
||||||
|
if (descriptorMap->MasterBase > FLASH_DESCRIPTOR_MAX_BASE
|
||||||
|
|| descriptorMap->MasterBase == descriptorMap->RegionBase
|
||||||
|
|| descriptorMap->MasterBase == descriptorMap->ComponentBase) {
|
||||||
|
msg(tr("reconstructIntelImage: invalid descriptor master base %1h").hexarg2(descriptorMap->MasterBase, 2));
|
||||||
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
if (descriptorMap->RegionBase > FLASH_DESCRIPTOR_MAX_BASE
|
||||||
|
|| descriptorMap->RegionBase == descriptorMap->ComponentBase) {
|
||||||
|
msg(tr("reconstructIntelImage: invalid descriptor region base %1h").hexarg2(descriptorMap->RegionBase, 2));
|
||||||
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
if (descriptorMap->ComponentBase > FLASH_DESCRIPTOR_MAX_BASE) {
|
||||||
|
msg(tr("reconstructIntelImage: invalid descriptor component base %1h").hexarg2(descriptorMap->ComponentBase, 2));
|
||||||
|
return ERR_INVALID_FLASH_DESCRIPTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8((const UINT8*)descriptor.constData(), descriptorMap->RegionBase);
|
const FLASH_DESCRIPTOR_REGION_SECTION* regionSection = (const FLASH_DESCRIPTOR_REGION_SECTION*)calculateAddress8((const UINT8*)descriptor.constData(), descriptorMap->RegionBase);
|
||||||
QByteArray gbe;
|
QByteArray gbe;
|
||||||
UINT32 gbeBegin = calculateRegionOffset(regionSection->GbeBase);
|
UINT32 gbeBegin = calculateRegionOffset(regionSection->GbeBase);
|
||||||
@ -3107,6 +3207,12 @@ UINT8 FfsEngine::reconstructVolume(const QModelIndex & index, QByteArray & recon
|
|||||||
QByteArray body = model->body(index);
|
QByteArray body = model->body(index);
|
||||||
EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)header.data();
|
EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)header.data();
|
||||||
|
|
||||||
|
// Check sanity of HeaderLength
|
||||||
|
if (volumeHeader->HeaderLength > header.size()) {
|
||||||
|
msg(tr("reconstructVolume: invalid volume header length, reconstruction is not possible"), index);
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
// Recalculate volume header checksum
|
// Recalculate volume header checksum
|
||||||
volumeHeader->Checksum = 0;
|
volumeHeader->Checksum = 0;
|
||||||
volumeHeader->Checksum = calculateChecksum16((const UINT16*)volumeHeader, volumeHeader->HeaderLength);
|
volumeHeader->Checksum = calculateChecksum16((const UINT16*)volumeHeader, volumeHeader->HeaderLength);
|
||||||
@ -3170,8 +3276,8 @@ UINT8 FfsEngine::reconstructVolume(const QModelIndex & index, QByteArray & recon
|
|||||||
// Calculate relative base address
|
// Calculate relative base address
|
||||||
UINT32 relbase = fileOffset + sectionOffset + model->header(image).size();
|
UINT32 relbase = fileOffset + sectionOffset + model->header(image).size();
|
||||||
// Calculate offset of image relative to file base
|
// Calculate offset of image relative to file base
|
||||||
UINT32 imagebase;
|
UINT32 imagebase = 0;
|
||||||
result = getBase(model->body(image), imagebase);
|
result = getBase(model->body(image), imagebase); // imagebase passed by reference
|
||||||
if (!result) {
|
if (!result) {
|
||||||
// Calculate volume base
|
// Calculate volume base
|
||||||
volumeBase = imagebase - relbase;
|
volumeBase = imagebase - relbase;
|
||||||
@ -3694,6 +3800,12 @@ UINT8 FfsEngine::reconstructSection(const QModelIndex& index, const UINT32 base,
|
|||||||
if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
|
if (guidDefinedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
|
||||||
// CRC32 section
|
// CRC32 section
|
||||||
if (QByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_CRC32) {
|
if (QByteArray((const char*)&guidDefinedHeader->SectionDefinitionGuid, sizeof(EFI_GUID)) == EFI_GUIDED_SECTION_CRC32) {
|
||||||
|
// Check header size
|
||||||
|
if ((UINT32)header.size() != sizeof(EFI_GUID_DEFINED_SECTION) + sizeof(UINT32)) {
|
||||||
|
msg(tr("reconstructSection: invalid CRC32 section size %1h (%2)")
|
||||||
|
.hexarg(header.size()).arg(header.size()), index);
|
||||||
|
return ERR_INVALID_SECTION;
|
||||||
|
}
|
||||||
// Calculate CRC32 of section data
|
// Calculate CRC32 of section data
|
||||||
UINT32 crc = crc32(0, (const UINT8*)compressed.constData(), compressed.size());
|
UINT32 crc = crc32(0, (const UINT8*)compressed.constData(), compressed.size());
|
||||||
// Store new CRC32
|
// Store new CRC32
|
||||||
@ -3831,6 +3943,10 @@ UINT8 FfsEngine::reconstruct(const QModelIndex &index, QByteArray& reconstructed
|
|||||||
|
|
||||||
UINT8 FfsEngine::growVolume(QByteArray & header, const UINT32 size, UINT32 & newSize)
|
UINT8 FfsEngine::growVolume(QByteArray & header, const UINT32 size, UINT32 & newSize)
|
||||||
{
|
{
|
||||||
|
// Check sanity
|
||||||
|
if ((UINT32)header.size() < sizeof(EFI_FIRMWARE_VOLUME_HEADER))
|
||||||
|
return ERR_INVALID_VOLUME;
|
||||||
|
|
||||||
// Adjust new size to be representable by current FvBlockMap
|
// Adjust new size to be representable by current FvBlockMap
|
||||||
EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)header.data();
|
EFI_FIRMWARE_VOLUME_HEADER* volumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)header.data();
|
||||||
EFI_FV_BLOCK_MAP_ENTRY* blockMap = (EFI_FV_BLOCK_MAP_ENTRY*)(header.data() + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
|
EFI_FV_BLOCK_MAP_ENTRY* blockMap = (EFI_FV_BLOCK_MAP_ENTRY*)(header.data() + sizeof(EFI_FIRMWARE_VOLUME_HEADER));
|
||||||
@ -4042,11 +4158,15 @@ UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
|||||||
QByteArray file = executable;
|
QByteArray file = executable;
|
||||||
|
|
||||||
// Populate DOS header
|
// Populate DOS header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_DOS_HEADER))
|
||||||
|
return ERR_INVALID_FILE;
|
||||||
EFI_IMAGE_DOS_HEADER* dosHeader = (EFI_IMAGE_DOS_HEADER*)file.data();
|
EFI_IMAGE_DOS_HEADER* dosHeader = (EFI_IMAGE_DOS_HEADER*)file.data();
|
||||||
|
|
||||||
// Check signature
|
// Check signature
|
||||||
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
||||||
UINT32 offset = dosHeader->e_lfanew;
|
UINT32 offset = dosHeader->e_lfanew;
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_PE_HEADER))
|
||||||
|
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||||
EFI_IMAGE_PE_HEADER* peHeader = (EFI_IMAGE_PE_HEADER*)(file.data() + offset);
|
EFI_IMAGE_PE_HEADER* peHeader = (EFI_IMAGE_PE_HEADER*)(file.data() + offset);
|
||||||
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
||||||
return ERR_UNKNOWN_IMAGE_TYPE;
|
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||||
@ -4054,8 +4174,12 @@ UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
|||||||
// Skip file header
|
// Skip file header
|
||||||
offset += sizeof(EFI_IMAGE_FILE_HEADER);
|
offset += sizeof(EFI_IMAGE_FILE_HEADER);
|
||||||
// Check optional header magic
|
// Check optional header magic
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(UINT16))
|
||||||
|
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||||
UINT16 magic = *(UINT16*)(file.data() + offset);
|
UINT16 magic = *(UINT16*)(file.data() + offset);
|
||||||
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER32))
|
||||||
|
return ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (EFI_IMAGE_OPTIONAL_HEADER32*)(file.data() + offset);
|
EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (EFI_IMAGE_OPTIONAL_HEADER32*)(file.data() + offset);
|
||||||
delta = base - optHeader->ImageBase;
|
delta = base - optHeader->ImageBase;
|
||||||
if (!delta)
|
if (!delta)
|
||||||
@ -4067,6 +4191,8 @@ UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
|||||||
optHeader->ImageBase = base;
|
optHeader->ImageBase = base;
|
||||||
}
|
}
|
||||||
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER64))
|
||||||
|
return ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (EFI_IMAGE_OPTIONAL_HEADER64*)(file.data() + offset);
|
EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (EFI_IMAGE_OPTIONAL_HEADER64*)(file.data() + offset);
|
||||||
delta = base - optHeader->ImageBase;
|
delta = base - optHeader->ImageBase;
|
||||||
if (!delta)
|
if (!delta)
|
||||||
@ -4082,6 +4208,8 @@ UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
|||||||
}
|
}
|
||||||
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
||||||
// Populate TE header
|
// Populate TE header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_TE_HEADER))
|
||||||
|
return ERR_INVALID_FILE;
|
||||||
EFI_IMAGE_TE_HEADER* teHeader = (EFI_IMAGE_TE_HEADER*)file.data();
|
EFI_IMAGE_TE_HEADER* teHeader = (EFI_IMAGE_TE_HEADER*)file.data();
|
||||||
delta = base - teHeader->ImageBase;
|
delta = base - teHeader->ImageBase;
|
||||||
if (!delta)
|
if (!delta)
|
||||||
@ -4121,7 +4249,10 @@ UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
|||||||
|
|
||||||
// Run this relocation record
|
// Run this relocation record
|
||||||
while (Reloc < RelocEnd) {
|
while (Reloc < RelocEnd) {
|
||||||
UINT8* data = (UINT8*)(file.data() + RelocBase->VirtualAddress - teFixup + (*Reloc & 0x0FFF));
|
UINT32 RelocLocation = RelocBase->VirtualAddress - teFixup + (*Reloc & 0x0FFF);
|
||||||
|
if ((UINT32)file.size() < RelocLocation)
|
||||||
|
return ERR_BAD_RELOCATION_ENTRY;
|
||||||
|
UINT8* data = (UINT8*)(file.data() + RelocLocation);
|
||||||
switch ((*Reloc) >> 12) {
|
switch ((*Reloc) >> 12) {
|
||||||
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
||||||
// Do nothing
|
// Do nothing
|
||||||
@ -4197,11 +4328,15 @@ UINT8 FfsEngine::getEntryPoint(const QByteArray &file, UINT32& entryPoint)
|
|||||||
return ERR_INVALID_FILE;
|
return ERR_INVALID_FILE;
|
||||||
|
|
||||||
// Populate DOS header
|
// Populate DOS header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_DOS_HEADER))
|
||||||
|
return ERR_INVALID_FILE;
|
||||||
const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)file.constData();
|
const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)file.constData();
|
||||||
|
|
||||||
// Check signature
|
// Check signature
|
||||||
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
||||||
UINT32 offset = dosHeader->e_lfanew;
|
UINT32 offset = dosHeader->e_lfanew;
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_PE_HEADER))
|
||||||
|
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||||
const EFI_IMAGE_PE_HEADER* peHeader = (const EFI_IMAGE_PE_HEADER*)(file.constData() + offset);
|
const EFI_IMAGE_PE_HEADER* peHeader = (const EFI_IMAGE_PE_HEADER*)(file.constData() + offset);
|
||||||
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
||||||
return ERR_UNKNOWN_IMAGE_TYPE;
|
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||||
@ -4213,10 +4348,14 @@ UINT8 FfsEngine::getEntryPoint(const QByteArray &file, UINT32& entryPoint)
|
|||||||
// Check optional header magic
|
// Check optional header magic
|
||||||
const UINT16 magic = *(const UINT16*)(file.constData() + offset);
|
const UINT16 magic = *(const UINT16*)(file.constData() + offset);
|
||||||
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER32))
|
||||||
|
return ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
const EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER32*)(file.constData() + offset);
|
const EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER32*)(file.constData() + offset);
|
||||||
entryPoint = optHeader->ImageBase + optHeader->AddressOfEntryPoint;
|
entryPoint = optHeader->ImageBase + optHeader->AddressOfEntryPoint;
|
||||||
}
|
}
|
||||||
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER64))
|
||||||
|
return ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
const EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER64*)(file.constData() + offset);
|
const EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER64*)(file.constData() + offset);
|
||||||
entryPoint = optHeader->ImageBase + optHeader->AddressOfEntryPoint;
|
entryPoint = optHeader->ImageBase + optHeader->AddressOfEntryPoint;
|
||||||
}
|
}
|
||||||
@ -4225,6 +4364,8 @@ UINT8 FfsEngine::getEntryPoint(const QByteArray &file, UINT32& entryPoint)
|
|||||||
}
|
}
|
||||||
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
||||||
// Populate TE header
|
// Populate TE header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_TE_HEADER))
|
||||||
|
return ERR_INVALID_FILE;
|
||||||
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)file.constData();
|
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)file.constData();
|
||||||
UINT32 teFixup = teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
UINT32 teFixup = teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
||||||
entryPoint = teHeader->ImageBase + teHeader->AddressOfEntryPoint - teFixup;
|
entryPoint = teHeader->ImageBase + teHeader->AddressOfEntryPoint - teFixup;
|
||||||
@ -4238,11 +4379,15 @@ UINT8 FfsEngine::getBase(const QByteArray& file, UINT32& base)
|
|||||||
return ERR_INVALID_FILE;
|
return ERR_INVALID_FILE;
|
||||||
|
|
||||||
// Populate DOS header
|
// Populate DOS header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_DOS_HEADER))
|
||||||
|
return ERR_INVALID_FILE;
|
||||||
const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)file.constData();
|
const EFI_IMAGE_DOS_HEADER* dosHeader = (const EFI_IMAGE_DOS_HEADER*)file.constData();
|
||||||
|
|
||||||
// Check signature
|
// Check signature
|
||||||
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
if (dosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE){
|
||||||
UINT32 offset = dosHeader->e_lfanew;
|
UINT32 offset = dosHeader->e_lfanew;
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_PE_HEADER))
|
||||||
|
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||||
const EFI_IMAGE_PE_HEADER* peHeader = (const EFI_IMAGE_PE_HEADER*)(file.constData() + offset);
|
const EFI_IMAGE_PE_HEADER* peHeader = (const EFI_IMAGE_PE_HEADER*)(file.constData() + offset);
|
||||||
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
if (peHeader->Signature != EFI_IMAGE_PE_SIGNATURE)
|
||||||
return ERR_UNKNOWN_IMAGE_TYPE;
|
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||||
@ -4254,10 +4399,14 @@ UINT8 FfsEngine::getBase(const QByteArray& file, UINT32& base)
|
|||||||
// Check optional header magic
|
// Check optional header magic
|
||||||
const UINT16 magic = *(const UINT16*)(file.constData() + offset);
|
const UINT16 magic = *(const UINT16*)(file.constData() + offset);
|
||||||
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
if (magic == EFI_IMAGE_PE_OPTIONAL_HDR32_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER32))
|
||||||
|
return ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
const EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER32*)(file.constData() + offset);
|
const EFI_IMAGE_OPTIONAL_HEADER32* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER32*)(file.constData() + offset);
|
||||||
base = optHeader->ImageBase;
|
base = optHeader->ImageBase;
|
||||||
}
|
}
|
||||||
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
else if (magic == EFI_IMAGE_PE_OPTIONAL_HDR64_MAGIC) {
|
||||||
|
if ((UINT32)file.size() < offset + sizeof(EFI_IMAGE_OPTIONAL_HEADER64))
|
||||||
|
return ERR_UNKNOWN_PE_OPTIONAL_HEADER_TYPE;
|
||||||
const EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER64*)(file.constData() + offset);
|
const EFI_IMAGE_OPTIONAL_HEADER64* optHeader = (const EFI_IMAGE_OPTIONAL_HEADER64*)(file.constData() + offset);
|
||||||
base = optHeader->ImageBase;
|
base = optHeader->ImageBase;
|
||||||
}
|
}
|
||||||
@ -4266,6 +4415,8 @@ UINT8 FfsEngine::getBase(const QByteArray& file, UINT32& base)
|
|||||||
}
|
}
|
||||||
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
else if (dosHeader->e_magic == EFI_IMAGE_TE_SIGNATURE){
|
||||||
// Populate TE header
|
// Populate TE header
|
||||||
|
if ((UINT32)file.size() < sizeof(EFI_IMAGE_TE_HEADER))
|
||||||
|
return ERR_INVALID_FILE;
|
||||||
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)file.constData();
|
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)file.constData();
|
||||||
//!TODO: add handling
|
//!TODO: add handling
|
||||||
base = teHeader->ImageBase;
|
base = teHeader->ImageBase;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
UEFITool::UEFITool(QWidget *parent) :
|
UEFITool::UEFITool(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::UEFITool),
|
ui(new Ui::UEFITool),
|
||||||
version(tr("0.21.4"))
|
version(tr("0.21.5"))
|
||||||
{
|
{
|
||||||
clipboard = QApplication::clipboard();
|
clipboard = QApplication::clipboard();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user