BIOSUtilities v24.10.18

Removed all Python built-in library keyword arguments (#55)
This commit is contained in:
Plato Mavropoulos 2024-10-18 13:37:52 +03:00
parent 010b5a47d4
commit 35455f735c
27 changed files with 228 additions and 229 deletions

View file

@ -1,3 +1,7 @@
24.10.18
Removed all Python built-in library keyword arguments (#55)
24.10.17
Fixed "skip user action prompts" argument being ignored

View file

@ -5,4 +5,4 @@
Copyright (C) 2018-2024 Plato Mavropoulos
"""
__version__ = '24.10.17'
__version__ = '24.10.18'

View file

@ -40,7 +40,7 @@ class AmiBiosGuardHeader(ctypes.LittleEndianStructure):
printer(message=['Size :', f'0x{self.Size:X}'], padding=padding, new_line=False)
printer(message=['Checksum:', f'0x{self.Checksum:04X}'], padding=padding, new_line=False)
printer(message=['Tag :', self.Tag.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Tag :', self.Tag.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Flags :', f'0x{self.Flags:02X}'], padding=padding, new_line=False)
@ -68,9 +68,9 @@ class IntelBiosGuardHeader(ctypes.LittleEndianStructure):
id_byte: bytes = bytes(self.PlatformID)
id_text: str = re.sub(r'[\n\t\r\x00 ]', '', id_byte.decode(encoding='utf-8', errors='ignore'))
id_text: str = re.sub(r'[\n\t\r\x00 ]', '', id_byte.decode('utf-8', 'ignore'))
id_hexs: str = f'{int.from_bytes(bytes=id_byte, byteorder="big"):0{0x10 * 2}X}'
id_hexs: str = f'{int.from_bytes(id_byte, byteorder="big"):0{0x10 * 2}X}'
id_guid: str = f'{{{id_hexs[:8]}-{id_hexs[8:12]}-{id_hexs[12:16]}-{id_hexs[16:20]}-{id_hexs[20:]}}}'
@ -192,9 +192,9 @@ class IntelBiosGuardSignatureRsa3k(ctypes.LittleEndianStructure):
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
modulus: str = f'{int.from_bytes(bytes=self.Modulus, byteorder="little"):0{0x180 * 2}X}'[:64]
modulus: str = f'{int.from_bytes(self.Modulus, byteorder="little"):0{0x180 * 2}X}'[:64]
exponent: str = f'0x{self.Exponent:X}'
signature: str = f'{int.from_bytes(bytes=self.Signature, byteorder="little"):0{0x180 * 2}X}'[:64]
signature: str = f'{int.from_bytes(self.Signature, byteorder="little"):0{0x180 * 2}X}'[:64]
printer(message=['Modulus :', modulus], padding=padding, new_line=False)
printer(message=['Exponent :', exponent], padding=padding, new_line=False)
@ -286,7 +286,7 @@ class AmiPfatExtract(BIOSUtility):
_ = self.parse_bg_script(script_data=pfat_buffer[bg_script_bgn:bg_script_end], padding=padding + 12)
with open(file=file_path, mode='ab') as out_dat:
with open(file_path, 'ab') as out_dat:
out_dat.write(bg_data_bin)
all_blocks_dict[file_index] += bg_data_bin
@ -302,12 +302,11 @@ class AmiPfatExtract(BIOSUtility):
pfat_oob_path: str = os.path.join(extract_path, pfat_oob_name)
with open(file=pfat_oob_path, mode='wb') as out_oob:
with open(pfat_oob_path, 'wb') as out_oob:
out_oob.write(pfat_oob_data)
if self.check_format(input_object=pfat_oob_data):
self.parse_format(input_object=pfat_oob_data, extract_path=extract_folder(pfat_oob_path),
padding=padding)
self.parse_format(input_object=pfat_oob_data, extract_path=extract_folder(pfat_oob_path), padding=padding)
in_all_data: bytes = b''.join([block[1] for block in sorted(all_blocks_dict.items())])
@ -315,7 +314,7 @@ class AmiPfatExtract(BIOSUtility):
in_all_path: str = os.path.join(extract_path, in_all_name)
with open(file=in_all_path, mode='wb') as out_all:
with open(in_all_path, 'wb') as out_all:
out_all.write(in_all_data + pfat_oob_data)
return True
@ -364,7 +363,7 @@ class AmiPfatExtract(BIOSUtility):
input_buffer: bytes = file_to_bytes(in_object=input_object)
match: re.Match[bytes] | None = PAT_AMI_PFAT.search(string=input_buffer)
match: re.Match[bytes] | None = PAT_AMI_PFAT.search(input_buffer)
return input_buffer[match.start() - 0x8:] if match else b''
@ -431,7 +430,7 @@ class AmiPfatExtract(BIOSUtility):
hdr_data: bytes = buffer[self.PFAT_AMI_HDR_LEN:hdr_size]
hdr_text: list[str] = hdr_data.decode(encoding='utf-8').splitlines()
hdr_text: list[str] = hdr_data.decode('utf-8').splitlines()
printer(message='AMI BIOS Guard Header:\n', padding=padding)

View file

@ -45,9 +45,9 @@ class UafHeader(ctypes.LittleEndianStructure):
def _get_reserved(self) -> str:
res_bytes: bytes = bytes(self.Reserved)
res_hex: str = f'0x{int.from_bytes(bytes=res_bytes, byteorder="big"):0{0x4 * 2}X}'
res_hex: str = f'0x{int.from_bytes(res_bytes, byteorder="big"):0{0x4 * 2}X}'
res_str: str = re.sub(r'[\n\t\r\x00 ]', '', res_bytes.decode(encoding='utf-8', errors='ignore'))
res_str: str = re.sub(r'[\n\t\r\x00 ]', '', res_bytes.decode('utf-8', 'ignore'))
res_txt: str = f' ({res_str})' if len(res_str) else ''
@ -56,7 +56,7 @@ class UafHeader(ctypes.LittleEndianStructure):
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
printer(message=['Tag :', self.ModuleTag.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Tag :', self.ModuleTag.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Size :', f'0x{self.ModuleSize:X}'], padding=padding, new_line=False)
printer(message=['Checksum :', f'0x{self.Checksum:04X}'], padding=padding, new_line=False)
printer(message=['Unknown 0 :', f'0x{self.Unknown0:02X}'], padding=padding, new_line=False)
@ -146,7 +146,7 @@ class DisHeader(ctypes.LittleEndianStructure):
printer(message=['Password Size:', f'0x{self.PasswordSize:X}'], padding=padding, new_line=False)
printer(message=['Entry Count :', self.EntryCount], padding=padding, new_line=False)
printer(message=['Password :', self.Password.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Password :', self.Password.decode('utf-8')], padding=padding, new_line=False)
class DisModule(ctypes.LittleEndianStructure):
@ -169,8 +169,8 @@ class DisModule(ctypes.LittleEndianStructure):
enabled_disabled: str = self.ENDIS.get(self.EnabledDisabled, f'Unknown ({self.EnabledDisabled})')
shown_hidden: str = self.SHOWN.get(self.ShownHidden, f'Unknown ({self.ShownHidden})')
command: str = self.Command.decode(encoding='utf-8').strip()
description: str = self.Description.decode(encoding='utf-8').strip()
command: str = self.Command.decode('utf-8').strip()
description: str = self.Description.decode('utf-8').strip()
printer(message=['State :', enabled_disabled], padding=padding, new_line=False)
printer(message=['Display :', shown_hidden], padding=padding, new_line=False)
@ -324,15 +324,15 @@ class AmiUcpExtract(BIOSUtility):
uaf_buf_bin: bytes = b'' # Buffer of largest detected @UAF|@HPU
uaf_buf_tag: str = '@UAF' # Tag of largest detected @UAF|@HPU
for uaf in PAT_AMI_UCP.finditer(string=buffer):
uaf_len_cur: int = int.from_bytes(bytes=buffer[uaf.start() + 0x4:uaf.start() + 0x8], byteorder='little')
for uaf in PAT_AMI_UCP.finditer(buffer):
uaf_len_cur: int = int.from_bytes(buffer[uaf.start() + 0x4:uaf.start() + 0x8], byteorder='little')
if uaf_len_cur > uaf_len_max:
uaf_len_max = uaf_len_cur
uaf_buf_bin = buffer[uaf.start():uaf.start() + uaf_len_max]
uaf_buf_tag = uaf.group(0)[:4].decode(encoding='utf-8', errors='ignore')
uaf_buf_tag = uaf.group(0)[:4].decode('utf-8', 'ignore')
return uaf_buf_bin, uaf_buf_tag
@ -346,7 +346,7 @@ class AmiUcpExtract(BIOSUtility):
# Parse @UAF|@HPU Module Structure
uaf_hdr: Any = ctypes_struct(buffer=buffer, start_offset=uaf_off, class_object=UafHeader)
uaf_tag: str = uaf_hdr.ModuleTag.decode(encoding='utf-8') # Get unique @UAF|@HPU Module Tag
uaf_tag: str = uaf_hdr.ModuleTag.decode('utf-8') # Get unique @UAF|@HPU Module Tag
uaf_all.append([uaf_tag, uaf_off, uaf_hdr]) # Store @UAF|@HPU Module Info
@ -357,7 +357,7 @@ class AmiUcpExtract(BIOSUtility):
# Check if @UAF|@HPU Module @NAL exists and place it first
# Parsing @NAL first allows naming all @UAF|@HPU Modules
for mod_idx, mod_val in enumerate(iterable=uaf_all):
for mod_idx, mod_val in enumerate(uaf_all):
if mod_val[0] == '@NAL':
uaf_all.insert(1, uaf_all.pop(mod_idx)) # After UII for visual purposes
@ -447,7 +447,7 @@ class AmiUcpExtract(BIOSUtility):
info_data: bytes = uaf_data_raw[max(self.UII_HDR_LEN, info_hdr.InfoSize):info_hdr.UIISize]
# Get @UII Module Info/Description text field
info_desc: str = info_data.decode(encoding='utf-8', errors='ignore').strip('\x00 ')
info_desc: str = info_data.decode('utf-8', 'ignore').strip('\x00 ')
printer(message='Utility Identification Information:\n', padding=padding + 4)
@ -457,7 +457,7 @@ class AmiUcpExtract(BIOSUtility):
self._chk16_validate(data=uaf_data_raw, tag='@UII > Info', padding=padding + 8)
# Store/Save @UII Module Info in file
with open(file=uaf_fname[:-4] + '.txt', mode='a', encoding='utf-8') as uii_out:
with open(uaf_fname[:-4] + '.txt', 'a', encoding='utf-8') as uii_out:
with contextlib.redirect_stdout(uii_out):
info_hdr.struct_print(description=info_desc, padding=0) # Store @UII Module Info
@ -478,7 +478,7 @@ class AmiUcpExtract(BIOSUtility):
# Store/Save @UAF|@HPU Module file
if uaf_tag != '@UII': # Skip @UII binary, already parsed
with open(file=uaf_fname, mode='wb') as uaf_out:
with open(uaf_fname, 'wb') as uaf_out:
uaf_out.write(uaf_data_raw)
# @UAF|@HPU Module EFI/Tiano Decompression
@ -487,10 +487,10 @@ class AmiUcpExtract(BIOSUtility):
dec_fname: str = uaf_fname.replace('.temp', uaf_fext)
if efi_decompress(in_path=uaf_fname, out_path=dec_fname, padding=padding + 4):
with open(file=dec_fname, mode='rb') as dec:
with open(dec_fname, 'rb') as dec:
uaf_data_raw = dec.read() # Read back the @UAF|@HPU Module decompressed Raw data
os.remove(path=uaf_fname) # Successful decompression, delete compressed @UAF|@HPU Module file
os.remove(uaf_fname) # Successful decompression, delete compressed @UAF|@HPU Module file
uaf_fname = dec_fname # Adjust @UAF|@HPU Module file path to the decompressed one
@ -498,7 +498,7 @@ class AmiUcpExtract(BIOSUtility):
if uaf_tag in self.UAF_TAG_DICT and self.UAF_TAG_DICT[uaf_tag][2] == 'Text':
printer(message=f'{self.UAF_TAG_DICT[uaf_tag][1]}:', padding=padding + 4)
printer(message=uaf_data_raw.decode(encoding='utf-8', errors='ignore'), padding=padding + 8)
printer(message=uaf_data_raw.decode('utf-8', 'ignore'), padding=padding + 8)
# Parse Default Command Status @UAF|@HPU Module (@DIS)
if len(uaf_data_raw) and uaf_tag == '@DIS':
@ -510,7 +510,7 @@ class AmiUcpExtract(BIOSUtility):
dis_hdr.struct_print(padding=padding + 8) # Print @DIS Module Raw Header Info
# Store/Save @DIS Module Header Info in file
with open(file=uaf_fname[:-3] + 'txt', mode='a', encoding='utf-8') as dis:
with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis:
with contextlib.redirect_stdout(dis):
dis_hdr.struct_print(padding=0) # Store @DIS Module Header Info
@ -528,17 +528,17 @@ class AmiUcpExtract(BIOSUtility):
dis_mod.struct_print(padding=padding + 12) # Print @DIS Module Raw Entry Info
# Store/Save @DIS Module Entry Info in file
with open(file=uaf_fname[:-3] + 'txt', mode='a', encoding='utf-8') as dis:
with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis:
with contextlib.redirect_stdout(dis):
printer(message=None)
dis_mod.struct_print(padding=4) # Store @DIS Module Entry Info
os.remove(path=uaf_fname) # Delete @DIS Module binary, info exported as text
os.remove(uaf_fname) # Delete @DIS Module binary, info exported as text
# Parse Name List @UAF|@HPU Module (@NAL)
if len(uaf_data_raw) >= 5 and (uaf_tag, uaf_data_raw[0], uaf_data_raw[4]) == ('@NAL', 0x40, 0x3A):
nal_info: list[str] = uaf_data_raw.decode(encoding='utf-8',
nal_info: list[str] = uaf_data_raw.decode('utf-8',
errors='ignore').replace('\r', '').strip().split('\n')
printer(message='AMI UCP Module Name List:\n', padding=padding + 4)
@ -571,7 +571,7 @@ class AmiUcpExtract(BIOSUtility):
if insyde_ifd_extract.parse_format(input_object=uaf_fname, extract_path=extract_folder(ins_dir),
padding=padding + 4):
os.remove(path=uaf_fname) # Delete raw nested Insyde IFD image after successful extraction
os.remove(uaf_fname) # Delete raw nested Insyde IFD image after successful extraction
ami_pfat_extract: AmiPfatExtract = AmiPfatExtract()
@ -582,10 +582,10 @@ class AmiUcpExtract(BIOSUtility):
ami_pfat_extract.parse_format(input_object=uaf_data_raw, extract_path=extract_folder(pfat_dir),
padding=padding + 4)
os.remove(path=uaf_fname) # Delete raw PFAT BIOS image after successful extraction
os.remove(uaf_fname) # Delete raw PFAT BIOS image after successful extraction
# Detect Intel Engine firmware image and show ME Analyzer advice
if uaf_tag.startswith('@ME') and PAT_INTEL_ENGINE.search(string=uaf_data_raw):
if uaf_tag.startswith('@ME') and PAT_INTEL_ENGINE.search(uaf_data_raw):
printer(message='Intel Management Engine (ME) Firmware:\n', padding=padding + 4)
printer(message='Use "ME Analyzer" from https://github.com/platomav/MEAnalyzer',
padding=padding + 8, new_line=False)
@ -598,7 +598,7 @@ class AmiUcpExtract(BIOSUtility):
self.parse_format(input_object=uaf_data_raw, extract_path=extract_folder(uaf_dir),
padding=padding + 4) # Call recursively
os.remove(path=uaf_fname) # Delete raw nested AMI UCP image after successful extraction
os.remove(uaf_fname) # Delete raw nested AMI UCP image after successful extraction
return nal_dict

View file

@ -57,12 +57,12 @@ class IntelBiosId(ctypes.LittleEndianStructure):
@staticmethod
def _decode(field: bytes) -> str:
return struct.pack('B' * len(field), *field).decode(encoding='utf-16', errors='ignore').strip('\x00 ')
return struct.pack('B' * len(field), *field).decode('utf-16', 'ignore').strip('\x00 ')
def get_bios_id(self) -> dict[str, str]:
""" Get Apple/Intel EFI BIOS ID """
intel_sig: str = self.Signature.decode(encoding='utf-8')
intel_sig: str = self.Signature.decode('utf-8')
board_id: str = self._decode(field=self.BoardID)
board_ext: str = self._decode(field=self.BoardExt)
@ -142,13 +142,13 @@ class AppleEfiIdentify(BIOSUtility):
input_path = os.path.join(runtime_root(), 'APPLE_EFI_ID_INPUT_BUFFER_CHECK.tmp')
input_buffer = input_object
with open(file=input_path, mode='wb') as check_out:
with open(input_path, 'wb') as check_out:
check_out.write(input_buffer)
else:
return False
try:
if PAT_INTEL_IBIOSI.search(string=input_buffer):
if PAT_INTEL_IBIOSI.search(input_buffer):
return True
_ = subprocess.run([uefifind_path(), input_path, 'body', 'list', self.PAT_UEFIFIND],
@ -173,10 +173,10 @@ class AppleEfiIdentify(BIOSUtility):
else:
input_path = os.path.join(runtime_root(), 'APPLE_EFI_ID_INPUT_BUFFER_PARSE.bin')
with open(file=input_path, mode='wb') as parse_out:
with open(input_path, 'wb') as parse_out:
parse_out.write(input_buffer)
bios_id_match: Match[bytes] | None = PAT_INTEL_IBIOSI.search(string=input_buffer)
bios_id_match: Match[bytes] | None = PAT_INTEL_IBIOSI.search(input_buffer)
if bios_id_match:
bios_id_res: str = f'0x{bios_id_match.start():X}'
@ -195,11 +195,11 @@ class AppleEfiIdentify(BIOSUtility):
_ = subprocess.run([uefiextract_path(), input_path, bios_id_res, '-o', extract_path, '-m', 'body'],
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
with open(file=os.path.join(extract_path, 'body.bin'), mode='rb') as raw_body:
with open(os.path.join(extract_path, 'body.bin'), 'rb') as raw_body:
body_buffer: bytes = raw_body.read()
# Detect decompressed $IBIOSI$ pattern
bios_id_match = PAT_INTEL_IBIOSI.search(string=body_buffer)
bios_id_match = PAT_INTEL_IBIOSI.search(body_buffer)
if not bios_id_match:
raise RuntimeError('Failed to detect decompressed $IBIOSI$ pattern!')
@ -231,7 +231,7 @@ class AppleEfiIdentify(BIOSUtility):
return True
def _apple_rom_version(self, input_buffer: bytes | bytearray, padding: int = 0) -> bool:
rom_version_match: Match[bytes] | None = PAT_APPLE_ROM_VER.search(string=input_buffer)
rom_version_match: Match[bytes] | None = PAT_APPLE_ROM_VER.search(input_buffer)
if rom_version_match:
rom_version_match_off: int = rom_version_match.start()

View file

@ -35,7 +35,7 @@ class AppleEfiIm4pSplit(BIOSUtility):
input_buffer: bytes = file_to_bytes(in_object=input_object)
if PAT_APPLE_IM4P.search(string=input_buffer) and PAT_INTEL_FD.search(string=input_buffer):
if PAT_APPLE_IM4P.search(input_buffer) and PAT_INTEL_FD.search(input_buffer):
return True
return False
@ -50,7 +50,7 @@ class AppleEfiIm4pSplit(BIOSUtility):
make_dirs(in_path=extract_path, delete=True)
# Detect IM4P EFI pattern
im4p_match: Match[bytes] | None = PAT_APPLE_IM4P.search(string=input_buffer)
im4p_match: Match[bytes] | None = PAT_APPLE_IM4P.search(input_buffer)
if not im4p_match:
return False
@ -62,7 +62,7 @@ class AppleEfiIm4pSplit(BIOSUtility):
mefi_data_bgn: int = im4p_match.start() + input_buffer[im4p_match.start() - 0x1]
# IM4P mefi payload size
mefi_data_len: int = int.from_bytes(bytes=input_buffer[im4p_match.end() + 0x5:im4p_match.end() + 0x9],
mefi_data_len: int = int.from_bytes(input_buffer[im4p_match.end() + 0x5:im4p_match.end() + 0x9],
byteorder='big')
# Check if mefi is followed by _MEFIBIN
@ -78,7 +78,7 @@ class AppleEfiIm4pSplit(BIOSUtility):
input_buffer = input_buffer[efi_data_bgn:efi_data_bgn + efi_data_len]
# Parse Intel Flash Descriptor pattern matches
for ifd in PAT_INTEL_FD.finditer(string=input_buffer):
for ifd in PAT_INTEL_FD.finditer(input_buffer):
# Component Base Address from FD start (ICH8-ICH10 = 1, IBX = 2, CPT+ = 3)
ifd_flmap0_fcba: int = input_buffer[ifd.start() + 0x4] * 0x10
@ -107,7 +107,7 @@ class AppleEfiIm4pSplit(BIOSUtility):
# Calculate Intel Flash Descriptor Flash Component Total Size
# Component Count (00 = 1, 01 = 2)
ifd_flmap0_nc: int = ((int.from_bytes(bytes=input_buffer[ifd_match_end:ifd_match_end + 0x4],
ifd_flmap0_nc: int = ((int.from_bytes(input_buffer[ifd_match_end:ifd_match_end + 0x4],
byteorder='little') >> 8) & 3) + 1
# PCH/ICH Strap Length (ME 2-8 & TXE 0-2 & SPS 1-2 <= 0x12, ME 9+ & TXE 3+ & SPS 3+ >= 0x13)
@ -142,7 +142,7 @@ class AppleEfiIm4pSplit(BIOSUtility):
output_path: str = os.path.join(extract_path, f'{output_name}_[{ifd_data_txt}].fd')
with open(file=output_path, mode='wb') as output_image:
with open(output_path, 'wb') as output_image:
output_image.write(output_data)
printer(message=f'Split Apple EFI image at {ifd_data_txt}!', padding=padding)

View file

@ -56,7 +56,7 @@ class AppleEfiPbzxExtract(BIOSUtility):
input_buffer: bytes = file_to_bytes(in_object=input_object)
return bool(PAT_APPLE_PBZX.search(string=input_buffer, endpos=4))
return bool(PAT_APPLE_PBZX.search(input_buffer, 0, 4))
def parse_format(self, input_object: str | bytes | bytearray, extract_path: str, padding: int = 0) -> bool:
""" Parse & Extract Apple PBZX image """
@ -113,14 +113,14 @@ class AppleEfiPbzxExtract(BIOSUtility):
cpio_path: str = os.path.join(extract_path, f'{cpio_name}.cpio')
with open(file=cpio_path, mode='wb') as cpio_object:
with open(cpio_path, 'wb') as cpio_object:
cpio_object.write(cpio_bin)
# Decompress PBZX > CPIO archive with 7-Zip
if is_szip_supported(in_path=cpio_path, padding=padding, args=['-tCPIO'], silent=False):
if szip_decompress(in_path=cpio_path, out_path=extract_path, in_name='CPIO',
padding=padding, args=['-tCPIO']):
os.remove(path=cpio_path) # Successful extraction, delete PBZX > CPIO archive
os.remove(cpio_path) # Successful extraction, delete PBZX > CPIO archive
else:
return False
else:

View file

@ -38,7 +38,7 @@ class AppleEfiPkgExtract(BIOSUtility):
else:
input_path = os.path.join(runtime_root(), 'APPLE_EFI_PKG_INPUT_BUFFER_CHECK.bin')
with open(file=input_path, mode='wb') as input_path_object:
with open(input_path, 'wb') as input_path_object:
input_path_object.write(input_buffer)
for pkg_type in ('XAR', 'TAR', 'DMG'):
@ -48,7 +48,7 @@ class AppleEfiPkgExtract(BIOSUtility):
break
if input_path != input_object:
os.remove(path=input_path)
os.remove(input_path)
return is_apple_efi_pkg
@ -60,7 +60,7 @@ class AppleEfiPkgExtract(BIOSUtility):
else:
input_path = os.path.join(runtime_root(), 'APPLE_EFI_PKG_INPUT_BUFFER_PARSE.bin')
with open(file=input_path, mode='wb') as input_path_object:
with open(input_path, 'wb') as input_path_object:
input_path_object.write(file_to_bytes(in_object=input_object))
make_dirs(in_path=extract_path, delete=True)
@ -78,7 +78,7 @@ class AppleEfiPkgExtract(BIOSUtility):
return False
if input_path != input_object:
os.remove(path=input_path)
os.remove(input_path)
for work_file in path_files(in_path=working_dir):
if is_file(in_path=work_file) and is_access(in_path=work_file):
@ -205,7 +205,7 @@ class AppleEfiPkgExtract(BIOSUtility):
in_path=efi_source), padding=padding + 8):
efi_dest: str = os.path.join(path_parent(in_path=efi_source), efi_id_module.efi_file_name)
os.rename(src=efi_source, dst=efi_dest)
os.replace(efi_source, efi_dest)
for efi_final in path_files(in_path=working_dir):
if is_file(in_path=efi_final) and is_access(in_path=efi_final):

View file

@ -8,10 +8,9 @@ Copyright (C) 2018-2024 Plato Mavropoulos
"""
import os
import stat
from biosutilities.common.compression import szip_decompress
from biosutilities.common.paths import extract_folder, is_file, make_dirs, safe_name
from biosutilities.common.paths import clear_readonly, extract_folder, is_file, make_dirs, safe_name
from biosutilities.common.patterns import PAT_AWARD_LZH
from biosutilities.common.system import printer
from biosutilities.common.templates import BIOSUtility
@ -28,7 +27,7 @@ class AwardBiosExtract(BIOSUtility):
in_buffer: bytes = file_to_bytes(in_object=input_object)
return bool(PAT_AWARD_LZH.search(string=in_buffer))
return bool(PAT_AWARD_LZH.search(in_buffer))
def parse_format(self, input_object: str | bytes | bytearray, extract_path: str, padding: int = 0) -> bool:
""" Parse & Extract Award BIOS image """
@ -37,8 +36,8 @@ class AwardBiosExtract(BIOSUtility):
make_dirs(in_path=extract_path, delete=True)
for lzh_match in PAT_AWARD_LZH.finditer(string=input_buffer):
lzh_type: str = lzh_match.group(0).decode(encoding='utf-8')
for lzh_match in PAT_AWARD_LZH.finditer(input_buffer):
lzh_type: str = lzh_match.group(0).decode('utf-8')
lzh_text: str = f'LZH-{lzh_type.strip("-").upper()}'
@ -46,7 +45,7 @@ class AwardBiosExtract(BIOSUtility):
mod_bgn: int = lzh_bgn - 0x2
hdr_len: int = input_buffer[mod_bgn]
mod_len: int = int.from_bytes(bytes=input_buffer[mod_bgn + 0x7:mod_bgn + 0xB], byteorder='little')
mod_len: int = int.from_bytes(input_buffer[mod_bgn + 0x7:mod_bgn + 0xB], byteorder='little')
mod_end: int = lzh_bgn + hdr_len + mod_len
mod_bin: bytes = input_buffer[mod_bgn:mod_end]
@ -58,8 +57,7 @@ class AwardBiosExtract(BIOSUtility):
continue
if len(mod_bin) >= 0x16:
tag_txt: str = safe_name(in_name=mod_bin[0x16:0x16 + mod_bin[0x15]].decode(
encoding='utf-8', errors='ignore').strip())
tag_txt: str = safe_name(in_name=mod_bin[0x16:0x16 + mod_bin[0x15]].decode('utf-8', 'ignore').strip())
else:
tag_txt = f'{mod_bgn:X}_{mod_end:X}'
@ -69,7 +67,7 @@ class AwardBiosExtract(BIOSUtility):
lzh_path: str = f'{mod_path}.lzh'
with open(file=lzh_path, mode='wb') as lzh_file:
with open(lzh_path, 'wb') as lzh_file:
lzh_file.write(mod_bin) # Store LZH archive
# 7-Zip returns critical exit code (i.e. 2) if LZH CRC is wrong, do not check result
@ -78,9 +76,9 @@ class AwardBiosExtract(BIOSUtility):
# Manually check if 7-Zip extracted LZH due to its CRC check issue
if is_file(in_path=mod_path):
os.chmod(path=lzh_path, mode=stat.S_IWRITE)
clear_readonly(in_path=lzh_path)
os.remove(path=lzh_path) # Successful extraction, delete LZH archive
os.remove(lzh_path) # Successful extraction, delete LZH archive
# Extract any nested LZH archives
if self.check_format(input_object=mod_path):

View file

@ -12,7 +12,7 @@ def checksum_16(data: bytes | bytearray, value: int = 0, order: str = 'little')
for idx in range(0, len(data), 2):
# noinspection PyTypeChecker
value += int.from_bytes(bytes=data[idx:idx + 2], byteorder=order) # type: ignore
value += int.from_bytes(data[idx:idx + 2], byteorder=order) # type: ignore
value &= 0xFFFF

View file

@ -55,7 +55,7 @@ def is_szip_supported(in_path: str, padding: int = 0, args: list | None = None,
szip_c: list[str] = [szip_path(), 't', *szip_switches(in_switches=[*args]), in_path]
szip_t: subprocess.CompletedProcess[bytes] = subprocess.run(args=szip_c, check=False)
szip_t: subprocess.CompletedProcess[bytes] = subprocess.run(szip_c, check=False)
szip_code_assert(exit_code=szip_t.returncode)
except Exception as error: # pylint: disable=broad-except
@ -77,7 +77,7 @@ def szip_decompress(in_path: str, out_path: str, in_name: str = 'archive', paddi
szip_c: list[str] = [szip_path(), 'x', *szip_switches(in_switches=[*args, f'-o{out_path}']), in_path]
szip_x: subprocess.CompletedProcess[bytes] = subprocess.run(args=szip_c, check=False)
szip_x: subprocess.CompletedProcess[bytes] = subprocess.run(szip_c, check=False)
if check:
szip_code_assert(exit_code=szip_x.returncode)
@ -99,9 +99,9 @@ def szip_decompress(in_path: str, out_path: str, in_name: str = 'archive', paddi
def efi_compress_sizes(data: bytes | bytearray) -> tuple[int, int]:
""" Get EFI compression sizes """
size_compress: int = int.from_bytes(bytes=data[0x0:0x4], byteorder='little')
size_compress: int = int.from_bytes(data[0x0:0x4], byteorder='little')
size_original: int = int.from_bytes(bytes=data[0x4:0x8], byteorder='little')
size_original: int = int.from_bytes(data[0x4:0x8], byteorder='little')
return size_compress, size_original
@ -126,10 +126,10 @@ def efi_decompress(in_path: str, out_path: str, padding: int = 0, silent: bool =
""" EFI/Tiano Decompression via TianoCompress """
try:
subprocess.run(args=[tiano_path(), '-d', in_path, '-o', out_path, '-q', comp_type],
subprocess.run([tiano_path(), '-d', in_path, '-o', out_path, '-q', comp_type],
check=True, stdout=subprocess.DEVNULL)
with open(file=in_path, mode='rb') as file:
with open(in_path, 'rb') as file:
_, size_orig = efi_compress_sizes(data=file.read())
if os.path.getsize(out_path) != size_orig:

View file

@ -65,8 +65,8 @@ def ms_pe_info_show(pe_file: pefile.PE, padding: int = 0) -> None:
if isinstance(pe_info, dict):
for title, value in pe_info.items():
info_title: str = title.decode(encoding='utf-8', errors='ignore').strip()
info_value: str = value.decode(encoding='utf-8', errors='ignore').strip()
info_title: str = title.decode('utf-8', 'ignore').strip()
info_value: str = value.decode('utf-8', 'ignore').strip()
if info_title and info_value:
printer(message=f'{info_title}: {info_value}', padding=padding, new_line=False)

View file

@ -28,7 +28,7 @@ def get_external_path(cmd: str | list | tuple) -> str:
external_path: str | None = external_root if is_dir(in_path=external_root) else None
for command in cmd if isinstance(cmd, (list, tuple)) else [to_string(in_object=cmd)]:
command_path: str | None = shutil.which(cmd=command, path=external_path)
command_path: str | None = shutil.which(command, path=external_path)
if command_path and is_file(in_path=command_path):
return command_path
@ -42,16 +42,15 @@ def big_script_tool() -> Type | None:
try:
bgst: str = get_external_path(cmd='big_script_tool')
bgst_spec: ModuleSpec | None = spec_from_file_location(
name='big_script_tool', location=re.sub(r'\.PY$', '.py', bgst))
bgst_spec: ModuleSpec | None = spec_from_file_location('big_script_tool', re.sub(r'\.PY$', '.py', bgst))
if bgst_spec and isinstance(bgst_spec.loader, Loader):
bgst_module: ModuleType | None = module_from_spec(spec=bgst_spec)
bgst_module: ModuleType | None = module_from_spec(bgst_spec)
if bgst_module:
sys.modules['big_script_tool'] = bgst_module
bgst_spec.loader.exec_module(module=bgst_module)
bgst_spec.loader.exec_module(bgst_module)
return getattr(bgst_module, 'BigScript')
except OSError:

View file

@ -28,7 +28,7 @@ def safe_name(in_name: str) -> str:
name_repr: str = repr(in_name).strip("'")
return re.sub(pattern=r'[\\/:"*?<>|]+', repl='_', string=name_repr)
return re.sub(r'[\\/:"*?<>|]+', '_', name_repr)
def safe_path(base_path: str, user_paths: str | list | tuple) -> str:
@ -65,7 +65,7 @@ def is_safe_path(base_path: str, target_path: str) -> bool:
target_path = real_path(in_path=target_path)
common_path: str = os.path.commonpath(paths=(base_path, target_path))
common_path: str = os.path.commonpath((base_path, target_path))
return base_path == common_path
@ -73,7 +73,7 @@ def is_safe_path(base_path: str, target_path: str) -> bool:
def norm_path(base_path: str, user_path: str) -> str:
""" Create normalized base path + OS separator + user path """
return os.path.normpath(path=base_path + os.sep + user_path)
return os.path.normpath(base_path + os.sep + user_path)
def real_path(in_path: str) -> str:
@ -132,7 +132,7 @@ def delete_dirs(in_path: str) -> None:
""" Delete folder(s), if present """
if is_dir(in_path=in_path):
shutil.rmtree(path=in_path, onerror=clear_readonly_callback) # pylint: disable=deprecated-argument
shutil.rmtree(in_path, onerror=clear_readonly_callback) # pylint: disable=deprecated-argument
def delete_file(in_path: str) -> None:
@ -141,22 +141,22 @@ def delete_file(in_path: str) -> None:
if Path(in_path).is_file():
clear_readonly(in_path=in_path)
os.remove(path=in_path)
os.remove(in_path)
def copy_file(in_path: str, out_path: str, metadata: bool = False) -> None:
""" Copy file to path with or w/o metadata """
if metadata:
shutil.copy2(src=in_path, dst=out_path)
shutil.copy2(in_path, out_path)
else:
shutil.copy(src=in_path, dst=out_path)
shutil.copy(in_path, out_path)
def clear_readonly(in_path: str) -> None:
""" Clear read-only file attribute """
os.chmod(path=in_path, mode=stat.S_IWRITE)
os.chmod(in_path, stat.S_IWRITE)
def clear_readonly_callback(in_func: Callable, in_path: str, _) -> None:
@ -164,7 +164,7 @@ def clear_readonly_callback(in_func: Callable, in_path: str, _) -> None:
clear_readonly(in_path=in_path)
in_func(path=in_path)
in_func(in_path)
def path_files(in_path: str, follow_links: bool = False, root_only: bool = False) -> list[str]:
@ -172,9 +172,9 @@ def path_files(in_path: str, follow_links: bool = False, root_only: bool = False
file_paths: list[str] = []
for root_path, _, file_names in os.walk(top=in_path, followlinks=follow_links):
for root_path, _, file_names in os.walk(in_path, followlinks=follow_links):
for file_name in file_names:
file_path: str = os.path.abspath(path=os.path.join(root_path, file_name))
file_path: str = os.path.abspath(os.path.join(root_path, file_name))
if is_file(in_path=file_path):
file_paths.append(file_path)
@ -194,14 +194,14 @@ def is_dir(in_path: str) -> bool:
def is_file(in_path: str, allow_broken_links: bool = False) -> bool:
""" Check if path is a regural file or symlink (valid or broken) """
in_path_abs: str = os.path.abspath(path=in_path)
in_path_abs: str = os.path.abspath(in_path)
if os.path.lexists(path=in_path_abs):
if os.path.lexists(in_path_abs):
if not is_dir(in_path=in_path_abs):
if allow_broken_links:
return os.path.isfile(path=in_path_abs) or os.path.islink(path=in_path_abs)
return os.path.isfile(in_path_abs) or os.path.islink(in_path_abs)
return os.path.isfile(path=in_path_abs)
return os.path.isfile(in_path_abs)
return False
@ -212,13 +212,13 @@ def is_access(in_path: str, access_mode: int = os.R_OK, follow_links: bool = Fal
if not follow_links and os.access not in os.supports_follow_symlinks:
follow_links = True
return os.access(path=in_path, mode=access_mode, follow_symlinks=follow_links)
return os.access(in_path, access_mode, follow_symlinks=follow_links)
def is_empty_dir(in_path: str, follow_links: bool = False) -> bool:
""" Check if directory is empty (file-wise) """
for _, _, filenames in os.walk(top=in_path, followlinks=follow_links):
for _, _, filenames in os.walk(in_path, followlinks=follow_links):
if filenames:
return False

View file

@ -10,112 +10,112 @@ import re
from typing import Final
PAT_AMI_PFAT: Final[re.Pattern[bytes]] = re.compile(
pattern=br'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS',
br'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS',
flags=re.DOTALL
)
PAT_AMI_UCP: Final[re.Pattern[bytes]] = re.compile(
pattern=br'@(UAF|HPU).{12}@',
br'@(UAF|HPU).{12}@',
flags=re.DOTALL
)
PAT_APPLE_ROM_VER: Final[re.Pattern[bytes]] = re.compile(
pattern=br'Apple ROM Version\x0A\x20{2}'
br'Apple ROM Version\x0A\x20{2}'
)
PAT_APPLE_IM4P: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x16\x04IM4P\x16\x04mefi'
br'\x16\x04IM4P\x16\x04mefi'
)
PAT_APPLE_PBZX: Final[re.Pattern[bytes]] = re.compile(
pattern=br'pbzx'
br'pbzx'
)
PAT_AWARD_LZH: Final[re.Pattern[bytes]] = re.compile(
pattern=br'-lh[04567]-'
br'-lh[04567]-'
)
PAT_DELL_FTR: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90'
br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90'
)
PAT_DELL_HDR: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C',
br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C',
flags=re.DOTALL
)
PAT_DELL_PKG: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x72\x13\x55\x00.{45}7zXZ',
br'\x72\x13\x55\x00.{45}7zXZ',
flags=re.DOTALL
)
PAT_FUJITSU_SFX: Final[re.Pattern[bytes]] = re.compile(
pattern=br'FjSfxBinay\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE',
br'FjSfxBinay\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE',
flags=re.DOTALL
)
PAT_INSYDE_IFL: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\$_IFLASH'
br'\$_IFLASH'
)
PAT_INSYDE_SFX: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x0D\x0A;!@InstallEnd@!\x0D\x0A(7z\xBC\xAF\x27|\x6E\xF4\x79\x5F\x4E)'
br'\x0D\x0A;!@InstallEnd@!\x0D\x0A(7z\xBC\xAF\x27|\x6E\xF4\x79\x5F\x4E)'
)
PAT_INTEL_ENGINE: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x04\x00{3}[\xA1\xE1]\x00{3}.{8}\x86\x80.{9}\x00\$((MN2)|(MAN))',
br'\x04\x00{3}[\xA1\xE1]\x00{3}.{8}\x86\x80.{9}\x00\$((MN2)|(MAN))',
flags=re.DOTALL
)
PAT_INTEL_FD: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x5A\xA5\xF0\x0F.{172}\xFF{16}',
br'\x5A\xA5\xF0\x0F.{172}\xFF{16}',
flags=re.DOTALL
)
PAT_INTEL_IBIOSI: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\$IBIOSI\$.{16}\x2E\x00.{6}\x2E\x00.{8}\x2E\x00.{6}\x2E\x00.{20}\x00{2}',
br'\$IBIOSI\$.{16}\x2E\x00.{6}\x2E\x00.{8}\x2E\x00.{6}\x2E\x00.{20}\x00{2}',
flags=re.DOTALL
)
PAT_MICROSOFT_CAB: Final[re.Pattern[bytes]] = re.compile(
pattern=br'MSCF\x00{4}'
br'MSCF\x00{4}'
)
PAT_MICROSOFT_MZ: Final[re.Pattern[bytes]] = re.compile(
pattern=br'MZ'
br'MZ'
)
PAT_MICROSOFT_PE: Final[re.Pattern[bytes]] = re.compile(
pattern=br'PE\x00{2}'
br'PE\x00{2}'
)
PAT_PHOENIX_TDK: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\$PACK\x00{3}..\x00{2}.\x00{3}',
br'\$PACK\x00{3}..\x00{2}.\x00{3}',
flags=re.DOTALL
)
PAT_PORTWELL_EFI: Final[re.Pattern[bytes]] = re.compile(
pattern=br'<U{2}>'
br'<U{2}>'
)
PAT_TOSHIBA_COM: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x00{2}[\x00-\x02]BIOS.{20}[\x00\x01]',
br'\x00{2}[\x00-\x02]BIOS.{20}[\x00\x01]',
flags=re.DOTALL
)
PAT_VAIO_CAB: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE',
br'\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE',
flags=re.DOTALL
)
PAT_VAIO_CFG: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\[Setting]\x0D\x0A'
br'\[Setting]\x0D\x0A'
)
PAT_VAIO_CHK: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x0AUseVAIOCheck='
br'\x0AUseVAIOCheck='
)
PAT_VAIO_EXT: Final[re.Pattern[bytes]] = re.compile(
pattern=br'\x0AExtractPathByUser='
br'\x0AExtractPathByUser='
)

View file

@ -37,7 +37,7 @@ def printer(message: str | list | tuple | None = None, padding: int = 0, new_lin
message_output: str = '\n' if new_line else ''
for message_line_index, message_line_text in enumerate(iterable=message_string.split('\n')):
for message_line_index, message_line_text in enumerate(message_string.split('\n')):
line_new: str = '' if message_line_index == 0 else '\n'
line_text: str = message_line_text.strip() if strip else message_line_text

View file

@ -78,7 +78,7 @@ class BIOSUtility:
if is_dir(in_path=extract_path):
for suffix in range(2, self.MAX_FAT32_ITEMS):
renamed_path: str = f'{os.path.normpath(path=extract_path)}_{to_ordinal(in_number=suffix)}'
renamed_path: str = f'{os.path.normpath(extract_path)}_{to_ordinal(in_number=suffix)}'
if not is_dir(in_path=renamed_path):
extract_path = renamed_path

View file

@ -38,7 +38,7 @@ def file_to_bytes(in_object: str | bytes | bytearray) -> bytes:
""" Get bytes from given buffer or file path """
if not isinstance(in_object, (bytes, bytearray)):
with open(file=to_string(in_object=in_object), mode='rb') as object_data:
with open(to_string(in_object=in_object), 'rb') as object_data:
object_bytes: bytes = object_data.read()
else:
object_bytes = in_object
@ -50,7 +50,7 @@ def bytes_to_hex(in_buffer: bytes, order: str, data_len: int, slice_len: int | N
""" Converts bytes to hex string, controlling endianess, data size and string slicing """
# noinspection PyTypeChecker
return f'{int.from_bytes(bytes=in_buffer, byteorder=order):0{data_len * 2}X}'[:slice_len] # type: ignore
return f'{int.from_bytes(in_buffer, byteorder=order):0{data_len * 2}X}'[:slice_len] # type: ignore
def remove_quotes(in_text: str) -> str:

View file

@ -44,7 +44,7 @@ class DellPfsHeader(ctypes.LittleEndianStructure):
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
printer(message=['Header Tag :', self.Tag.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Header Tag :', self.Tag.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Header Version:', self.HeaderVersion], padding=padding, new_line=False)
printer(message=['Payload Size :', f'0x{self.PayloadSize:X}'], padding=padding, new_line=False)
@ -65,7 +65,7 @@ class DellPfsFooter(ctypes.LittleEndianStructure):
printer(message=['Payload Size :', f'0x{self.PayloadSize:X}'], padding=padding, new_line=False)
printer(message=['Payload Checksum:', f'0x{self.Checksum:08X}'], padding=padding, new_line=False)
printer(message=['Footer Tag :', self.Tag.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Footer Tag :', self.Tag.decode('utf-8')], padding=padding, new_line=False)
class DellPfsEntryBase(ctypes.LittleEndianStructure):
@ -88,8 +88,8 @@ class DellPfsEntryBase(ctypes.LittleEndianStructure):
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
guid: str = f'{int.from_bytes(bytes=self.GUID, byteorder="little"):0{0x10 * 2}X}'
unknown: str = f'{int.from_bytes(bytes=self.Unknown, byteorder="little"):0{len(self.Unknown) * 8}X}'
guid: str = f'{int.from_bytes(self.GUID, byteorder="little"):0{0x10 * 2}X}'
unknown: str = f'{int.from_bytes(self.Unknown, byteorder="little"):0{len(self.Unknown) * 8}X}'
version: str = DellPfsExtract.get_entry_ver(version_fields=self.Version, version_types=self.VersionType)
printer(message=['Entry GUID :', guid], padding=padding, new_line=False)
@ -136,7 +136,7 @@ class DellPfsInfo(ctypes.LittleEndianStructure):
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
guid: str = f'{int.from_bytes(bytes=self.GUID, byteorder="little"):0{0x10 * 2}X}'
guid: str = f'{int.from_bytes(self.GUID, byteorder="little"):0{0x10 * 2}X}'
printer(message=['Info Version:', self.HeaderVersion], padding=padding, new_line=False)
printer(message=['Entry GUID :', guid], padding=padding, new_line=False)
@ -182,16 +182,16 @@ class DellPfsMetadata(ctypes.LittleEndianStructure):
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
model_ids: str = self.ModelIDs.decode(encoding='utf-8').removesuffix(',END')
model_ids: str = self.ModelIDs.decode('utf-8').removesuffix(',END')
printer(message=['Model IDs :', model_ids], padding=padding, new_line=False)
printer(message=['File Name :', self.FileName.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['File Version :', self.FileVersion.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Date :', self.Date.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Brand :', self.Brand.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Model File :', self.ModelFile.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Model Name :', self.ModelName.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Model Version:', self.ModelVersion.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['File Name :', self.FileName.decode('utf-8')], padding=padding, new_line=False)
printer(message=['File Version :', self.FileVersion.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Date :', self.Date.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Brand :', self.Brand.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Model File :', self.ModelFile.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Model Name :', self.ModelName.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Model Version:', self.ModelVersion.decode('utf-8')], padding=padding, new_line=False)
class DellPfsPfatMetadata(ctypes.LittleEndianStructure):
@ -269,7 +269,7 @@ class DellPfsExtract(BIOSUtility):
in_path=input_object) else 'Image': input_buffer}
# Parse each Dell PFS image contained in the input file
for pfs_index, (pfs_name, pfs_buffer) in enumerate(iterable=pfs_results.items(), start=1):
for pfs_index, (pfs_name, pfs_buffer) in enumerate(pfs_results.items(), start=1):
# At ThinOS PKG packages, multiple PFS images may be included in separate model-named folders
pfs_path: str = os.path.join(extract_path, f'{pfs_index} {pfs_name}') if is_dell_pkg else extract_path
@ -335,7 +335,7 @@ class DellPfsExtract(BIOSUtility):
return pfs_results
lzma_len_off: int = thinos_pkg_match.start() + 0x10
lzma_len_int: int = int.from_bytes(bytes=input_buffer[lzma_len_off:lzma_len_off + 0x4], byteorder='little')
lzma_len_int: int = int.from_bytes(input_buffer[lzma_len_off:lzma_len_off + 0x4], byteorder='little')
lzma_bin_off: int = thinos_pkg_match.end() - 0x5
lzma_bin_dat: bytes = input_buffer[lzma_bin_off:lzma_bin_off + lzma_len_int]
@ -350,13 +350,13 @@ class DellPfsExtract(BIOSUtility):
pkg_tar_path: str = os.path.join(working_path, 'THINOS_PKG.TAR')
with open(file=pkg_tar_path, mode='wb') as pkg_payload:
with open(pkg_tar_path, 'wb') as pkg_payload:
pkg_payload.write(lzma.decompress(lzma_bin_dat))
if is_szip_supported(in_path=pkg_tar_path, padding=0, args=['-tTAR']):
if szip_decompress(in_path=pkg_tar_path, out_path=working_path, in_name='TAR', padding=0,
args=['-tTAR'], check=True, silent=True):
os.remove(path=pkg_tar_path)
os.remove(pkg_tar_path)
else:
return pfs_results
else:
@ -389,7 +389,7 @@ class DellPfsExtract(BIOSUtility):
is_duplicate: bool = False # Initialize duplicate/nested PFS ZLIB offset
for zlib_o in pfs_zlib_init:
zlib_o_size: int = int.from_bytes(bytes=buffer[zlib_o.start() - 0x5:zlib_o.start() - 0x1],
zlib_o_size: int = int.from_bytes(buffer[zlib_o.start() - 0x5:zlib_o.start() - 0x1],
byteorder='little')
# If current PFS ZLIB offset is within another PFS ZLIB range (start-end), set as duplicate
@ -438,7 +438,7 @@ class DellPfsExtract(BIOSUtility):
is_zlib_error = True
# Store the compressed zlib stream size from the header contents
compressed_size_hdr: int = int.from_bytes(bytes=header_data[:0x4], byteorder='little')
compressed_size_hdr: int = int.from_bytes(header_data[:0x4], byteorder='little')
# Store the compressed zlib stream end offset
compressed_end: int = compressed_start + compressed_size_hdr
@ -468,7 +468,7 @@ class DellPfsExtract(BIOSUtility):
is_zlib_error = True
# Store the compressed zlib stream size from the footer contents
compressed_size_ftr: int = int.from_bytes(bytes=footer_data[:0x4], byteorder='little')
compressed_size_ftr: int = int.from_bytes(footer_data[:0x4], byteorder='little')
# Check if the compressed zlib stream is complete, based on footer
if compressed_size_ftr != compressed_size_hdr:
@ -590,7 +590,7 @@ class DellPfsExtract(BIOSUtility):
# Get PFS Information Header GUID in Big Endian format, in order
# to match each Info to the equivalent stored PFS Entry details.
entry_guid = f'{int.from_bytes(bytes=filename_info_hdr.GUID, byteorder="little"):0{0x10 * 2}X}'
entry_guid = f'{int.from_bytes(filename_info_hdr.GUID, byteorder="little"):0{0x10 * 2}X}'
# Get PFS FileName Structure values
entry_info_mod: Any = ctypes_struct(buffer=filename_info, start_offset=info_start + self.PFS_INFO_LEN,
@ -607,7 +607,7 @@ class DellPfsExtract(BIOSUtility):
name_data: bytes = filename_info[name_start:name_start + name_size] # PFS Entry's FileName buffer
# PFS Entry's FileName value
entry_name: str = safe_name(in_name=name_data.decode(encoding='utf-16').strip())
entry_name: str = safe_name(in_name=name_data.decode('utf-16').strip())
# Show PFS FileName Structure info
if self.arguments.structure:
@ -646,11 +646,11 @@ class DellPfsExtract(BIOSUtility):
# As Nested PFS Entry Name, we'll use the actual PFS File Name
# Replace common Windows reserved/illegal filename characters
entry_name = safe_name(in_name=entry_info.FileName.decode(encoding='utf-8').removesuffix('.exe')
entry_name = safe_name(in_name=entry_info.FileName.decode('utf-8').removesuffix('.exe')
.removesuffix('.bin'))
# As Nested PFS Entry Version, we'll use the actual PFS File Version
entry_version = entry_info.FileVersion.decode(encoding='utf-8')
entry_version = entry_info.FileVersion.decode('utf-8')
# Store all relevant Nested PFS Metadata/Information details
info_all.append([entry_guid, entry_name, entry_version])
@ -696,12 +696,12 @@ class DellPfsExtract(BIOSUtility):
# Show PFS Signature Size & Data (after DellPfsEntryR*)
sign_info_start: int = sign_start + self.PFS_INFO_LEN + pfs_entry_size
sign_size: int = int.from_bytes(bytes=signature_info[sign_info_start:sign_info_start + 0x2],
sign_size: int = int.from_bytes(signature_info[sign_info_start:sign_info_start + 0x2],
byteorder='little')
sign_data_raw: bytes = signature_info[sign_info_start + 0x2:sign_info_start + 0x2 + sign_size]
sign_data_txt: str = f'{int.from_bytes(bytes=sign_data_raw, byteorder="little"):0{sign_size * 2}X}'
sign_data_txt: str = f'{int.from_bytes(sign_data_raw, byteorder="little"):0{sign_size * 2}X}'
if self.arguments.structure:
printer(message='Signature Information:\n', padding=padding + 8)
@ -912,7 +912,7 @@ class DellPfsExtract(BIOSUtility):
entry_version: str = self.get_entry_ver(version_fields=pfs_entry.Version, version_types=pfs_entry.VersionType)
# Get PFS Entry GUID in Big Endian format
entry_guid: str = f'{int.from_bytes(bytes=pfs_entry.GUID, byteorder="little"):0{0x10 * 2}X}'
entry_guid: str = f'{int.from_bytes(pfs_entry.GUID, byteorder="little"):0{0x10 * 2}X}'
# PFS Entry Data starts after the PFS Entry Structure
entry_data_start: int = entry_start + entry_size
@ -1043,11 +1043,11 @@ class DellPfsExtract(BIOSUtility):
# The payload of sub-PFS PFAT Entries is not in proper order by default
# We can get each payload's order from PFAT Script > OpCode #2 (set I0 imm)
# PFAT Script OpCode #2 > Operand #3 stores the payload Offset in final image
pfat_entry_off: int = int.from_bytes(bytes=pfat_script_data[0xC:0x10], byteorder='little')
pfat_entry_off: int = int.from_bytes(pfat_script_data[0xC:0x10], byteorder='little')
# We can get each payload's length from PFAT Script > OpCode #4 (set I2 imm)
# PFAT Script OpCode #4 > Operand #3 stores the payload Length in final image
pfat_entry_len: int = int.from_bytes(bytes=pfat_script_data[0x1C:0x20], byteorder='little')
pfat_entry_len: int = int.from_bytes(pfat_script_data[0x1C:0x20], byteorder='little')
# Check that the PFAT Entry Length from Header & Script match
if pfat_hdr.DataSize != pfat_entry_len:
@ -1157,7 +1157,7 @@ class DellPfsExtract(BIOSUtility):
""" Get Dell PFS Entry Structure & Size via its Version """
# PFS Entry Version
pfs_entry_ver: int = int.from_bytes(bytes=buffer[offset + 0x10:offset + 0x14], byteorder='little')
pfs_entry_ver: int = int.from_bytes(buffer[offset + 0x10:offset + 0x14], byteorder='little')
if pfs_entry_ver == 1:
return DellPfsEntryR1, ctypes.sizeof(DellPfsEntryR1)
@ -1175,7 +1175,7 @@ class DellPfsExtract(BIOSUtility):
# Version Type (1 byte) determines the type of Version Value (2 bytes)
# Version Type 'N' is Number, 'A' is Text and ' ' is Empty/Unused
for index, field in enumerate(iterable=version_fields):
for index, field in enumerate(version_fields):
eol: str = '' if index == len(version_fields) - 1 else '.'
if version_types[index] == 65:
@ -1234,7 +1234,7 @@ class DellPfsExtract(BIOSUtility):
final_path: str = os.path.join(out_path, final_name)
with open(file=final_path, mode='wb') as pfs_out:
with open(final_path, 'wb') as pfs_out:
pfs_out.write(bin_buff) # Write final Data/Metadata Signature
return # Skip further processing for Signatures
@ -1253,7 +1253,7 @@ class DellPfsExtract(BIOSUtility):
final_path = os.path.join(out_path, final_name)
# Write final Data/Metadata Payload
with open(file=final_path, mode='w' if is_text else 'wb', encoding='utf-8' if is_text else None) as pfs_out:
with open(final_path, 'w' if is_text else 'wb', encoding='utf-8' if is_text else None) as pfs_out:
pfs_out.write(final_data)
def _bin_is_text(self, buffer: bytes | bytearray, file_type: str, is_metadata: bool, padding: int = 0) -> tuple:
@ -1273,15 +1273,15 @@ class DellPfsExtract(BIOSUtility):
if b',END' in buffer[-0x8:]: # Text Type 1
extension = '.txt'
buffer_text = buffer.decode(encoding='utf-8').split(',END')[0].replace(';', '\n')
buffer_text = buffer.decode('utf-8').split(',END')[0].replace(';', '\n')
elif buffer.startswith(b'VendorName=Dell'): # Text Type 2
extension = '.txt'
buffer_text = buffer.split(b'\x00')[0].decode(encoding='utf-8').replace(';', '\n')
buffer_text = buffer.split(b'\x00')[0].decode('utf-8').replace(';', '\n')
elif b'<Rimm x-schema="' in buffer[:0x50]: # XML Type
extension = '.xml'
buffer_text = buffer.decode(encoding='utf-8')
buffer_text = buffer.decode('utf-8')
elif file_type in ('NESTED_PFS', 'ZLIB') and is_metadata and len(buffer) == self.PFS_META_LEN: # Text Type 3
extension = '.txt'

View file

@ -28,7 +28,7 @@ class FujitsuSfxExtract(BIOSUtility):
input_buffer: bytes = file_to_bytes(in_object=input_object)
return bool(PAT_FUJITSU_SFX.search(string=input_buffer))
return bool(PAT_FUJITSU_SFX.search(input_buffer))
def parse_format(self, input_object: str | bytes | bytearray, extract_path: str, padding: int = 0) -> bool:
""" Parse & Extract Fujitsu SFX image """
@ -36,7 +36,7 @@ class FujitsuSfxExtract(BIOSUtility):
input_buffer: bytes = file_to_bytes(in_object=input_object)
# Microsoft CAB Header XOR 0xFF
match_cab: re.Match[bytes] | None = PAT_FUJITSU_SFX.search(string=input_buffer)
match_cab: re.Match[bytes] | None = PAT_FUJITSU_SFX.search(input_buffer)
if not match_cab:
return False
@ -47,10 +47,10 @@ class FujitsuSfxExtract(BIOSUtility):
cab_start: int = match_cab.start() + 0xA
# Get LE XOR-ed CAB size
cab_size: int = int.from_bytes(bytes=input_buffer[cab_start + 0x8:cab_start + 0xC], byteorder='little')
cab_size: int = int.from_bytes(input_buffer[cab_start + 0x8:cab_start + 0xC], byteorder='little')
# Create CAB size XOR value
xor_size: int = int.from_bytes(bytes=b'\xFF' * 0x4, byteorder='little')
xor_size: int = int.from_bytes(b'\xFF' * 0x4, byteorder='little')
# Perform XOR 0xFF and get actual CAB size
cab_size ^= xor_size
@ -58,10 +58,10 @@ class FujitsuSfxExtract(BIOSUtility):
printer(message='Removing obfuscation...', padding=padding + 4)
# Get BE XOR-ed CAB data
cab_data: int = int.from_bytes(bytes=input_buffer[cab_start:cab_start + cab_size], byteorder='big')
cab_data: int = int.from_bytes(input_buffer[cab_start:cab_start + cab_size], byteorder='big')
# Create CAB data XOR value
xor_data: int = int.from_bytes(bytes=b'\xFF' * cab_size, byteorder='big')
xor_data: int = int.from_bytes(b'\xFF' * cab_size, byteorder='big')
# Perform XOR 0xFF and get actual CAB data
raw_data: bytes = (cab_data ^ xor_data).to_bytes(cab_size, 'big')
@ -73,13 +73,13 @@ class FujitsuSfxExtract(BIOSUtility):
cab_path: str = os.path.join(extract_path, 'FjSfxBinay.cab')
# Create temporary CAB archive
with open(file=cab_path, mode='wb') as cab_file_object:
with open(cab_path, 'wb') as cab_file_object:
cab_file_object.write(raw_data)
if is_szip_supported(in_path=cab_path, padding=padding + 8, silent=False):
if szip_decompress(in_path=cab_path, out_path=extract_path, in_name='FjSfxBinay CAB',
padding=padding + 8, check=True):
os.remove(path=cab_path)
os.remove(cab_path)
else:
return False
else:

View file

@ -51,7 +51,7 @@ class FujitsuUpcExtract(BIOSUtility):
input_path = os.path.join(extract_path, f'{input_name}.UPC')
with open(file=input_path, mode='wb') as input_path_object:
with open(input_path, 'wb') as input_path_object:
input_path_object.write(file_to_bytes(in_object=input_object))
output_path: str = os.path.join(extract_path, f'{input_name}.bin')
@ -59,7 +59,7 @@ class FujitsuUpcExtract(BIOSUtility):
efi_status: bool = efi_decompress(in_path=input_path, out_path=output_path, padding=padding)
if input_path != input_object:
os.remove(path=input_path)
os.remove(input_path)
return efi_status

View file

@ -41,12 +41,12 @@ class IflashHeader(ctypes.LittleEndianStructure):
def get_image_tag(self) -> str:
""" Get Insyde iFlash image tag """
return self.ImageTag.decode(encoding='utf-8', errors='ignore').strip('_')
return self.ImageTag.decode('utf-8', 'ignore').strip('_')
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
printer(message=['Signature :', self.Signature.decode(encoding='utf-8')], padding=padding, new_line=False)
printer(message=['Signature :', self.Signature.decode('utf-8')], padding=padding, new_line=False)
printer(message=['Image Name:', self.get_image_tag()], padding=padding, new_line=False)
printer(message=['Image Size:', f'0x{self.ImageSize:X}'], padding=padding, new_line=False)
printer(message=['Total Size:', f'0x{self.TotalSize:X}'], padding=padding, new_line=False)
@ -88,7 +88,7 @@ class InsydeIfdExtract(BIOSUtility):
if bool(self._insyde_iflash_detect(input_buffer=input_buffer)):
return True
if bool(PAT_INSYDE_SFX.search(string=input_buffer)):
if bool(PAT_INSYDE_SFX.search(input_buffer)):
return True
return False
@ -114,7 +114,7 @@ class InsydeIfdExtract(BIOSUtility):
iflash_match_all: list = []
iflash_match_nan: list = [0x0, 0xFFFFFFFF]
for iflash_match in PAT_INSYDE_IFL.finditer(string=input_buffer):
for iflash_match in PAT_INSYDE_IFL.finditer(input_buffer):
ifl_bgn: int = iflash_match.start()
if len(input_buffer[ifl_bgn:]) <= self.INS_IFL_LEN:
@ -175,7 +175,7 @@ class InsydeIfdExtract(BIOSUtility):
out_path: str = os.path.join(extract_path, safe_name(in_name=out_name))
with open(file=out_path, mode='wb') as out_image:
with open(out_path, 'wb') as out_image:
out_image.write(img_bin)
printer(message=f'Successful Insyde iFlash > {img_tag} extraction!', padding=padding + 12)
@ -187,7 +187,7 @@ class InsydeIfdExtract(BIOSUtility):
def _insyde_packer_extract(self, input_buffer: bytes, extract_path: str, padding: int = 0) -> int:
""" Extract Insyde iFdPacker 7-Zip SFX 7z Update image """
match_sfx: re.Match[bytes] | None = PAT_INSYDE_SFX.search(string=input_buffer)
match_sfx: re.Match[bytes] | None = PAT_INSYDE_SFX.search(input_buffer)
if not match_sfx:
return 127
@ -201,7 +201,7 @@ class InsydeIfdExtract(BIOSUtility):
if sfx_buffer[:0x5] == b'\x6E\xF4\x79\x5F\x4E':
printer(message='Detected Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding=padding + 4)
for index, byte in enumerate(iterable=sfx_buffer):
for index, byte in enumerate(sfx_buffer):
sfx_buffer[index] = byte // 2 + (128 if byte % 2 else 0)
printer(message='Removed Insyde iFdPacker > 7-Zip SFX > Obfuscation!', padding=padding + 8)
@ -215,13 +215,13 @@ class InsydeIfdExtract(BIOSUtility):
sfx_path: str = os.path.join(extract_path, 'Insyde_iFdPacker_SFX.7z')
with open(file=sfx_path, mode='wb') as sfx_file_object:
with open(sfx_path, 'wb') as sfx_file_object:
sfx_file_object.write(sfx_buffer)
if is_szip_supported(in_path=sfx_path, padding=padding + 8, args=[f'-p{self.INS_SFX_PWD}'], silent=False):
if szip_decompress(in_path=sfx_path, out_path=extract_path, in_name='Insyde iFdPacker > 7-Zip SFX',
padding=padding + 8, args=[f'-p{self.INS_SFX_PWD}'], check=True):
os.remove(path=sfx_path)
os.remove(sfx_path)
else:
return 125
else:

View file

@ -47,7 +47,7 @@ class PanasonicBiosExtract(BIOSUtility):
if not pe_file:
return False
if ms_pe_desc(pe_file=pe_file, silent=True).decode(encoding='utf-8', errors='ignore').upper() not in (
if ms_pe_desc(pe_file=pe_file, silent=True).decode('utf-8', 'ignore').upper() not in (
self.PAN_PE_DESC_UNP, self.PAN_PE_DESC_UPD):
return False
@ -82,7 +82,7 @@ class PanasonicBiosExtract(BIOSUtility):
ms_pe_info_show(pe_file=upd_pe_file, padding=upd_padding + 4)
os.remove(path=upd_pe_path)
os.remove(upd_pe_path)
is_upd_extracted: bool = self._panasonic_res_extract(pe_file=upd_pe_file, extract_path=extract_path,
pe_name=upd_pe_name, padding=upd_padding + 8)
@ -107,18 +107,18 @@ class PanasonicBiosExtract(BIOSUtility):
input_data: bytes = file_to_bytes(in_object=input_object)
cab_match: re.Match[bytes] | None = PAT_MICROSOFT_CAB.search(string=input_data)
cab_match: re.Match[bytes] | None = PAT_MICROSOFT_CAB.search(input_data)
if cab_match:
cab_bgn: int = cab_match.start()
cab_end: int = cab_bgn + int.from_bytes(bytes=input_data[cab_bgn + 0x8:cab_bgn + 0xC], byteorder='little')
cab_end: int = cab_bgn + int.from_bytes(input_data[cab_bgn + 0x8:cab_bgn + 0xC], byteorder='little')
cab_tag: str = f'[0x{cab_bgn:06X}-0x{cab_end:06X}]'
cab_path: str = os.path.join(extract_path, f'CAB_{cab_tag}.cab')
with open(file=cab_path, mode='wb') as cab_file_object:
with open(cab_path, 'wb') as cab_file_object:
cab_file_object.write(input_data[cab_bgn:cab_end])
if is_szip_supported(in_path=cab_path, padding=padding, silent=False):
@ -126,7 +126,7 @@ class PanasonicBiosExtract(BIOSUtility):
if szip_decompress(in_path=cab_path, out_path=extract_path, in_name='CAB',
padding=padding + 4, check=True):
os.remove(path=cab_path) # Successful extraction, delete CAB archive
os.remove(cab_path) # Successful extraction, delete CAB archive
for extracted_file_path in path_files(in_path=extract_path):
if is_file(in_path=extracted_file_path) and is_access(in_path=extracted_file_path):
@ -136,7 +136,7 @@ class PanasonicBiosExtract(BIOSUtility):
if extracted_pe_file:
extracted_pe_desc: bytes = ms_pe_desc(pe_file=extracted_pe_file, silent=True)
if extracted_pe_desc.decode(encoding='utf-8', errors='ignore'
if extracted_pe_desc.decode('utf-8', 'ignore'
).upper() == self.PAN_PE_DESC_UPD:
return extracted_file_path
@ -173,7 +173,7 @@ class PanasonicBiosExtract(BIOSUtility):
try:
res_raw: bytes = lznt1.decompress(src=res_bin[0x8:])
if len(res_raw) != int.from_bytes(bytes=res_bin[0x4:0x8], byteorder='little'):
if len(res_raw) != int.from_bytes(res_bin[0x4:0x8], byteorder='little'):
raise ValueError('LZNT1_DECOMPRESS_BAD_SIZE')
printer(message='Successful LZNT1 decompression via Dissect!', padding=padding + 4)
@ -204,11 +204,11 @@ class PanasonicBiosExtract(BIOSUtility):
printer(message=None, new_line=False)
for line in io.BytesIO(res_raw).readlines():
line_text: str = line.decode(encoding='utf-8', errors='ignore').rstrip()
line_text: str = line.decode('utf-8', 'ignore').rstrip()
printer(message=line_text, padding=padding + 8, new_line=False)
with open(file=f'{res_out}.{res_ext}', mode='wb') as out_file_object:
with open(f'{res_out}.{res_ext}', 'wb') as out_file_object:
out_file_object.write(res_raw)
return is_rcdata
@ -236,7 +236,7 @@ class PanasonicBiosExtract(BIOSUtility):
printer(message=img_tag, padding=padding)
with open(file=img_out, mode='wb') as out_img_object:
with open(img_out, 'wb') as out_img_object:
out_img_object.write(img_bin)
printer(message='Successful PE Data extraction!', padding=padding + 4)

View file

@ -38,7 +38,7 @@ class PhoenixTdkHeader(ctypes.LittleEndianStructure):
]
def _get_tag(self) -> str:
return self.Tag.decode(encoding='utf-8', errors='ignore').strip()
return self.Tag.decode('utf-8', 'ignore').strip()
def struct_print(self, padding: int = 0) -> None:
""" Display structure information """
@ -71,7 +71,7 @@ class PhoenixTdkEntry(ctypes.LittleEndianStructure):
def get_name(self) -> str:
""" Get TDK Entry decoded name """
return self.Name.decode(encoding='utf-8', errors='replace').strip()
return self.Name.decode('utf-8', 'replace').strip()
def get_offset(self) -> int:
""" Get TDK Entry absolute offset """
@ -196,7 +196,7 @@ class PhoenixTdkExtract(BIOSUtility):
mod_file += f'_{entry_index + 1:02d}'
# Save TDK Entry data to output file
with open(file=mod_file, mode='wb') as out_file:
with open(mod_file, 'wb') as out_file:
out_file.write(mod_data)
return exit_code == 0
@ -209,7 +209,7 @@ class PhoenixTdkExtract(BIOSUtility):
tdk_base_off: int | None = None
# Scan input file for all Microsoft executable patterns (MZ) before TDK Header Offset
mz_all: list[Match[bytes]] = [mz for mz in PAT_MICROSOFT_MZ.finditer(string=in_buffer) if mz.start() < pack_off]
mz_all: list[Match[bytes]] = [mz for mz in PAT_MICROSOFT_MZ.finditer(in_buffer) if mz.start() < pack_off]
# Phoenix TDK Header structure is an index table for all TDK files
# Each TDK file is referenced from the TDK Packer executable base
@ -223,14 +223,14 @@ class PhoenixTdkExtract(BIOSUtility):
mz_off: int = mz_match.start()
# MZ (DOS) > PE (NT) image Offset is found at offset 0x3C-0x40 relative to MZ base
pe_off: int = mz_off + int.from_bytes(bytes=in_buffer[mz_off + 0x3C:mz_off + 0x40], byteorder='little')
pe_off: int = mz_off + int.from_bytes(in_buffer[mz_off + 0x3C:mz_off + 0x40], byteorder='little')
# Skip MZ (DOS) with bad PE (NT) image Offset
if pe_off == mz_off or pe_off >= pack_off:
continue
# Check if potential MZ > PE image magic value is valid
if PAT_MICROSOFT_PE.search(string=in_buffer[pe_off:pe_off + 0x4]):
if PAT_MICROSOFT_PE.search(in_buffer[pe_off:pe_off + 0x4]):
try:
# Parse detected MZ > PE > Image, quickly (fast_load)
pe_file: PE | None = ms_pe(in_file=in_buffer[mz_off:], silent=True)
@ -268,7 +268,7 @@ class PhoenixTdkExtract(BIOSUtility):
""" Scan input buffer for valid Phoenix TDK image """
# Scan input buffer for Phoenix TDK pattern
tdk_match: Match[bytes] | None = PAT_PHOENIX_TDK.search(string=in_buffer)
tdk_match: Match[bytes] | None = PAT_PHOENIX_TDK.search(in_buffer)
if not tdk_match:
return None, None

View file

@ -50,9 +50,9 @@ class PortwellEfiExtract(BIOSUtility):
return False
# EFI images start with PE Header MZ
if PAT_MICROSOFT_MZ.search(string=input_buffer[:0x2]):
if PAT_MICROSOFT_MZ.search(input_buffer[:0x2]):
# Portwell EFI files start with <UU>
if PAT_PORTWELL_EFI.search(string=pe_buffer[:0x4]):
if PAT_PORTWELL_EFI.search(pe_buffer[:0x4]):
return True
return False
@ -74,9 +74,9 @@ class PortwellEfiExtract(BIOSUtility):
printer(message=efi_title, padding=padding)
# Split EFI Payload into <UU> file chunks
efi_list: list[Match[bytes]] = list(PAT_PORTWELL_EFI.finditer(string=pe_data))
efi_list: list[Match[bytes]] = list(PAT_PORTWELL_EFI.finditer(pe_data))
for idx, val in enumerate(iterable=efi_list):
for idx, val in enumerate(efi_list):
efi_bgn: int = val.end()
efi_end: int = len(pe_data) if idx == len(efi_list) - 1 else efi_list[idx + 1].start()
@ -112,7 +112,7 @@ class PortwellEfiExtract(BIOSUtility):
pe_data_end: int = pe_data_bgn + pe_section.SizeOfRawData
# Decode any valid UTF-16 .data PE section info to a parsable text buffer
pe_data_txt: str = input_buffer[pe_data_bgn:pe_data_end].decode(encoding='utf-16', errors='ignore')
pe_data_txt: str = input_buffer[pe_data_bgn:pe_data_end].decode('utf-16', 'ignore')
# Search .data for UEFI Unpacker tag
unpacker_tag_bgn: int = pe_data_txt.find(unpacker_tag_txt)
@ -152,7 +152,7 @@ class PortwellEfiExtract(BIOSUtility):
file_path: str = os.path.join(extract_path, safe_name(in_name=file_name))
# Store EFI file data to drive
with open(file=file_path, mode='wb') as out_file:
with open(file_path, 'wb') as out_file:
out_file.write(file_data)
# Attempt to detect EFI compression & decompress when applicable
@ -161,11 +161,11 @@ class PortwellEfiExtract(BIOSUtility):
comp_fname: str = file_path + '.temp'
# Rename initial/compressed file
os.replace(src=file_path, dst=comp_fname)
os.replace(file_path, comp_fname)
# Successful decompression, delete compressed file
if efi_decompress(in_path=comp_fname, out_path=file_path, padding=padding + 8):
os.remove(path=comp_fname)
os.remove(comp_fname)
if __name__ == '__main__':

View file

@ -28,7 +28,7 @@ class ToshibaComExtract(BIOSUtility):
input_buffer: bytes = file_to_bytes(in_object=input_object)
return bool(PAT_TOSHIBA_COM.search(string=input_buffer, endpos=0x100))
return bool(PAT_TOSHIBA_COM.search(input_buffer, 0, 0x100))
def parse_format(self, input_object: str | bytes | bytearray, extract_path: str, padding: int = 0) -> bool:
""" Parse & Extract Toshiba BIOS COM image """
@ -40,7 +40,7 @@ class ToshibaComExtract(BIOSUtility):
else:
input_path = os.path.join(extract_path, 'toshiba_bios.com')
with open(file=input_path, mode='wb') as input_buffer:
with open(input_path, 'wb') as input_buffer:
input_buffer.write(file_to_bytes(in_object=input_object))
output_name: str = f'{safe_name(in_name=path_stem(in_path=input_path))}_extracted.bin'
@ -58,7 +58,7 @@ class ToshibaComExtract(BIOSUtility):
return False
if input_path != input_object:
os.remove(path=input_path)
os.remove(input_path)
printer(message='Successful extraction via ToshibaComExtractor!', padding=padding)

View file

@ -29,7 +29,7 @@ class VaioPackageExtract(BIOSUtility):
input_buffer: bytes = file_to_bytes(in_object=input_object)
return bool(PAT_VAIO_CFG.search(string=input_buffer))
return bool(PAT_VAIO_CFG.search(input_buffer))
def parse_format(self, input_object: str | bytes | bytearray, extract_path: str, padding: int = 0) -> bool:
""" Parse & Extract or Unlock VAIO Packaging Manager """
@ -56,7 +56,7 @@ class VaioPackageExtract(BIOSUtility):
""" Extract VAIO Packaging Manager executable """
# Microsoft CAB Header XOR 0xFF
match_cab: Match[bytes] | None = PAT_VAIO_CAB.search(string=buffer)
match_cab: Match[bytes] | None = PAT_VAIO_CAB.search(buffer)
if not match_cab:
return 1
@ -64,11 +64,10 @@ class VaioPackageExtract(BIOSUtility):
printer(message='Detected obfuscated CAB archive!', padding=padding)
# Get LE XOR CAB size
cab_size: int = int.from_bytes(bytes=buffer[match_cab.start() + 0x8:match_cab.start() + 0xC],
byteorder='little')
cab_size: int = int.from_bytes(buffer[match_cab.start() + 0x8:match_cab.start() + 0xC], byteorder='little')
# Create CAB size XOR value
xor_size: int = int.from_bytes(bytes=b'\xFF' * 0x4, byteorder='little')
xor_size: int = int.from_bytes(b'\xFF' * 0x4, byteorder='little')
# Perform XOR 0xFF and get actual CAB size
cab_size ^= xor_size
@ -76,10 +75,10 @@ class VaioPackageExtract(BIOSUtility):
printer(message='Removing obfuscation...', padding=padding + 4)
# Get BE XOR CAB data
cab_data: int = int.from_bytes(bytes=buffer[match_cab.start():match_cab.start() + cab_size], byteorder='big')
cab_data: int = int.from_bytes(buffer[match_cab.start():match_cab.start() + cab_size], byteorder='big')
# Create CAB data XOR value
xor_data: int = int.from_bytes(bytes=b'\xFF' * cab_size, byteorder='big')
xor_data: int = int.from_bytes(b'\xFF' * cab_size, byteorder='big')
# Perform XOR 0xFF and get actual CAB data
raw_data: bytes = (cab_data ^ xor_data).to_bytes(cab_size, 'big')
@ -89,13 +88,13 @@ class VaioPackageExtract(BIOSUtility):
cab_path: str = os.path.join(extract_path, f'{name}_Temporary.cab')
# Create temporary CAB archive
with open(file=cab_path, mode='wb') as cab_file:
with open(cab_path, 'wb') as cab_file:
cab_file.write(raw_data)
if is_szip_supported(in_path=cab_path, padding=padding + 8, silent=False):
if szip_decompress(in_path=cab_path, out_path=extract_path, in_name='VAIO CAB',
padding=padding + 8, check=True):
os.remove(path=cab_path)
os.remove(cab_path)
else:
return 3
else:
@ -109,7 +108,7 @@ class VaioPackageExtract(BIOSUtility):
input_buffer: bytearray = bytearray(buffer) if isinstance(buffer, bytes) else buffer
match_cfg: Match[bytes] | None = PAT_VAIO_CFG.search(string=input_buffer)
match_cfg: Match[bytes] | None = PAT_VAIO_CFG.search(input_buffer)
if not match_cfg:
return 1
@ -144,7 +143,7 @@ class VaioPackageExtract(BIOSUtility):
printer(message='Adjusting UseVAIOCheck entry...', padding=padding + 4)
# Find and replace UseVAIOCheck entry from 1/Yes/True to 0/No/False
vaio_check: Match[bytes] | None = PAT_VAIO_CHK.search(string=input_buffer[cfg_bgn:])
vaio_check: Match[bytes] | None = PAT_VAIO_CHK.search(input_buffer[cfg_bgn:])
if vaio_check:
input_buffer[cfg_bgn + vaio_check.end():cfg_bgn + vaio_check.end() + len(cfg_true)] = cfg_false
@ -156,7 +155,7 @@ class VaioPackageExtract(BIOSUtility):
printer(message='Adjusting ExtractPathByUser entry...', padding=padding + 4)
# Find and replace ExtractPathByUser entry from 0/No/False to 1/Yes/True
user_path: Match[bytes] | None = PAT_VAIO_EXT.search(string=input_buffer[cfg_bgn:])
user_path: Match[bytes] | None = PAT_VAIO_EXT.search(input_buffer[cfg_bgn:])
if user_path:
input_buffer[cfg_bgn + user_path.end():cfg_bgn + user_path.end() + len(cfg_false)] = cfg_true
@ -171,7 +170,7 @@ class VaioPackageExtract(BIOSUtility):
if vaio_check and user_path:
unlock_path: str = os.path.join(extract_path, f'{name}_Unlocked.exe')
with open(file=unlock_path, mode='wb') as unl_file:
with open(unlock_path, 'wb') as unl_file:
unl_file.write(input_buffer)
return 0