Added Award BIOS Module Extractor v2.0_a3

Improved 7-Zip exit code handling
This commit is contained in:
platomav 2022-06-26 19:09:01 +03:00
parent fc73921967
commit 82cd4336bd
7 changed files with 184 additions and 13 deletions

View file

@ -7,7 +7,7 @@ AMI UCP Update Extractor
Copyright (C) 2021-2022 Plato Mavropoulos Copyright (C) 2021-2022 Plato Mavropoulos
""" """
TITLE = 'AMI UCP Update Extractor v2.0_a16' TITLE = 'AMI UCP Update Extractor v2.0_a17'
import os import os
import re import re
@ -392,12 +392,12 @@ def uaf_extract(buffer, extract_path, mod_info, padding=0, is_checksum=False, na
nal_dict[info_tag] = (info_path,info_name) # Assign a file path & name to each Tag nal_dict[info_tag] = (info_path,info_name) # Assign a file path & name to each Tag
# Parse Insyde BIOS @UAF|@HPU Module (@INS) # Parse Insyde BIOS @UAF|@HPU Module (@INS)
if uaf_tag == '@INS' and is_szip_supported(uaf_fname, padding + 4): if uaf_tag == '@INS' and is_szip_supported(uaf_fname, padding + 4, check=True):
ins_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-SFX')) # Generate extraction directory ins_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-SFX')) # Generate extraction directory
printer('Insyde BIOS 7z SFX Archive:', padding + 4) printer('Insyde BIOS 7z SFX Archive:', padding + 4)
if szip_decompress(uaf_fname, ins_dir, '7z SFX', padding + 8) == 0: if szip_decompress(uaf_fname, ins_dir, '7z SFX', padding + 8, check=True) == 0:
os.remove(uaf_fname) # Successful extraction, delete @INS Module file/archive os.remove(uaf_fname) # Successful extraction, delete @INS Module file/archive
# Detect & Unpack AMI BIOS Guard (PFAT) BIOS image # Detect & Unpack AMI BIOS Guard (PFAT) BIOS image

102
Award_BIOS_Extract.py Normal file
View file

@ -0,0 +1,102 @@
#!/usr/bin/env python3
#coding=utf-8
"""
Award BIOS Extract
Award BIOS Module Extractor
Copyright (C) 2018-2022 Plato Mavropoulos
"""
TITLE = 'Award BIOS Module Extractor v2.0_a3'
import os
import sys
# Stop __pycache__ generation
sys.dont_write_bytecode = True
from common.comp_szip import szip_decompress
from common.path_ops import make_dirs, safe_name
from common.patterns import PAT_AWARD_LZH
from common.system import script_init, argparse_init, printer
from common.text_ops import file_to_bytes
# Check if input is Award BIOS image
def is_award_bios(in_file):
in_buffer = file_to_bytes(in_file)
return bool(PAT_AWARD_LZH.search(in_buffer))
# Parse & Extract Award BIOS image
def award_bios_extract(input_file, output_path, padding=0):
input_buffer = file_to_bytes(input_file)
extract_path = os.path.join(f'{output_path}_extracted')
make_dirs(extract_path, delete=True)
for lzh_match in PAT_AWARD_LZH.finditer(input_buffer):
lzh_type = lzh_match.group(0).decode('utf-8')
lzh_text = f'LZH-{lzh_type.strip("-").upper()}'
lzh_bgn = lzh_match.start()
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
mod_bin = input_buffer[mod_bgn:mod_end]
tag_bgn = mod_bgn + 0x16
tag_end = tag_bgn + input_buffer[mod_bgn + 0x15]
tag_txt = input_buffer[tag_bgn:tag_end].decode('utf-8','ignore')
printer(f'{lzh_text} > {tag_txt} [0x{mod_bgn:06X}-0x{mod_end:06X}]', padding)
mod_path = os.path.join(extract_path, safe_name(tag_txt))
lzh_path = f'{mod_path}.lzh'
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
szip_decompress(lzh_path, extract_path, lzh_text, padding + 4, check=False)
# Manually check if 7-Zip extracted LZH due to its CRC check issue
if os.path.isfile(mod_path):
os.remove(lzh_path) # Successful extraction, delete LZH archive
# Extract any nested LZH archives
if is_award_bios(mod_path):
# Recursively extract nested Award BIOS modules
award_bios_extract(mod_path, mod_path, padding + 8)
if __name__ == '__main__':
# Set argparse Arguments
argparser = argparse_init()
arguments = argparser.parse_args()
# Initialize script (must be after argparse)
exit_code,input_files,output_path,padding = script_init(TITLE, arguments, 4)
for input_file in input_files:
input_name = os.path.basename(input_file)
printer(['***', input_name], padding - 4)
with open(input_file, 'rb') as in_file: input_buffer = in_file.read()
if not is_award_bios(input_buffer):
printer('Error: This is not an Award BIOS image!', padding)
continue # Next input file
extract_path = os.path.join(output_path, input_name)
award_bios_extract(input_buffer, extract_path, padding)
exit_code -= 1
printer('Done!', pause=True)
sys.exit(exit_code)

View file

@ -7,7 +7,7 @@ Panasonic BIOS Package Extractor
Copyright (C) 2018-2022 Plato Mavropoulos Copyright (C) 2018-2022 Plato Mavropoulos
""" """
TITLE = 'Panasonic BIOS Package Extractor v2.0_a7' TITLE = 'Panasonic BIOS Package Extractor v2.0_a8'
import os import os
import io import io
@ -64,10 +64,10 @@ def panasonic_cab_extract(buffer, extract_path, padding=0):
with open(cab_path, 'wb') as cab_file: with open(cab_path, 'wb') as cab_file:
cab_file.write(cab_bin) # Store CAB archive cab_file.write(cab_bin) # Store CAB archive
if is_szip_supported(cab_path, padding): if is_szip_supported(cab_path, padding, check=True):
printer(f'Panasonic BIOS Package > PE > CAB {cab_tag}', padding) printer(f'Panasonic BIOS Package > PE > CAB {cab_tag}', padding)
if szip_decompress(cab_path, extract_path, 'CAB', padding + 4) == 0: if szip_decompress(cab_path, extract_path, 'CAB', padding + 4, check=True) == 0:
os.remove(cab_path) # Successful extraction, delete CAB archive os.remove(cab_path) # Successful extraction, delete CAB archive
else: else:
return pe_path, pe_file, pe_info return pe_path, pe_file, pe_info

View file

@ -5,6 +5,7 @@
* [**AMI BIOS Guard Extractor**](#ami-bios-guard-extractor) * [**AMI BIOS Guard Extractor**](#ami-bios-guard-extractor)
* [**AMI UCP Update Extractor**](#ami-ucp-update-extractor) * [**AMI UCP Update Extractor**](#ami-ucp-update-extractor)
* [**Award BIOS Module Extractor**](#award-bios-module-extractor)
* [**Dell PFS Update Extractor**](#dell-pfs-update-extractor) * [**Dell PFS Update Extractor**](#dell-pfs-update-extractor)
* [**Panasonic BIOS Package Extractor**](#panasonic-bios-package-extractor) * [**Panasonic BIOS Package Extractor**](#panasonic-bios-package-extractor)
* [**Phoenix TDK Packer Extractor**](#phoenix-tdk-packer-extractor) * [**Phoenix TDK Packer Extractor**](#phoenix-tdk-packer-extractor)
@ -137,6 +138,64 @@ Some Anti-Virus software may claim that the built/frozen/compiled executable con
![]() ![]()
## **Award BIOS Module Extractor**
![]()
#### **Description**
Parses Award BIOS images and extracts their modules (e.g. RAID, MEMINIT, \_EN_CODE, awardext etc). It supports all Award BIOS image revisions and formats, including those which contain LZH compressed files. The output comprises only final firmware components which are directly usable by end users.
#### **Usage**
You can either Drag & Drop or manually enter Award BIOS image file(s). Optional arguments:
* -h or --help : show help message and exit
* -v or --version : show utility name and version
* -i or --input-dir : extract from given input directory
* -o or --output-dir : extract in given output directory
* -e or --auto-exit : skip press enter to exit prompts
#### **Compatibility**
Should work at all Windows, Linux or macOS operating systems which have Python 3.8 support.
#### **Prerequisites**
To run the utility, you must have the following 3rd party tool at the "external" project directory:
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux)
#### **Build/Freeze/Compile with PyInstaller**
PyInstaller can build/freeze/compile the utility at all three supported platforms, it is simple to run and gets updated often.
1. Make sure Python 3.8.0 or newer is installed:
> python --version
2. Use pip to install PyInstaller:
> pip3 install pyinstaller
3. Place prerequisite at the "external" project directory:
> 7-Zip Console
4. Build/Freeze/Compile:
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Award_BIOS_Extract.py
At dist folder you should find the final utility executable
#### **Anti-Virus False Positives**
Some Anti-Virus software may claim that the built/frozen/compiled executable contains viruses. Any such detections are false positives, usually of PyInstaller. You can switch to a better Anti-Virus software, report the false positive to their support, add the executable to the exclusions, build/freeze/compile yourself or use the Python script directly.
#### **Pictures**
![]()
## **Dell PFS Update Extractor** ## **Dell PFS Update Extractor**
![]() ![]()

View file

@ -7,7 +7,7 @@ VAIO Packaging Manager Extractor
Copyright (C) 2019-2022 Plato Mavropoulos Copyright (C) 2019-2022 Plato Mavropoulos
""" """
TITLE = 'VAIO Packaging Manager Extractor v3.0_a5' TITLE = 'VAIO Packaging Manager Extractor v3.0_a6'
import os import os
import sys import sys
@ -53,8 +53,8 @@ def vaio_cabinet(name, buffer, extract_path, padding=0):
with open(cab_path, 'wb') as cab_file: cab_file.write(cab_data) # Create temporary CAB archive with open(cab_path, 'wb') as cab_file: cab_file.write(cab_data) # Create temporary CAB archive
if is_szip_supported(cab_path, padding + 8): if is_szip_supported(cab_path, padding + 8, check=True):
if szip_decompress(cab_path, extract_path, 'CAB', padding + 8) == 0: if szip_decompress(cab_path, extract_path, 'CAB', padding + 8, check=True) == 0:
os.remove(cab_path) # Successful extraction, delete temporary CAB archive os.remove(cab_path) # Successful extraction, delete temporary CAB archive
else: else:
return 3 return 3

View file

@ -18,10 +18,17 @@ def get_szip_path():
return safe_path(project_root(), ['external',exec_name]) return safe_path(project_root(), ['external',exec_name])
# Check 7-Zip bad exit codes (0 OK, 1 Warning)
def check_bad_exit_code(exit_code):
if exit_code not in (0,1):
raise Exception(f'BAD_EXIT_CODE_{exit_code}')
# Check if file is 7-Zip supported # Check if file is 7-Zip supported
def is_szip_supported(in_path, padding=0, silent=False): def is_szip_supported(in_path, padding=0, check=False, silent=False):
try: try:
subprocess.run([get_szip_path(), 't', in_path, '-bso0', '-bse0', '-bsp0'], check=True) szip_t = subprocess.run([get_szip_path(), 't', in_path, '-bso0', '-bse0', '-bsp0'], check=False)
if check: check_bad_exit_code(szip_t.returncode)
except: except:
if not silent: if not silent:
printer(f'Error: 7-Zip could not check support for file {in_path}!', padding) printer(f'Error: 7-Zip could not check support for file {in_path}!', padding)
@ -31,11 +38,13 @@ def is_szip_supported(in_path, padding=0, silent=False):
return True return True
# Archive decompression via 7-Zip # Archive decompression via 7-Zip
def szip_decompress(in_path, out_path, in_name, padding=0, silent=False): def szip_decompress(in_path, out_path, in_name, padding=0, check=False, silent=False):
if not in_name: in_name = 'archive' if not in_name: in_name = 'archive'
try: try:
subprocess.run([get_szip_path(), 'x', '-aou', '-bso0', '-bse0', '-bsp0', '-o' + out_path, in_path], check=True) szip_x = subprocess.run([get_szip_path(), 'x', '-aou', '-bso0', '-bse0', '-bsp0', '-o' + out_path, in_path], check=False)
if check: check_bad_exit_code(szip_x.returncode)
if not os.path.isdir(out_path): raise Exception('EXTRACT_DIR_MISSING') if not os.path.isdir(out_path): raise Exception('EXTRACT_DIR_MISSING')
except: except:

View file

@ -9,6 +9,7 @@ import re
PAT_AMI_PFAT = re.compile(br'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS', re.DOTALL) PAT_AMI_PFAT = re.compile(br'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS', re.DOTALL)
PAT_AMI_UCP = re.compile(br'@(UAF|HPU).{12}@', re.DOTALL) PAT_AMI_UCP = re.compile(br'@(UAF|HPU).{12}@', re.DOTALL)
PAT_AWARD_LZH = re.compile(br'-lh[04567]-')
PAT_DELL_FTR = re.compile(br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90') PAT_DELL_FTR = re.compile(br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90')
PAT_DELL_HDR = re.compile(br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C', re.DOTALL) PAT_DELL_HDR = re.compile(br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C', re.DOTALL)
PAT_DELL_PKG = re.compile(br'\x72\x13\x55\x00.{45}7zXZ', re.DOTALL) PAT_DELL_PKG = re.compile(br'\x72\x13\x55\x00.{45}7zXZ', re.DOTALL)