Version 0.2.1

Added checks for files with invalid size
This commit is contained in:
Nikolaj Schlej 2013-10-08 18:59:09 +02:00
parent 4afe74850d
commit 05f1becfe6
5 changed files with 67 additions and 84 deletions

View File

@ -70,6 +70,7 @@ typedef uint16_t CHAR16;
#define ERR_INVALID_VOLUME 11 #define ERR_INVALID_VOLUME 11
#define ERR_VOLUME_REVISION_NOT_SUPPORTED 12 #define ERR_VOLUME_REVISION_NOT_SUPPORTED 12
#define ERR_UNKNOWN_FFS 13 #define ERR_UNKNOWN_FFS 13
#define ERR_INVALID_FILE 14
// EFI GUID // EFI GUID

10
ffs.cpp
View File

@ -17,7 +17,10 @@ const UINT8 ffsAlignmentTable[] =
UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize) UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize)
{ {
UINT8 counter = 0; if(!buffer)
return 0;
UINT8 counter = 0;
while(bufferSize--) while(bufferSize--)
counter += buffer[bufferSize]; counter += buffer[bufferSize];
return ~counter + 1; return ~counter + 1;
@ -25,7 +28,10 @@ UINT8 calculateChecksum8(UINT8* buffer, UINT32 bufferSize)
UINT16 calculateChecksum16(UINT8* buffer, UINT32 bufferSize) UINT16 calculateChecksum16(UINT8* buffer, UINT32 bufferSize)
{ {
UINT16 counter = 0; if(!buffer)
return 0;
UINT16 counter = 0;
while(bufferSize--) while(bufferSize--)
counter += buffer[bufferSize]; counter += buffer[bufferSize];
return ~counter + 1; return ~counter + 1;

View File

@ -561,6 +561,13 @@ UINT8 UEFITool::parseVolume(const QByteArray & volume, UINT32 volumeBase, UINT8
QByteArray file = volume.mid(fileIndex, uint24ToUint32(fileHeader->Size)); QByteArray file = volume.mid(fileIndex, uint24ToUint32(fileHeader->Size));
QByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER)); QByteArray header = file.left(sizeof(EFI_FFS_FILE_HEADER));
// Check file size to at least sizeof(EFI_FFS_FILE_HEADER)
if (file.size() < sizeof(EFI_FFS_FILE_HEADER))
{
debug(tr("File with invalid size"));
return ERR_INVALID_FILE;
}
// We are at empty space in the end of volume // We are at empty space in the end of volume
if (header.count(empty) == header.size()) { if (header.count(empty) == header.size()) {
QByteArray body = volume.right(volume.size() - fileIndex); QByteArray body = volume.right(volume.size() - fileIndex);
@ -736,7 +743,6 @@ UINT8 UEFITool::parseFile(const QByteArray & file, UINT8 revision, bool erasePol
UINT32 dataSize; UINT32 dataSize;
QModelIndex index; QModelIndex index;
UINT32 result; UINT32 result;
bool lzmaHeaderFound;
switch (sectionHeader->Type) switch (sectionHeader->Type)
{ {
@ -796,55 +802,26 @@ UINT8 UEFITool::parseFile(const QByteArray & file, UINT8 revision, bool erasePol
if (LzmaGetInfo(data, dataSize, &decompressedSize) != ERR_SUCCESS if (LzmaGetInfo(data, dataSize, &decompressedSize) != ERR_SUCCESS
|| decompressedSize != compressedSectionHeader->UncompressedLength) || decompressedSize != compressedSectionHeader->UncompressedLength)
{ {
// Shitty file with some data between COMPRESSED_SECTION_HEADER and LZMA_HEADER // Shitty file with a section header between COMPRESSED_SECTION_HEADER and LZMA_HEADER
// Search for LZMA header in body data = (VOID*) (file.constData() + sectionIndex + sizeof(EFI_COMPRESSION_SECTION) + sizeof(EFI_COMMON_SECTION_HEADER));
// Header structure: UINT8 LzmaProperties | UINT32 DictionarySize | UINT64 DecompressedSize dataSize = uint24ToUint32(sectionHeader->Size) - sizeof(EFI_COMPRESSION_SECTION) - sizeof(EFI_COMMON_SECTION_HEADER);
// We can't determine first two fiels here, but Decompressed size is known, so search for it if (LzmaGetInfo(data, dataSize, &decompressedSize) != ERR_SUCCESS)
INT32 lzmaHeaderIndex = body.indexOf(QByteArray((const char*)&compressedSectionHeader->UncompressedLength, debug(tr("LzmaGetInfo failed"));
sizeof(compressedSectionHeader->UncompressedLength)).append('\x00').append('\x00').append('\x00').append('\x00'));
lzmaHeaderIndex -= LZMA_PROPS_SIZE;
// LZMA header not found
if (lzmaHeaderIndex < 0)
{
lzmaHeaderFound = false;
debug(tr("Lzma header not found"));
}
// LZMA header found
else if (lzmaHeaderIndex) {
data = (VOID*) (file.constData() + sectionIndex + sizeof(EFI_COMPRESSION_SECTION) + lzmaHeaderIndex);
dataSize = uint24ToUint32(sectionHeader->Size) - sizeof(EFI_COMPRESSION_SECTION) - lzmaHeaderIndex;
// Get buffer sizes again
if (LzmaGetInfo(data, dataSize, &decompressedSize) != ERR_SUCCESS
|| decompressedSize != compressedSectionHeader->UncompressedLength)
{
debug(tr("LzmaGetInfo failed on LZMA header"));
lzmaHeaderFound = false;
}
else
debug(tr("Padding of size %1 between CompressedSectionHeader and LzmaHeader")
.arg(lzmaHeaderIndex));
}
lzmaHeaderFound = true;
} }
else decompressed = new UINT8[decompressedSize];
lzmaHeaderFound = true; // Decompress section data
// Decompress if header is found if (LzmaDecompress(data, dataSize, decompressed) != ERR_SUCCESS)
if (lzmaHeaderFound) { debug(tr("LzmaDecompress failed"));
decompressed = new UINT8[decompressedSize]; else
// Decompress section data {
if (LzmaDecompress(data, dataSize, decompressed) != ERR_SUCCESS) body = QByteArray::fromRawData((const char*) decompressed, decompressedSize);
debug(tr("LzmaDecompress failed")); // Parse stored file
else result = parseFile(body, revision, erasePolarity, index);
{ if (result)
body = QByteArray::fromRawData((const char*) decompressed, decompressedSize); debug(tr("Compressed section with LZMA compression can not be parsed as file (%1)").arg(result));
// Parse stored file }
result = parseFile(body, revision, erasePolarity, index);
if (result)
debug(tr("Compressed section with LZMA compression can not be parsed as file (%1)").arg(result));
}
delete[] decompressed; delete[] decompressed;
}
break; break;
default: default:
body = file.mid(sectionIndex + sizeof(EFI_COMPRESSION_SECTION), sectionSize - sizeof(EFI_COMPRESSION_SECTION)); body = file.mid(sectionIndex + sizeof(EFI_COMPRESSION_SECTION), sectionSize - sizeof(EFI_COMPRESSION_SECTION));

View File

@ -30,5 +30,4 @@ HEADERS += uefitool.h \
Tiano/EfiTianoCompress.h Tiano/EfiTianoCompress.h
FORMS += uefitool.ui FORMS += uefitool.ui
RC_FILE = uefitool.rc RC_FILE = uefitool.rc
ICON = uefitool.icns
ICON = uefitool.icns

View File

@ -20,7 +20,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>UEFITool 0.2.0</string> <string>UEFITool 0.2.1</string>
</property> </property>
<widget class="QWidget" name="centralWidget"> <widget class="QWidget" name="centralWidget">
<property name="sizePolicy"> <property name="sizePolicy">