Implement LZMAF86 support

references #197
This commit is contained in:
vit9696 2020-03-06 23:54:20 +03:00
parent 6fdc69415b
commit 0f2ede398d
9 changed files with 84 additions and 10 deletions

View File

@ -20,6 +20,7 @@ SET(PROJECT_SOURCES
../common/treemodel.cpp ../common/treemodel.cpp
../common/utility.cpp ../common/utility.cpp
../common/LZMA/LzmaDecompress.c ../common/LZMA/LzmaDecompress.c
../common/LZMA/SDK/C/Bra86.c
../common/LZMA/SDK/C/LzmaDec.c ../common/LZMA/SDK/C/LzmaDec.c
../common/Tiano/EfiTianoDecompress.c ../common/Tiano/EfiTianoDecompress.c
../common/ustring.cpp ../common/ustring.cpp

View File

@ -19,6 +19,7 @@ SET(PROJECT_SOURCES
../common/treemodel.cpp ../common/treemodel.cpp
../common/utility.cpp ../common/utility.cpp
../common/LZMA/LzmaDecompress.c ../common/LZMA/LzmaDecompress.c
../common/LZMA/SDK/C/Bra86.c
../common/LZMA/SDK/C/LzmaDec.c ../common/LZMA/SDK/C/LzmaDec.c
../common/Tiano/EfiTianoDecompress.c ../common/Tiano/EfiTianoDecompress.c
../common/ustring.cpp ../common/ustring.cpp

View File

@ -86,6 +86,7 @@ SOURCES += uefitool_main.cpp \
../common/treemodel.cpp \ ../common/treemodel.cpp \
../common/LZMA/LzmaCompress.c \ ../common/LZMA/LzmaCompress.c \
../common/LZMA/LzmaDecompress.c \ ../common/LZMA/LzmaDecompress.c \
../common/LZMA/SDK/C/Bra86.c \
../common/LZMA/SDK/C/LzFind.c \ ../common/LZMA/SDK/C/LzFind.c \
../common/LZMA/SDK/C/LzmaDec.c \ ../common/LZMA/SDK/C/LzmaDec.c \
../common/LZMA/SDK/C/LzmaEnc.c \ ../common/LZMA/SDK/C/LzmaEnc.c \

View File

@ -16,6 +16,7 @@
#include "../basetypes.h" #include "../basetypes.h"
#include "SDK/C/LzmaDec.h" #include "SDK/C/LzmaDec.h"
#include "SDK/C/Bra.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -132,7 +132,9 @@ typedef ptrdiff_t INTN;
#define COMPRESSION_ALGORITHM_UNDECIDED 4 #define COMPRESSION_ALGORITHM_UNDECIDED 4
#define COMPRESSION_ALGORITHM_LZMA 5 #define COMPRESSION_ALGORITHM_LZMA 5
#define COMPRESSION_ALGORITHM_LZMA_INTEL_LEGACY 6 #define COMPRESSION_ALGORITHM_LZMA_INTEL_LEGACY 6
#define COMPRESSION_ALGORITHM_GZIP 7 #define COMPRESSION_ALGORITHM_LZMAF86 7
#define COMPRESSION_ALGORITHM_GZIP 8
// Item create modes // Item create modes
#define CREATE_MODE_APPEND 0 #define CREATE_MODE_APPEND 0

View File

@ -456,6 +456,7 @@ typedef struct EFI_COMPRESSION_SECTION_APPLE_ {
#define EFI_NOT_COMPRESSED 0x00 #define EFI_NOT_COMPRESSED 0x00
#define EFI_STANDARD_COMPRESSION 0x01 #define EFI_STANDARD_COMPRESSION 0x01
#define EFI_CUSTOMIZED_COMPRESSION 0x02 #define EFI_CUSTOMIZED_COMPRESSION 0x02
#define EFI_CUSTOMIZED_COMPRESSION_LZMAF86 0x86
//GUID defined section //GUID defined section
typedef struct EFI_GUID_DEFINED_SECTION_ { typedef struct EFI_GUID_DEFINED_SECTION_ {

View File

@ -2762,7 +2762,7 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size()); info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
} }
// LZMA compressed section // LZMA compressed section
else if (baGuid == EFI_GUIDED_SECTION_LZMA || baGuid == EFI_GUIDED_SECTION_LZMAF86) { else if (baGuid == EFI_GUIDED_SECTION_LZMA) {
USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed); USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION, algorithm, dictionarySize, processed, efiDecompressed);
if (result) { if (result) {
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index); msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
@ -2779,6 +2779,24 @@ USTATUS FfsParser::parseGuidedSectionBody(const UModelIndex & index)
parseCurrentSection = false; parseCurrentSection = false;
} }
} }
// LZMAF86 compressed section
else if (baGuid == EFI_GUIDED_SECTION_LZMAF86) {
USTATUS result = decompress(model->body(index), EFI_CUSTOMIZED_COMPRESSION_LZMAF86, algorithm, dictionarySize, processed, efiDecompressed);
if (result) {
msg(usprintf("%s: decompression failed with error ", __FUNCTION__) + errorCodeToUString(result), index);
return U_SUCCESS;
}
if (algorithm == COMPRESSION_ALGORITHM_LZMAF86) {
info += UString("\nCompression algorithm: LZMAF86");
info += usprintf("\nDecompressed size: %Xh (%u)", processed.size(), processed.size());
info += usprintf("\nLZMA dictionary size: %Xh", dictionarySize);
}
else {
info += UString("\nCompression algorithm: unknown");
parseCurrentSection = false;
}
}
// GZip compressed section // GZip compressed section
else if (baGuid == EFI_GUIDED_SECTION_GZIP) { else if (baGuid == EFI_GUIDED_SECTION_GZIP) {
USTATUS result = gzipDecompress(model->body(index), processed); USTATUS result = gzipDecompress(model->body(index), processed);

View File

@ -283,7 +283,7 @@ make_partition_table_consistent:
// Add tree item // Add tree item
UINT8 type = Subtypes::CodeFptPartition + partitions[i].ptEntry.Type; UINT8 type = Subtypes::CodeFptPartition + partitions[i].ptEntry.Type;
partitionIndex = model->addItem(partitions[i].ptEntry.Offset, Types::FptPartition, type, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent); partitionIndex = model->addItem(partitions[i].ptEntry.Offset, Types::FptPartition, type, name, UString(), info, UByteArray(), partition, UByteArray(), Fixed, parent);
if (type == Subtypes::CodeFptPartition && partition.size() >= sizeof(UINT32) && readUnaligned((const UINT32*)partition.constData()) == CPD_SIGNATURE) { if (type == Subtypes::CodeFptPartition && partition.size() >= (int) sizeof(UINT32) && readUnaligned((const UINT32*)partition.constData()) == CPD_SIGNATURE) {
// Parse code partition contents // Parse code partition contents
UModelIndex cpdIndex; UModelIndex cpdIndex;
ffsParser->parseCpdRegion(partition, partitions[i].ptEntry.Offset, partitionIndex, cpdIndex); ffsParser->parseCpdRegion(partition, partitions[i].ptEntry.Offset, partitionIndex, cpdIndex);

View File

@ -163,10 +163,11 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
switch (compressionType) switch (compressionType)
{ {
case EFI_NOT_COMPRESSED: case EFI_NOT_COMPRESSED: {
decompressedData = compressedData; decompressedData = compressedData;
algorithm = COMPRESSION_ALGORITHM_NONE; algorithm = COMPRESSION_ALGORITHM_NONE;
return U_SUCCESS; return U_SUCCESS;
}
case EFI_STANDARD_COMPRESSION: { case EFI_STANDARD_COMPRESSION: {
// Set default algorithm to unknown // Set default algorithm to unknown
algorithm = COMPRESSION_ALGORITHM_UNKNOWN; algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
@ -227,7 +228,7 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
free(scratch); free(scratch);
return result; return result;
} }
case EFI_CUSTOMIZED_COMPRESSION: case EFI_CUSTOMIZED_COMPRESSION: {
// Set default algorithm to unknown // Set default algorithm to unknown
algorithm = COMPRESSION_ALGORITHM_UNKNOWN; algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
@ -271,11 +272,59 @@ USTATUS decompress(const UByteArray & compressedData, const UINT8 compressionTyp
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize); decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
free(decompressed); free(decompressed);
return U_SUCCESS; return U_SUCCESS;
default: }
case EFI_CUSTOMIZED_COMPRESSION_LZMAF86: {
// Set default algorithm to unknown
algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
// Get buffer sizes
data = (const UINT8*)compressedData.constData();
dataSize = compressedData.size();
// Get info as normal LZMA section
if (U_SUCCESS != LzmaGetInfo(data, dataSize, &decompressedSize)) {
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
}
algorithm = COMPRESSION_ALGORITHM_LZMAF86;
// Allocate memory
decompressed = (UINT8*)malloc(decompressedSize);
if (!decompressed) {
return U_OUT_OF_MEMORY;
}
// Decompress section data
if (U_SUCCESS != LzmaDecompress(data, dataSize, decompressed)) {
free(decompressed);
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
}
if (decompressedSize > INT32_MAX) {
free(decompressed);
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
}
// After LZMA decompression, the data need to be converted to the raw data.
UINT32 state = 0;
const UINT8 x86LookAhead = 4;
if (decompressedSize != x86LookAhead + x86_Convert(decompressed, decompressedSize, 0, &state, 0)) {
free(decompressed);
return U_CUSTOMIZED_DECOMPRESSION_FAILED;
}
dictionarySize = readUnaligned((UINT32*)(data + 1)); // LZMA dictionary size is stored in bytes 1-4 of LZMA properties header
decompressedData = UByteArray((const char*)decompressed, (int)decompressedSize);
free(decompressed);
return U_SUCCESS;
}
default: {
algorithm = COMPRESSION_ALGORITHM_UNKNOWN; algorithm = COMPRESSION_ALGORITHM_UNKNOWN;
return U_UNKNOWN_COMPRESSION_TYPE; return U_UNKNOWN_COMPRESSION_TYPE;
} }
} }
}
// 8bit sum calculation routine // 8bit sum calculation routine
UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize) UINT8 calculateSum8(const UINT8* buffer, UINT32 bufferSize)