mirror of
https://github.com/platomav/BIOSUtilities.git
synced 2025-05-13 06:34:42 -04:00
Created common template for executing all utilities
Unified extracted output directory naming logic Multiple code fixes, refactors and improvements
This commit is contained in:
parent
5f364f4759
commit
6de50c422f
26 changed files with 377 additions and 1169 deletions
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Skip all external files
|
||||||
|
external/*
|
||||||
|
|
||||||
|
# Keep external > requirements file
|
||||||
|
!external/requirements.txt
|
|
@ -7,7 +7,7 @@ AMI BIOS Guard Extractor
|
||||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'AMI BIOS Guard Extractor v4.0_a11'
|
TITLE = 'AMI BIOS Guard Extractor v4.0_a12'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -19,10 +19,11 @@ sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.externals import get_bgs_tool
|
from common.externals import get_bgs_tool
|
||||||
from common.num_ops import get_ordinal
|
from common.num_ops import get_ordinal
|
||||||
from common.path_ops import make_dirs, safe_name
|
from common.path_ops import make_dirs, safe_name, get_extract_path, extract_suffix
|
||||||
from common.patterns import PAT_AMI_PFAT
|
from common.patterns import PAT_AMI_PFAT
|
||||||
from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t
|
from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
class AmiBiosGuardHeader(ctypes.LittleEndianStructure):
|
class AmiBiosGuardHeader(ctypes.LittleEndianStructure):
|
||||||
|
@ -147,7 +148,7 @@ def parse_bg_script(script_data, padding=0):
|
||||||
is_opcode_div = len(script_data) % 8 == 0
|
is_opcode_div = len(script_data) % 8 == 0
|
||||||
|
|
||||||
if not is_opcode_div:
|
if not is_opcode_div:
|
||||||
printer('Error: Script not divisible by OpCode length!', padding, False)
|
printer('Error: Script is not divisible by OpCode length!', padding, False)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@ -161,7 +162,7 @@ def parse_bg_script(script_data, padding=0):
|
||||||
BigScript = get_bgs_tool()
|
BigScript = get_bgs_tool()
|
||||||
|
|
||||||
if not BigScript:
|
if not BigScript:
|
||||||
printer('Error: BIOS Guard Script Tool dependency missing!', padding, False)
|
printer('Note: BIOS Guard Script Tool optional dependency is missing!', padding, False)
|
||||||
|
|
||||||
return 3
|
return 3
|
||||||
|
|
||||||
|
@ -220,7 +221,7 @@ def parse_pfat_hdr(buffer, padding=0):
|
||||||
|
|
||||||
return block_all, hdr_size, files_count
|
return block_all, hdr_size, files_count
|
||||||
|
|
||||||
def parse_pfat_file(input_file, output_path, padding=0):
|
def parse_pfat_file(input_file, extract_path, padding=0):
|
||||||
input_buffer = file_to_bytes(input_file)
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
pfat_buffer = get_ami_pfat(input_buffer)
|
pfat_buffer = get_ami_pfat(input_buffer)
|
||||||
|
@ -228,9 +229,7 @@ def parse_pfat_file(input_file, output_path, padding=0):
|
||||||
file_path = ''
|
file_path = ''
|
||||||
all_blocks_dict = {}
|
all_blocks_dict = {}
|
||||||
|
|
||||||
extract_name = os.path.basename(output_path)
|
extract_name = os.path.basename(extract_path).rstrip(extract_suffix())
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
|
@ -299,7 +298,7 @@ def parse_pfat_file(input_file, output_path, padding=0):
|
||||||
out_oob.write(pfat_oob_data)
|
out_oob.write(pfat_oob_data)
|
||||||
|
|
||||||
if is_ami_pfat(pfat_oob_data):
|
if is_ami_pfat(pfat_oob_data):
|
||||||
parse_pfat_file(pfat_oob_data, pfat_oob_path, padding)
|
parse_pfat_file(pfat_oob_data, get_extract_path(pfat_oob_path), padding)
|
||||||
|
|
||||||
in_all_data = b''.join([block[1] for block in sorted(all_blocks_dict.items())])
|
in_all_data = b''.join([block[1] for block in sorted(all_blocks_dict.items())])
|
||||||
|
|
||||||
|
@ -317,32 +316,4 @@ PFAT_BLK_HDR_LEN = ctypes.sizeof(IntelBiosGuardHeader)
|
||||||
PFAT_BLK_S2K_LEN = ctypes.sizeof(IntelBiosGuardSignature2k)
|
PFAT_BLK_S2K_LEN = ctypes.sizeof(IntelBiosGuardSignature2k)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_ami_pfat, parse_pfat_file).run_utility()
|
||||||
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_ami_pfat(input_buffer):
|
|
||||||
printer('Error: This is not an AMI BIOS Guard (PFAT) image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
parse_pfat_file(input_buffer, extract_path, padding)
|
|
||||||
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -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_a19'
|
TITLE = 'AMI UCP Update Extractor v2.0_a20'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -21,10 +21,11 @@ sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.checksums import get_chk_16
|
from common.checksums import get_chk_16
|
||||||
from common.comp_efi import efi_decompress, is_efi_compressed
|
from common.comp_efi import efi_decompress, is_efi_compressed
|
||||||
from common.path_ops import agnostic_path, make_dirs, safe_name, safe_path
|
from common.path_ops import agnostic_path, make_dirs, safe_name, safe_path, get_extract_path
|
||||||
from common.patterns import PAT_AMI_UCP, PAT_INTEL_ENG
|
from common.patterns import PAT_AMI_UCP, PAT_INTEL_ENG
|
||||||
from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t
|
from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes, to_string
|
from common.text_ops import file_to_bytes, to_string
|
||||||
|
|
||||||
from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file
|
from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file
|
||||||
|
@ -211,15 +212,13 @@ def get_uaf_mod(buffer, uaf_off=0x0):
|
||||||
return uaf_all
|
return uaf_all
|
||||||
|
|
||||||
# Parse & Extract AMI UCP structures
|
# Parse & Extract AMI UCP structures
|
||||||
def ucp_extract(in_file, out_path, padding=0, checksum=False):
|
def ucp_extract(in_file, extract_path, padding=0, checksum=False):
|
||||||
input_buffer = file_to_bytes(in_file)
|
input_buffer = file_to_bytes(in_file)
|
||||||
|
|
||||||
nal_dict = {} # Initialize @NAL Dictionary per UCP
|
nal_dict = {} # Initialize @NAL Dictionary per UCP
|
||||||
|
|
||||||
printer('Utility Configuration Program', padding)
|
printer('Utility Configuration Program', padding)
|
||||||
|
|
||||||
extract_path = os.path.join(f'{out_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
# Get best AMI UCP Pattern match based on @UAF|@HPU Size
|
# Get best AMI UCP Pattern match based on @UAF|@HPU Size
|
||||||
|
@ -419,14 +418,14 @@ def uaf_extract(buffer, extract_path, mod_info, padding=0, checksum=False, nal_d
|
||||||
if uaf_tag == '@INS' and is_insyde_ifd(uaf_fname):
|
if uaf_tag == '@INS' and is_insyde_ifd(uaf_fname):
|
||||||
ins_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-IFD')) # Generate extraction directory
|
ins_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-IFD')) # Generate extraction directory
|
||||||
|
|
||||||
if insyde_ifd_extract(uaf_fname, ins_dir, padding + 4) == 0:
|
if insyde_ifd_extract(uaf_fname, get_extract_path(ins_dir), padding + 4) == 0:
|
||||||
os.remove(uaf_fname) # Delete raw nested Insyde IFD image after successful extraction
|
os.remove(uaf_fname) # Delete raw nested Insyde IFD image after successful extraction
|
||||||
|
|
||||||
# Detect & Unpack AMI BIOS Guard (PFAT) BIOS image
|
# Detect & Unpack AMI BIOS Guard (PFAT) BIOS image
|
||||||
if is_ami_pfat(uaf_data_raw):
|
if is_ami_pfat(uaf_data_raw):
|
||||||
pfat_dir = os.path.join(extract_path, safe_name(uaf_name))
|
pfat_dir = os.path.join(extract_path, safe_name(uaf_name))
|
||||||
|
|
||||||
parse_pfat_file(uaf_data_raw, pfat_dir, padding + 4)
|
parse_pfat_file(uaf_data_raw, get_extract_path(pfat_dir), padding + 4)
|
||||||
|
|
||||||
os.remove(uaf_fname) # Delete raw PFAT BIOS image after successful extraction
|
os.remove(uaf_fname) # Delete raw PFAT BIOS image after successful extraction
|
||||||
|
|
||||||
|
@ -439,7 +438,7 @@ def uaf_extract(buffer, extract_path, mod_info, padding=0, checksum=False, nal_d
|
||||||
if is_ami_ucp(uaf_data_raw):
|
if is_ami_ucp(uaf_data_raw):
|
||||||
uaf_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-UCP')) # Generate extraction directory
|
uaf_dir = os.path.join(extract_path, safe_name(f'{uaf_tag}_nested-UCP')) # Generate extraction directory
|
||||||
|
|
||||||
ucp_extract(uaf_data_raw, uaf_dir, padding + 4, checksum) # Call recursively
|
ucp_extract(uaf_data_raw, get_extract_path(uaf_dir), padding + 4, checksum) # Call recursively
|
||||||
|
|
||||||
os.remove(uaf_fname) # Delete raw nested AMI UCP image after successful extraction
|
os.remove(uaf_fname) # Delete raw nested AMI UCP image after successful extraction
|
||||||
|
|
||||||
|
@ -511,35 +510,6 @@ UAF_TAG_DICT = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
utility = BIOSUtility(TITLE, is_ami_ucp, ucp_extract)
|
||||||
argparser = argparse_init()
|
utility.parse_argument('-c', '--checksum', help='verify AMI UCP Checksums (slow)', action='store_true')
|
||||||
argparser.add_argument('-c', '--checksum', help='verify AMI UCP Checksums (slow)', action='store_true')
|
utility.run_utility()
|
||||||
arguments = argparser.parse_args()
|
|
||||||
|
|
||||||
checksum = arguments.checksum # Set Checksum verification optional argument
|
|
||||||
|
|
||||||
# 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_ami_ucp(input_buffer):
|
|
||||||
printer('Error: This is not an AMI UCP Update executable!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
ucp_extract(input_buffer, extract_path, padding, checksum)
|
|
||||||
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Apple EFI Image Identifier
|
||||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Apple EFI Image Identifier v2.0_a4'
|
TITLE = 'Apple EFI Image Identifier v2.0_a5'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -23,7 +23,8 @@ from common.externals import get_uefifind_path, get_uefiextract_path
|
||||||
from common.path_ops import del_dirs, path_parent, path_suffixes
|
from common.path_ops import del_dirs, path_parent, path_suffixes
|
||||||
from common.patterns import PAT_APPLE_EFI
|
from common.patterns import PAT_APPLE_EFI
|
||||||
from common.struct_ops import char, get_struct, uint8_t
|
from common.struct_ops import char, get_struct, uint8_t
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
class IntelBiosId(ctypes.LittleEndianStructure):
|
class IntelBiosId(ctypes.LittleEndianStructure):
|
||||||
|
@ -92,11 +93,11 @@ def is_apple_efi(input_file):
|
||||||
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Parse & Identify (or Rename) Apple EFI image
|
# Parse & Identify (or Rename) Apple EFI image
|
||||||
def apple_efi_identify(input_file, output_path, padding=0, rename=False):
|
def apple_efi_identify(input_file, extract_path, padding=0, rename=False):
|
||||||
if not os.path.isfile(input_file):
|
if not os.path.isfile(input_file):
|
||||||
printer('Error: Could not find input file path!', padding)
|
printer('Error: Could not find input file path!', padding)
|
||||||
|
|
||||||
|
@ -116,22 +117,20 @@ def apple_efi_identify(input_file, output_path, padding=0, rename=False):
|
||||||
bios_id_res = subprocess.check_output([get_uefifind_path(), input_file, 'body', 'list', PAT_UEFIFIND],
|
bios_id_res = subprocess.check_output([get_uefifind_path(), input_file, 'body', 'list', PAT_UEFIFIND],
|
||||||
text=True)[:36]
|
text=True)[:36]
|
||||||
|
|
||||||
temp_dir = os.path.join(f'{output_path}_uefiextract')
|
del_dirs(extract_path) # UEFIExtract must create its output folder itself, make sure it is not present
|
||||||
|
|
||||||
del_dirs(temp_dir) # UEFIExtract must create its output folder itself, make sure it is not present
|
_ = subprocess.run([get_uefiextract_path(), input_file, bios_id_res, '-o', extract_path, '-m', 'body'],
|
||||||
|
|
||||||
_ = subprocess.run([get_uefiextract_path(), input_file, bios_id_res, '-o', temp_dir, '-m', 'body'],
|
|
||||||
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
with open(os.path.join(temp_dir, 'body.bin'), 'rb') as raw_body:
|
with open(os.path.join(extract_path, 'body.bin'), 'rb') as raw_body:
|
||||||
body_buffer = raw_body.read()
|
body_buffer = raw_body.read()
|
||||||
|
|
||||||
bios_id_match = PAT_APPLE_EFI.search(body_buffer) # Detect decompressed $IBIOSI$ pattern
|
bios_id_match = PAT_APPLE_EFI.search(body_buffer) # Detect decompressed $IBIOSI$ pattern
|
||||||
|
|
||||||
bios_id_hdr = get_struct(body_buffer, bios_id_match.start(), IntelBiosId)
|
bios_id_hdr = get_struct(body_buffer, bios_id_match.start(), IntelBiosId)
|
||||||
|
|
||||||
del_dirs(temp_dir) # Successful UEFIExtract extraction, remove its output (temp) folder
|
del_dirs(extract_path) # Successful UEFIExtract extraction, remove its output (temp) folder
|
||||||
except:
|
except Exception:
|
||||||
printer('Error: Failed to parse compressed $IBIOSI$ pattern!', padding)
|
printer('Error: Failed to parse compressed $IBIOSI$ pattern!', padding)
|
||||||
|
|
||||||
return 2
|
return 2
|
||||||
|
@ -163,31 +162,6 @@ def apple_efi_identify(input_file, output_path, padding=0, rename=False):
|
||||||
PAT_UEFIFIND = f'244942494F534924{"."*32}2E00{"."*12}2E00{"."*16}2E00{"."*12}2E00{"."*40}0000'
|
PAT_UEFIFIND = f'244942494F534924{"."*32}2E00{"."*12}2E00{"."*16}2E00{"."*12}2E00{"."*40}0000'
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
utility = BIOSUtility(TITLE, is_apple_efi, apple_efi_identify)
|
||||||
argparser = argparse_init()
|
utility.parse_argument('-r', '--rename', help='rename EFI image based on its tag', action='store_true')
|
||||||
argparser.add_argument('-r', '--rename', help='rename EFI image based on its tag', action='store_true')
|
utility.run_utility()
|
||||||
arguments = argparser.parse_args()
|
|
||||||
|
|
||||||
rename = arguments.rename # Set EFI image tag renaming optional argument
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
if not is_apple_efi(input_file):
|
|
||||||
printer('Error: This is not an Apple EFI image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if apple_efi_identify(input_file, extract_path, padding, rename) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Apple EFI IM4P Splitter
|
||||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Apple EFI IM4P Splitter v3.0_a4'
|
TITLE = 'Apple EFI IM4P Splitter v3.0_a5'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -17,7 +17,8 @@ sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.path_ops import make_dirs, path_stem
|
from common.path_ops import make_dirs, path_stem
|
||||||
from common.patterns import PAT_APPLE_IM4P, PAT_INTEL_IFD
|
from common.patterns import PAT_APPLE_IM4P, PAT_INTEL_IFD
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
# Check if input is Apple EFI IM4P image
|
# Check if input is Apple EFI IM4P image
|
||||||
|
@ -31,13 +32,11 @@ def is_apple_im4p(input_file):
|
||||||
return bool(is_im4p and is_ifd)
|
return bool(is_im4p and is_ifd)
|
||||||
|
|
||||||
# Parse & Split Apple EFI IM4P image
|
# Parse & Split Apple EFI IM4P image
|
||||||
def apple_im4p_split(input_file, output_path, padding=0):
|
def apple_im4p_split(input_file, extract_path, padding=0):
|
||||||
exit_codes = []
|
exit_codes = []
|
||||||
|
|
||||||
input_buffer = file_to_bytes(input_file)
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
# Detect IM4P EFI pattern
|
# Detect IM4P EFI pattern
|
||||||
|
@ -143,28 +142,4 @@ def apple_im4p_split(input_file, output_path, padding=0):
|
||||||
IFD_COMP_LEN = {3: 0x400000, 4: 0x800000, 5: 0x1000000, 6: 0x2000000}
|
IFD_COMP_LEN = {3: 0x400000, 4: 0x800000, 5: 0x1000000, 6: 0x2000000}
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_apple_im4p, apple_im4p_split).run_utility()
|
||||||
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)
|
|
||||||
|
|
||||||
if not is_apple_im4p(input_file):
|
|
||||||
printer('Error: This is not an Apple EFI IM4P image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if apple_im4p_split(input_file, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Apple EFI PBZX Extractor
|
||||||
Copyright (C) 2021-2022 Plato Mavropoulos
|
Copyright (C) 2021-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Apple EFI PBZX Extractor v1.0_a4'
|
TITLE = 'Apple EFI PBZX Extractor v1.0_a5'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -21,7 +21,8 @@ from common.comp_szip import is_szip_supported, szip_decompress
|
||||||
from common.path_ops import make_dirs, path_stem
|
from common.path_ops import make_dirs, path_stem
|
||||||
from common.patterns import PAT_APPLE_PBZX
|
from common.patterns import PAT_APPLE_PBZX
|
||||||
from common.struct_ops import get_struct, uint32_t
|
from common.struct_ops import get_struct, uint32_t
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
class PbzxChunk(ctypes.BigEndianStructure):
|
class PbzxChunk(ctypes.BigEndianStructure):
|
||||||
|
@ -47,11 +48,9 @@ def is_apple_pbzx(input_file):
|
||||||
return bool(PAT_APPLE_PBZX.search(input_buffer[:0x4]))
|
return bool(PAT_APPLE_PBZX.search(input_buffer[:0x4]))
|
||||||
|
|
||||||
# Parse & Extract Apple PBZX image
|
# Parse & Extract Apple PBZX image
|
||||||
def apple_pbzx_extract(input_file, output_path, padding=0):
|
def apple_pbzx_extract(input_file, extract_path, padding=0):
|
||||||
input_buffer = file_to_bytes(input_file)
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
cpio_bin = b'' # Initialize PBZX > CPIO Buffer
|
cpio_bin = b'' # Initialize PBZX > CPIO Buffer
|
||||||
|
@ -78,7 +77,7 @@ def apple_pbzx_extract(input_file, output_path, padding=0):
|
||||||
cpio_bin += lzma.LZMADecompressor().decompress(comp_bin)
|
cpio_bin += lzma.LZMADecompressor().decompress(comp_bin)
|
||||||
|
|
||||||
printer('Successful LZMA decompression!', padding + 8)
|
printer('Successful LZMA decompression!', padding + 8)
|
||||||
except:
|
except Exception:
|
||||||
# Otherwise, Chunk data is not compressed
|
# Otherwise, Chunk data is not compressed
|
||||||
cpio_bin += comp_bin
|
cpio_bin += comp_bin
|
||||||
|
|
||||||
|
@ -116,28 +115,4 @@ def apple_pbzx_extract(input_file, output_path, padding=0):
|
||||||
PBZX_CHUNK_HDR_LEN = ctypes.sizeof(PbzxChunk)
|
PBZX_CHUNK_HDR_LEN = ctypes.sizeof(PbzxChunk)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_apple_pbzx, apple_pbzx_extract).run_utility()
|
||||||
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)
|
|
||||||
|
|
||||||
if not is_apple_pbzx(input_file):
|
|
||||||
printer('Error: This is not an Apple PBZX image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if apple_pbzx_extract(input_file, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Apple EFI Package Extractor
|
||||||
Copyright (C) 2019-2022 Plato Mavropoulos
|
Copyright (C) 2019-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Apple EFI Package Extractor v2.0_a4'
|
TITLE = 'Apple EFI Package Extractor v2.0_a5'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -16,9 +16,10 @@ import sys
|
||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.comp_szip import is_szip_supported, szip_decompress
|
from common.comp_szip import is_szip_supported, szip_decompress
|
||||||
from common.path_ops import copy_file, del_dirs, get_path_files, make_dirs, path_name, path_parent
|
from common.path_ops import copy_file, del_dirs, get_path_files, make_dirs, path_name, path_parent, get_extract_path
|
||||||
from common.patterns import PAT_APPLE_PKG
|
from common.patterns import PAT_APPLE_PKG
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
from Apple_EFI_ID import apple_efi_identify, is_apple_efi
|
from Apple_EFI_ID import apple_efi_identify, is_apple_efi
|
||||||
|
@ -35,11 +36,11 @@ def is_apple_pkg(input_file):
|
||||||
def efi_split_rename(in_file, out_path, padding=0):
|
def efi_split_rename(in_file, out_path, padding=0):
|
||||||
exit_codes = []
|
exit_codes = []
|
||||||
|
|
||||||
working_dir = f'{in_file}_extracted'
|
working_dir = get_extract_path(in_file)
|
||||||
|
|
||||||
if is_apple_im4p(in_file):
|
if is_apple_im4p(in_file):
|
||||||
printer(f'Splitting IM4P via {is_apple_im4p.__module__}...', padding)
|
printer(f'Splitting IM4P via {is_apple_im4p.__module__}...', padding)
|
||||||
im4p_exit = apple_im4p_split(in_file, in_file, padding + 4)
|
im4p_exit = apple_im4p_split(in_file, working_dir, padding + 4)
|
||||||
exit_codes.append(im4p_exit)
|
exit_codes.append(im4p_exit)
|
||||||
else:
|
else:
|
||||||
make_dirs(working_dir, delete=True)
|
make_dirs(working_dir, delete=True)
|
||||||
|
@ -59,13 +60,11 @@ def efi_split_rename(in_file, out_path, padding=0):
|
||||||
return sum(exit_codes)
|
return sum(exit_codes)
|
||||||
|
|
||||||
# Parse & Extract Apple EFI PKG packages
|
# Parse & Extract Apple EFI PKG packages
|
||||||
def apple_pkg_extract(input_file, output_path, padding=0):
|
def apple_pkg_extract(input_file, extract_path, padding=0):
|
||||||
if not os.path.isfile(input_file):
|
if not os.path.isfile(input_file):
|
||||||
printer('Error: Could not find input file path!', padding)
|
printer('Error: Could not find input file path!', padding)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
xar_path = os.path.join(extract_path, 'xar')
|
xar_path = os.path.join(extract_path, 'xar')
|
||||||
|
@ -82,12 +81,13 @@ def apple_pkg_extract(input_file, output_path, padding=0):
|
||||||
pbzx_module = is_apple_pbzx.__module__
|
pbzx_module = is_apple_pbzx.__module__
|
||||||
if is_apple_pbzx(xar_file):
|
if is_apple_pbzx(xar_file):
|
||||||
printer(f'Extracting PBZX via {pbzx_module}...', padding + 4)
|
printer(f'Extracting PBZX via {pbzx_module}...', padding + 4)
|
||||||
if apple_pbzx_extract(xar_file, xar_file, padding + 8) == 0:
|
pbzx_path = get_extract_path(xar_file)
|
||||||
|
if apple_pbzx_extract(xar_file, pbzx_path, padding + 8) == 0:
|
||||||
printer(f'Succesfull PBZX extraction via {pbzx_module}!', padding + 4)
|
printer(f'Succesfull PBZX extraction via {pbzx_module}!', padding + 4)
|
||||||
for pbzx_file in get_path_files(f'{xar_file}_extracted'):
|
for pbzx_file in get_path_files(pbzx_path):
|
||||||
if path_name(pbzx_file) == 'UpdateBundle.zip':
|
if path_name(pbzx_file) == 'UpdateBundle.zip':
|
||||||
if is_szip_supported(pbzx_file, padding + 8, args=['-tZIP'], check=True):
|
if is_szip_supported(pbzx_file, padding + 8, args=['-tZIP'], check=True):
|
||||||
zip_path = f'{pbzx_file}_extracted'
|
zip_path = get_extract_path(pbzx_file)
|
||||||
if szip_decompress(pbzx_file, zip_path, 'ZIP', padding + 8, args=['-tZIP'], check=True) == 0:
|
if szip_decompress(pbzx_file, zip_path, 'ZIP', padding + 8, args=['-tZIP'], check=True) == 0:
|
||||||
for zip_file in get_path_files(zip_path):
|
for zip_file in get_path_files(zip_path):
|
||||||
if path_name(path_parent(zip_file)) == 'MacEFI':
|
if path_name(path_parent(zip_file)) == 'MacEFI':
|
||||||
|
@ -114,11 +114,11 @@ def apple_pkg_extract(input_file, output_path, padding=0):
|
||||||
|
|
||||||
if path_name(xar_file) == 'Scripts':
|
if path_name(xar_file) == 'Scripts':
|
||||||
if is_szip_supported(xar_file, padding + 4, args=['-tGZIP'], check=True):
|
if is_szip_supported(xar_file, padding + 4, args=['-tGZIP'], check=True):
|
||||||
gzip_path = f'{xar_file}_extracted'
|
gzip_path = get_extract_path(xar_file)
|
||||||
if szip_decompress(xar_file, gzip_path, 'GZIP', padding + 4, args=['-tGZIP'], check=True) == 0:
|
if szip_decompress(xar_file, gzip_path, 'GZIP', padding + 4, args=['-tGZIP'], check=True) == 0:
|
||||||
for gzip_file in get_path_files(gzip_path):
|
for gzip_file in get_path_files(gzip_path):
|
||||||
if is_szip_supported(gzip_file, padding + 8, args=['-tCPIO'], check=True):
|
if is_szip_supported(gzip_file, padding + 8, args=['-tCPIO'], check=True):
|
||||||
cpio_path = f'{gzip_file}_extracted'
|
cpio_path = get_extract_path(gzip_file)
|
||||||
if szip_decompress(gzip_file, cpio_path, 'CPIO', padding + 8, args=['-tCPIO'], check=True) == 0:
|
if szip_decompress(gzip_file, cpio_path, 'CPIO', padding + 8, args=['-tCPIO'], check=True) == 0:
|
||||||
for cpio_file in get_path_files(cpio_path):
|
for cpio_file in get_path_files(cpio_path):
|
||||||
if path_name(path_parent(cpio_file)) == 'EFIPayloads':
|
if path_name(path_parent(cpio_file)) == 'EFIPayloads':
|
||||||
|
@ -145,28 +145,4 @@ def apple_pkg_extract(input_file, output_path, padding=0):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_apple_pkg, apple_pkg_extract).run_utility()
|
||||||
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)
|
|
||||||
|
|
||||||
if not is_apple_pkg(input_file):
|
|
||||||
printer('Error: This is not an Apple EFI PKG package!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if apple_pkg_extract(input_file, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Award BIOS Module Extractor
|
||||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Award BIOS Module Extractor v2.0_a4'
|
TITLE = 'Award BIOS Module Extractor v2.0_a5'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -16,9 +16,10 @@ import sys
|
||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.comp_szip import szip_decompress
|
from common.comp_szip import szip_decompress
|
||||||
from common.path_ops import make_dirs, safe_name
|
from common.path_ops import make_dirs, safe_name, get_extract_path
|
||||||
from common.patterns import PAT_AWARD_LZH
|
from common.patterns import PAT_AWARD_LZH
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
# Check if input is Award BIOS image
|
# Check if input is Award BIOS image
|
||||||
|
@ -28,11 +29,9 @@ def is_award_bios(in_file):
|
||||||
return bool(PAT_AWARD_LZH.search(in_buffer))
|
return bool(PAT_AWARD_LZH.search(in_buffer))
|
||||||
|
|
||||||
# Parse & Extract Award BIOS image
|
# Parse & Extract Award BIOS image
|
||||||
def award_bios_extract(input_file, output_path, padding=0):
|
def award_bios_extract(input_file, extract_path, padding=0):
|
||||||
input_buffer = file_to_bytes(input_file)
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
for lzh_match in PAT_AWARD_LZH.finditer(input_buffer):
|
for lzh_match in PAT_AWARD_LZH.finditer(input_buffer):
|
||||||
|
@ -69,35 +68,7 @@ def award_bios_extract(input_file, output_path, padding=0):
|
||||||
# Extract any nested LZH archives
|
# Extract any nested LZH archives
|
||||||
if is_award_bios(mod_path):
|
if is_award_bios(mod_path):
|
||||||
# Recursively extract nested Award BIOS modules
|
# Recursively extract nested Award BIOS modules
|
||||||
award_bios_extract(mod_path, mod_path, padding + 8)
|
award_bios_extract(mod_path, get_extract_path(mod_path), padding + 8)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_award_bios, award_bios_extract).run_utility()
|
||||||
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)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Dell PFS/PKG Update Extractor
|
||||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Dell PFS/PKG Update Extractor v6.0_a12'
|
TITLE = 'Dell PFS/PKG Update Extractor v6.0_a13'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import io
|
import io
|
||||||
|
@ -25,7 +25,8 @@ from common.comp_szip import is_szip_supported, szip_decompress
|
||||||
from common.path_ops import del_dirs, get_path_files, make_dirs, path_name, path_parent, path_stem, safe_name
|
from common.path_ops import del_dirs, get_path_files, make_dirs, path_name, path_parent, path_stem, safe_name
|
||||||
from common.patterns import PAT_DELL_FTR, PAT_DELL_HDR, PAT_DELL_PKG
|
from common.patterns import PAT_DELL_FTR, PAT_DELL_HDR, PAT_DELL_PKG
|
||||||
from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t, uint64_t
|
from common.struct_ops import char, get_struct, uint8_t, uint16_t, uint32_t, uint64_t
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
from AMI_PFAT_Extract import IntelBiosGuardHeader, IntelBiosGuardSignature2k, parse_bg_script
|
from AMI_PFAT_Extract import IntelBiosGuardHeader, IntelBiosGuardSignature2k, parse_bg_script
|
||||||
|
@ -225,6 +226,28 @@ def is_dell_pfs(in_file):
|
||||||
|
|
||||||
return bool(is_pkg or is_hdr and is_ftr)
|
return bool(is_pkg or is_hdr and is_ftr)
|
||||||
|
|
||||||
|
# Parse & Extract Dell PFS/PKG Update image
|
||||||
|
def pfs_pkg_parse(in_file, output_path, padding=0, structure=True, advanced=True):
|
||||||
|
in_buffer = file_to_bytes(in_file)
|
||||||
|
|
||||||
|
make_dirs(output_path, delete=True)
|
||||||
|
|
||||||
|
is_dell_pkg = is_pfs_pkg(in_buffer)
|
||||||
|
|
||||||
|
if is_dell_pkg:
|
||||||
|
pfs_results = thinos_pkg_extract(in_buffer, output_path)
|
||||||
|
else:
|
||||||
|
pfs_results = {path_stem(in_file) if os.path.isfile(in_file) else 'Image': in_buffer}
|
||||||
|
|
||||||
|
# Parse each Dell PFS image contained in the input file
|
||||||
|
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 = os.path.join(output_path, f'{pfs_index} {pfs_name}') if is_dell_pkg else output_path
|
||||||
|
# Parse each PFS ZLIB section
|
||||||
|
for zlib_offset in get_section_offsets(pfs_buffer):
|
||||||
|
# Call the PFS ZLIB section parser function
|
||||||
|
pfs_section_parse(pfs_buffer, zlib_offset, pfs_path, pfs_name, pfs_index, 1, False, padding, structure, advanced)
|
||||||
|
|
||||||
# Extract Dell ThinOS PKG 7zXZ
|
# Extract Dell ThinOS PKG 7zXZ
|
||||||
def thinos_pkg_extract(in_file, output_path):
|
def thinos_pkg_extract(in_file, output_path):
|
||||||
in_buffer = file_to_bytes(in_file)
|
in_buffer = file_to_bytes(in_file)
|
||||||
|
@ -296,7 +319,7 @@ def get_section_offsets(buffer):
|
||||||
return pfs_zlib_list
|
return pfs_zlib_list
|
||||||
|
|
||||||
# Dell PFS ZLIB Section Parser
|
# Dell PFS ZLIB Section Parser
|
||||||
def pfs_section_parse(zlib_data, zlib_start, output_path, pfs_name, pfs_index, pfs_count, is_rec, padding, structure=True, advanced=True):
|
def pfs_section_parse(zlib_data, zlib_start, output_path, pfs_name, pfs_index, pfs_count, is_rec, padding=0, structure=True, advanced=True):
|
||||||
is_zlib_error = False # Initialize PFS ZLIB-related error state
|
is_zlib_error = False # Initialize PFS ZLIB-related error state
|
||||||
|
|
||||||
section_type = zlib_data[zlib_start - 0x1] # Byte before PFS ZLIB Section pattern is Section Type (e.g. AA, BB)
|
section_type = zlib_data[zlib_start - 0x1] # Byte before PFS ZLIB Section pattern is Section Type (e.g. AA, BB)
|
||||||
|
@ -365,34 +388,34 @@ def pfs_section_parse(zlib_data, zlib_start, output_path, pfs_name, pfs_index, p
|
||||||
if is_zlib_error:
|
if is_zlib_error:
|
||||||
raise Exception('ZLIB_ERROR') # ZLIB errors are critical
|
raise Exception('ZLIB_ERROR') # ZLIB errors are critical
|
||||||
section_data = zlib.decompress(compressed_data) # ZLIB decompression
|
section_data = zlib.decompress(compressed_data) # ZLIB decompression
|
||||||
except:
|
except Exception:
|
||||||
section_data = zlib_data # Fallback to raw ZLIB data upon critical error
|
section_data = zlib_data # Fallback to raw ZLIB data upon critical error
|
||||||
|
|
||||||
# Call the PFS Extract function on the decompressed PFS ZLIB Section
|
# Call the PFS Extract function on the decompressed PFS ZLIB Section
|
||||||
pfs_extract(section_data, pfs_index, pfs_name, pfs_count, section_path, padding, structure, advanced)
|
pfs_extract(section_data, pfs_index, pfs_name, pfs_count, section_path, padding, structure, advanced)
|
||||||
|
|
||||||
# Parse & Extract Dell PFS Volume
|
# Parse & Extract Dell PFS Volume
|
||||||
def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, structure=True, advanced=True):
|
def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, padding=0, structure=True, advanced=True):
|
||||||
# Show PFS Volume indicator
|
# Show PFS Volume indicator
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS Volume:', pfs_padd)
|
printer('PFS Volume:', padding)
|
||||||
|
|
||||||
# Get PFS Header Structure values
|
# Get PFS Header Structure values
|
||||||
pfs_hdr = get_struct(buffer, 0, DellPfsHeader)
|
pfs_hdr = get_struct(buffer, 0, DellPfsHeader)
|
||||||
|
|
||||||
# Validate that a PFS Header was parsed
|
# Validate that a PFS Header was parsed
|
||||||
if pfs_hdr.Tag != b'PFS.HDR.':
|
if pfs_hdr.Tag != b'PFS.HDR.':
|
||||||
printer('Error: PFS Header could not be found!', pfs_padd + 4)
|
printer('Error: PFS Header could not be found!', padding + 4)
|
||||||
|
|
||||||
return # Critical error, abort
|
return # Critical error, abort
|
||||||
|
|
||||||
# Show PFS Header Structure info
|
# Show PFS Header Structure info
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS Header:\n', pfs_padd + 4)
|
printer('PFS Header:\n', padding + 4)
|
||||||
pfs_hdr.struct_print(pfs_padd + 8)
|
pfs_hdr.struct_print(padding + 8)
|
||||||
|
|
||||||
# Validate that a known PFS Header Version was encountered
|
# Validate that a known PFS Header Version was encountered
|
||||||
chk_hdr_ver(pfs_hdr.HeaderVersion, 'PFS', pfs_padd + 8)
|
chk_hdr_ver(pfs_hdr.HeaderVersion, 'PFS', padding + 8)
|
||||||
|
|
||||||
# Get PFS Payload Data
|
# Get PFS Payload Data
|
||||||
pfs_payload = buffer[PFS_HEAD_LEN:PFS_HEAD_LEN + pfs_hdr.PayloadSize]
|
pfs_payload = buffer[PFS_HEAD_LEN:PFS_HEAD_LEN + pfs_hdr.PayloadSize]
|
||||||
|
@ -407,7 +430,7 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
while len(pfs_payload[entry_start:entry_start + pfs_entry_size]) == pfs_entry_size:
|
while len(pfs_payload[entry_start:entry_start + pfs_entry_size]) == pfs_entry_size:
|
||||||
# Analyze PFS Entry Structure and get relevant info
|
# Analyze PFS Entry Structure and get relevant info
|
||||||
_,entry_version,entry_guid,entry_data,entry_data_sig,entry_met,entry_met_sig,next_entry = \
|
_,entry_version,entry_guid,entry_data,entry_data_sig,entry_met,entry_met_sig,next_entry = \
|
||||||
parse_pfs_entry(pfs_payload, entry_start, pfs_entry_size, pfs_entry_struct, 'PFS Entry', pfs_padd, structure)
|
parse_pfs_entry(pfs_payload, entry_start, pfs_entry_size, pfs_entry_struct, 'PFS Entry', padding, structure)
|
||||||
|
|
||||||
entry_type = 'OTHER' # Adjusted later if PFS Entry is Zlib, PFAT, PFS Info, Model Info
|
entry_type = 'OTHER' # Adjusted later if PFS Entry is Zlib, PFAT, PFS Info, Model Info
|
||||||
|
|
||||||
|
@ -444,12 +467,12 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
|
|
||||||
# Show PFS Information Header Structure info
|
# Show PFS Information Header Structure info
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS Information Header:\n', pfs_padd + 4)
|
printer('PFS Information Header:\n', padding + 4)
|
||||||
entry_info_hdr.struct_print(pfs_padd + 8)
|
entry_info_hdr.struct_print(padding + 8)
|
||||||
|
|
||||||
# Validate that a known PFS Information Header Version was encountered
|
# Validate that a known PFS Information Header Version was encountered
|
||||||
if entry_info_hdr.HeaderVersion != 1:
|
if entry_info_hdr.HeaderVersion != 1:
|
||||||
printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', pfs_padd + 8)
|
printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', padding + 8)
|
||||||
break # Skip PFS Information Entries/Descriptors in case of unknown PFS Information Header Version
|
break # Skip PFS Information Entries/Descriptors in case of unknown PFS Information Header Version
|
||||||
|
|
||||||
# Get PFS Information Header GUID in Big Endian format to match each Info to the equivalent stored PFS Entry details
|
# Get PFS Information Header GUID in Big Endian format to match each Info to the equivalent stored PFS Entry details
|
||||||
|
@ -468,8 +491,8 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
|
|
||||||
# Show PFS FileName Structure info
|
# Show PFS FileName Structure info
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS FileName Entry:\n', pfs_padd + 8)
|
printer('PFS FileName Entry:\n', padding + 8)
|
||||||
entry_info_mod.struct_print(pfs_padd + 12, entry_name)
|
entry_info_mod.struct_print(padding + 12, entry_name)
|
||||||
|
|
||||||
# Get PFS FileName Version string via "Version" and "VersionType" fields
|
# Get PFS FileName Version string via "Version" and "VersionType" fields
|
||||||
# PFS FileName Version string must be preferred over PFS Entry's Version
|
# PFS FileName Version string must be preferred over PFS Entry's Version
|
||||||
|
@ -496,8 +519,8 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
|
|
||||||
# Show Nested PFS Metadata Structure info
|
# Show Nested PFS Metadata Structure info
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS Metadata Information:\n', pfs_padd + 4)
|
printer('PFS Metadata Information:\n', padding + 4)
|
||||||
entry_info.struct_print(pfs_padd + 8)
|
entry_info.struct_print(padding + 8)
|
||||||
|
|
||||||
# As Nested PFS Entry Name, we'll use the actual PFS File Name
|
# As Nested PFS Entry Name, we'll use the actual PFS File Name
|
||||||
# Replace common Windows reserved/illegal filename characters
|
# Replace common Windows reserved/illegal filename characters
|
||||||
|
@ -520,12 +543,12 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
|
|
||||||
# Show PFS Information Header Structure info
|
# Show PFS Information Header Structure info
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS Information Header:\n', pfs_padd + 4)
|
printer('PFS Information Header:\n', padding + 4)
|
||||||
entry_info_hdr.struct_print(pfs_padd + 8)
|
entry_info_hdr.struct_print(padding + 8)
|
||||||
|
|
||||||
# Validate that a known PFS Information Header Version was encountered
|
# Validate that a known PFS Information Header Version was encountered
|
||||||
if entry_info_hdr.HeaderVersion != 1:
|
if entry_info_hdr.HeaderVersion != 1:
|
||||||
printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', pfs_padd + 8)
|
printer(f'Error: Unknown PFS Information Header Version {entry_info_hdr.HeaderVersion}!', padding + 8)
|
||||||
break # Skip PFS Signature Entries/Descriptors in case of unknown Header Version
|
break # Skip PFS Signature Entries/Descriptors in case of unknown Header Version
|
||||||
|
|
||||||
# PFS Signature Entries/Descriptors have DellPfsInfo + DellPfsEntryR* + Sign Size [0x2] + Sign Data [Sig Size]
|
# PFS Signature Entries/Descriptors have DellPfsInfo + DellPfsEntryR* + Sign Size [0x2] + Sign Data [Sig Size]
|
||||||
|
@ -536,8 +559,8 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
|
|
||||||
# Show PFS Information Header Structure info
|
# Show PFS Information Header Structure info
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS Information Entry:\n', pfs_padd + 8)
|
printer('PFS Information Entry:\n', padding + 8)
|
||||||
entry_hdr.struct_print(pfs_padd + 12)
|
entry_hdr.struct_print(padding + 12)
|
||||||
|
|
||||||
# Show PFS Signature Size & Data (after DellPfsEntryR*)
|
# Show PFS Signature Size & Data (after DellPfsEntryR*)
|
||||||
sign_info_start = sign_start + PFS_INFO_LEN + pfs_entry_size
|
sign_info_start = sign_start + PFS_INFO_LEN + pfs_entry_size
|
||||||
|
@ -546,9 +569,9 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
sign_data_txt = f'{int.from_bytes(sign_data_raw, "little"):0{sign_size * 2}X}'
|
sign_data_txt = f'{int.from_bytes(sign_data_raw, "little"):0{sign_size * 2}X}'
|
||||||
|
|
||||||
if structure:
|
if structure:
|
||||||
printer('Signature Information:\n', pfs_padd + 8)
|
printer('Signature Information:\n', padding + 8)
|
||||||
printer(f'Signature Size: 0x{sign_size:X}', pfs_padd + 12, False)
|
printer(f'Signature Size: 0x{sign_size:X}', padding + 12, False)
|
||||||
printer(f'Signature Data: {sign_data_txt[:32]} [...]', pfs_padd + 12, False)
|
printer(f'Signature Data: {sign_data_txt[:32]} [...]', padding + 12, False)
|
||||||
|
|
||||||
# The next PFS Signature Entry/Descriptor starts after the previous Signature Data
|
# The next PFS Signature Entry/Descriptor starts after the previous Signature Data
|
||||||
sign_start += (PFS_INFO_LEN + pfs_entry_size + 0x2 + sign_size)
|
sign_start += (PFS_INFO_LEN + pfs_entry_size + 0x2 + sign_size)
|
||||||
|
@ -578,7 +601,7 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
if pfat_entry_hdr.Tag == b'PFS.HDR.' and is_pfat:
|
if pfat_entry_hdr.Tag == b'PFS.HDR.' and is_pfat:
|
||||||
entry_type = 'PFAT' # Re-set PFS Entry Type from OTHER to PFAT, to use such info afterwards
|
entry_type = 'PFAT' # Re-set PFS Entry Type from OTHER to PFAT, to use such info afterwards
|
||||||
|
|
||||||
entry_data = parse_pfat_pfs(pfat_entry_hdr, entry_data, pfs_padd, structure) # Parse sub-PFS PFAT Volume
|
entry_data = parse_pfat_pfs(pfat_entry_hdr, entry_data, padding, structure) # Parse sub-PFS PFAT Volume
|
||||||
|
|
||||||
# Parse PFS Entry which contains zlib-compressed sub-PFS Volume
|
# Parse PFS Entry which contains zlib-compressed sub-PFS Volume
|
||||||
elif pfs_zlib_offsets:
|
elif pfs_zlib_offsets:
|
||||||
|
@ -599,7 +622,7 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
sub_pfs_path = os.path.join(output_path, f'{pfs_count} {safe_name(sub_pfs_name)}')
|
sub_pfs_path = os.path.join(output_path, f'{pfs_count} {safe_name(sub_pfs_name)}')
|
||||||
|
|
||||||
# Recursively call the PFS ZLIB Section Parser function for the sub-PFS Volume (pfs_index = pfs_count)
|
# Recursively call the PFS ZLIB Section Parser function for the sub-PFS Volume (pfs_index = pfs_count)
|
||||||
pfs_section_parse(entry_data, offset, sub_pfs_path, sub_pfs_name, pfs_count, pfs_count, True, pfs_padd + 4, structure, advanced)
|
pfs_section_parse(entry_data, offset, sub_pfs_path, sub_pfs_name, pfs_count, pfs_count, True, padding + 4, structure, advanced)
|
||||||
|
|
||||||
entries_all[index][4] = entry_data # Adjust PFS Entry Data after parsing PFAT (same ZLIB raw data, not stored afterwards)
|
entries_all[index][4] = entry_data # Adjust PFS Entry Data after parsing PFAT (same ZLIB raw data, not stored afterwards)
|
||||||
entries_all[index][3] = entry_type # Adjust PFS Entry Type from OTHER to PFAT or ZLIB (ZLIB is ignored at file extraction)
|
entries_all[index][3] = entry_type # Adjust PFS Entry Type from OTHER to PFAT or ZLIB (ZLIB is ignored at file extraction)
|
||||||
|
@ -668,16 +691,16 @@ def pfs_extract(buffer, pfs_index, pfs_name, pfs_count, output_path, pfs_padd, s
|
||||||
# Write/Extract PFS Entry files
|
# Write/Extract PFS Entry files
|
||||||
for file in write_files:
|
for file in write_files:
|
||||||
full_name = f'{pfs_index} {pfs_name} -- {file_index} {file_name} v{file_version}' # Full PFS Entry Name
|
full_name = f'{pfs_index} {pfs_name} -- {file_index} {file_name} v{file_version}' # Full PFS Entry Name
|
||||||
pfs_file_write(file[0], file[1], file_type, full_name, output_path, pfs_padd, structure, advanced)
|
pfs_file_write(file[0], file[1], file_type, full_name, output_path, padding, structure, advanced)
|
||||||
|
|
||||||
# Get PFS Footer Data after PFS Header Payload
|
# Get PFS Footer Data after PFS Header Payload
|
||||||
pfs_footer = buffer[PFS_HEAD_LEN + pfs_hdr.PayloadSize:PFS_HEAD_LEN + pfs_hdr.PayloadSize + PFS_FOOT_LEN]
|
pfs_footer = buffer[PFS_HEAD_LEN + pfs_hdr.PayloadSize:PFS_HEAD_LEN + pfs_hdr.PayloadSize + PFS_FOOT_LEN]
|
||||||
|
|
||||||
# Analyze PFS Footer Structure
|
# Analyze PFS Footer Structure
|
||||||
chk_pfs_ftr(pfs_footer, pfs_payload, pfs_hdr.PayloadSize, 'PFS', pfs_padd, structure)
|
chk_pfs_ftr(pfs_footer, pfs_payload, pfs_hdr.PayloadSize, 'PFS', padding, structure)
|
||||||
|
|
||||||
# Analyze Dell PFS Entry Structure
|
# Analyze Dell PFS Entry Structure
|
||||||
def parse_pfs_entry(entry_buffer, entry_start, entry_size, entry_struct, text, padding, structure=True):
|
def parse_pfs_entry(entry_buffer, entry_start, entry_size, entry_struct, text, padding=0, structure=True):
|
||||||
# Get PFS Entry Structure values
|
# Get PFS Entry Structure values
|
||||||
pfs_entry = get_struct(entry_buffer, entry_start, entry_struct)
|
pfs_entry = get_struct(entry_buffer, entry_start, entry_struct)
|
||||||
|
|
||||||
|
@ -723,7 +746,7 @@ def parse_pfs_entry(entry_buffer, entry_start, entry_size, entry_struct, text, p
|
||||||
return pfs_entry, entry_version, entry_guid, entry_data, entry_data_sig, entry_met, entry_met_sig, entry_met_sig_end
|
return pfs_entry, entry_version, entry_guid, entry_data, entry_data_sig, entry_met, entry_met_sig, entry_met_sig_end
|
||||||
|
|
||||||
# Parse Dell PFS Volume with PFAT Payload
|
# Parse Dell PFS Volume with PFAT Payload
|
||||||
def parse_pfat_pfs(entry_hdr, entry_data, padding, structure=True):
|
def parse_pfat_pfs(entry_hdr, entry_data, padding=0, structure=True):
|
||||||
# Show PFS Volume indicator
|
# Show PFS Volume indicator
|
||||||
if structure:
|
if structure:
|
||||||
printer('PFS Volume:', padding + 4)
|
printer('PFS Volume:', padding + 4)
|
||||||
|
@ -886,7 +909,7 @@ def get_entry_ver(version_fields, version_types):
|
||||||
return version
|
return version
|
||||||
|
|
||||||
# Check if Dell PFS Header Version is known
|
# Check if Dell PFS Header Version is known
|
||||||
def chk_hdr_ver(version, text, padding):
|
def chk_hdr_ver(version, text, padding=0):
|
||||||
if version in (1,2):
|
if version in (1,2):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -895,7 +918,7 @@ def chk_hdr_ver(version, text, padding):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Analyze Dell PFS Footer Structure
|
# Analyze Dell PFS Footer Structure
|
||||||
def chk_pfs_ftr(footer_buffer, data_buffer, data_size, text, padding, structure=True):
|
def chk_pfs_ftr(footer_buffer, data_buffer, data_size, text, padding=0, structure=True):
|
||||||
# Get PFS Footer Structure values
|
# Get PFS Footer Structure values
|
||||||
pfs_ftr = get_struct(footer_buffer, 0, DellPfsFooter)
|
pfs_ftr = get_struct(footer_buffer, 0, DellPfsFooter)
|
||||||
|
|
||||||
|
@ -920,7 +943,7 @@ def chk_pfs_ftr(footer_buffer, data_buffer, data_size, text, padding, structure=
|
||||||
printer(f'Error: Invalid {text} Footer Payload Checksum!', padding + 4)
|
printer(f'Error: Invalid {text} Footer Payload Checksum!', padding + 4)
|
||||||
|
|
||||||
# Write/Extract Dell PFS Entry Files (Data, Metadata, Signature)
|
# Write/Extract Dell PFS Entry Files (Data, Metadata, Signature)
|
||||||
def pfs_file_write(bin_buff, bin_name, bin_type, full_name, out_path, padding, structure=True, advanced=True):
|
def pfs_file_write(bin_buff, bin_name, bin_type, full_name, out_path, padding=0, structure=True, advanced=True):
|
||||||
# Store Data/Metadata Signature (advanced users only)
|
# Store Data/Metadata Signature (advanced users only)
|
||||||
if bin_name.startswith('sign'):
|
if bin_name.startswith('sign'):
|
||||||
final_name = f'{safe_name(full_name)}.{bin_name.split("_")[1]}.sig'
|
final_name = f'{safe_name(full_name)}.{bin_name.split("_")[1]}.sig'
|
||||||
|
@ -944,7 +967,7 @@ def pfs_file_write(bin_buff, bin_name, bin_type, full_name, out_path, padding, s
|
||||||
pfs_out.write(final_data) # Write final Data/Metadata Payload
|
pfs_out.write(final_data) # Write final Data/Metadata Payload
|
||||||
|
|
||||||
# Check if Dell PFS Entry file/data is Text/XML and Convert
|
# Check if Dell PFS Entry file/data is Text/XML and Convert
|
||||||
def bin_is_text(buffer, file_type, is_metadata, pfs_padd, structure=True, advanced=True):
|
def bin_is_text(buffer, file_type, is_metadata, padding=0, structure=True, advanced=True):
|
||||||
is_text = False
|
is_text = False
|
||||||
write_mode = 'wb'
|
write_mode = 'wb'
|
||||||
extension = '.bin'
|
extension = '.bin'
|
||||||
|
@ -975,8 +998,8 @@ def bin_is_text(buffer, file_type, is_metadata, pfs_padd, structure=True, advanc
|
||||||
|
|
||||||
# Show Model/PCR XML Information, if applicable
|
# Show Model/PCR XML Information, if applicable
|
||||||
if structure and is_text and not is_metadata: # Metadata is shown at initial DellPfsMetadata analysis
|
if structure and is_text and not is_metadata: # Metadata is shown at initial DellPfsMetadata analysis
|
||||||
printer(f'PFS { {".txt": "Model", ".xml": "PCR XML"}[extension] } Information:\n', pfs_padd + 8)
|
printer(f'PFS { {".txt": "Model", ".xml": "PCR XML"}[extension] } Information:\n', padding + 8)
|
||||||
_ = [printer(line.strip('\r'), pfs_padd + 12, False) for line in buffer.split('\n') if line]
|
_ = [printer(line.strip('\r'), padding + 12, False) for line in buffer.split('\n') if line]
|
||||||
|
|
||||||
# Only for non-advanced users due to signature (.sig) invalidation
|
# Only for non-advanced users due to signature (.sig) invalidation
|
||||||
if advanced:
|
if advanced:
|
||||||
|
@ -994,52 +1017,8 @@ PFS_PFAT_LEN = ctypes.sizeof(DellPfsPfatMetadata)
|
||||||
PFAT_HDR_LEN = ctypes.sizeof(IntelBiosGuardHeader)
|
PFAT_HDR_LEN = ctypes.sizeof(IntelBiosGuardHeader)
|
||||||
PFAT_SIG_LEN = ctypes.sizeof(IntelBiosGuardSignature2k)
|
PFAT_SIG_LEN = ctypes.sizeof(IntelBiosGuardSignature2k)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse arguments
|
utility = BIOSUtility(TITLE, is_dell_pfs, pfs_pkg_parse)
|
||||||
argparser = argparse_init()
|
utility.parse_argument('-a', '--advanced', help='extract signatures and metadata', action='store_true')
|
||||||
argparser.add_argument('-a', '--advanced', help='extract signatures and metadata', action='store_true')
|
utility.parse_argument('-s', '--structure', help='show PFS structure information', action='store_true')
|
||||||
argparser.add_argument('-s', '--structure', help='show PFS structure information', action='store_true')
|
utility.run_utility()
|
||||||
arguments = argparser.parse_args()
|
|
||||||
|
|
||||||
advanced = arguments.advanced # Set Advanced user mode optional argument
|
|
||||||
structure = arguments.structure # Set Structure output mode optional argument
|
|
||||||
|
|
||||||
# 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_dell_pfs(input_buffer):
|
|
||||||
printer('Error: This is not a Dell PFS/PKG Update image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, f'{input_name}_extracted')
|
|
||||||
|
|
||||||
is_dell_pkg = is_pfs_pkg(input_buffer)
|
|
||||||
|
|
||||||
if is_dell_pkg:
|
|
||||||
pfs_results = thinos_pkg_extract(input_buffer, extract_path)
|
|
||||||
else:
|
|
||||||
pfs_results = {path_stem(input_file): input_buffer}
|
|
||||||
|
|
||||||
# Parse each Dell PFS image contained in the input file
|
|
||||||
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 = os.path.join(extract_path, f'{pfs_index} {pfs_name}') if is_dell_pkg else extract_path
|
|
||||||
# Parse each PFS ZLIB section
|
|
||||||
for zlib_offset in get_section_offsets(pfs_buffer):
|
|
||||||
# Call the PFS ZLIB section parser function
|
|
||||||
pfs_section_parse(pfs_buffer, zlib_offset, pfs_path, pfs_name, pfs_index, 1, False, padding, structure, advanced)
|
|
||||||
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Fujitsu SFX BIOS Extractor
|
||||||
Copyright (C) 2019-2022 Plato Mavropoulos
|
Copyright (C) 2019-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Fujitsu SFX BIOS Extractor v3.0_a2'
|
TITLE = 'Fujitsu SFX BIOS Extractor v3.0_a3'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -18,7 +18,8 @@ sys.dont_write_bytecode = True
|
||||||
from common.comp_szip import is_szip_supported, szip_decompress
|
from common.comp_szip import is_szip_supported, szip_decompress
|
||||||
from common.path_ops import make_dirs
|
from common.path_ops import make_dirs
|
||||||
from common.patterns import PAT_FUJITSU_SFX
|
from common.patterns import PAT_FUJITSU_SFX
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
# Check if input is Fujitsu SFX image
|
# Check if input is Fujitsu SFX image
|
||||||
|
@ -71,11 +72,9 @@ def fujitsu_cabinet(in_file, extract_path, padding=0):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Parse & Extract Fujitsu SFX image
|
# Parse & Extract Fujitsu SFX image
|
||||||
def fujitsu_sfx_extract(in_file, output_path, padding=0):
|
def fujitsu_sfx_extract(in_file, extract_path, padding=0):
|
||||||
buffer = file_to_bytes(in_file)
|
buffer = file_to_bytes(in_file)
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
if fujitsu_cabinet(buffer, extract_path, padding) == 0:
|
if fujitsu_cabinet(buffer, extract_path, padding) == 0:
|
||||||
|
@ -87,32 +86,4 @@ def fujitsu_sfx_extract(in_file, output_path, padding=0):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_fujitsu_sfx, fujitsu_sfx_extract).run_utility()
|
||||||
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()
|
|
||||||
|
|
||||||
# Check if Fujitsu SFX pattern was found on image
|
|
||||||
if not is_fujitsu_sfx(input_buffer):
|
|
||||||
printer('Error: This is not a Fujitsu SFX image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if fujitsu_sfx_extract(input_buffer, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Fujitsu UPC BIOS Extractor
|
||||||
Copyright (C) 2021-2022 Plato Mavropoulos
|
Copyright (C) 2021-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Fujitsu UPC BIOS Extractor v2.0_a4'
|
TITLE = 'Fujitsu UPC BIOS Extractor v2.0_a5'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -17,7 +17,7 @@ sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.comp_efi import efi_decompress, is_efi_compressed
|
from common.comp_efi import efi_decompress, is_efi_compressed
|
||||||
from common.path_ops import make_dirs, path_suffixes
|
from common.path_ops import make_dirs, path_suffixes
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
# Check if input is Fujitsu UPC image
|
# Check if input is Fujitsu UPC image
|
||||||
|
@ -31,9 +31,7 @@ def is_fujitsu_upc(in_file):
|
||||||
return is_ext and is_efi
|
return is_ext and is_efi
|
||||||
|
|
||||||
# Parse & Extract Fujitsu UPC image
|
# Parse & Extract Fujitsu UPC image
|
||||||
def fujitsu_upc_extract(input_file, output_path, padding=0):
|
def fujitsu_upc_extract(input_file, extract_path, padding=0):
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
image_base = os.path.basename(input_file)
|
image_base = os.path.basename(input_file)
|
||||||
|
@ -43,31 +41,4 @@ def fujitsu_upc_extract(input_file, output_path, padding=0):
|
||||||
return efi_decompress(input_file, image_path, padding)
|
return efi_decompress(input_file, image_path, padding)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_fujitsu_upc, fujitsu_upc_extract).run_utility()
|
||||||
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_fujitsu_upc(input_buffer):
|
|
||||||
printer('Error: This is not a Fujitsu UPC BIOS image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if fujitsu_upc_extract(input_file, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Insyde iFlash/iFdPacker Extractor
|
||||||
Copyright (C) 2022 Plato Mavropoulos
|
Copyright (C) 2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Insyde iFlash/iFdPacker Extractor v2.0_a10'
|
TITLE = 'Insyde iFlash/iFdPacker Extractor v2.0_a11'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -17,10 +17,11 @@ import ctypes
|
||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.comp_szip import is_szip_supported, szip_decompress
|
from common.comp_szip import is_szip_supported, szip_decompress
|
||||||
from common.path_ops import get_path_files, make_dirs, safe_name
|
from common.path_ops import get_path_files, make_dirs, safe_name, get_extract_path
|
||||||
from common.patterns import PAT_INSYDE_IFL, PAT_INSYDE_SFX
|
from common.patterns import PAT_INSYDE_IFL, PAT_INSYDE_SFX
|
||||||
from common.struct_ops import char, get_struct, uint32_t
|
from common.struct_ops import char, get_struct, uint32_t
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
class IflashHeader(ctypes.LittleEndianStructure):
|
class IflashHeader(ctypes.LittleEndianStructure):
|
||||||
|
@ -57,11 +58,9 @@ def is_insyde_ifd(input_file):
|
||||||
return is_ifl or is_sfx
|
return is_ifl or is_sfx
|
||||||
|
|
||||||
# Parse & Extract Insyde iFlash/iFdPacker Update images
|
# Parse & Extract Insyde iFlash/iFdPacker Update images
|
||||||
def insyde_ifd_extract(input_file, output_path, padding=0):
|
def insyde_ifd_extract(input_file, extract_path, padding=0):
|
||||||
input_buffer = file_to_bytes(input_file)
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
iflash_code = insyde_iflash_extract(input_buffer, extract_path, padding)
|
iflash_code = insyde_iflash_extract(input_buffer, extract_path, padding)
|
||||||
|
|
||||||
ifdpack_path = os.path.join(extract_path, 'Insyde iFdPacker SFX')
|
ifdpack_path = os.path.join(extract_path, 'Insyde iFdPacker SFX')
|
||||||
|
@ -190,7 +189,7 @@ def insyde_packer_extract(input_buffer, extract_path, padding=0):
|
||||||
if is_insyde_ifd(sfx_file):
|
if is_insyde_ifd(sfx_file):
|
||||||
printer(f'{os.path.basename(sfx_file)}', padding + 12)
|
printer(f'{os.path.basename(sfx_file)}', padding + 12)
|
||||||
|
|
||||||
ifd_code = insyde_ifd_extract(sfx_file, sfx_file, padding + 16)
|
ifd_code = insyde_ifd_extract(sfx_file, get_extract_path(sfx_file), padding + 16)
|
||||||
|
|
||||||
exit_codes.append(ifd_code)
|
exit_codes.append(ifd_code)
|
||||||
|
|
||||||
|
@ -215,32 +214,4 @@ INS_IFL_IMG = {
|
||||||
INS_IFL_LEN = ctypes.sizeof(IflashHeader)
|
INS_IFL_LEN = ctypes.sizeof(IflashHeader)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_insyde_ifd, insyde_ifd_extract).run_utility()
|
||||||
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_insyde_ifd(input_buffer):
|
|
||||||
printer('Error: This is not an Insyde iFlash/iFdPacker Update image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
insyde_ifd_extract(input_buffer, extract_path, padding)
|
|
||||||
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -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_a9'
|
TITLE = 'Panasonic BIOS Package Extractor v2.0_a10'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import io
|
import io
|
||||||
|
@ -22,7 +22,8 @@ from common.comp_szip import is_szip_supported, szip_decompress
|
||||||
from common.path_ops import get_path_files, make_dirs, path_stem, safe_name
|
from common.path_ops import get_path_files, make_dirs, path_stem, safe_name
|
||||||
from common.pe_ops import get_pe_file, get_pe_info, is_pe_file, show_pe_info
|
from common.pe_ops import get_pe_file, get_pe_info, is_pe_file, show_pe_info
|
||||||
from common.patterns import PAT_MICROSOFT_CAB
|
from common.patterns import PAT_MICROSOFT_CAB
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file
|
from AMI_PFAT_Extract import is_ami_pfat, parse_pfat_file
|
||||||
|
@ -111,7 +112,7 @@ def panasonic_res_extract(pe_name, pe_file, extract_path, padding=0):
|
||||||
res_raw = lznt1.decompress(res_bin[0x8:])
|
res_raw = lznt1.decompress(res_bin[0x8:])
|
||||||
|
|
||||||
printer('Succesfull LZNT1 decompression via lznt1!', padding + 8)
|
printer('Succesfull LZNT1 decompression via lznt1!', padding + 8)
|
||||||
except:
|
except Exception:
|
||||||
res_raw = res_bin
|
res_raw = res_bin
|
||||||
|
|
||||||
printer('Succesfull PE Resource extraction!', padding + 8)
|
printer('Succesfull PE Resource extraction!', padding + 8)
|
||||||
|
@ -161,10 +162,8 @@ def panasonic_img_extract(pe_name, pe_path, pe_file, extract_path, padding=0):
|
||||||
return bool(img_bin)
|
return bool(img_bin)
|
||||||
|
|
||||||
# Parse & Extract Panasonic BIOS Package PE
|
# Parse & Extract Panasonic BIOS Package PE
|
||||||
def panasonic_pkg_extract(input_path, input_buffer, output_path, padding=0):
|
def panasonic_pkg_extract(input_file, extract_path, padding=0):
|
||||||
is_upd_res,is_upd_img = [False] * 2
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
|
@ -178,7 +177,7 @@ def panasonic_pkg_extract(input_path, input_buffer, output_path, padding=0):
|
||||||
if not pkg_pe_info:
|
if not pkg_pe_info:
|
||||||
return 3
|
return 3
|
||||||
|
|
||||||
pkg_pe_name = path_stem(input_path)
|
pkg_pe_name = path_stem(input_file)
|
||||||
|
|
||||||
printer(f'Panasonic BIOS Package > PE ({pkg_pe_name})\n', padding)
|
printer(f'Panasonic BIOS Package > PE ({pkg_pe_name})\n', padding)
|
||||||
|
|
||||||
|
@ -195,6 +194,8 @@ def panasonic_pkg_extract(input_path, input_buffer, output_path, padding=0):
|
||||||
|
|
||||||
show_pe_info(upd_pe_info, padding + 16)
|
show_pe_info(upd_pe_info, padding + 16)
|
||||||
|
|
||||||
|
is_upd_res, is_upd_img = False, False
|
||||||
|
|
||||||
is_upd_res = panasonic_res_extract(upd_pe_name, upd_pe_file, extract_path, padding + 16)
|
is_upd_res = panasonic_res_extract(upd_pe_name, upd_pe_file, extract_path, padding + 16)
|
||||||
|
|
||||||
if not is_upd_res:
|
if not is_upd_res:
|
||||||
|
@ -205,32 +206,4 @@ def panasonic_pkg_extract(input_path, input_buffer, output_path, padding=0):
|
||||||
return 0 if is_upd_res or is_upd_img else 1
|
return 0 if is_upd_res or is_upd_img else 1
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_panasonic_pkg, panasonic_pkg_extract).run_utility()
|
||||||
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()
|
|
||||||
|
|
||||||
# Check if Panasonic BIOS Package pattern was found on executable
|
|
||||||
if not is_panasonic_pkg(input_buffer):
|
|
||||||
printer('Error: This is not a Panasonic BIOS Package executable!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if panasonic_pkg_extract(input_file, input_buffer, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Phoenix TDK Packer Extractor
|
||||||
Copyright (C) 2021-2022 Plato Mavropoulos
|
Copyright (C) 2021-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Phoenix TDK Packer Extractor v2.0_a9'
|
TITLE = 'Phoenix TDK Packer Extractor v2.0_a10'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -21,7 +21,8 @@ from common.path_ops import make_dirs, safe_name
|
||||||
from common.pe_ops import get_pe_file, get_pe_info
|
from common.pe_ops import get_pe_file, get_pe_info
|
||||||
from common.patterns import PAT_MICROSOFT_MZ, PAT_MICROSOFT_PE, PAT_PHOENIX_TDK
|
from common.patterns import PAT_MICROSOFT_MZ, PAT_MICROSOFT_PE, PAT_PHOENIX_TDK
|
||||||
from common.struct_ops import char, get_struct, uint32_t
|
from common.struct_ops import char, get_struct, uint32_t
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
class PhoenixTdkHeader(ctypes.LittleEndianStructure):
|
class PhoenixTdkHeader(ctypes.LittleEndianStructure):
|
||||||
|
@ -110,7 +111,7 @@ def get_tdk_base(in_buffer, pack_off):
|
||||||
|
|
||||||
# Parse detected MZ > PE > Info > Product Name
|
# Parse detected MZ > PE > Info > Product Name
|
||||||
pe_name = pe_info.get(b'ProductName',b'')
|
pe_name = pe_info.get(b'ProductName',b'')
|
||||||
except:
|
except Exception:
|
||||||
# Any error means no MZ > PE > Info > Product Name
|
# Any error means no MZ > PE > Info > Product Name
|
||||||
pe_name = b''
|
pe_name = b''
|
||||||
|
|
||||||
|
@ -152,12 +153,10 @@ def is_phoenix_tdk(in_file):
|
||||||
return bool(get_phoenix_tdk(buffer)[1] is not None)
|
return bool(get_phoenix_tdk(buffer)[1] is not None)
|
||||||
|
|
||||||
# Parse & Extract Phoenix Tools Development Kit (TDK) Packer
|
# Parse & Extract Phoenix Tools Development Kit (TDK) Packer
|
||||||
def phoenix_tdk_extract(input_file, output_path, padding=0):
|
def phoenix_tdk_extract(input_file, extract_path, padding=0):
|
||||||
input_buffer = file_to_bytes(input_file)
|
|
||||||
|
|
||||||
exit_code = 0
|
exit_code = 0
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
|
@ -214,7 +213,7 @@ def phoenix_tdk_extract(input_file, output_path, padding=0):
|
||||||
if tdk_mod.get_compression() == 'LZMA':
|
if tdk_mod.get_compression() == 'LZMA':
|
||||||
try:
|
try:
|
||||||
mod_data = lzma.LZMADecompressor().decompress(mod_data)
|
mod_data = lzma.LZMADecompressor().decompress(mod_data)
|
||||||
except:
|
except Exception:
|
||||||
printer('Error: Phoenix TDK Entry > LZMA decompression failed!\n', padding + 12, pause=True)
|
printer('Error: Phoenix TDK Entry > LZMA decompression failed!\n', padding + 12, pause=True)
|
||||||
exit_code = 5
|
exit_code = 5
|
||||||
|
|
||||||
|
@ -241,32 +240,4 @@ TDK_MOD_LEN = ctypes.sizeof(PhoenixTdkEntry)
|
||||||
TDK_DUMMY_LEN = 0x200
|
TDK_DUMMY_LEN = 0x200
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_phoenix_tdk, phoenix_tdk_extract).run_utility()
|
||||||
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()
|
|
||||||
|
|
||||||
# Check if Phoenix TDK Packer pattern was found on executable
|
|
||||||
if not is_phoenix_tdk(input_buffer):
|
|
||||||
printer('Error: This is not a Phoenix TDK Packer executable!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if phoenix_tdk_extract(input_buffer, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Portwell EFI Update Extractor
|
||||||
Copyright (C) 2021-2022 Plato Mavropoulos
|
Copyright (C) 2021-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Portwell EFI Update Extractor v2.0_a11'
|
TITLE = 'Portwell EFI Update Extractor v2.0_a12'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -19,7 +19,8 @@ from common.comp_efi import efi_decompress, is_efi_compressed
|
||||||
from common.path_ops import make_dirs, safe_name
|
from common.path_ops import make_dirs, safe_name
|
||||||
from common.pe_ops import get_pe_file
|
from common.pe_ops import get_pe_file
|
||||||
from common.patterns import PAT_MICROSOFT_MZ, PAT_PORTWELL_EFI
|
from common.patterns import PAT_MICROSOFT_MZ, PAT_PORTWELL_EFI
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
FILE_NAMES = {
|
FILE_NAMES = {
|
||||||
|
@ -36,7 +37,7 @@ def is_portwell_efi(in_file):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pe_buffer = get_portwell_pe(in_buffer)[1]
|
pe_buffer = get_portwell_pe(in_buffer)[1]
|
||||||
except:
|
except Exception:
|
||||||
pe_buffer = b''
|
pe_buffer = b''
|
||||||
|
|
||||||
is_mz = PAT_MICROSOFT_MZ.search(in_buffer[:0x2]) # EFI images start with PE Header MZ
|
is_mz = PAT_MICROSOFT_MZ.search(in_buffer[:0x2]) # EFI images start with PE Header MZ
|
||||||
|
@ -54,10 +55,10 @@ def get_portwell_pe(in_buffer):
|
||||||
return pe_file, pe_data
|
return pe_file, pe_data
|
||||||
|
|
||||||
# Parse & Extract Portwell UEFI Unpacker
|
# Parse & Extract Portwell UEFI Unpacker
|
||||||
def portwell_efi_extract(input_buffer, output_path, padding=0):
|
def portwell_efi_extract(input_file, extract_path, padding=0):
|
||||||
efi_files = [] # Initialize EFI Payload file chunks
|
efi_files = [] # Initialize EFI Payload file chunks
|
||||||
|
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
|
@ -132,32 +133,4 @@ def parse_efi_files(extract_path, efi_files, padding):
|
||||||
os.remove(comp_fname) # Successful decompression, delete compressed file
|
os.remove(comp_fname) # Successful decompression, delete compressed file
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_portwell_efi, portwell_efi_extract).run_utility()
|
||||||
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_portwell_efi(input_buffer):
|
|
||||||
printer('Error: This is not a Portwell EFI Update Package!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
portwell_efi_extract(input_buffer, extract_path, padding)
|
|
||||||
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
419
README.md
419
README.md
|
@ -50,32 +50,6 @@ Optionally, to decompile the AMI PFAT \> Intel BIOS Guard Scripts, you must have
|
||||||
|
|
||||||
* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py)
|
* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py)
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisites at the "external" project directory:
|
|
||||||
|
|
||||||
> BIOS Guard Script Tool (optional)
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/AMI_PFAT_Extract.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -114,34 +88,6 @@ Optionally, to decompile the AMI UCP \> AMI PFAT \> Intel BIOS Guard Scripts (wh
|
||||||
|
|
||||||
* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py)
|
* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py)
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisites at the "external" project directory:
|
|
||||||
|
|
||||||
> TianoCompress\
|
|
||||||
> 7-Zip Console\
|
|
||||||
> BIOS Guard Script Tool (optional)
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/AMI_UCP_Extract.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -172,28 +118,6 @@ Should work at all Windows, Linux or macOS operating systems which have Python 3
|
||||||
|
|
||||||
To run the utility, you do not need any prerequisites.
|
To run the utility, you do not need any prerequisites.
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --noupx --onefile \<path-to-project\>\/Apple_EFI_IM4P.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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -228,33 +152,6 @@ To run the utility, you must have the following 3rd party tools at the "external
|
||||||
* [UEFIFind](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIFind.exe for Windows or UEFIFind for Linux](https://github.com/LongSoft/UEFITool/releases))
|
* [UEFIFind](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIFind.exe for Windows or UEFIFind for Linux](https://github.com/LongSoft/UEFITool/releases))
|
||||||
* [UEFIExtract](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIExtract.exe for Windows or UEFIExtract for Linux](https://github.com/LongSoft/UEFITool/releases))
|
* [UEFIExtract](https://github.com/LongSoft/UEFITool/) (i.e. [UEFIExtract.exe for Windows or UEFIExtract for Linux](https://github.com/LongSoft/UEFITool/releases))
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisites at the "external" project directory:
|
|
||||||
|
|
||||||
> UEFIFind\
|
|
||||||
> UEFIExtract
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Apple_EFI_ID.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -287,32 +184,6 @@ To run the utility, you must have the following 3rd party tools at the "external
|
||||||
|
|
||||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux)
|
* [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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisites at the "external" project directory:
|
|
||||||
|
|
||||||
> 7-Zip Console
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Apple_EFI_PKG.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -345,32 +216,6 @@ To run the utility, you must have the following 3rd party tools at the "external
|
||||||
|
|
||||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux)
|
* [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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisites at the "external" project directory:
|
|
||||||
|
|
||||||
> 7-Zip Console
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Apple_EFI_PBZX.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -403,32 +248,6 @@ To run the utility, you must have the following 3rd party tool at the "external"
|
||||||
|
|
||||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux)
|
* [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.10.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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -463,32 +282,6 @@ Optionally, to decompile the Intel BIOS Guard (PFAT) Scripts, you must have the
|
||||||
|
|
||||||
* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py)
|
* [BIOS Guard Script Tool](https://github.com/platomav/BGScriptTool) (i.e. big_script_tool.py)
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisites at the "external" project directory:
|
|
||||||
|
|
||||||
> BIOS Guard Script Tool (optional)
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Dell_PFS_Extract.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -521,32 +314,6 @@ To run the utility, you must have the following 3rd party tool at the "external"
|
||||||
|
|
||||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux)
|
* [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.10.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\>\/Fujitsu_SFX_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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -579,32 +346,6 @@ To run the utility, you must have the following 3rd party tool at the "external"
|
||||||
|
|
||||||
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux)
|
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress 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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisite at the "external" project directory:
|
|
||||||
|
|
||||||
> TianoCompress
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Fujitsu_UPC_Extract.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -635,28 +376,6 @@ Should work at all Windows, Linux or macOS operating systems which have Python 3
|
||||||
|
|
||||||
To run the utility, you do not need any prerequisites.
|
To run the utility, you do not need any prerequisites.
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --noupx --onefile \<path-to-project\>\/Insyde_IFD_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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -694,36 +413,6 @@ Moreover, you must have the following 3rd party tool at the "external" project d
|
||||||
|
|
||||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux)
|
* [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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Use pip to install pefile and lznt1:
|
|
||||||
|
|
||||||
> pip3 install pefile lznt1
|
|
||||||
|
|
||||||
4. Place prerequisite at the "external" project directory:
|
|
||||||
|
|
||||||
> 7-Zip Console
|
|
||||||
|
|
||||||
5. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Panasonic_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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -756,32 +445,6 @@ To run the utility, you must have the following 3rd party Python module installe
|
||||||
|
|
||||||
* [pefile](https://pypi.org/project/pefile/)
|
* [pefile](https://pypi.org/project/pefile/)
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Use pip to install pefile:
|
|
||||||
|
|
||||||
> pip3 install pefile
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --noupx --onefile \<path-to-project\>\/Phoenix_TDK_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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -820,36 +483,6 @@ Moreover, you must have the following 3rd party tool at the "external" project d
|
||||||
|
|
||||||
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress for Linux)
|
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress 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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Use pip to install pefile:
|
|
||||||
|
|
||||||
> pip3 install pefile
|
|
||||||
|
|
||||||
4. Place prerequisite at the "external" project directory:
|
|
||||||
|
|
||||||
> TianoCompress
|
|
||||||
|
|
||||||
5. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Portwell_EFI_Extract.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -882,32 +515,6 @@ To run the utility, you must have the following 3rd party tool at the "external"
|
||||||
|
|
||||||
* [ToshibaComExtractor](https://github.com/LongSoft/ToshibaComExtractor) (i.e. [comextract.exe for Windows or comextract for Linux](https://github.com/LongSoft/ToshibaComExtractor/releases))
|
* [ToshibaComExtractor](https://github.com/LongSoft/ToshibaComExtractor) (i.e. [comextract.exe for Windows or comextract for Linux](https://github.com/LongSoft/ToshibaComExtractor/releases))
|
||||||
|
|
||||||
#### **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.10.0 or newer is installed:
|
|
||||||
|
|
||||||
> python --version
|
|
||||||
|
|
||||||
2. Use pip to install PyInstaller:
|
|
||||||
|
|
||||||
> pip3 install pyinstaller
|
|
||||||
|
|
||||||
3. Place prerequisite at the "external" project directory:
|
|
||||||
|
|
||||||
> ToshibaComExtractor
|
|
||||||
|
|
||||||
4. Build/Freeze/Compile:
|
|
||||||
|
|
||||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Toshiba_COM_Extract.py
|
|
||||||
|
|
||||||
You should find the final utility executable at "dist" folder
|
|
||||||
|
|
||||||
#### **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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
||||||
|
@ -940,32 +547,6 @@ To run the utility, you must have the following 3rd party tool at the "external"
|
||||||
|
|
||||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zzs for Linux)
|
* [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.10.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\>\/VAIO_Package_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**
|
#### **Pictures**
|
||||||
|
|
||||||
![]()
|
![]()
|
|
@ -7,7 +7,7 @@ Toshiba BIOS COM Extractor
|
||||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
TITLE = 'Toshiba BIOS COM Extractor v2.0_a3'
|
TITLE = 'Toshiba BIOS COM Extractor v2.0_a4'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -16,9 +16,11 @@ import subprocess
|
||||||
# Stop __pycache__ generation
|
# Stop __pycache__ generation
|
||||||
sys.dont_write_bytecode = True
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
from common.path_ops import make_dirs, path_stem, path_suffixes, project_root, safe_path
|
from common.externals import get_comextract_path
|
||||||
|
from common.path_ops import make_dirs, path_stem, path_suffixes
|
||||||
from common.patterns import PAT_TOSHIBA_COM
|
from common.patterns import PAT_TOSHIBA_COM
|
||||||
from common.system import argparse_init, get_os_ver, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
# Check if input is Toshiba BIOS COM image
|
# Check if input is Toshiba BIOS COM image
|
||||||
|
@ -31,15 +33,12 @@ def is_toshiba_com(in_file):
|
||||||
|
|
||||||
return is_ext and is_com
|
return is_ext and is_com
|
||||||
|
|
||||||
# Get ToshibaComExtractor path
|
|
||||||
def get_comextract_path():
|
|
||||||
exec_name = 'comextract.exe' if get_os_ver()[1] else 'comextract'
|
|
||||||
|
|
||||||
return safe_path(project_root(), ['external',exec_name])
|
|
||||||
|
|
||||||
# Parse & Extract Toshiba BIOS COM image
|
# Parse & Extract Toshiba BIOS COM image
|
||||||
def toshiba_com_extract(input_file, output_path, padding=0):
|
def toshiba_com_extract(input_file, extract_path, padding=0):
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
if not os.path.isfile(input_file):
|
||||||
|
printer('Error: Could not find input file path!', padding)
|
||||||
|
|
||||||
|
return 1
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
|
@ -51,41 +50,14 @@ def toshiba_com_extract(input_file, output_path, padding=0):
|
||||||
|
|
||||||
if not os.path.isfile(output_file):
|
if not os.path.isfile(output_file):
|
||||||
raise Exception('EXTRACT_FILE_MISSING')
|
raise Exception('EXTRACT_FILE_MISSING')
|
||||||
except:
|
except Exception:
|
||||||
printer(f'Error: ToshibaComExtractor could not extract file {input_file}!', padding)
|
printer(f'Error: ToshibaComExtractor could not extract file {input_file}!', padding)
|
||||||
|
|
||||||
return 1
|
return 2
|
||||||
|
|
||||||
printer(f'Succesfull {output_name} extraction via ToshibaComExtractor!', padding)
|
printer(f'Succesfull {output_name} extraction via ToshibaComExtractor!', padding)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_toshiba_com, toshiba_com_extract).run_utility()
|
||||||
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_toshiba_com(input_file):
|
|
||||||
printer('Error: This is not a Toshiba BIOS COM image!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if toshiba_com_extract(input_file, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -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_a7'
|
TITLE = 'VAIO Packaging Manager Extractor v3.0_a8'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -18,7 +18,8 @@ sys.dont_write_bytecode = True
|
||||||
from common.comp_szip import is_szip_supported, szip_decompress
|
from common.comp_szip import is_szip_supported, szip_decompress
|
||||||
from common.path_ops import make_dirs
|
from common.path_ops import make_dirs
|
||||||
from common.patterns import PAT_VAIO_CAB, PAT_VAIO_CFG, PAT_VAIO_CHK, PAT_VAIO_EXT
|
from common.patterns import PAT_VAIO_CAB, PAT_VAIO_CFG, PAT_VAIO_CHK, PAT_VAIO_EXT
|
||||||
from common.system import argparse_init, printer, script_init
|
from common.system import printer
|
||||||
|
from common.templates import BIOSUtility
|
||||||
from common.text_ops import file_to_bytes
|
from common.text_ops import file_to_bytes
|
||||||
|
|
||||||
# Check if input is VAIO Packaging Manager
|
# Check if input is VAIO Packaging Manager
|
||||||
|
@ -125,14 +126,16 @@ def vaio_unlock(name, buffer, extract_path, padding=0):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Parse & Extract or Unlock VAIO Packaging Manager
|
# Parse & Extract or Unlock VAIO Packaging Manager
|
||||||
def vaio_pkg_extract(name, buffer, output_path, padding=0):
|
def vaio_pkg_extract(input_file, extract_path, padding=0):
|
||||||
extract_path = os.path.join(f'{output_path}_extracted')
|
input_buffer = file_to_bytes(input_file)
|
||||||
|
|
||||||
|
input_name = os.path.basename(input_file)
|
||||||
|
|
||||||
make_dirs(extract_path, delete=True)
|
make_dirs(extract_path, delete=True)
|
||||||
|
|
||||||
if vaio_cabinet(name, buffer, extract_path, padding) == 0:
|
if vaio_cabinet(input_name, input_buffer, extract_path, padding) == 0:
|
||||||
printer('Successfully Extracted!', padding)
|
printer('Successfully Extracted!', padding)
|
||||||
elif vaio_unlock(name, bytearray(buffer), extract_path, padding) == 0:
|
elif vaio_unlock(input_name, bytearray(input_buffer), extract_path, padding) == 0:
|
||||||
printer('Successfully Unlocked!', padding)
|
printer('Successfully Unlocked!', padding)
|
||||||
else:
|
else:
|
||||||
printer('Error: Failed to Extract or Unlock executable!', padding)
|
printer('Error: Failed to Extract or Unlock executable!', padding)
|
||||||
|
@ -141,32 +144,4 @@ def vaio_pkg_extract(name, buffer, output_path, padding=0):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Set argparse Arguments
|
BIOSUtility(TITLE, is_vaio_pkg, vaio_pkg_extract).run_utility()
|
||||||
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()
|
|
||||||
|
|
||||||
# Check if VAIO Packaging Manager pattern was found on executable
|
|
||||||
if not is_vaio_pkg(input_buffer):
|
|
||||||
printer('Error: This is not a VAIO Packaging Manager executable!', padding)
|
|
||||||
|
|
||||||
continue # Next input file
|
|
||||||
|
|
||||||
extract_path = os.path.join(output_path, input_name)
|
|
||||||
|
|
||||||
if vaio_pkg_extract(input_name, input_buffer, extract_path, padding) == 0:
|
|
||||||
exit_code -= 1
|
|
||||||
|
|
||||||
printer('Done!', pause=True)
|
|
||||||
|
|
||||||
sys.exit(exit_code)
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ def efi_decompress(in_path, out_path, padding=0, silent=False, comp_type='--uefi
|
||||||
|
|
||||||
if os.path.getsize(out_path) != size_orig:
|
if os.path.getsize(out_path) != size_orig:
|
||||||
raise Exception('EFI_DECOMPRESS_ERROR')
|
raise Exception('EFI_DECOMPRESS_ERROR')
|
||||||
except:
|
except Exception:
|
||||||
if not silent:
|
if not silent:
|
||||||
printer(f'Error: TianoCompress could not extract file {in_path}!', padding)
|
printer(f'Error: TianoCompress could not extract file {in_path}!', padding)
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ def is_szip_supported(in_path, padding=0, args=None, check=False, silent=False):
|
||||||
|
|
||||||
if check:
|
if check:
|
||||||
check_bad_exit_code(szip_t.returncode)
|
check_bad_exit_code(szip_t.returncode)
|
||||||
except:
|
except Exception:
|
||||||
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)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ def szip_decompress(in_path, out_path, in_name, padding=0, args=None, check=Fals
|
||||||
|
|
||||||
if not os.path.isdir(out_path):
|
if not os.path.isdir(out_path):
|
||||||
raise Exception('EXTRACT_DIR_MISSING')
|
raise Exception('EXTRACT_DIR_MISSING')
|
||||||
except:
|
except Exception:
|
||||||
if not silent:
|
if not silent:
|
||||||
printer(f'Error: 7-Zip could not extract {in_name} file {in_path}!', padding)
|
printer(f'Error: 7-Zip could not extract {in_name} file {in_path}!', padding)
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,9 @@ from common.system import get_os_ver
|
||||||
# https://github.com/platomav/BGScriptTool by Plato Mavropoulos
|
# https://github.com/platomav/BGScriptTool by Plato Mavropoulos
|
||||||
def get_bgs_tool():
|
def get_bgs_tool():
|
||||||
try:
|
try:
|
||||||
from external.big_script_tool import BigScript
|
# noinspection PyUnresolvedReferences
|
||||||
except:
|
from external.big_script_tool import BigScript # pylint: disable=E0401,E0611
|
||||||
|
except Exception:
|
||||||
BigScript = None
|
BigScript = None
|
||||||
|
|
||||||
return BigScript
|
return BigScript
|
||||||
|
@ -22,10 +23,16 @@ def get_bgs_tool():
|
||||||
def get_uefifind_path():
|
def get_uefifind_path():
|
||||||
exec_name = f'UEFIFind{".exe" if get_os_ver()[1] else ""}'
|
exec_name = f'UEFIFind{".exe" if get_os_ver()[1] else ""}'
|
||||||
|
|
||||||
return safe_path(project_root(), ['external',exec_name])
|
return safe_path(project_root(), ['external', exec_name])
|
||||||
|
|
||||||
# Get UEFIExtract path
|
# Get UEFIExtract path
|
||||||
def get_uefiextract_path():
|
def get_uefiextract_path():
|
||||||
exec_name = f'UEFIExtract{".exe" if get_os_ver()[1] else ""}'
|
exec_name = f'UEFIExtract{".exe" if get_os_ver()[1] else ""}'
|
||||||
|
|
||||||
return safe_path(project_root(), ['external',exec_name])
|
return safe_path(project_root(), ['external', exec_name])
|
||||||
|
|
||||||
|
# Get ToshibaComExtractor path
|
||||||
|
def get_comextract_path():
|
||||||
|
exec_name = f'comextract{".exe" if get_os_ver()[1] else ""}'
|
||||||
|
|
||||||
|
return safe_path(project_root(), ['external', exec_name])
|
||||||
|
|
|
@ -130,58 +130,13 @@ def get_dequoted_path(in_path):
|
||||||
|
|
||||||
return out_path
|
return out_path
|
||||||
|
|
||||||
# Get absolute file path of argparse object
|
# Set utility extraction stem
|
||||||
def get_argparse_path(argparse_path):
|
def extract_suffix():
|
||||||
if not argparse_path:
|
return '_extracted'
|
||||||
# Use runtime directory if no user path is specified
|
|
||||||
absolute_path = runtime_root()
|
|
||||||
else:
|
|
||||||
# Check if user specified path is absolute
|
|
||||||
if is_path_absolute(argparse_path):
|
|
||||||
absolute_path = argparse_path
|
|
||||||
# Otherwise, make it runtime directory relative
|
|
||||||
else:
|
|
||||||
absolute_path = safe_path(runtime_root(), argparse_path)
|
|
||||||
|
|
||||||
return absolute_path
|
|
||||||
|
|
||||||
# Process input files (argparse object)
|
# Get utility extraction path
|
||||||
def process_input_files(argparse_args, sys_argv=None):
|
def get_extract_path(in_path, suffix=extract_suffix()):
|
||||||
input_files = []
|
return f'{in_path}{suffix}'
|
||||||
|
|
||||||
if sys_argv is None:
|
|
||||||
sys_argv = []
|
|
||||||
|
|
||||||
if len(sys_argv) >= 2:
|
|
||||||
# Drag & Drop or CLI
|
|
||||||
if argparse_args.input_dir:
|
|
||||||
input_path_user = argparse_args.input_dir
|
|
||||||
input_path_full = get_argparse_path(input_path_user) if input_path_user else ''
|
|
||||||
input_files = get_path_files(input_path_full)
|
|
||||||
else:
|
|
||||||
# Parse list of input files (i.e. argparse FileType objects)
|
|
||||||
for file_object in argparse_args.files:
|
|
||||||
# Store each argparse FileType object's name (i.e. path)
|
|
||||||
input_files.append(file_object.name)
|
|
||||||
# Close each argparse FileType object (i.e. allow input file changes)
|
|
||||||
file_object.close()
|
|
||||||
|
|
||||||
# Set output fallback value for missing argparse Output and Input Path
|
|
||||||
output_fallback = path_parent(input_files[0]) if input_files else None
|
|
||||||
|
|
||||||
# Set output path via argparse Output path or argparse Input path or first input file path
|
|
||||||
output_path = argparse_args.output_dir or argparse_args.input_dir or output_fallback
|
|
||||||
else:
|
|
||||||
# Script w/o parameters
|
|
||||||
input_path_user = get_dequoted_path(input('\nEnter input directory path: '))
|
|
||||||
input_path_full = get_argparse_path(input_path_user) if input_path_user else ''
|
|
||||||
input_files = get_path_files(input_path_full)
|
|
||||||
|
|
||||||
output_path = get_dequoted_path(input('\nEnter output directory path: '))
|
|
||||||
|
|
||||||
output_path_final = get_argparse_path(output_path)
|
|
||||||
|
|
||||||
return input_files, output_path_final
|
|
||||||
|
|
||||||
# Get project's root directory
|
# Get project's root directory
|
||||||
def project_root():
|
def project_root():
|
||||||
|
|
|
@ -21,7 +21,7 @@ def get_pe_file(in_file, fast=True):
|
||||||
try:
|
try:
|
||||||
# Analyze detected MZ > PE image buffer
|
# Analyze detected MZ > PE image buffer
|
||||||
pe_file = pefile.PE(data=in_buffer, fast_load=fast)
|
pe_file = pefile.PE(data=in_buffer, fast_load=fast)
|
||||||
except:
|
except Exception:
|
||||||
pe_file = None
|
pe_file = None
|
||||||
|
|
||||||
return pe_file
|
return pe_file
|
||||||
|
@ -34,7 +34,7 @@ def get_pe_info(pe_file):
|
||||||
|
|
||||||
# Retrieve MZ > PE > FileInfo > StringTable information
|
# Retrieve MZ > PE > FileInfo > StringTable information
|
||||||
pe_info = pe_file.FileInfo[0][0].StringTable[0].entries
|
pe_info = pe_file.FileInfo[0][0].StringTable[0].entries
|
||||||
except:
|
except Exception:
|
||||||
pe_info = {}
|
pe_info = {}
|
||||||
|
|
||||||
return pe_info
|
return pe_info
|
||||||
|
|
|
@ -6,12 +6,8 @@ Copyright (C) 2022 Plato Mavropoulos
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import ctypes
|
|
||||||
import argparse
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
from common.text_ops import padder, to_string
|
from common.text_ops import padder, to_string
|
||||||
from common.path_ops import process_input_files
|
|
||||||
|
|
||||||
# Get Python Version (tuple)
|
# Get Python Version (tuple)
|
||||||
def get_py_ver():
|
def get_py_ver():
|
||||||
|
@ -59,62 +55,6 @@ def check_sys_os():
|
||||||
if os_win:
|
if os_win:
|
||||||
sys.stdout.reconfigure(encoding='utf-8')
|
sys.stdout.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
# Initialize common argparse arguments
|
|
||||||
def argparse_init():
|
|
||||||
argparser = argparse.ArgumentParser()
|
|
||||||
|
|
||||||
argparser.add_argument('files', type=argparse.FileType('r'), nargs='*')
|
|
||||||
argparser.add_argument('-e', '--auto-exit', help='skip press enter to exit prompts', action='store_true')
|
|
||||||
argparser.add_argument('-v', '--version', help='show utility name and version', action='store_true')
|
|
||||||
argparser.add_argument('-o', '--output-dir', help='extract in given output directory')
|
|
||||||
argparser.add_argument('-i', '--input-dir', help='extract from given input directory')
|
|
||||||
|
|
||||||
return argparser
|
|
||||||
|
|
||||||
# Initialize Script (must be after argparse)
|
|
||||||
def script_init(title, arguments, padding=0):
|
|
||||||
# Pretty Python exception handler
|
|
||||||
sys.excepthook = nice_exc_handler
|
|
||||||
|
|
||||||
# Check Python Version
|
|
||||||
check_sys_py()
|
|
||||||
|
|
||||||
# Check OS Platform
|
|
||||||
check_sys_os()
|
|
||||||
|
|
||||||
# Show Script Title
|
|
||||||
printer(title, new_line=False)
|
|
||||||
|
|
||||||
# Show Utility Version on demand
|
|
||||||
if arguments.version:
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# Set console/terminal window title (Windows only)
|
|
||||||
if get_os_ver()[1]:
|
|
||||||
ctypes.windll.kernel32.SetConsoleTitleW(title)
|
|
||||||
|
|
||||||
# Process input files and generate output path
|
|
||||||
input_files,output_path = process_input_files(arguments, sys.argv)
|
|
||||||
|
|
||||||
# Count input files for exit code
|
|
||||||
input_count = len(input_files)
|
|
||||||
|
|
||||||
return input_count, input_files, output_path, padding
|
|
||||||
|
|
||||||
# https://stackoverflow.com/a/781074 by Torsten Marek
|
|
||||||
def nice_exc_handler(exc_type, exc_value, tb):
|
|
||||||
if exc_type is KeyboardInterrupt:
|
|
||||||
printer('')
|
|
||||||
else:
|
|
||||||
printer('Error: Script crashed, please report the following:\n')
|
|
||||||
|
|
||||||
traceback.print_exception(exc_type, exc_value, tb)
|
|
||||||
|
|
||||||
if not is_auto_exit():
|
|
||||||
input('\nPress enter to exit')
|
|
||||||
|
|
||||||
sys.exit(127)
|
|
||||||
|
|
||||||
# Show message(s) while controlling padding, newline, pausing & separator
|
# Show message(s) while controlling padding, newline, pausing & separator
|
||||||
def printer(in_message='', padd_count=0, new_line=True, pause=False, sep_char=' '):
|
def printer(in_message='', padd_count=0, new_line=True, pause=False, sep_char=' '):
|
||||||
message = to_string(in_message, sep_char)
|
message = to_string(in_message, sep_char)
|
||||||
|
|
152
common/templates.py
Normal file
152
common/templates.py
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#coding=utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
Copyright (C) 2022 Plato Mavropoulos
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import ctypes
|
||||||
|
import argparse
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
from common.path_ops import runtime_root, is_path_absolute, safe_path, get_dequoted_path, get_path_files, path_parent, get_extract_path
|
||||||
|
from common.system import check_sys_py, check_sys_os, get_os_ver, printer, is_auto_exit
|
||||||
|
|
||||||
|
class BIOSUtility:
|
||||||
|
|
||||||
|
def __init__(self, title, check, main, padding=0):
|
||||||
|
self._title = title
|
||||||
|
self._main = main
|
||||||
|
self._check = check
|
||||||
|
self._padding = padding
|
||||||
|
self._arguments_kw = {}
|
||||||
|
|
||||||
|
# Initialize argparse argument parser
|
||||||
|
self._argparser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
self._argparser.add_argument('files', type=argparse.FileType('r', encoding='utf-8'), nargs='*')
|
||||||
|
self._argparser.add_argument('-e', '--auto-exit', help='skip press enter to exit prompts', action='store_true')
|
||||||
|
self._argparser.add_argument('-v', '--version', help='show utility name and version', action='store_true')
|
||||||
|
self._argparser.add_argument('-o', '--output-dir', help='extract in given output directory')
|
||||||
|
self._argparser.add_argument('-i', '--input-dir', help='extract from given input directory')
|
||||||
|
|
||||||
|
self._arguments,self._arguments_unk = self._argparser.parse_known_args()
|
||||||
|
|
||||||
|
# Managed Python exception handler
|
||||||
|
sys.excepthook = self._exception_handler
|
||||||
|
|
||||||
|
# Check Python Version
|
||||||
|
check_sys_py()
|
||||||
|
|
||||||
|
# Check OS Platform
|
||||||
|
check_sys_os()
|
||||||
|
|
||||||
|
# Show Script Title
|
||||||
|
printer(self._title, new_line=False)
|
||||||
|
|
||||||
|
# Show Utility Version on demand
|
||||||
|
if self._arguments.version:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Set console/terminal window title (Windows only)
|
||||||
|
if get_os_ver()[1]:
|
||||||
|
ctypes.windll.kernel32.SetConsoleTitleW(self._title)
|
||||||
|
|
||||||
|
# Process input files and generate output path
|
||||||
|
self._process_input_files()
|
||||||
|
|
||||||
|
# Count input files for exit code
|
||||||
|
self.exit_code = len(self._input_files)
|
||||||
|
|
||||||
|
def parse_argument(self, *args, **kwargs):
|
||||||
|
_dest = self._argparser.add_argument(*args, **kwargs).dest
|
||||||
|
self._arguments = self._argparser.parse_known_args(self._arguments_unk)[0]
|
||||||
|
self._arguments_kw.update({_dest: self._arguments.__dict__[_dest]})
|
||||||
|
|
||||||
|
def run_utility(self):
|
||||||
|
for _input_file in self._input_files:
|
||||||
|
_input_name = os.path.basename(_input_file)
|
||||||
|
|
||||||
|
printer(['***', _input_name], self._padding)
|
||||||
|
|
||||||
|
if not self._check(_input_file):
|
||||||
|
printer('Error: This is not a supported input!', self._padding + 4)
|
||||||
|
|
||||||
|
continue # Next input file
|
||||||
|
|
||||||
|
_extract_path = os.path.join(self._output_path, get_extract_path(_input_name))
|
||||||
|
|
||||||
|
if self._main(_input_file, _extract_path, self._padding + 4, **self._arguments_kw) in [0, None]:
|
||||||
|
self.exit_code -= 1
|
||||||
|
|
||||||
|
#print(self.exit_code)
|
||||||
|
|
||||||
|
printer('Done!', pause=True)
|
||||||
|
|
||||||
|
sys.exit(self.exit_code)
|
||||||
|
|
||||||
|
# Process input files
|
||||||
|
def _process_input_files(self):
|
||||||
|
self._input_files = []
|
||||||
|
|
||||||
|
if len(sys.argv) >= 2:
|
||||||
|
# Drag & Drop or CLI
|
||||||
|
if self._arguments.input_dir:
|
||||||
|
_input_path_user = self._arguments.input_dir
|
||||||
|
_input_path_full = self._get_input_path(_input_path_user) if _input_path_user else ''
|
||||||
|
self._input_files = get_path_files(_input_path_full)
|
||||||
|
else:
|
||||||
|
# Parse list of input files (i.e. argparse FileType objects)
|
||||||
|
for _file_object in self._arguments.files:
|
||||||
|
# Store each argparse FileType object's name (i.e. path)
|
||||||
|
self._input_files.append(_file_object.name)
|
||||||
|
# Close each argparse FileType object (i.e. allow input file changes)
|
||||||
|
_file_object.close()
|
||||||
|
|
||||||
|
# Set output fallback value for missing argparse Output and Input Path
|
||||||
|
_output_fallback = path_parent(self._input_files[0]) if self._input_files else None
|
||||||
|
|
||||||
|
# Set output path via argparse Output path or argparse Input path or first input file path
|
||||||
|
_output_path = self._arguments.output_dir or self._arguments.input_dir or _output_fallback
|
||||||
|
else:
|
||||||
|
# Script w/o parameters
|
||||||
|
_input_path_user = get_dequoted_path(input('\nEnter input directory path: '))
|
||||||
|
_input_path_full = self._get_input_path(_input_path_user) if _input_path_user else ''
|
||||||
|
self._input_files = get_path_files(_input_path_full)
|
||||||
|
|
||||||
|
_output_path = get_dequoted_path(input('\nEnter output directory path: '))
|
||||||
|
|
||||||
|
self._output_path = self._get_input_path(_output_path)
|
||||||
|
|
||||||
|
# Get absolute input file path
|
||||||
|
@staticmethod
|
||||||
|
def _get_input_path(input_path):
|
||||||
|
if not input_path:
|
||||||
|
# Use runtime directory if no user path is specified
|
||||||
|
absolute_path = runtime_root()
|
||||||
|
else:
|
||||||
|
# Check if user specified path is absolute
|
||||||
|
if is_path_absolute(input_path):
|
||||||
|
absolute_path = input_path
|
||||||
|
# Otherwise, make it runtime directory relative
|
||||||
|
else:
|
||||||
|
absolute_path = safe_path(runtime_root(), input_path)
|
||||||
|
|
||||||
|
return absolute_path
|
||||||
|
|
||||||
|
# https://stackoverflow.com/a/781074 by Torsten Marek
|
||||||
|
@staticmethod
|
||||||
|
def _exception_handler(exc_type, exc_value, exc_traceback):
|
||||||
|
if exc_type is KeyboardInterrupt:
|
||||||
|
printer('')
|
||||||
|
else:
|
||||||
|
printer('Error: Utility crashed, please report the following:\n')
|
||||||
|
|
||||||
|
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
||||||
|
|
||||||
|
if not is_auto_exit():
|
||||||
|
input('\nPress enter to exit')
|
||||||
|
|
||||||
|
sys.exit(127)
|
4
external/requirements.txt
vendored
4
external/requirements.txt
vendored
|
@ -1,2 +1,2 @@
|
||||||
lznt1==0.2
|
lznt1 >= 0.2
|
||||||
pefile==2022.5.30
|
pefile >= 2022.5.30
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue