Skip to content

Commit

Permalink
Use gzip instead of zlib for Qualcomm decompression (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeggor authored Aug 12, 2023
1 parent f289219 commit f05ed14
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
2 changes: 1 addition & 1 deletion uefi_firmware/guids/efiguids_qualcomm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"""

GUIDS = {
'QC_ZLIB_CUSTOM_DECOMPRESS_GUID': [0x1d301fe9, 0xbe79, 0x4353, 0x91, 0xc2, 0xd2, 0x3b, 0xc9, 0x59, 0xae, 0x0c],
'QC_GZIP_CUSTOM_DECOMPRESS_GUID': [0x1d301fe9, 0xbe79, 0x4353, 0x91, 0xc2, 0xd2, 0x3b, 0xc9, 0x59, 0xae, 0x0c],
}
23 changes: 16 additions & 7 deletions uefi_firmware/structs/uefi_structs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@
]

FIRMWARE_GUIDED_GUIDS = {
"LZMA_COMPRESSED": "ee4e5898-3914-4259-9d6e-dc7bd79403cf",
"LZMA_COMPRESSED_HP": "0ed85e23-f253-413f-a03c-901987b04397",
"TIANO_COMPRESSED": "a31280ad-481e-41b6-95e8-127f4c984779",
"FIRMWARE_VOLUME": "24400798-3807-4a42-b413-a1ecee205dd8",
#"VOLUME_SECTION": "367ae684-335d-4671-a16d-899dbfea6b88",
"STATIC_GUID": "fc1bcdb0-7d31-49aa-936a-a4600d9dd083",
"ZLIB_COMPRESSED_QC": "1d301fe9-be79-4353-91c2-d23bc959ae0c"
"LZMA_COMPRESSED": "ee4e5898-3914-4259-9d6e-dc7bd79403cf",
"LZMA_COMPRESSED_HP": "0ed85e23-f253-413f-a03c-901987b04397",
"TIANO_COMPRESSED": "a31280ad-481e-41b6-95e8-127f4c984779",
"FIRMWARE_VOLUME": "24400798-3807-4a42-b413-a1ecee205dd8",
#"VOLUME_SECTION": "367ae684-335d-4671-a16d-899dbfea6b88",
"STATIC_GUID": "fc1bcdb0-7d31-49aa-936a-a4600d9dd083",
"GZIP_COMPRESSED_QC": "1d301fe9-be79-4353-91c2-d23bc959ae0c",
"ZLIB_COMPRESSED_AMD": "ce3233f5-2cd6-4d87-9152-4a238bb6d1c4",
}

FIRMWARE_FREEFORM_GUIDS = {
Expand Down Expand Up @@ -197,3 +198,11 @@ class FirmwareVolumeType(ctypes.LittleEndianStructure):
("Reserved2", uint8_t),
("Revision", uint8_t)
]

class EfiAmdZlibSectionHeader(ctypes.LittleEndianStructure):
_pack_ = 1
_fields_ = [
("ZeroHeader", uint8_t * 0x14),
("CompressedSize", uint32_t),
("ZeroFooter", uint8_t * (0x100 - 0x14 - 4))
]
34 changes: 28 additions & 6 deletions uefi_firmware/uefi.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
'''
from __future__ import print_function

import gzip
import logging
import os
import struct
import logging
import zlib

from .base import FirmwareObject, StructuredObject, RawObject, AutoRawObject
Expand Down Expand Up @@ -634,10 +635,19 @@ def decompress_guid(alg):
status = decompress_guid(efi_compressor.LzmaDecompress)
elif sguid(self.guid) == FIRMWARE_GUIDED_GUIDS["TIANO_COMPRESSED"]:
status = decompress_guid(efi_compressor.TianoDecompress)
elif sguid(self.guid) == FIRMWARE_GUIDED_GUIDS["ZLIB_COMPRESSED_QC"]:
elif sguid(self.guid) == FIRMWARE_GUIDED_GUIDS["ZLIB_COMPRESSED_AMD"]:
body = self.preamble + self.data
if len(body) < 0x100:
dlog(self, sguid(self.guid), 'error, invalid AMD zlib section header size')
return False
header = EfiAmdZlibSectionHeader.from_buffer_copy(body[:0x100])
compressed_data = body[0x100:]
if len(compressed_data) != header.CompressedSize:
dlog(self, sguid(self.guid), 'error, invalid AMD zlib section header')
return False
try:
data = zlib.decompress(self.preamble + self.data, 31)
if data is not None:
data = zlib.decompress(compressed_data)
if data:
self.subtype = 0
self.data = data
self.process_subsections()
Expand All @@ -646,7 +656,20 @@ def decompress_guid(alg):
dlog(self, sguid(self.guid), 'error, empty zlib decompress')
except zlib.error as err:
status = False
dlog(self, sguid(self.guid), 'zlib error: ' + str(err))
dlog(self, sguid(self.guid), 'zlib error: %s' % str(err))
elif sguid(self.guid) == FIRMWARE_GUIDED_GUIDS["GZIP_COMPRESSED_QC"]:
try:
data = gzip.decompress(self.preamble + self.data)
if data:
self.subtype = 0
self.data = data
self.process_subsections()
else:
status = False
dlog(self, sguid(self.guid), 'error, empty gzip decompress')
except Exception as err:
status = False
dlog(self, sguid(self.guid), 'gzip error: %s' % str(err))
# Todo: check for processing required attribute
elif sguid(self.guid) == FIRMWARE_GUIDED_GUIDS["STATIC_GUID"]:
# Todo: verify this (FirmwareFile hack)
Expand All @@ -669,7 +692,6 @@ def decompress_guid(alg):
if not status:
dlog(self, sguid(self.guid), 'Could not parse GUID object')
return status
pass

def build(self, generate_checksum=False, debug=False):
data = self._build_subsections(generate_checksum)
Expand Down

0 comments on commit f05ed14

Please sign in to comment.