mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-05-13 06:34:42 -04:00
multiple fixes
This commit is contained in:
parent
9d623c91e6
commit
df95f0755c
8 changed files with 101 additions and 65 deletions
|
@ -1,6 +1,6 @@
|
|||
/* uefiextract_main.cpp
|
||||
|
||||
Copyright (c) 2015, Nikolaj Schlej. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. 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
|
||||
|
@ -19,8 +19,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
a.setOrganizationName("CodeRush");
|
||||
a.setOrganizationDomain("coderush.me");
|
||||
a.setOrganizationName("LongSoft");
|
||||
a.setOrganizationDomain("longsoft.me");
|
||||
a.setApplicationName("UEFIExtract");
|
||||
|
||||
UEFIExtract w;
|
||||
|
@ -52,7 +52,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
}
|
||||
else {
|
||||
std::cout << "UEFIExtract 0.4.4" << std::endl << std::endl <<
|
||||
std::cout << "UEFIExtract 0.4.5" << 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;
|
||||
|
|
|
@ -34,6 +34,7 @@ F7731B4C-58A2-4DF4-8980-5645D39ECE58 10 P:0FBA6C24380F:0FBA7424380F
|
|||
|
||||
# PowerManagement | Sandy Bridge with ME 8.xx, Ivy Bridge
|
||||
8C783970-F02A-4A4D-AF09-8797A51EEC8D 10 P:75080FBAE80F89442430:EB080FBAE80F89442430
|
||||
|
||||
# PowerManagement | New SB-E/IB-E
|
||||
8C783970-F02A-4A4D-AF09-8797A51EEC8D 10 P:0FBA6C24380F:0FBA7424380F
|
||||
|
||||
|
@ -50,3 +51,10 @@ F7731B4C-58A2-4DF4-8980-5645D39ECE58 10 P:0FBA6C24380F:0FBA7424380F
|
|||
# SiInit | Kaby Lake
|
||||
299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9 10 P:81E10080000033C1:9090909090909090
|
||||
299D6F8B-2EC9-4E40-9EC6-DDAA7EBF5FD9 12 P:81E10080000033C1:9090909090909090
|
||||
|
||||
# SiInit | Skylake-X
|
||||
D71C8BA4-4AF2-4D0D-B1BA-F2409F0C20D3 10 P:81E10080000033C1:9090909090909090
|
||||
D71C8BA4-4AF2-4D0D-B1BA-F2409F0C20D3 12 P:81E10080000033C1:9090909090909090
|
||||
|
||||
# PpmInitialize | Skylake-X, Kaby Lake-X
|
||||
3FFCAE95-23CF-4967-94F5-16352F68E43B 10 P:0FBAE80F:0FBAE00F
|
|
@ -1,6 +1,6 @@
|
|||
/* uefipatch_main.cpp
|
||||
|
||||
Copyright (c) 2017, LongSoft. All rights reserved.
|
||||
Copyright (c) 2018, LongSoft. 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.11 - UEFI image file patching utility" << std::endl << std::endl <<
|
||||
std::cout << "UEFIPatch 0.3.12 - 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;
|
||||
|
|
|
@ -19,8 +19,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
a.setOrganizationName("CodeRush");
|
||||
a.setOrganizationDomain("coderush.me");
|
||||
a.setOrganizationName("LongSoft");
|
||||
a.setOrganizationDomain("longsoft.me");
|
||||
a.setApplicationName("UEFIReplace");
|
||||
|
||||
UEFIReplace r;
|
||||
|
@ -28,7 +28,7 @@ int main(int argc, char *argv[])
|
|||
QStringList args = a.arguments();
|
||||
|
||||
if (args.length() < 5) {
|
||||
std::cout << "UEFIReplace 0.3.9 - UEFI image file replacement utility" << std::endl << std::endl <<
|
||||
std::cout << "UEFIReplace 0.1.1 - UEFI image file replacement utility" << std::endl << std::endl <<
|
||||
"Usage: UEFIReplace image_file guid section_type contents_file" << std::endl;
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -871,7 +871,7 @@ UINT8 FfsEngine::parseBios(const QByteArray & bios, const QModelIndex & parent)
|
|||
if (msgUnknownRevision)
|
||||
msg(tr("parseBios: unknown volume revision %1").arg(volumeHeader->Revision), index);
|
||||
if (msgSizeMismach)
|
||||
msg(tr("parseBios: volume size stored in header %1h differs from calculated using block map %3h")
|
||||
msg(tr("parseBios: volume size stored in header %1h differs from calculated using block map %2h")
|
||||
.hexarg(volumeSize).arg(bmVolumeSize),
|
||||
index);
|
||||
|
||||
|
@ -1825,7 +1825,11 @@ UINT8 FfsEngine::parseSection(const QByteArray & section, QModelIndex & index, c
|
|||
// Get TE info
|
||||
bool msgInvalidSignature = false;
|
||||
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)body.constData();
|
||||
UINT32 teFixup = teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
||||
|
||||
// Most EFI images today include teFixup in ImageBase value,
|
||||
// which doesn't follow the UEFI spec, but is so popular that
|
||||
// only a few images out of thousands are different
|
||||
UINT32 teFixup = 0; //teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
||||
if (teHeader->Signature != EFI_IMAGE_TE_SIGNATURE) {
|
||||
info += tr("\nSignature: %1h, invalid").hexarg2(teHeader->Signature, 4);
|
||||
msgInvalidSignature = true;
|
||||
|
@ -3543,18 +3547,21 @@ UINT8 FfsEngine::reconstructVolume(const QModelIndex & index, QByteArray & recon
|
|||
volumeSize = newSize;
|
||||
}
|
||||
}
|
||||
|
||||
// Check new volume size
|
||||
if ((UINT32)(header.size() + reconstructed.size()) > volumeSize)
|
||||
{
|
||||
msg(tr("reconstructVolume: volume grow failed"), index);
|
||||
return ERR_INVALID_VOLUME;
|
||||
}
|
||||
}
|
||||
// Use current volume body
|
||||
else
|
||||
else {
|
||||
reconstructed = model->body(index);
|
||||
|
||||
// BUGBUG: volume size may change during this operation for volumes withour files in them
|
||||
// but such volumes are fairly rare
|
||||
}
|
||||
|
||||
// Check new volume size
|
||||
if ((UINT32)(header.size() + reconstructed.size()) != volumeSize) {
|
||||
msg(tr("reconstructVolume: volume size can't be changed"), index);
|
||||
return ERR_INVALID_VOLUME;
|
||||
}
|
||||
|
||||
// Reconstruction successful
|
||||
reconstructed = header.append(reconstructed);
|
||||
|
||||
|
@ -3574,6 +3581,7 @@ UINT8 FfsEngine::reconstructVolume(const QModelIndex & index, QByteArray & recon
|
|||
volumeHeader->Checksum = calculateChecksum16((const UINT16*)volumeHeader, volumeHeader->HeaderLength);
|
||||
}
|
||||
}
|
||||
|
||||
// Store new free space offset, if needed
|
||||
if (model->text(index).contains("AppleFSO ")) {
|
||||
// Get current CRC32 value from volume header
|
||||
|
@ -3716,14 +3724,19 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision,
|
|||
offset += section.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use current file body
|
||||
else
|
||||
reconstructed = model->body(index);
|
||||
|
||||
// Correct file size
|
||||
UINT8 tailSize = (revision == 1 && (fileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT)) ? sizeof(UINT16) : 0;
|
||||
if (revision > 1 && (fileHeader->Attributes & FFS_ATTRIB_LARGE_FILE)) {
|
||||
uint32ToUint24(EFI_SECTION2_IS_USED, fileHeader->Size);
|
||||
EFI_FFS_FILE_HEADER2* fileHeader2 = (EFI_FFS_FILE_HEADER2*) fileHeader;
|
||||
EFI_FFS_FILE_HEADER2* fileHeader2 = (EFI_FFS_FILE_HEADER2*)fileHeader;
|
||||
fileHeader2->ExtendedSize = sizeof(EFI_FFS_FILE_HEADER2) + reconstructed.size() + tailSize;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (sizeof(EFI_FFS_FILE_HEADER) + reconstructed.size() + tailSize > 0xFFFFFF) {
|
||||
msg(tr("reconstructFile: resulting file size is too big"), index);
|
||||
return ERR_INVALID_FILE;
|
||||
|
@ -3735,10 +3748,6 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision,
|
|||
fileHeader->IntegrityCheck.Checksum.Header = 0;
|
||||
fileHeader->IntegrityCheck.Checksum.File = 0;
|
||||
fileHeader->IntegrityCheck.Checksum.Header = 0x100 - (calculateSum8((const UINT8*)header.constData(), header.size()) - fileHeader->State);
|
||||
}
|
||||
// Use current file body
|
||||
else
|
||||
reconstructed = model->body(index);
|
||||
|
||||
// Recalculate data checksum, if needed
|
||||
if (fileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {
|
||||
|
@ -3755,6 +3764,7 @@ UINT8 FfsEngine::reconstructFile(const QModelIndex& index, const UINT8 revision,
|
|||
UINT8 ft = ~fileHeader->IntegrityCheck.Checksum.File;
|
||||
reconstructed.append(ht).append(ft);
|
||||
}
|
||||
|
||||
// Set file state
|
||||
state = EFI_FILE_DATA_VALID | EFI_FILE_HEADER_VALID | EFI_FILE_HEADER_CONSTRUCTION;
|
||||
if (erasePolarity == ERASE_POLARITY_TRUE)
|
||||
|
@ -3793,7 +3803,7 @@ UINT8 FfsEngine::reconstructSection(const QModelIndex& index, const UINT32 base,
|
|||
QByteArray header = model->header(index);
|
||||
EFI_COMMON_SECTION_HEADER* commonHeader = (EFI_COMMON_SECTION_HEADER*)header.data();
|
||||
bool extended = false;
|
||||
if(uint24ToUint32(commonHeader->Size) == 0xFFFFFF) {
|
||||
if (uint24ToUint32(commonHeader->Size) == 0xFFFFFF) {
|
||||
extended = true;
|
||||
}
|
||||
|
||||
|
@ -3894,19 +3904,21 @@ UINT8 FfsEngine::reconstructSection(const QModelIndex& index, const UINT32 base,
|
|||
.arg(model->subtype(index)), index);
|
||||
return ERR_INVALID_SECTION;
|
||||
}
|
||||
}
|
||||
// Leaf section
|
||||
else {
|
||||
reconstructed = model->body(index);
|
||||
}
|
||||
|
||||
// Correct section size
|
||||
if (extended) {
|
||||
EFI_COMMON_SECTION_HEADER2 * extHeader = (EFI_COMMON_SECTION_HEADER2*) commonHeader;
|
||||
EFI_COMMON_SECTION_HEADER2 * extHeader = (EFI_COMMON_SECTION_HEADER2*)commonHeader;
|
||||
extHeader->ExtendedSize = header.size() + reconstructed.size();
|
||||
uint32ToUint24(0xFFFFFF, commonHeader->Size);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
uint32ToUint24(header.size() + reconstructed.size(), commonHeader->Size);
|
||||
}
|
||||
}
|
||||
// Leaf section
|
||||
else
|
||||
reconstructed = model->body(index);
|
||||
|
||||
// Rebase PE32 or TE image, if needed
|
||||
if ((model->subtype(index) == EFI_SECTION_PE32 || model->subtype(index) == EFI_SECTION_TE) &&
|
||||
|
@ -3914,14 +3926,22 @@ UINT8 FfsEngine::reconstructSection(const QModelIndex& index, const UINT32 base,
|
|||
model->subtype(index.parent()) == EFI_FV_FILETYPE_PEIM ||
|
||||
model->subtype(index.parent()) == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
|
||||
UINT16 teFixup = 0;
|
||||
//TODO: add proper handling
|
||||
/*if (model->subtype(index) == EFI_SECTION_TE) {
|
||||
const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)model->body(index).constData();
|
||||
teFixup = teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
||||
}*/
|
||||
|
||||
// Most EFI images today include teFixup in ImageBase value,
|
||||
// which doesn't follow the UEFI spec, but is so popular that
|
||||
// only a few images out of thousands are different
|
||||
|
||||
// There are some heuristics possible here to detect if an entry point is calculated correctly
|
||||
// or needs a proper fixup, but new_engine already have them and it's better to work on proper
|
||||
// builder for it than trying to fix this mess
|
||||
|
||||
//if (model->subtype(index) == EFI_SECTION_TE) {
|
||||
// const EFI_IMAGE_TE_HEADER* teHeader = (const EFI_IMAGE_TE_HEADER*)model->body(index).constData();
|
||||
// teFixup = teHeader->StrippedSize - sizeof(EFI_IMAGE_TE_HEADER);
|
||||
//
|
||||
|
||||
if (base) {
|
||||
result = rebase(reconstructed, base - teFixup + header.size());
|
||||
result = rebase(reconstructed, base - teFixup + header.size(), index);
|
||||
if (result) {
|
||||
msg(tr("reconstructSection: executable section rebase failed"), index);
|
||||
return result;
|
||||
|
@ -4217,7 +4237,7 @@ UINT8 FfsEngine::findTextPattern(const QModelIndex & index, const QString & patt
|
|||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
||||
UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base, const QModelIndex & index)
|
||||
{
|
||||
UINT32 delta; // Difference between old and new base addresses
|
||||
UINT32 relocOffset; // Offset of relocation region
|
||||
|
@ -4290,6 +4310,9 @@ UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
|||
relocSize = teHeader->DataDirectory[EFI_IMAGE_TE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||
// Set new base
|
||||
teHeader->ImageBase = base;
|
||||
|
||||
// Warn the user about possible outcome of incorrect rebase of TE image
|
||||
msg(tr("rebase: can't determine if TE image base is adjusted or not, rebased TE image may stop working"), index);
|
||||
}
|
||||
else
|
||||
return ERR_UNKNOWN_IMAGE_TYPE;
|
||||
|
@ -4319,6 +4342,12 @@ UINT8 FfsEngine::rebase(QByteArray &executable, const UINT32 base)
|
|||
|
||||
// Run this relocation record
|
||||
while (Reloc < RelocEnd) {
|
||||
if (*Reloc == 0x0000) {
|
||||
// Skip last emtpy reloc entry
|
||||
Reloc += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
UINT32 RelocLocation = RelocBase->VirtualAddress - teFixup + (*Reloc & 0x0FFF);
|
||||
if ((UINT32)file.size() < RelocLocation)
|
||||
return ERR_BAD_RELOCATION_ENTRY;
|
||||
|
|
|
@ -84,7 +84,6 @@ public:
|
|||
UINT8 reconstructIntelImage(const QModelIndex& index, QByteArray & reconstructed);
|
||||
UINT8 reconstructRegion(const QModelIndex& index, QByteArray & reconstructed, bool includeHeader = true);
|
||||
UINT8 reconstructPadding(const QModelIndex& index, QByteArray & reconstructed);
|
||||
UINT8 reconstructBios(const QModelIndex& index, QByteArray & reconstructed);
|
||||
UINT8 reconstructVolume(const QModelIndex& index, QByteArray & reconstructed);
|
||||
UINT8 reconstructFile(const QModelIndex& index, const UINT8 revision, const UINT8 erasePolarity, const UINT32 base, QByteArray& reconstructed);
|
||||
UINT8 reconstructSection(const QModelIndex& index, const UINT32 base, QByteArray & reconstructed);
|
||||
|
@ -126,7 +125,7 @@ private:
|
|||
// Rebase routines
|
||||
UINT8 getBase(const QByteArray& file, UINT32& base);
|
||||
UINT8 getEntryPoint(const QByteArray& file, UINT32 &entryPoint);
|
||||
UINT8 rebase(QByteArray & executable, const UINT32 base);
|
||||
UINT8 rebase(QByteArray & executable, const UINT32 base, const QModelIndex & index);
|
||||
void rebasePeiFiles(const QModelIndex & index);
|
||||
|
||||
// Patch routines
|
||||
|
|
|
@ -69,7 +69,7 @@ QString itemSubtypeToQString(const UINT8 type, const UINT8 subtype)
|
|||
case Types::Image:
|
||||
if (subtype == Subtypes::IntelImage)
|
||||
return QObject::tr("Intel");
|
||||
else if (Subtypes::UefiImage)
|
||||
else if (subtype == Subtypes::UefiImage)
|
||||
return QObject::tr("UEFI");
|
||||
else
|
||||
return QObject::tr("Unknown subtype");
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
UEFITool::UEFITool(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::UEFITool),
|
||||
version(tr("0.22.2"))
|
||||
version(tr("0.22.3"))
|
||||
{
|
||||
clipboard = QApplication::clipboard();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue