mirror of
https://github.com/LongSoft/UEFITool.git
synced 2025-05-20 18:25:27 -04:00
UEFIPatch 0.2.0 / UEFITool 0.18.0
- updated EFI11/Tiano compression and decompression code to UDK2014 versions - UEFIPatch rewritten to support offset-based patches and patterns with placeholder symbols
This commit is contained in:
parent
a3854ad059
commit
c23aef47be
11 changed files with 2227 additions and 2429 deletions
|
@ -56,6 +56,7 @@ UINT8 UEFIPatch::patchFromFile(QString path)
|
|||
if (result)
|
||||
return result;
|
||||
|
||||
UINT8 counter = 0;
|
||||
while (!file.atEnd()) {
|
||||
QByteArray line = file.readLine();
|
||||
// Use sharp sign as commentary
|
||||
|
@ -68,20 +69,46 @@ UINT8 UEFIPatch::patchFromFile(QString path)
|
|||
|
||||
QUuid uuid = QUuid(list.at(0));
|
||||
QByteArray guid = QByteArray::fromRawData((const char*)&uuid.data1, sizeof(EFI_GUID));
|
||||
result = patchFile(model->index(0, 0), guid, QByteArray::fromHex(list.at(1)), QByteArray::fromHex(list.at(2)));
|
||||
if (result)
|
||||
bool converted;
|
||||
UINT8 sectionType = (UINT8)list.at(1).toUShort(&converted, 16);
|
||||
if (!converted)
|
||||
return ERR_INVALID_PARAMETER;
|
||||
|
||||
QVector<PatchData> patches;
|
||||
|
||||
for (int i = 2; i < list.count(); i++) {
|
||||
QList<QByteArray> patchList = list.at(i).split(':');
|
||||
PatchData patch;
|
||||
patch.type = *(UINT8*)patchList.at(0).constData();
|
||||
if (patch.type == PATCH_TYPE_PATTERN) {
|
||||
patch.offset = 0xFFFFFFFF;
|
||||
patch.hexFindPattern = patchList.at(1);
|
||||
patch.hexReplacePattern = patchList.at(2);
|
||||
patches.append(patch);
|
||||
}
|
||||
else if (patch.type == PATCH_TYPE_OFFSET) {
|
||||
patch.offset = patchList.at(1).toUInt(NULL, 16);
|
||||
patch.hexReplacePattern = patchList.at(2);
|
||||
patches.append(patch);
|
||||
}
|
||||
else {
|
||||
// Ignore unknown patch type
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result = patchFile(model->index(0, 0), guid, sectionType, patches);
|
||||
if (result && result != ERR_NOTHING_TO_PATCH)
|
||||
return result;
|
||||
counter++;
|
||||
}
|
||||
|
||||
QByteArray reconstructed;
|
||||
result = ffsEngine->reconstructImageFile(reconstructed);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (reconstructed == buffer) {
|
||||
return ERR_ITEM_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (reconstructed == buffer)
|
||||
return ERR_NOTHING_TO_PATCH;
|
||||
|
||||
QFile outputFile;
|
||||
outputFile.setFileName(path.append(".patched"));
|
||||
if (!outputFile.open(QFile::WriteOnly))
|
||||
|
@ -94,72 +121,29 @@ UINT8 UEFIPatch::patchFromFile(QString path)
|
|||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT8 UEFIPatch::patch(QString path, QString fileGuid, QString findPattern, QString replacePattern)
|
||||
{
|
||||
QFileInfo fileInfo = QFileInfo(path);
|
||||
|
||||
if (!fileInfo.exists())
|
||||
return ERR_FILE_OPEN;
|
||||
|
||||
QFile inputFile;
|
||||
inputFile.setFileName(path);
|
||||
|
||||
if (!inputFile.open(QFile::ReadOnly))
|
||||
return ERR_FILE_READ;
|
||||
|
||||
QByteArray buffer = inputFile.readAll();
|
||||
inputFile.close();
|
||||
|
||||
UINT8 result = ffsEngine->parseImageFile(buffer);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
|
||||
QUuid uuid = QUuid(fileGuid);
|
||||
QByteArray guid = QByteArray::fromRawData((const char*)&uuid.data1, sizeof(EFI_GUID));
|
||||
result = patchFile(model->index(0, 0), guid, QByteArray::fromHex(findPattern.toLatin1()), QByteArray::fromHex(replacePattern.toLatin1()));
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
QByteArray reconstructed;
|
||||
result = ffsEngine->reconstructImageFile(reconstructed);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
if (reconstructed == buffer) {
|
||||
return ERR_ITEM_NOT_FOUND;
|
||||
}
|
||||
|
||||
QFile outputFile;
|
||||
outputFile.setFileName(path.append(".patched"));
|
||||
if (!outputFile.open(QFile::WriteOnly))
|
||||
return ERR_FILE_WRITE;
|
||||
|
||||
outputFile.resize(0);
|
||||
outputFile.write(reconstructed);
|
||||
outputFile.close();
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT8 UEFIPatch::patchFile(const QModelIndex & index, const QByteArray & fileGuid, const QByteArray & findPattern, const QByteArray & replacePattern)
|
||||
UINT8 UEFIPatch::patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches)
|
||||
{
|
||||
|
||||
if (!model || !index.isValid())
|
||||
return ERR_INVALID_PARAMETER;
|
||||
|
||||
if (model->type(index) == Types::File && model->header(index).left(sizeof(EFI_GUID)) == fileGuid) {
|
||||
return ffsEngine->patch(index, findPattern, replacePattern, PATCH_MODE_BODY);
|
||||
if (model->type(index) == Types::Section && model->subtype(index) == sectionType) {
|
||||
QModelIndex fileIndex = model->findParentOfType(index, Types::File);
|
||||
if (model->type(fileIndex) == Types::File &&
|
||||
model->header(fileIndex).left(sizeof(EFI_GUID)) == fileGuid)
|
||||
{
|
||||
return ffsEngine->patch(index, patches);
|
||||
}
|
||||
}
|
||||
|
||||
int childCount = model->rowCount(index);
|
||||
if (childCount > 0) {
|
||||
UINT8 result;
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
result = patchFile(index.child(i, 0), fileGuid, findPattern, replacePattern);
|
||||
if (result)
|
||||
if (model->rowCount(index) > 0) {
|
||||
for (int i = 0; i < model->rowCount(index); i++) {
|
||||
UINT8 result = patchFile(index.child(i, 0), fileGuid, sectionType, patches);
|
||||
if (!result)
|
||||
break;
|
||||
else if (result != ERR_NOTHING_TO_PATCH)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
return ERR_NOTHING_TO_PATCH;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
UINT8 patch(QString path, QString fileGuid, QString findPattern, QString replacePattern);
|
||||
|
||||
private:
|
||||
UINT8 patchFile(const QModelIndex & index, const QByteArray & fileGuid, const QByteArray & findPattern, const QByteArray & replacePattern);
|
||||
UINT8 patchFile(const QModelIndex & index, const QByteArray & fileGuid, const UINT8 sectionType, const QVector<PatchData> & patches);
|
||||
FfsEngine* ffsEngine;
|
||||
TreeModel* model;
|
||||
};
|
||||
|
|
|
@ -27,31 +27,34 @@ int main(int argc, char *argv[])
|
|||
UINT8 result = ERR_SUCCESS;
|
||||
UINT32 argumentsCount = a.arguments().length();
|
||||
|
||||
|
||||
if (argumentsCount == 2) {
|
||||
result = w.patchFromFile(a.arguments().at(1));
|
||||
}
|
||||
else if (argumentsCount == 5) {
|
||||
result = w.patch(a.arguments().at(1), a.arguments().at(2), a.arguments().at(3), a.arguments().at(4));
|
||||
else {
|
||||
std::cout << "UEFIPatch 0.2.0 - 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;
|
||||
}
|
||||
else
|
||||
result = ERR_INVALID_PARAMETER;
|
||||
|
||||
switch (result) {
|
||||
case ERR_INVALID_PARAMETER:
|
||||
std::cout << "UEFIPatch 0.1.0 - UEFI image file patching utility" << std::endl << std::endl <<
|
||||
"Usage: UEFIPatch image_file [ffs_file_guid search_pattern replace_pattern]" << std::endl << std::endl <<
|
||||
"image_file - full or relative path to UEFI image file" << std::endl <<
|
||||
"ffs_file_guid - GUID of FFS file to be patched" << std::endl <<
|
||||
"search_pattern - pattern to search" << std::endl <<
|
||||
"replace_pattern - pattern to replace" << std::endl << std::endl <<
|
||||
"If only image_file parameter is specified, patches will be read from patches.txt file";
|
||||
break;
|
||||
case ERR_SUCCESS:
|
||||
std::cout << "Image patched" << std::endl;
|
||||
break;
|
||||
case ERR_ITEM_NOT_FOUND:
|
||||
std::cout << "FFS file or search pattern not found in input file" << std::endl;
|
||||
case ERR_INVALID_PARAMETER:
|
||||
std::cout << "Function called with invalid parameter" << std::endl;
|
||||
break;
|
||||
case ERR_NOTHING_TO_PATCH:
|
||||
std::cout << "No patches can be applied to input file" << std::endl;
|
||||
break;
|
||||
case ERR_UNKNOWN_PATCH_TYPE:
|
||||
std::cout << "Unknown patch type" << std::endl;
|
||||
break;
|
||||
case ERR_PATCH_OFFSET_OUT_OF_BOUNDS:
|
||||
std::cout << "Patch offset out of bounds" << std::endl;
|
||||
break;
|
||||
case ERR_INVALID_SYMBOL:
|
||||
std::cout << "Pattern format mismatch" << std::endl;
|
||||
break;
|
||||
case ERR_INVALID_FILE:
|
||||
std::cout << "patches.txt file not found or can't be read" << std::endl;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue