2024-04-23 18:22:53 -04:00
|
|
|
#!/usr/bin/env python3 -B
|
|
|
|
# coding=utf-8
|
2022-06-26 12:09:01 -04:00
|
|
|
|
|
|
|
"""
|
|
|
|
Award BIOS Extract
|
|
|
|
Award BIOS Module Extractor
|
2024-04-23 18:22:53 -04:00
|
|
|
Copyright (C) 2018-2024 Plato Mavropoulos
|
2022-06-26 12:09:01 -04:00
|
|
|
"""
|
|
|
|
|
|
|
|
import os
|
2024-04-23 18:22:53 -04:00
|
|
|
import stat
|
2022-06-26 12:09:01 -04:00
|
|
|
|
|
|
|
from common.comp_szip import szip_decompress
|
2024-04-23 18:22:53 -04:00
|
|
|
from common.path_ops import get_extract_path, make_dirs, safe_name
|
2022-06-26 12:09:01 -04:00
|
|
|
from common.patterns import PAT_AWARD_LZH
|
2022-09-12 16:09:12 -04:00
|
|
|
from common.system import printer
|
|
|
|
from common.templates import BIOSUtility
|
2022-06-26 12:09:01 -04:00
|
|
|
from common.text_ops import file_to_bytes
|
|
|
|
|
2024-04-23 18:22:53 -04:00
|
|
|
TITLE = 'Award BIOS Module Extractor v3.0'
|
|
|
|
|
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
def is_award_bios(in_file):
|
2024-04-23 18:22:53 -04:00
|
|
|
""" Check if input is Award BIOS image """
|
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
in_buffer = file_to_bytes(in_file)
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
return bool(PAT_AWARD_LZH.search(in_buffer))
|
|
|
|
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-09-12 16:09:12 -04:00
|
|
|
def award_bios_extract(input_file, extract_path, padding=0):
|
2024-04-23 18:22:53 -04:00
|
|
|
""" Parse & Extract Award BIOS image """
|
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
input_buffer = file_to_bytes(input_file)
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
make_dirs(extract_path, delete=True)
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
for lzh_match in PAT_AWARD_LZH.finditer(input_buffer):
|
|
|
|
lzh_type = lzh_match.group(0).decode('utf-8')
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
lzh_text = f'LZH-{lzh_type.strip("-").upper()}'
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
lzh_bgn = lzh_match.start()
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
mod_bgn = lzh_bgn - 0x2
|
|
|
|
hdr_len = input_buffer[mod_bgn]
|
|
|
|
mod_len = int.from_bytes(input_buffer[mod_bgn + 0x7:mod_bgn + 0xB], 'little')
|
|
|
|
mod_end = lzh_bgn + hdr_len + mod_len
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
mod_bin = input_buffer[mod_bgn:mod_end]
|
2024-04-23 18:22:53 -04:00
|
|
|
|
|
|
|
if len(mod_bin) != 0x2 + hdr_len + mod_len:
|
|
|
|
printer(f'Error: Skipped incomplete LZH stream at 0x{mod_bgn:X}!', padding, False)
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
tag_txt = safe_name(mod_bin[0x16:0x16 + mod_bin[0x15]].decode('utf-8', 'ignore').strip())
|
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
printer(f'{lzh_text} > {tag_txt} [0x{mod_bgn:06X}-0x{mod_end:06X}]', padding)
|
2024-04-23 18:22:53 -04:00
|
|
|
|
|
|
|
mod_path = os.path.join(extract_path, tag_txt)
|
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
lzh_path = f'{mod_path}.lzh'
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
with open(lzh_path, 'wb') as lzh_file:
|
2024-04-23 18:22:53 -04:00
|
|
|
lzh_file.write(mod_bin) # Store LZH archive
|
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
# 7-Zip returns critical exit code (i.e. 2) if LZH CRC is wrong, do not check result
|
|
|
|
szip_decompress(lzh_path, extract_path, lzh_text, padding + 4, check=False)
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
# Manually check if 7-Zip extracted LZH due to its CRC check issue
|
|
|
|
if os.path.isfile(mod_path):
|
2024-04-23 18:22:53 -04:00
|
|
|
os.chmod(lzh_path, stat.S_IWRITE)
|
|
|
|
|
|
|
|
os.remove(lzh_path) # Successful extraction, delete LZH archive
|
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
# Extract any nested LZH archives
|
|
|
|
if is_award_bios(mod_path):
|
|
|
|
# Recursively extract nested Award BIOS modules
|
2022-09-12 16:09:12 -04:00
|
|
|
award_bios_extract(mod_path, get_extract_path(mod_path), padding + 8)
|
2022-06-26 12:09:01 -04:00
|
|
|
|
2024-04-23 18:22:53 -04:00
|
|
|
|
2022-06-26 12:09:01 -04:00
|
|
|
if __name__ == '__main__':
|
2024-04-23 18:22:53 -04:00
|
|
|
BIOSUtility(title=TITLE, check=is_award_bios, main=award_bios_extract).run_utility()
|