mirror of
https://github.com/platomav/BIOSUtilities.git
synced 2025-05-13 06:34:42 -04:00
Initial refactor commit
Added AMI UCP BIOS Extractor v2.0_a1 Added AMI BIOS Guard Extractor v4.0_a1
This commit is contained in:
parent
2029ffc8b7
commit
132457afda
14 changed files with 1240 additions and 731 deletions
352
AMI_PFAT_Extract.py
Normal file
352
AMI_PFAT_Extract.py
Normal file
|
@ -0,0 +1,352 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
"""
|
||||
AMI PFAT Extract
|
||||
AMI BIOS Guard Extractor
|
||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||
"""
|
||||
|
||||
title = 'AMI BIOS Guard Extractor v4.0_a1'
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import shutil
|
||||
import ctypes
|
||||
|
||||
# Stop __pycache__ generation
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
from common.patterns import PAT_AMI_PFAT
|
||||
from common.externals import get_bgs_tool
|
||||
from common.num_ops import get_ordinal
|
||||
from common.text_ops import padder
|
||||
from common.path_ops import argparse_init, process_input_files, safe_name
|
||||
from common.struct_ops import get_struct, char, uint8_t, uint16_t, uint32_t
|
||||
from common.system import nice_exc_handler, check_sys_py, check_sys_os, show_title, print_input
|
||||
|
||||
class AmiBiosGuardHeader(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('Size', uint32_t), # 0x00 Header + Entries
|
||||
('Checksum', uint32_t), # 0x04 ?
|
||||
('Tag', char*8), # 0x04 _AMIPFAT
|
||||
('Flags', uint8_t), # 0x10 ?
|
||||
# 0x11
|
||||
]
|
||||
|
||||
def struct_print(self, padding):
|
||||
p = padder(padding)
|
||||
|
||||
print(p + 'Size :', '0x%X' % self.Size)
|
||||
print(p + 'Checksum:', '0x%0.4X' % self.Checksum)
|
||||
print(p + 'Tag :', self.Tag.decode('utf-8'))
|
||||
print(p + 'Flags :', '0x%0.2X' % self.Flags)
|
||||
|
||||
class IntelBiosGuardHeader(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('BGVerMajor', uint16_t), # 0x00
|
||||
('BGVerMinor', uint16_t), # 0x02
|
||||
('PlatformID', uint8_t*16), # 0x04
|
||||
('Attributes', uint32_t), # 0x14
|
||||
('ScriptVerMajor', uint16_t), # 0x16
|
||||
('ScriptVerMinor', uint16_t), # 0x18
|
||||
('ScriptSize', uint32_t), # 0x1C
|
||||
('DataSize', uint32_t), # 0x20
|
||||
('BIOSSVN', uint32_t), # 0x24
|
||||
('ECSVN', uint32_t), # 0x28
|
||||
('VendorInfo', uint32_t), # 0x2C
|
||||
# 0x30
|
||||
]
|
||||
|
||||
def get_platform_id(self):
|
||||
id_byte = bytes(self.PlatformID)
|
||||
|
||||
id_text = re.sub(r'[\n\t\r\x00 ]', '', id_byte.decode('utf-8','ignore'))
|
||||
|
||||
id_hexs = '%0.*X' % (0x10 * 2, int.from_bytes(id_byte, 'big'))
|
||||
id_guid = '{%s-%s-%s-%s-%s}' % (id_hexs[:8], id_hexs[8:12], id_hexs[12:16], id_hexs[16:20], id_hexs[20:])
|
||||
|
||||
return '%s %s' % (id_text, id_guid)
|
||||
|
||||
def get_flags(self):
|
||||
attr = IntelBiosGuardHeaderGetAttributes()
|
||||
attr.asbytes = self.Attributes
|
||||
|
||||
return attr.b.SFAM, attr.b.ProtectEC, attr.b.GFXMitDis, attr.b.FTU, attr.b.Reserved
|
||||
|
||||
def struct_print(self, padding):
|
||||
p = padder(padding)
|
||||
|
||||
no_yes = ['No','Yes']
|
||||
f1,f2,f3,f4,f5 = self.get_flags()
|
||||
|
||||
print(p + 'BIOS Guard Version :', '%d.%d' % (self.BGVerMajor, self.BGVerMinor))
|
||||
print(p + 'Platform Identity :', self.get_platform_id())
|
||||
print(p + 'Signed Flash Address Map :', no_yes[f1])
|
||||
print(p + 'Protected EC OpCodes :', no_yes[f2])
|
||||
print(p + 'Graphics Security Disable :', no_yes[f3])
|
||||
print(p + 'Fault Tolerant Update :', no_yes[f4])
|
||||
print(p + 'Attributes Reserved :', '0x%X' % f5)
|
||||
print(p + 'Script Version :', '%d.%d' % (self.ScriptVerMajor, self.ScriptVerMinor))
|
||||
print(p + 'Script Size :', '0x%X' % self.ScriptSize)
|
||||
print(p + 'Data Size :', '0x%X' % self.DataSize)
|
||||
print(p + 'BIOS Security Version Number:', '0x%X' % self.BIOSSVN)
|
||||
print(p + 'EC Security Version Number :', '0x%X' % self.ECSVN)
|
||||
print(p + 'Vendor Information :', '0x%X' % self.VendorInfo)
|
||||
|
||||
class IntelBiosGuardHeaderAttributes(ctypes.LittleEndianStructure):
|
||||
_fields_ = [
|
||||
('SFAM', uint32_t, 1), # Signed Flash Address Map
|
||||
('ProtectEC', uint32_t, 1), # Protected EC OpCodes
|
||||
('GFXMitDis', uint32_t, 1), # GFX Security Disable
|
||||
('FTU', uint32_t, 1), # Fault Tolerant Update
|
||||
('Reserved', uint32_t, 28) # Reserved/Unknown
|
||||
]
|
||||
|
||||
class IntelBiosGuardHeaderGetAttributes(ctypes.Union):
|
||||
_fields_ = [
|
||||
('b', IntelBiosGuardHeaderAttributes),
|
||||
('asbytes', uint32_t)
|
||||
]
|
||||
|
||||
class IntelBiosGuardSignature2k(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('Unknown0', uint32_t), # 0x000
|
||||
('Unknown1', uint32_t), # 0x004
|
||||
('Modulus', uint32_t*64), # 0x008
|
||||
('Exponent', uint32_t), # 0x108
|
||||
('Signature', uint32_t*64), # 0x10C
|
||||
# 0x20C
|
||||
]
|
||||
|
||||
def struct_print(self, padding):
|
||||
p = padder(padding)
|
||||
|
||||
Modulus = '%0.*X' % (0x100 * 2, int.from_bytes(self.Modulus, 'little'))
|
||||
Signature = '%0.*X' % (0x100 * 2, int.from_bytes(self.Signature, 'little'))
|
||||
|
||||
print(p + 'Unknown 0:', '0x%X' % self.Unknown0)
|
||||
print(p + 'Unknown 1:', '0x%X' % self.Unknown1)
|
||||
print(p + 'Modulus :', '%s [...]' % Modulus[:32])
|
||||
print(p + 'Exponent :', '0x%X' % self.Exponent)
|
||||
print(p + 'Signature:', '%s [...]' % Signature[:32])
|
||||
|
||||
def get_ami_pfat(input_buffer):
|
||||
match = PAT_AMI_PFAT.search(input_buffer)
|
||||
|
||||
buffer = input_buffer[match.start() - 0x8:] if match else b''
|
||||
|
||||
return match, buffer
|
||||
|
||||
def get_file_name(index, title):
|
||||
return safe_name('%0.2d -- %s' % (index, title))
|
||||
|
||||
def parse_bg_script(script_data, padding):
|
||||
is_opcode_div = len(script_data) % 8 == 0
|
||||
|
||||
if not is_opcode_div:
|
||||
print('%sError: Script not divisible by OpCode length!' % padder(padding))
|
||||
|
||||
return 1
|
||||
|
||||
is_begin_end = script_data[:8] + script_data[-8:] == b'\x01' + b'\x00' * 7 + b'\xFF' + b'\x00' * 7
|
||||
|
||||
if not is_begin_end:
|
||||
print('%sError: Script lacks Begin and/or End OpCodes!' % padder(padding))
|
||||
|
||||
return 2
|
||||
|
||||
BigScript = get_bgs_tool()
|
||||
|
||||
if not BigScript:
|
||||
print('%sError: BIOS Guard Script Tool dependency missing!' % padder(padding))
|
||||
|
||||
return 3
|
||||
|
||||
script = BigScript(code_bytes=script_data).to_string().replace('\t',' ').split('\n')
|
||||
|
||||
for opcode in script:
|
||||
if opcode.endswith(('begin','end')): spacing = padder(padding)
|
||||
elif opcode.endswith(':'): spacing = padder(padding + 4)
|
||||
else: spacing = padder(padding + 12)
|
||||
|
||||
operands = [operand for operand in opcode.split(' ') if operand]
|
||||
print(spacing + ('{:<12s}' + '{:<11s}' * (len(operands) - 1)).format(*operands))
|
||||
|
||||
return 0
|
||||
|
||||
def parse_pfat_hdr(buffer, padding):
|
||||
block_all = []
|
||||
|
||||
pfat_hdr = get_struct(buffer, 0x0, AmiBiosGuardHeader)
|
||||
|
||||
hdr_size = pfat_hdr.Size
|
||||
hdr_data = buffer[PFAT_AMI_HDR_LEN:hdr_size]
|
||||
hdr_text = hdr_data.decode('utf-8').splitlines()
|
||||
|
||||
print('\n%sAMI BIOS Guard Header:\n' % padder(padding))
|
||||
|
||||
pfat_hdr.struct_print(padding + 4)
|
||||
|
||||
hdr_title,*hdr_files = hdr_text
|
||||
|
||||
files_count = len(hdr_files)
|
||||
|
||||
hdr_tag,*hdr_indexes = hdr_title.split('II')
|
||||
|
||||
print('\n%s%s\n' % (padder(padding + 4), hdr_tag))
|
||||
|
||||
bgt_indexes = [int(h, 16) for h in re.findall(r'.{1,4}', hdr_indexes[0])] if hdr_indexes else []
|
||||
|
||||
for index,entry in enumerate(hdr_files):
|
||||
entry_parts = entry.split(';')
|
||||
|
||||
info = entry_parts[0].split()
|
||||
name = entry_parts[1]
|
||||
|
||||
flags = int(info[0])
|
||||
param = info[1]
|
||||
count = int(info[2])
|
||||
|
||||
order = get_ordinal((bgt_indexes[index] if bgt_indexes else index) + 1)
|
||||
|
||||
desc = '%s (Index: %0.2d, Flash: %s, Parameter: %s, Flags: 0x%X, Blocks: %d)' % (name, index + 1, order, param, flags, count)
|
||||
|
||||
block_all += [(desc, name, order, param, flags, index, i, count) for i in range(count)]
|
||||
|
||||
_ = [print(padder(padding + 8) + block[0]) for block in block_all if block[6] == 0]
|
||||
|
||||
return block_all, hdr_size, files_count
|
||||
|
||||
def parse_pfat_file(buffer, output_path, padding):
|
||||
file_path = ''
|
||||
all_blocks_dict = {}
|
||||
|
||||
extract_name = os.path.basename(output_path)
|
||||
|
||||
extract_path = os.path.join(output_path + '_extracted', '')
|
||||
|
||||
if os.path.isdir(extract_path): shutil.rmtree(extract_path)
|
||||
|
||||
os.mkdir(extract_path)
|
||||
|
||||
block_all,block_off,file_count = parse_pfat_hdr(buffer, padding)
|
||||
|
||||
for block in block_all:
|
||||
file_desc,file_name,_,_,_,file_index,block_index,block_count = block
|
||||
|
||||
if block_index == 0:
|
||||
print('\n%s%s' % (padder(padding + 4), file_desc))
|
||||
|
||||
file_path = os.path.join(extract_path, get_file_name(file_index + 1, file_name))
|
||||
|
||||
all_blocks_dict[file_index] = b''
|
||||
|
||||
block_status = '%d/%d' % (block_index + 1, block_count)
|
||||
|
||||
bg_hdr = get_struct(buffer, block_off, IntelBiosGuardHeader)
|
||||
|
||||
print('\n%sIntel BIOS Guard %s Header:\n' % (padder(padding + 8), block_status))
|
||||
|
||||
bg_hdr.struct_print(padding + 12)
|
||||
|
||||
bg_script_bgn = block_off + PFAT_BLK_HDR_LEN
|
||||
bg_script_end = bg_script_bgn + bg_hdr.ScriptSize
|
||||
bg_script_bin = buffer[bg_script_bgn:bg_script_end]
|
||||
|
||||
bg_data_bgn = bg_script_end
|
||||
bg_data_end = bg_data_bgn + bg_hdr.DataSize
|
||||
bg_data_bin = buffer[bg_data_bgn:bg_data_end]
|
||||
|
||||
block_off = bg_data_end # Assume next block starts at data end
|
||||
|
||||
is_sfam,_,_,_,_ = bg_hdr.get_flags() # SFAM, ProtectEC, GFXMitDis, FTU, Reserved
|
||||
|
||||
if is_sfam:
|
||||
bg_sig_bgn = bg_data_end
|
||||
bg_sig_end = bg_sig_bgn + PFAT_BLK_S2K_LEN
|
||||
bg_sig_bin = buffer[bg_sig_bgn:bg_sig_end]
|
||||
|
||||
if len(bg_sig_bin) == PFAT_BLK_S2K_LEN:
|
||||
bg_sig = get_struct(bg_sig_bin, 0x0, IntelBiosGuardSignature2k)
|
||||
|
||||
print('\n%sIntel BIOS Guard %s Signature:\n' % (padder(padding + 8), block_status))
|
||||
|
||||
bg_sig.struct_print(padding + 12)
|
||||
|
||||
block_off = bg_sig_end # Adjust next block to start at data + signature end
|
||||
|
||||
print('\n%sIntel BIOS Guard %s Script:\n' % (padder(padding + 8), block_status))
|
||||
|
||||
_ = parse_bg_script(bg_script_bin, padding + 12)
|
||||
|
||||
with open(file_path, 'ab') as out_dat: out_dat.write(bg_data_bin)
|
||||
|
||||
all_blocks_dict[file_index] += bg_data_bin
|
||||
|
||||
pfat_oob_data = buffer[block_off:] # Store out-of-bounds data after the end of PFAT files
|
||||
|
||||
pfat_oob_path = os.path.join(extract_path, get_file_name(file_count + 1, extract_name + '_OOB.bin'))
|
||||
|
||||
with open(pfat_oob_path, 'wb') as out_oob: out_oob.write(pfat_oob_data)
|
||||
|
||||
oob_pfat_match,pfat_oob_buffer = get_ami_pfat(pfat_oob_data)
|
||||
|
||||
if oob_pfat_match: parse_pfat_file(pfat_oob_buffer, pfat_oob_path, padding)
|
||||
|
||||
in_all_data = b''.join([block[1] for block in sorted(all_blocks_dict.items())])
|
||||
|
||||
in_all_path = os.path.join(extract_path, get_file_name(0, extract_name + '_ALL.bin'))
|
||||
|
||||
with open(in_all_path, 'wb') as out_all: out_all.write(in_all_data + pfat_oob_data)
|
||||
|
||||
PFAT_AMI_HDR_LEN = ctypes.sizeof(AmiBiosGuardHeader)
|
||||
PFAT_BLK_HDR_LEN = ctypes.sizeof(IntelBiosGuardHeader)
|
||||
PFAT_BLK_S2K_LEN = ctypes.sizeof(IntelBiosGuardSignature2k)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Show script title
|
||||
show_title(title)
|
||||
|
||||
# Set argparse Arguments
|
||||
argparser = argparse_init()
|
||||
arguments = argparser.parse_args()
|
||||
|
||||
# Pretty Python exception handler (must be after argparse)
|
||||
sys.excepthook = nice_exc_handler
|
||||
|
||||
# Check Python Version (must be after argparse)
|
||||
check_sys_py()
|
||||
|
||||
# Check OS Platform (must be after argparse)
|
||||
check_sys_os()
|
||||
|
||||
# Process input files and generate output path
|
||||
input_files,output_path = process_input_files(arguments, sys.argv)
|
||||
|
||||
# Initial output padding count
|
||||
padding = 4
|
||||
|
||||
for input_file in input_files:
|
||||
input_name = os.path.basename(input_file)
|
||||
|
||||
print('\n*** %s' % input_name)
|
||||
|
||||
with open(input_file, 'rb') as in_file: input_buffer = in_file.read()
|
||||
|
||||
pfat_match,pfat_buffer = get_ami_pfat(input_buffer)
|
||||
|
||||
if not pfat_match:
|
||||
print('\n%sError: This is not an AMI BIOS Guard (PFAT) image!' % padder(padding))
|
||||
|
||||
continue # Next input file
|
||||
|
||||
extract_path = os.path.join(output_path, input_name)
|
||||
|
||||
parse_pfat_file(pfat_buffer, extract_path, padding)
|
||||
|
||||
print_input('\nDone!')
|
514
AMI_UCP_Extract.py
Normal file
514
AMI_UCP_Extract.py
Normal file
|
@ -0,0 +1,514 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
"""
|
||||
AMI UCP Extract
|
||||
AMI UCP BIOS Extractor
|
||||
Copyright (C) 2021-2022 Plato Mavropoulos
|
||||
"""
|
||||
|
||||
title = 'AMI UCP BIOS Extractor v2.0_a1'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import struct
|
||||
import ctypes
|
||||
import contextlib
|
||||
|
||||
# Stop __pycache__ generation
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
from common.patterns import PAT_AMI_UCP, PAT_INTEL_ENG
|
||||
from common.checksums import checksum16
|
||||
from common.text_ops import padder
|
||||
from common.a7z_comp import a7z_decompress, is_7z_supported
|
||||
from common.efi_comp import efi_decompress, is_efi_compressed
|
||||
from common.path_ops import argparse_init, process_input_files, safe_name
|
||||
from common.struct_ops import get_struct, char, uint8_t, uint16_t, uint32_t
|
||||
from common.system import nice_exc_handler, check_sys_py, check_sys_os, show_title, print_input
|
||||
from AMI_PFAT_Extract import get_ami_pfat, parse_pfat_file
|
||||
|
||||
class UafHeader(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('ModuleTag', char*4), # 0x00
|
||||
('ModuleSize', uint32_t), # 0x04
|
||||
('Checksum', uint16_t), # 0x08
|
||||
('Unknown0', uint8_t), # 0x0A
|
||||
('Unknown1', uint8_t), # 0x0A
|
||||
('Reserved', uint32_t), # 0x0C
|
||||
# 0x10
|
||||
]
|
||||
|
||||
def struct_print(self, padding):
|
||||
p = padder(padding)
|
||||
|
||||
print(p + 'Tag :', self.ModuleTag.decode('utf-8'))
|
||||
print(p + 'Size :', '0x%X' % self.ModuleSize)
|
||||
print(p + 'Checksum :', '0x%0.4X' % self.Checksum)
|
||||
print(p + 'Unknown 0 :', '0x%0.2X' % self.Unknown0)
|
||||
print(p + 'Unknown 1 :', '0x%0.2X' % self.Unknown1)
|
||||
print(p + 'Reserved :', '0x%0.8X' % self.Reserved)
|
||||
|
||||
class UafModule(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('CompressSize', uint32_t), # 0x00
|
||||
('OriginalSize', uint32_t), # 0x04
|
||||
# 0x08
|
||||
]
|
||||
|
||||
def struct_print(self, padding, filename):
|
||||
p = padder(padding)
|
||||
|
||||
print(p + 'Compress Size:', '0x%X' % self.CompressSize)
|
||||
print(p + 'Original Size:', '0x%X' % self.OriginalSize)
|
||||
print(p + 'File Name :', filename)
|
||||
|
||||
class UiiHeader(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('UIISize', uint16_t), # 0x00
|
||||
('Checksum', uint16_t), # 0x02
|
||||
('UtilityVersion', uint32_t), # 0x04 AFU|BGT (Unknown, Signed)
|
||||
('InfoSize', uint16_t), # 0x08
|
||||
('SupportBIOS', uint8_t), # 0x0A
|
||||
('SupportOS', uint8_t), # 0x0B
|
||||
('DataBusWidth', uint8_t), # 0x0C
|
||||
('ProgramType', uint8_t), # 0x0D
|
||||
('ProgramMode', uint8_t), # 0x0E
|
||||
('SourceSafeRel', uint8_t), # 0x0F
|
||||
# 0x10
|
||||
]
|
||||
|
||||
SBI = {1: 'ALL', 2: 'AMIBIOS8', 3: 'UEFI', 4: 'AMIBIOS8/UEFI'}
|
||||
SOS = {1: 'DOS', 2: 'EFI', 3: 'Windows', 4: 'Linux', 5: 'FreeBSD', 6: 'MacOS', 128: 'Multi-Platform'}
|
||||
DBW = {1: '16b', 2: '16/32b', 3: '32b', 4: '64b'}
|
||||
PTP = {1: 'Executable', 2: 'Library', 3: 'Driver'}
|
||||
PMD = {1: 'API', 2: 'Console', 3: 'GUI', 4: 'Console/GUI'}
|
||||
|
||||
def struct_print(self, padding, description):
|
||||
p = padder(padding)
|
||||
|
||||
SupportBIOS = self.SBI.get(self.SupportBIOS, 'Unknown (%d)' % self.SupportBIOS)
|
||||
SupportOS = self.SOS.get(self.SupportOS, 'Unknown (%d)' % self.SupportOS)
|
||||
DataBusWidth = self.DBW.get(self.DataBusWidth, 'Unknown (%d)' % self.DataBusWidth)
|
||||
ProgramType = self.PTP.get(self.ProgramType, 'Unknown (%d)' % self.ProgramType)
|
||||
ProgramMode = self.PMD.get(self.ProgramMode, 'Unknown (%d)' % self.ProgramMode)
|
||||
|
||||
print(p + 'UII Size :', '0x%X' % self.UIISize)
|
||||
print(p + 'Checksum :', '0x%0.4X' % self.Checksum)
|
||||
print(p + 'Tool Version :', '0x%0.8X' % self.UtilityVersion)
|
||||
print(p + 'Info Size :', '0x%X' % self.InfoSize)
|
||||
print(p + 'Supported BIOS:', SupportBIOS)
|
||||
print(p + 'Supported OS :', SupportOS)
|
||||
print(p + 'Data Bus Width:', DataBusWidth)
|
||||
print(p + 'Program Type :', ProgramType)
|
||||
print(p + 'Program Mode :', ProgramMode)
|
||||
print(p + 'SourceSafe Tag:', '%0.2d' % self.SourceSafeRel)
|
||||
print(p + 'Description :', description)
|
||||
|
||||
class DisHeader(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('PasswordSize', uint16_t), # 0x00
|
||||
('EntryCount', uint16_t), # 0x02
|
||||
('Password', char*12), # 0x04
|
||||
# 0x10
|
||||
]
|
||||
|
||||
def struct_print(self, padding):
|
||||
p = padder(padding)
|
||||
|
||||
print(p + 'Password Size:', '0x%X' % self.PasswordSize)
|
||||
print(p + 'Entry Count :', self.EntryCount)
|
||||
print(p + 'Password :', self.Password.decode('utf-8'))
|
||||
|
||||
class DisModule(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('EnabledDisabled', uint8_t), # 0x00
|
||||
('ShownHidden', uint8_t), # 0x01
|
||||
('Command', char*32), # 0x02
|
||||
('Description', char*256), # 0x22
|
||||
# 0x122
|
||||
]
|
||||
|
||||
ENDIS = {0: 'Disabled', 1: 'Enabled'}
|
||||
SHOWN = {0: 'Hidden', 1: 'Shown', 2: 'Shown Only'}
|
||||
|
||||
def struct_print(self, padding):
|
||||
p = padder(padding)
|
||||
|
||||
EnabledDisabled = self.ENDIS.get(self.EnabledDisabled, 'Unknown (%d)' % self.EnabledDisabled)
|
||||
ShownHidden = self.SHOWN.get(self.ShownHidden, 'Unknown (%d)' % self.ShownHidden)
|
||||
|
||||
print(p + 'State :', EnabledDisabled)
|
||||
print(p + 'Display :', ShownHidden)
|
||||
print(p + 'Command :', self.Command.decode('utf-8').strip())
|
||||
print(p + 'Description:', self.Description.decode('utf-8').strip())
|
||||
|
||||
# Validate @UAF Module Checksum-16
|
||||
def chk16_validate(data, tag, padd=0):
|
||||
if checksum16(data) != 0:
|
||||
print_input('\n%sError: Invalid UCP Module %s Checksum!' % (padder(padd), tag))
|
||||
else:
|
||||
print('\n%sChecksum of UCP Module %s is valid!' % (padder(padd), tag))
|
||||
|
||||
# Get all input file AMI UCP patterns
|
||||
def get_ami_ucp(buffer):
|
||||
uaf_len_max = 0x0 # Length of largest detected @UAF
|
||||
uaf_hdr_off = 0x0 # Offset of largest detected @UAF
|
||||
uaf_buf_bin = b'' # Buffer of largest detected @UAF
|
||||
|
||||
for uaf in PAT_AMI_UCP.finditer(buffer):
|
||||
uaf_len_cur = int.from_bytes(buffer[uaf.start() + 0x4:uaf.start() + 0x8], 'little')
|
||||
|
||||
if uaf_len_cur > uaf_len_max:
|
||||
uaf_len_max = uaf_len_cur
|
||||
uaf_hdr_off = uaf.start()
|
||||
uaf_buf_bin = buffer[uaf_hdr_off:uaf_hdr_off + uaf_len_max]
|
||||
|
||||
return uaf_hdr_off, uaf_buf_bin
|
||||
|
||||
# Get list of @UAF Modules
|
||||
def get_uaf_mod(buffer, uaf_off=0x0):
|
||||
uaf_all = [] # Initialize list of all @UAF Modules
|
||||
|
||||
while buffer[uaf_off] == 0x40: # ASCII of @ is 0x40
|
||||
uaf_hdr = get_struct(buffer, uaf_off, UafHeader) # Parse @UAF Module Structure
|
||||
|
||||
uaf_tag = uaf_hdr.ModuleTag.decode('utf-8') # Get unique @UAF Module Tag
|
||||
|
||||
uaf_all.append([uaf_tag, uaf_off, uaf_hdr]) # Store @UAF Module Info
|
||||
|
||||
uaf_off += uaf_hdr.ModuleSize # Adjust to next @UAF Module offset
|
||||
|
||||
if uaf_off >= len(buffer): break # Stop parsing at EOF
|
||||
|
||||
# Check if @UAF Module NAL exists and place it first
|
||||
# Parsing NAL first allows naming all @UAF Modules
|
||||
for mod_idx,mod_val in enumerate(uaf_all):
|
||||
if mod_val[0] == '@NAL':
|
||||
uaf_all.insert(1, uaf_all.pop(mod_idx)) # After UII for visual purposes
|
||||
break # NAL found, skip the rest
|
||||
|
||||
return uaf_all
|
||||
|
||||
# Parse & Extract AMI UCP structures
|
||||
def ucp_extract(buffer, output_path, padding=0, is_chk16=False):
|
||||
nal_dict = {} # Initialize @NAL Dictionary per UCP
|
||||
|
||||
print('\n%sUtility Configuration Program' % padder(padding))
|
||||
|
||||
extract_path = os.path.join(output_path + '_extracted', '')
|
||||
|
||||
if os.path.isdir(extract_path): shutil.rmtree(extract_path)
|
||||
|
||||
os.mkdir(extract_path)
|
||||
|
||||
uaf_hdr = get_struct(buffer, 0, UafHeader) # Parse @UAF Header Structure
|
||||
|
||||
print('\n%sUtility Auxiliary File > @UAF:\n' % padder(padding + 4))
|
||||
|
||||
uaf_hdr.struct_print(padding + 8)
|
||||
|
||||
fake = struct.pack('<II', len(buffer), len(buffer)) # Generate UafModule Structure
|
||||
|
||||
uaf_mod = get_struct(fake, 0x0, UafModule) # Parse UAF Module EFI Structure
|
||||
|
||||
uaf_mod.struct_print(padding + 8, UAF_TAG_DICT['@UAF'][0]) # Print @UAF Module EFI Info
|
||||
|
||||
if is_chk16: chk16_validate(buffer, '@UAF', padding + 8)
|
||||
|
||||
uaf_all = get_uaf_mod(buffer, UAF_HDR_LEN)
|
||||
|
||||
for mod_info in uaf_all:
|
||||
nal_dict = uaf_extract(buffer, extract_path, mod_info, padding + 8, is_chk16, nal_dict)
|
||||
|
||||
# Parse & Extract AMI UCP > @UAF Module/Section
|
||||
def uaf_extract(buffer, extract_path, mod_info, padding=0, is_chk16=False, nal_dict=None):
|
||||
if nal_dict is None: nal_dict = {}
|
||||
|
||||
uaf_tag,uaf_off,uaf_hdr = mod_info
|
||||
|
||||
uaf_data_all = buffer[uaf_off:uaf_off + uaf_hdr.ModuleSize] # @UAF Module Entire Data
|
||||
|
||||
uaf_data_mod = uaf_data_all[UAF_HDR_LEN:] # @UAF Module EFI Data
|
||||
|
||||
uaf_data_raw = uaf_data_mod[UAF_MOD_LEN:] # @UAF Module Raw Data
|
||||
|
||||
print('\n%sUtility Auxiliary File > %s:\n' % (padder(padding), uaf_tag))
|
||||
|
||||
uaf_hdr.struct_print(padding + 4) # Print @UAF Module Info
|
||||
|
||||
uaf_mod = get_struct(buffer, uaf_off + UAF_HDR_LEN, UafModule) # Parse UAF Module EFI Structure
|
||||
|
||||
is_comp = uaf_mod.CompressSize != uaf_mod.OriginalSize # Detect @UAF Module EFI Compression
|
||||
|
||||
if uaf_tag in nal_dict: uaf_name = nal_dict[uaf_tag] # Always prefer NAL naming first
|
||||
elif uaf_tag in UAF_TAG_DICT: uaf_name = UAF_TAG_DICT[uaf_tag][0] # Otherwise use built-in naming
|
||||
elif uaf_tag == '@ROM': uaf_name = 'BIOS.bin' # BIOS/PFAT Firmware (w/o Signature)
|
||||
elif uaf_tag.startswith('@R0'): uaf_name = 'BIOS_0%s.bin' % uaf_tag[3:] # BIOS/PFAT Firmware
|
||||
elif uaf_tag.startswith('@S0'): uaf_name = 'BIOS_0%s.sig' % uaf_tag[3:] # BIOS/PFAT Signature
|
||||
elif uaf_tag.startswith('@DR'): uaf_name = 'DROM_0%s.bin' % uaf_tag[3:] # Thunderbolt Retimer Firmware
|
||||
elif uaf_tag.startswith('@DS'): uaf_name = 'DROM_0%s.sig' % uaf_tag[3:] # Thunderbolt Retimer Signature
|
||||
elif uaf_tag.startswith('@EC'): uaf_name = 'EC_0%s.bin' % uaf_tag[3:] # Embedded Controller Firmware
|
||||
elif uaf_tag.startswith('@ME'): uaf_name = 'ME_0%s.bin' % uaf_tag[3:] # Management Engine Firmware
|
||||
else: uaf_name = uaf_tag # Could not name the @UAF Module, use Tag instead
|
||||
|
||||
uaf_fext = '' if uaf_name != uaf_tag else '.bin'
|
||||
|
||||
uaf_mod.struct_print(padding + 4, uaf_name + uaf_fext) # Print @UAF Module EFI Info
|
||||
|
||||
# Check if unknown @UAF Module Tag is present in NAL but not in built-in dictionary
|
||||
if uaf_tag in nal_dict and uaf_tag not in UAF_TAG_DICT and not uaf_tag.startswith(('@ROM','@R0','@S0','@DR','@DS')):
|
||||
print_input('\n%sNote: Detected new AMI UCP Module %s (%s) in NAL!' % (padder(padding), uaf_tag, nal_dict[uaf_tag]))
|
||||
|
||||
# Generate @UAF Module File name, depending on whether decompression will be required
|
||||
uaf_fname = os.path.join(extract_path, safe_name(uaf_name + ('.temp' if is_comp else uaf_fext)))
|
||||
|
||||
if is_chk16: chk16_validate(uaf_data_all, uaf_tag, padding + 4)
|
||||
|
||||
# Parse Utility Identification Information @UAF Module (@UII)
|
||||
if uaf_tag == '@UII':
|
||||
info_hdr = get_struct(uaf_data_raw, 0, UiiHeader) # Parse @UII Module Raw Structure
|
||||
|
||||
info_data = uaf_data_raw[max(UII_HDR_LEN,info_hdr.InfoSize):info_hdr.UIISize] # @UII Module Info Data
|
||||
|
||||
# Get @UII Module Info/Description text field
|
||||
info_desc = info_data.decode('utf-8','ignore').strip('\x00 ')
|
||||
|
||||
print('\n%sUtility Identification Information:\n' % padder(padding + 4))
|
||||
|
||||
info_hdr.struct_print(padding + 8, info_desc) # Print @UII Module Info
|
||||
|
||||
if is_chk16: chk16_validate(uaf_data_raw, '@UII > Info', padding + 8)
|
||||
|
||||
# Store/Save @UII Module Info in file
|
||||
with open(uaf_fname[:-4] + '.txt', 'a', encoding='utf-8') as uii_out:
|
||||
with contextlib.redirect_stdout(uii_out):
|
||||
info_hdr.struct_print(0, info_desc) # Store @UII Module Info
|
||||
|
||||
# Adjust @UAF Module Raw Data for extraction
|
||||
if is_comp:
|
||||
# Some Compressed @UAF Module EFI data lack necessary EOF padding
|
||||
if uaf_mod.CompressSize > len(uaf_data_raw):
|
||||
comp_padd = b'\x00' * (uaf_mod.CompressSize - len(uaf_data_raw))
|
||||
uaf_data_raw = uaf_data_mod[:UAF_MOD_LEN] + uaf_data_raw + comp_padd # Add missing padding for decompression
|
||||
else:
|
||||
uaf_data_raw = uaf_data_mod[:UAF_MOD_LEN] + uaf_data_raw # Add the EFI/Tiano Compression info before Raw Data
|
||||
else:
|
||||
uaf_data_raw = uaf_data_raw[:uaf_mod.OriginalSize] # No compression, extend to end of Original @UAF Module size
|
||||
|
||||
# Store/Save @UAF Module file
|
||||
if uaf_tag != '@UII': # Skip @UII binary, already parsed
|
||||
with open(uaf_fname, 'wb') as uaf_out: uaf_out.write(uaf_data_raw)
|
||||
|
||||
# @UAF Module EFI/Tiano Decompression
|
||||
if is_comp and is_efi_compressed(uaf_data_raw, False):
|
||||
dec_fname = uaf_fname.replace('.temp', uaf_fext) # Decompressed @UAF Module file path
|
||||
|
||||
if efi_decompress(uaf_fname, dec_fname, padding + 4) == 0:
|
||||
with open(dec_fname, 'rb') as dec: uaf_data_raw = dec.read() # Read back the @UAF Module decompressed Raw data
|
||||
|
||||
os.remove(uaf_fname) # Successful decompression, delete compressed @UAF Module file
|
||||
|
||||
uaf_fname = dec_fname # Adjust @UAF Module file path to the decompressed one
|
||||
|
||||
# Process and Print known text only @UAF Modules (after EFI/Tiano Decompression)
|
||||
if uaf_tag in UAF_TAG_DICT and UAF_TAG_DICT[uaf_tag][2] == 'Text':
|
||||
print('\n%s%s:' % (padder(padding + 4), UAF_TAG_DICT[uaf_tag][1]))
|
||||
print('\n%s%s' % (padder(padding + 8), uaf_data_raw.decode('utf-8','ignore')))
|
||||
|
||||
# Parse Default Command Status @UAF Module (@DIS)
|
||||
if len(uaf_data_raw) and uaf_tag == '@DIS':
|
||||
dis_hdr = get_struct(uaf_data_raw, 0x0, DisHeader) # Parse @DIS Module Raw Header Structure
|
||||
|
||||
print('\n%sDefault Command Status Header:\n' % padder(padding + 4))
|
||||
|
||||
dis_hdr.struct_print(padding + 8) # Print @DIS Module Raw Header Info
|
||||
|
||||
# Store/Save @DIS Module Header Info in file
|
||||
with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis:
|
||||
with contextlib.redirect_stdout(dis):
|
||||
dis_hdr.struct_print(0) # Store @DIS Module Header Info
|
||||
|
||||
dis_data = uaf_data_raw[DIS_HDR_LEN:] # @DIS Module Entries Data
|
||||
|
||||
# Parse all @DIS Module Entries
|
||||
for mod_idx in range(dis_hdr.EntryCount):
|
||||
dis_mod = get_struct(dis_data, mod_idx * DIS_MOD_LEN, DisModule) # Parse @DIS Module Raw Entry Structure
|
||||
|
||||
print('\n%sDefault Command Status Entry %0.2d/%0.2d:\n' % (padder(padding + 8), mod_idx + 1, dis_hdr.EntryCount))
|
||||
|
||||
dis_mod.struct_print(padding + 12) # Print @DIS Module Raw Entry Info
|
||||
|
||||
# Store/Save @DIS Module Entry Info in file
|
||||
with open(uaf_fname[:-3] + 'txt', 'a', encoding='utf-8') as dis:
|
||||
with contextlib.redirect_stdout(dis):
|
||||
print()
|
||||
dis_mod.struct_print(4) # Store @DIS Module Entry Info
|
||||
|
||||
os.remove(uaf_fname) # Delete @DIS Module binary, info exported as text
|
||||
|
||||
# Parse Name|Non-AMI List (?) @UAF Module (@NAL)
|
||||
if len(uaf_data_raw) >= 5 and (uaf_tag,uaf_data_raw[0],uaf_data_raw[4]) == ('@NAL',0x40,0x3A):
|
||||
nal_info = uaf_data_raw.decode('utf-8','ignore').replace('\r','').strip().split('\n')
|
||||
|
||||
print('\n%s@UAF Module Name List:\n' % padder(padding + 4))
|
||||
|
||||
# Parse all @NAL Module Entries
|
||||
for info in nal_info:
|
||||
info_tag,info_val = info.split(':',1)
|
||||
|
||||
print('%s%s : %s' % (padder(padding + 8), info_tag, info_val)) # Print @NAL Module Tag-Path Info
|
||||
|
||||
nal_dict[info_tag] = os.path.basename(info_val) # Assign a file name (w/o path) to each Tag
|
||||
|
||||
# Parse Insyde BIOS @UAF Module (@INS)
|
||||
if uaf_tag == '@INS' and is_7z_supported(uaf_fname):
|
||||
ins_dir = os.path.join(extract_path, safe_name(uaf_tag + '_nested-SFX')) # Generate extraction directory
|
||||
|
||||
print('\n%sInsyde BIOS 7z SFX Archive:' % padder(padding + 4))
|
||||
|
||||
if a7z_decompress(uaf_fname, ins_dir, '7z SFX', padding + 8) == 0:
|
||||
os.remove(uaf_fname) # Successful extraction, delete @INS Module file/archive
|
||||
|
||||
# Detect & Unpack AMI BIOS Guard (PFAT) BIOS image
|
||||
pfat_match,pfat_buffer = get_ami_pfat(uaf_data_raw)
|
||||
|
||||
if pfat_match:
|
||||
pfat_dir = os.path.join(extract_path, safe_name(uaf_name))
|
||||
|
||||
parse_pfat_file(pfat_buffer, pfat_dir, padding + 4)
|
||||
|
||||
os.remove(uaf_fname) # Delete PFAT Module file after extraction
|
||||
|
||||
# Detect Intel Engine firmware image and show ME Analyzer advice
|
||||
if uaf_tag.startswith('@ME') and PAT_INTEL_ENG.search(uaf_data_raw):
|
||||
print('\n%sIntel Management Engine (ME) Firmware:\n' % padder(padding + 4))
|
||||
print('%sUse "ME Analyzer" from https://github.com/platomav/MEAnalyzer' % padder(padding + 8))
|
||||
|
||||
# Get best Nested AMI UCP Pattern match based on @UAF Size
|
||||
nested_uaf_off,nested_uaf_bin = get_ami_ucp(uaf_data_raw)
|
||||
|
||||
# Parse Nested AMI UCP Structure
|
||||
if nested_uaf_off:
|
||||
uaf_dir = os.path.join(extract_path, safe_name(uaf_tag + '_nested-UCP')) # Generate extraction directory
|
||||
|
||||
ucp_extract(nested_uaf_bin, uaf_dir, padding + 4, is_chk16) # Call recursively
|
||||
|
||||
os.remove(uaf_fname) # Delete raw nested AMI UCP Structure after successful recursion/extraction
|
||||
|
||||
return nal_dict
|
||||
|
||||
# Get common ctypes Structure Sizes
|
||||
UAF_HDR_LEN = ctypes.sizeof(UafHeader)
|
||||
UAF_MOD_LEN = ctypes.sizeof(UafModule)
|
||||
DIS_HDR_LEN = ctypes.sizeof(DisHeader)
|
||||
DIS_MOD_LEN = ctypes.sizeof(DisModule)
|
||||
UII_HDR_LEN = ctypes.sizeof(UiiHeader)
|
||||
|
||||
# AMI UCP Tag Dictionary
|
||||
UAF_TAG_DICT = {
|
||||
'@3FI' : ['HpBiosUpdate32.efi', '', ''],
|
||||
'@3S2' : ['HpBiosUpdate32.s12', '', ''],
|
||||
'@3S4' : ['HpBiosUpdate32.s14', '', ''],
|
||||
'@3S9' : ['HpBiosUpdate32.s09', '', ''],
|
||||
'@3SG' : ['HpBiosUpdate32.sig', '', ''],
|
||||
'@AMI' : ['UCP_Nested.bin', 'Nested AMI UCP', ''],
|
||||
'@B12' : ['BiosMgmt.s12', '', ''],
|
||||
'@B14' : ['BiosMgmt.s14', '', ''],
|
||||
'@B32' : ['BiosMgmt32.s12', '', ''],
|
||||
'@B34' : ['BiosMgmt32.s14', '', ''],
|
||||
'@B39' : ['BiosMgmt32.s09', '', ''],
|
||||
'@B3E' : ['BiosMgmt32.efi', '', ''],
|
||||
'@BM9' : ['BiosMgmt.s09', '', ''],
|
||||
'@BME' : ['BiosMgmt.efi', '', ''],
|
||||
'@CKV' : ['Check_Version.txt', 'Check Version', 'Text'],
|
||||
'@CMD' : ['AFU_Command.txt', 'AMI AFU Command', 'Text'],
|
||||
'@CPM' : ['AC_Message.txt', 'Confirm Power Message', ''],
|
||||
'@DCT' : ['DevCon32.exe', 'Device Console WIN32', ''],
|
||||
'@DCX' : ['DevCon64.exe', 'Device Console WIN64', ''],
|
||||
'@DFE' : ['HpDevFwUpdate.efi', '', ''],
|
||||
'@DFS' : ['HpDevFwUpdate.s12', '', ''],
|
||||
'@DIS' : ['Command_Status.bin', 'Default Command Status', ''],
|
||||
'@ENB' : ['ENBG64.exe', '', ''],
|
||||
'@INS' : ['Insyde_Nested.bin', 'Nested Insyde SFX', ''],
|
||||
'@M32' : ['HpBiosMgmt32.s12', '', ''],
|
||||
'@M34' : ['HpBiosMgmt32.s14', '', ''],
|
||||
'@M39' : ['HpBiosMgmt32.s09', '', ''],
|
||||
'@M3I' : ['HpBiosMgmt32.efi', '', ''],
|
||||
'@MEC' : ['FWUpdLcl.txt', 'Intel FWUpdLcl Command', 'Text'],
|
||||
'@MED' : ['FWUpdLcl_DOS.exe', 'Intel FWUpdLcl DOS', ''],
|
||||
'@MET' : ['FWUpdLcl_WIN32.exe', 'Intel FWUpdLcl WIN32', ''],
|
||||
'@MFI' : ['HpBiosMgmt.efi', '', ''],
|
||||
'@MS2' : ['HpBiosMgmt.s12', '', ''],
|
||||
'@MS4' : ['HpBiosMgmt.s14', '', ''],
|
||||
'@MS9' : ['HpBiosMgmt.s09', '', ''],
|
||||
'@NAL' : ['UAF_List.txt', 'Name List', ''],
|
||||
'@OKM' : ['OK_Message.txt', 'OK Message', ''],
|
||||
'@PFC' : ['BGT_Command.txt', 'AMI BGT Command', 'Text'],
|
||||
'@R3I' : ['CryptRSA32.efi', '', ''],
|
||||
'@RFI' : ['CryptRSA.efi', '', ''],
|
||||
'@UAF' : ['UCP_Main.bin', 'Utility Auxiliary File', ''],
|
||||
'@UFI' : ['HpBiosUpdate.efi', '', ''],
|
||||
'@UII' : ['UCP_Info.txt', 'Utility Identification Information', ''],
|
||||
'@US2' : ['HpBiosUpdate.s12', '', ''],
|
||||
'@US4' : ['HpBiosUpdate.s14', '', ''],
|
||||
'@US9' : ['HpBiosUpdate.s09', '', ''],
|
||||
'@USG' : ['HpBiosUpdate.sig', '', ''],
|
||||
'@VER' : ['OEM_Version.txt', 'OEM Version', 'Text'],
|
||||
'@VXD' : ['amifldrv.vxd', '', ''],
|
||||
'@W32' : ['amifldrv32.sys', '', ''],
|
||||
'@W64' : ['amifldrv64.sys', '', ''],
|
||||
}
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Show script title
|
||||
show_title(title)
|
||||
|
||||
# Set argparse Arguments
|
||||
argparser = argparse_init()
|
||||
argparser.add_argument('-c', '--checksum', help='verify AMI UCP Checksums (slow)', action='store_true')
|
||||
arguments = argparser.parse_args()
|
||||
|
||||
# Pretty Python exception handler (must be after argparse)
|
||||
sys.excepthook = nice_exc_handler
|
||||
|
||||
# Check Python Version (must be after argparse)
|
||||
check_sys_py()
|
||||
|
||||
# Check OS Platform (must be after argparse)
|
||||
check_sys_os()
|
||||
|
||||
# Process input files and generate output path
|
||||
input_files,output_path = process_input_files(arguments, sys.argv)
|
||||
|
||||
# Initial output padding count
|
||||
padding = 4
|
||||
|
||||
for input_file in input_files:
|
||||
input_name = os.path.basename(input_file)
|
||||
|
||||
print('\n*** %s' % input_name)
|
||||
|
||||
with open(input_file, 'rb') as in_file: input_buffer = in_file.read()
|
||||
|
||||
# Get best AMI UCP Pattern match based on @UAF Size
|
||||
main_uaf_off,main_uaf_bin = get_ami_ucp(input_buffer)
|
||||
|
||||
if not main_uaf_off:
|
||||
print('\n%sError: This is not an AMI UCP BIOS executable!' % padder(padding))
|
||||
|
||||
continue # Next input file
|
||||
|
||||
extract_path = os.path.join(output_path, input_name)
|
||||
|
||||
ucp_extract(main_uaf_bin, extract_path, padding, arguments.checksum)
|
||||
|
||||
print('\n%sExtracted AMI UCP BIOS executable!' % padder(padding))
|
||||
|
||||
print_input('\nDone!')
|
759
README.md
759
README.md
|
@ -5,175 +5,39 @@
|
|||
|
||||
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DJDZD3PRGCSCL"><img border="0" title="BIOS Utilities Donation via Paypal or Debit/Credit Card" alt="BIOS Utilities Donation via Paypal or Debit/Credit Card" src="https://user-images.githubusercontent.com/11527726/109392268-e0f68280-7923-11eb-83d8-0a63f0d20783.png"></a>
|
||||
|
||||
* [**Dell PFS Update Extractor**](#dell-pfs-update-extractor)
|
||||
* [**AMI UCP BIOS Extractor**](#ami-ucp-bios-extractor)
|
||||
* [**AMI BIOS Guard Extractor**](#ami-bios-guard-extractor)
|
||||
* [**Phoenix SCT BIOS Extractor**](#phoenix-sct-bios-extractor)
|
||||
* [**Insyde iFlash Image Extractor**](#insyde-iflash-image-extractor)
|
||||
* [**Portwell EFI BIOS Extractor**](#portwell-efi-bios-extractor)
|
||||
* [**Panasonic BIOS Update Extractor**](#panasonic-bios-update-extractor)
|
||||
* [**VAIO Packaging Manager Extractor**](#vaio-packaging-manager-extractor)
|
||||
* [**Fujitsu UPC BIOS Extractor**](#fujitsu-upc-bios-extractor)
|
||||
* [**Fujitsu SFX BIOS Extractor**](#fujitsu-sfx-bios-extractor)
|
||||
* [**Award BIOS Module Extractor**](#award-bios-module-extractor)
|
||||
* [**Apple EFI Package Grabber**](#apple-efi-package-grabber)
|
||||
* [**Apple EFI File Renamer**](#apple-efi-file-renamer)
|
||||
* [**Apple EFI IM4P Splitter**](#apple-efi-im4p-splitter)
|
||||
* [**Apple EFI Package Extractor**](#apple-efi-package-extractor)
|
||||
|
||||
## **Dell PFS Update Extractor**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Dell PFS Update images and extracts their Firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and Utilities (e.g. Flasher etc) component sections. It supports all Dell PFS revisions and formats, including those which are originally LZMA compressed in ThinOS packages, ZLIB compressed or Intel BIOS Guard (PFAT) protected. The output comprises only final firmware components which are directly usable by end users. An optional advanced user mode is available as well, which additionally extracts firmware Signatures and more Metadata.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Dell PFS BIOS images. Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -a or --advanced : extract in advanced user mode
|
||||
* -v or --verbose : show PFS structure information
|
||||
* -e or --auto-exit : skip press enter to exit prompts
|
||||
* -o or --output-dir : extract in given output directory
|
||||
* -i or --input-dir : extract from given input directory
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To decompile the Intel BIOS Guard Scripts via the Python script, you need to additionally have the following 3rd party Python utility at the same directory:
|
||||
|
||||
* [BIOS Guard Script Tool](https://github.com/allowitsme/big-tool/tree/sdk-compat) (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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Copy BIOS Guard Script Tool dependency to build directory:
|
||||
|
||||
> Dell_PFS_Extract.py, big_script_tool.py
|
||||
|
||||
4. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Dell_PFS_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**
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## **AMI UCP BIOS Extractor**
|
||||
|
||||

|
||||
![]()
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses AMI UCP (Utility Configuration Program) BIOS images, extracts their SPI/BIOS/UEFI firmware components and shows all relevant info. It supports all AMI UCP revisions and formats, including those with nested AMI UCP or Insyde SFX structures. The output comprises only final firmware components and utilities which are directly usable by end users.
|
||||
|
||||
Note that AMI UCP BIOS images are protected by various checksums but, due to algorithmic performance reasons, AMI UCP BIOS Extractor does not check them by default. An optional parameter is provided though, for verifying all checksums during extraction.
|
||||
Parses AMI UCP (Utility Configuration Program) BIOS executables, extracts their firmware components (e.g. SPI/BIOS/UEFI, EC, ME etc) and shows all relevant info. It supports all AMI UCP revisions and formats, including those with nested AMI PFAT, AMI UCP or Insyde SFX structures. The output comprises only final firmware components and utilities which are directly usable by end users.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing AMI UCP BIOS images. Optional arguments:
|
||||
You can either Drag & Drop or manually enter AMI UCP BIOS executable file(s). Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -p or --path : parse files within given folder
|
||||
* -i or --input-dir : extract from given input directory
|
||||
* -o or --output-dir : extract in given output directory
|
||||
* -e or --auto-exit : skip press enter to exit prompts
|
||||
* -c or --checksum : verify AMI UCP Checksums (slow)
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script, you need to have the following 3rd party tools placed at the same directory:
|
||||
To run the utility, you must have the following 3rd party tools at the "external" project directory:
|
||||
|
||||
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe](https://github.com/tianocore/edk2-BaseTools-win32/))
|
||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe)
|
||||
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (e.g. [TianoCompress.exe for Windows](https://github.com/tianocore/edk2-BaseTools-win32/) or TianoCompress)
|
||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe for Windows or 7zz|7zzs)
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile AMI_UCP_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**
|
||||
|
||||

|
||||
|
||||
## **AMI BIOS Guard Extractor**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses AMI BIOS Guard (a.k.a. PFAT, Platform Firmware Armoring Technology) images, extracts their SPI/BIOS/UEFI firmware components and decompiles the Intel BIOS Guard Scripts. It supports all AMI PFAT revisions and formats, including those with nested AMI PFAT structures. The output comprises only final firmware components which are directly usable by end users.
|
||||
|
||||
Note that the AMI PFAT structure does not have an explicit component order. AMI's BIOS Guard Firmware Update Tool (AFUBGT) updates components based on the user/OEM provided Parameters and Options. That means that merging all the components together does not usually yield a proper SPI/BIOS/UEFI image. The utility does generate such a merged file with the name "X_00 -- AMI_PFAT_X_DATA_ALL.bin" but it is up to the end user to determine its usefulness. Moreover, any custom OEM data after the AMI PFAT structure are additionally stored in a file with the name "X_YY -- AMI_PFAT_X_DATA_END.bin" and it is once again up to the end user to determine its usefulness. In cases where the trailing custom OEM data include a nested AMI PFAT structure, the utility will process and extract it automatically as well.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing AMI BIOS Guard (PFAT) images.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To decompile the Intel BIOS Guard Scripts via the Python script, you need to additionally have the following 3rd party Python utility at the same directory:
|
||||
Optionally, to decompile the AMI UCP \> AMI PFAT \> Intel BIOS Guard Scripts (when applicable), you must have the following 3rd party utility at the "external" project directory:
|
||||
|
||||
* [BIOS Guard Script Tool](https://github.com/allowitsme/big-tool/tree/sdk-compat) (i.e. big_script_tool.py)
|
||||
|
||||
|
@ -189,13 +53,13 @@ PyInstaller can build/freeze/compile the utility at all three supported platform
|
|||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Copy BIOS Guard Script Tool dependency to build directory:
|
||||
3. Place any appropriate prerequisite at the project directory:
|
||||
|
||||
> AMI_PFAT_Extract.py, big_script_tool.py
|
||||
> TianoCompress, 7-Zip Console, BIOS Guard Script Tool
|
||||
|
||||
4. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile AMI_PFAT_Extract.py
|
||||
> pyinstaller --noupx --onefile \<path-to-project\>\/AMI_UCP_Extract.py
|
||||
|
||||
At dist folder you should find the final utility executable
|
||||
|
||||
|
@ -205,85 +69,26 @@ Some Anti-Virus software may claim that the built/frozen/compiled executable con
|
|||
|
||||
#### **Pictures**
|
||||
|
||||

|
||||
![]()
|
||||
|
||||
## **Phoenix SCT BIOS Extractor**
|
||||
## **AMI BIOS Guard Extractor**
|
||||
|
||||

|
||||
![]()
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Phoenix SecureCore Technology (SCT) BIOS images and extracts their SPI/BIOS/UEFI firmware components. It supports all Phoenix SCT revisions and formats, including those which are originally LZMA compressed. The output comprises only final firmware components which are directly usable by end users.
|
||||
Parses AMI BIOS Guard (a.k.a. PFAT, Platform Firmware Armoring Technology) images, extracts their SPI/BIOS/UEFI firmware components and decompiles the Intel BIOS Guard Scripts. It supports all AMI PFAT revisions and formats, including those with Index Information tables or nested AMI PFAT structures. The output comprises only final firmware components which are directly usable by end users.
|
||||
|
||||

|
||||
<sub><sup>*Icon owned by Phoenix*</sup></sub>
|
||||
Note that the AMI PFAT structure may not have an explicit component order. AMI's BIOS Guard Firmware Update Tool (AFUBGT) updates components based on the user/OEM provided Parameters and Options or Index Information table, when applicable. That means that merging all the components together does not usually yield a proper SPI/BIOS/UEFI image. The utility does generate such a merged file with the name "00 -- \<filename\>\_ALL.bin" but it is up to the end user to determine its usefulness. Moreover, any custom OEM data after the AMI PFAT structure are additionally stored in the last file with the name "\<n+1\> -- \_OOB.bin" and it is once again up to the end user to determine its usefulness. In cases where the trailing custom OEM data include a nested AMI PFAT structure, the utility will process and extract it automatically as well.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Phoenix SCT BIOS images. Optional arguments:
|
||||
You can either Drag & Drop or manually enter AMI BIOS Guard (PFAT) image file(s). Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -p or --path : parse files within given folder
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the utility, you do not need any 3rd party tool.
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Phoenix_SCT_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**
|
||||
|
||||

|
||||
|
||||
## **Insyde iFlash Image Extractor**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Insyde iFlash images and extracts their raw components (e.g. SPI/BIOS/UEFI, EC, ME, Flasher, Configuration etc).
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Insyde iFlash images. Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -v or --verbose : show iFlash structure information
|
||||
* -e or --auto-exit : skip press enter to exit prompts
|
||||
* -o or --output-dir : extract in given output directory
|
||||
* -i or --input-dir : extract from given input directory
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
* -o or --output-dir : extract in given output directory
|
||||
* -e or --auto-exit : skip press enter to exit prompts
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
|
@ -291,7 +96,9 @@ Should work at all Windows, Linux or macOS operating systems which have Python 3
|
|||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the utility, you do not need any 3rd party tool.
|
||||
Optionally, to decompile the AMI PFAT \> Intel BIOS Guard Scripts, you must have the following 3rd party utility at the "external" project directory:
|
||||
|
||||
* [BIOS Guard Script Tool](https://github.com/allowitsme/big-tool/tree/sdk-compat) (i.e. big_script_tool.py)
|
||||
|
||||
#### **Build/Freeze/Compile with PyInstaller**
|
||||
|
||||
|
@ -305,74 +112,13 @@ PyInstaller can build/freeze/compile the utility at all three supported platform
|
|||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
3. Place any appropriate prerequisite at the project directory:
|
||||
|
||||
> pyinstaller --noupx --onefile Insyde_iFlash_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**
|
||||
|
||||

|
||||
|
||||
## **Portwell EFI BIOS Extractor**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Portwell UEFI Unpacker EFI images (usually named "Update.efi"), extracts their SPI/BIOS/UEFI/EC firmware components and shows all relevant info. It supports all Portwell UEFI Unpacker revisions and formats, including those which contain Tiano compressed files. The output comprises only final firmware components and utilities which are directly usable by end users.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Portwell UEFI Unpacker EFI images. Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -p or --path : parse files within given folder
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script, you need to have the following 3rd party Python module installed:
|
||||
|
||||
* [pefile](https://pypi.org/project/pefile/)
|
||||
|
||||
> pip3 install pefile
|
||||
|
||||
To run the python script or its built/frozen/compiled binary, you need to additionally have the following 3rd party tool at the same directory:
|
||||
|
||||
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe](https://github.com/tianocore/edk2-BaseTools-win32/))
|
||||
|
||||
#### **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.7.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
|
||||
> BIOS Guard Script Tool
|
||||
|
||||
4. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Portwell_EFI_Extract.py
|
||||
> pyinstaller --noupx --onefile \<path-to-project\>\/AMI_PFAT_Extract.py
|
||||
|
||||
At dist folder you should find the final utility executable
|
||||
|
||||
|
@ -382,456 +128,7 @@ Some Anti-Virus software may claim that the built/frozen/compiled executable con
|
|||
|
||||
#### **Pictures**
|
||||
|
||||

|
||||
|
||||
## **Apple EFI Package Grabber**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses user-provided (DB) list of Apple Software Update CatalogURL .sucatalog links and saves all newer (since last run) EFI firmware package links into a text file. It removes any xml formatting, ignores false positives, removes duplicate links and sorts them in alphabetical order for easy comparison afterwards.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
First, you need to familiarize a bit with the DB (i.e. Apple_EFI_Grab.dat file). It consists of 3 sections: Last run DateTime (YYYY-MM-DD HH:MM:SS), Sucatalog links to check and EFI Package links which have been gathered so far across all runs. Before running the utility for the fist time, you need to insert the Sucatalog links into the DB, below the 1st line (DateTime). The Sucatalog links in the DB are stored in partial form, starting from "index" string. For example: "https://swscan.apple.com/content/catalogs/others/index-12.merged-1.sucatalog" must be stored as "index-12.merged-1.sucatalog" in the DB. The Sucatalog links are not pre-included in the DB but you can find them online (e.g. https://github.com/zhangyoufu/swscan.apple.com/blob/master/url.txt).
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the utility, you do not need any 3rd party tool.
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Apple_EFI_Grab.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.
|
||||
|
||||
## **Apple EFI File Renamer**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Apple EFI files and renames them based on Intel's official $IBIOSI$ tag as follows: Model_Version_Build_Year_Month_Day_Hour_Minute_Checksum. The checksum is calculated and added by the utility in order to differentiate any EFI files with the same $IBIOSI$ tag. In rare cases in which the $IBIOSI$ tag is compressed, the utility automatically first uses [LongSoft's UEFIFind and UEFIExtract](https://github.com/LongSoft/UEFITool) tools.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Apple EFI firmware.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script or its built/frozen/compiled binary, you need to have the following 3rd party tools at the same directory:
|
||||
|
||||
* [UEFIFind](https://github.com/LongSoft/UEFITool) (i.e. UEFIFind.exe)
|
||||
* [UEFIExtract](https://github.com/LongSoft/UEFITool) (i.e. UEFIExtract.exe)
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Apple_EFI_Rename.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.
|
||||
|
||||
## **Apple EFI IM4P Splitter**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Apple multiple EFI firmware .im4p files and splits all detected EFI firmware into separate SPI/BIOS images.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Apple EFI IM4P firmware.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the utility, you do not need any 3rd party tool.
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Apple_EFI_Split.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.
|
||||
|
||||
## **Apple EFI Package Extractor**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Apple EFI firmware packages (i.e. FirmwareUpdate.pkg, BridgeOSUpdateCustomer.pkg), extracts their EFI images, splits those in IM4P format and renames the final SPI/BIOS images accordingly. The utility automatically uses the free version of [AnyToISO](https://www.crystalidea.com/anytoiso) to extract the EFI .pkg files. The subsequent IM4P splitting and EFI renaming requires the presence of "Apple EFI IM4P Splitter" and "Apple EFI File Renamer" utilities.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Apple EFI firmware package (.pkg) files. Depending on where AnyToISO is installed on your system, you must change the "anytoiso_path" variable accordingly.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is **not** provided because the script requires the user to set the AnyToISO executable path variable. Remember that you need to include prerequisites such as AnyToISO, Apple EFI IM4P Splitter and Apple EFI File Renamer for the utility to work.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows & macOS operating systems which have Python 3.7 and AnyToISO support.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script, you need to have the following 3rd party tools installed or placed at the same directory:
|
||||
|
||||
* [AnyToISO](https://www.crystalidea.com/anytoiso) (i.e. anytoiso.exe)
|
||||
* [UEFIFind](https://github.com/LongSoft/UEFITool) (i.e. UEFIFind.exe)
|
||||
* [UEFIExtract](https://github.com/LongSoft/UEFITool) (i.e. UEFIExtract.exe)
|
||||
|
||||
#### **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. Note that, due to this utility's nature, you may need to perform some small script changes for a built/frozen/compiled binary to work.
|
||||
|
||||
1. Make sure Python 3.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Apple_EFI_Package.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.
|
||||
|
||||
## **Panasonic BIOS Update Extractor**
|
||||
|
||||

|
||||
<sub><sup>*Icon owned by Panasonic*</sup></sub>
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Panasonic BIOS Update executables and extracts their SPI/BIOS image. The utility automatically uses [Rustam Abdullaev's unpack_lznt1](https://github.com/rustyx/unpack_lznt1) tool in order to decompress the initially Microsoft LZNT1 compressed resource data.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Panasonic BIOS Update executables.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled Windows binary is provided by me. Thus, **you don't need to manually build/freeze/compile it**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script, you need to have the following 3rd party Python module installed:
|
||||
|
||||
* [pefile](https://pypi.org/project/pefile/)
|
||||
|
||||
> pip3 install pefile
|
||||
|
||||
To run the python script or its built/frozen/compiled binary, you need to additionally have the following 3rd party tool at the same directory:
|
||||
|
||||
* [unpack_lznt1](https://github.com/rustyx/unpack_lznt1) (i.e. unpack_lznt1.exe)
|
||||
|
||||
#### **Build/Freeze/Compile with PyInstaller**
|
||||
|
||||
PyInstaller can build/freeze/compile the utility at Windows, it is simple to run and gets updated often.
|
||||
|
||||
1. Make sure Python 3.7.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 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.
|
||||
|
||||
## **VAIO Packaging Manager Extractor**
|
||||
|
||||

|
||||
<sub><sup>*Icon owned by VAIO*</sup></sub>
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses VAIO Packaging Manager executables and extracts their contents. If direct extraction fails, it unlocks the executable in order to run at all systems and allow the user to choose the extraction location. The utility automatically uses [Igor Pavlov's 7-Zip](https://www.7-zip.org/) tool in order to decompress the initially obfuscated Microsoft CAB compressed contents.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing VAIO Packaging Manager executables.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script or its built/frozen/compiled binary, you need to have the following 3rd party tool at the same directory:
|
||||
|
||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe)
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile 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.
|
||||
|
||||
## **Fujitsu UPC BIOS Extractor**
|
||||
|
||||

|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Fujitsu UPC images and extracts their Tiano compressed SPI/BIOS firmware component. The output comprises only a final firmware component which is directly usable by end users.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Portwell UEFI Unpacker EFI images. Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -p or --path : parse files within given folder
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script or its built/frozen/compiled binary, you need to additionally have the following 3rd party tool at the same directory:
|
||||
|
||||
* [TianoCompress](https://github.com/tianocore/edk2/tree/master/BaseTools/Source/C/TianoCompress/) (i.e. [TianoCompress.exe](https://github.com/tianocore/edk2-BaseTools-win32/))
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile Fujitsu_UPC_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**
|
||||
|
||||

|
||||
|
||||
## **Fujitsu SFX BIOS Extractor**
|
||||
|
||||

|
||||
<sub><sup>*Icon owned by FUJITSU*</sup></sub>
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Fujitsu SFX BIOS executables and extracts their contents. The utility automatically uses [Igor Pavlov's 7-Zip](https://www.7-zip.org/) tool in order to decompress the initially obfuscated Microsoft CAB compressed contents.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Fujitsu SFX BIOS executables.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script or its built/frozen/compiled binary, you need to have the following 3rd party tool at the same directory:
|
||||
|
||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe)
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile 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.
|
||||
|
||||
## **Award BIOS Module Extractor**
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Award BIOS images and extracts their modules. The utility automatically uses [Igor Pavlov's 7-Zip](https://www.7-zip.org/) tool in order to decompress the initially LZH compressed sub-modules.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter the full path of a folder containing Award BIOS firmware.
|
||||
|
||||
#### **Download**
|
||||
|
||||
An already built/frozen/compiled binary is provided by me for Windows only. Thus, **you don't need to manually build/freeze/compile it under Windows**. Instead, download the latest version from the [Releases](https://github.com/platomav/BIOSUtilities/releases) tab. To extract the already built/frozen/compiled archive, you need to use programs which support RAR5 compression. Note that you need to manually apply any prerequisites.
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.7 support. Windows users who plan to use the already built/frozen/compiled binary must make sure that they have the latest Windows Updates installed which include all required "Universal C Runtime (CRT)" libraries.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the python script or its built/frozen/compiled binary, you need to have the following 3rd party tool at the same directory:
|
||||
|
||||
* [7-Zip Console](https://www.7-zip.org/) (i.e. 7z.exe)
|
||||
|
||||
#### **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.7.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile 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.
|
||||
![]()
|
||||
|
||||
###### _Donate Button Card Image: [Credit and Loan Pack](https://flaticon.com/free-icon/credit-card_3898076) by **Freepik** under Flaticon license_
|
||||
###### _Donate Button Paypal Image: [Credit Cards Pack](https://flaticon.com/free-icon/paypal_349278) by **Freepik** under Flaticon license_
|
45
common/a7z_comp.py
Normal file
45
common/a7z_comp.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from common.script_get import get_script_dir
|
||||
from common.system import get_os_ver
|
||||
from common.text_ops import padder
|
||||
|
||||
# Get 7z path
|
||||
def get_7z_path(static=False):
|
||||
exec_name = '7z.exe' if get_os_ver()[1] else ('7zzs' if static else '7zz')
|
||||
|
||||
exec_path = os.path.join(get_script_dir(), '..', 'external', exec_name)
|
||||
|
||||
return exec_path
|
||||
|
||||
# Check if file is 7z supported
|
||||
def is_7z_supported(in_path, static=False):
|
||||
try:
|
||||
subprocess.run([get_7z_path(static), 't', in_path, '-bso0', '-bse0', '-bsp0'], check=True)
|
||||
|
||||
except:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
# Archive decompression via 7-Zip
|
||||
def a7z_decompress(in_path, out_path, in_name, padding, static=False):
|
||||
if not in_name: in_name = 'archive'
|
||||
|
||||
try:
|
||||
subprocess.run([get_7z_path(static), 'x', '-aou', '-bso0', '-bse0', '-bsp0', '-o' + out_path, in_path], check=True)
|
||||
|
||||
if not os.path.isdir(out_path): raise Exception('EXTRACT_DIR_MISSING')
|
||||
|
||||
except:
|
||||
print('\n%sError: 7-Zip could not extract %s file %s!' % (padder(padding), in_name, in_path))
|
||||
|
||||
return 1
|
||||
|
||||
print('\n%sSuccesfull %s decompression via 7-Zip!' % (padder(padding), in_name))
|
||||
|
||||
return 0
|
13
common/checksums.py
Normal file
13
common/checksums.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
# Get Checksum 16-bit
|
||||
def checksum16(data):
|
||||
chk16 = 0
|
||||
|
||||
for idx in range(0, len(data), 2):
|
||||
chk16 += int.from_bytes(data[idx:idx + 2], 'little')
|
||||
|
||||
chk16 &= 0xFFFF
|
||||
|
||||
return chk16
|
51
common/efi_comp.py
Normal file
51
common/efi_comp.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from common.script_get import get_script_dir
|
||||
from common.system import get_os_ver
|
||||
from common.text_ops import padder
|
||||
|
||||
def get_compress_sizes(data):
|
||||
size_compress = int.from_bytes(data[0x0:0x4], 'little')
|
||||
size_original = int.from_bytes(data[0x4:0x8], 'little')
|
||||
|
||||
return size_compress, size_original
|
||||
|
||||
def is_efi_compressed(data, strict=True):
|
||||
size_comp,size_orig = get_compress_sizes(data)
|
||||
|
||||
check_diff = size_comp < size_orig
|
||||
|
||||
if strict: check_size = size_comp + 0x8 == len(data)
|
||||
else: check_size = size_comp + 0x8 <= len(data)
|
||||
|
||||
return check_diff and check_size
|
||||
|
||||
# Get TianoCompress path
|
||||
def tianocompress_path():
|
||||
exec_name = 'TianoCompress' + ('.exe' if get_os_ver()[1] else '')
|
||||
|
||||
exec_path = os.path.join(get_script_dir(), '..', 'external', exec_name)
|
||||
|
||||
return exec_path
|
||||
|
||||
# EFI/Tiano Decompression via TianoCompress
|
||||
def efi_decompress(in_path, out_path, padding, comp_type='--uefi'):
|
||||
try:
|
||||
subprocess.run([tianocompress_path(), '-d', in_path, '-o', out_path, '-q', comp_type], check=True, stdout=subprocess.DEVNULL)
|
||||
|
||||
with open(in_path, 'rb') as file: _,size_orig = get_compress_sizes(file.read())
|
||||
|
||||
if os.path.getsize(out_path) != size_orig: raise Exception('EFI_DECOMPRESS_ERROR')
|
||||
|
||||
except:
|
||||
print('\n%sError: TianoCompress could not extract file %s!' % (padder(padding), in_path))
|
||||
|
||||
return 1
|
||||
|
||||
print('\n%sSuccesfull EFI/Tiano decompression via TianoCompress!' % padder(padding))
|
||||
|
||||
return 0
|
11
common/externals.py
Normal file
11
common/externals.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
# https://github.com/allowitsme/big-tool by Dmitry Frolov
|
||||
def get_bgs_tool():
|
||||
try:
|
||||
from external.big_script_tool import BigScript
|
||||
except:
|
||||
BigScript = None
|
||||
|
||||
return BigScript
|
11
common/num_ops.py
Normal file
11
common/num_ops.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
# https://leancrew.com/all-this/2020/06/ordinals-in-python/ by Dr. Drang
|
||||
|
||||
def get_ordinal(number):
|
||||
s = ('th', 'st', 'nd', 'rd') + ('th',) * 10
|
||||
|
||||
v = number % 100
|
||||
|
||||
return f'{number}{s[v % 10]}' if v > 13 else f'{number}{s[v]}'
|
79
common/path_ops.py
Normal file
79
common/path_ops.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from common.script_get import get_script_dir
|
||||
|
||||
# Fix illegal/reserved Windows characters
|
||||
def safe_name(in_name):
|
||||
raw_name = repr(in_name).strip("'")
|
||||
|
||||
fix_name = re.sub(r'[\\/*?:"<>|]', '_', raw_name)
|
||||
|
||||
return fix_name
|
||||
|
||||
# Walk path to get all files
|
||||
def get_path_files(in_path):
|
||||
path_files = []
|
||||
|
||||
for root, _, files in os.walk(in_path):
|
||||
for name in files:
|
||||
path_files.append(os.path.join(root, name))
|
||||
|
||||
return path_files
|
||||
|
||||
# Get parent of path
|
||||
def get_path_parent(in_path):
|
||||
return Path(in_path).parent.absolute()
|
||||
|
||||
# Get absolute file path (argparse object)
|
||||
def get_absolute_path(argparse_path):
|
||||
script_dir = get_path_parent(get_script_dir())
|
||||
|
||||
if not argparse_path:
|
||||
absolute_path = script_dir # Use input file directory if no user path is specified
|
||||
else:
|
||||
# Check if user specified path is absolute, otherwise convert it to input file relative
|
||||
if Path(argparse_path).is_absolute(): absolute_path = argparse_path
|
||||
else: absolute_path = os.path.join(script_dir, argparse_path)
|
||||
|
||||
return absolute_path
|
||||
|
||||
# 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('-o', '--output-dir', help='extract in given output directory')
|
||||
argparser.add_argument('-i', '--input-dir', help='extract from given input directory')
|
||||
|
||||
return argparser
|
||||
|
||||
# Process input files (argparse object)
|
||||
def process_input_files(argparse_args, sys_argv=None):
|
||||
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_absolute_path(input_path_user) if input_path_user else ''
|
||||
input_files = get_path_files(input_path_full)
|
||||
else:
|
||||
input_files = [file.name for file in argparse_args.files]
|
||||
|
||||
output_path = get_absolute_path(argparse_args.output_dir or argparse_args.input_dir)
|
||||
else:
|
||||
# Script w/o parameters
|
||||
input_path_user = input('\nEnter input directory path: ')
|
||||
input_path_full = get_absolute_path(input_path_user) if input_path_user else ''
|
||||
input_files = get_path_files(input_path_full)
|
||||
|
||||
output_path = get_absolute_path(input('\nEnter output directory path: '))
|
||||
|
||||
return input_files, output_path
|
8
common/patterns.py
Normal file
8
common/patterns.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
import re
|
||||
|
||||
PAT_AMI_PFAT = re.compile(b'_AMIPFAT.AMI_BIOS_GUARD_FLASH_CONFIGURATIONS', re.DOTALL)
|
||||
PAT_AMI_UCP = re.compile(br'\x40\x55\x41\x46.{12}\x40', re.DOTALL)
|
||||
PAT_INTEL_ENG = re.compile(br'\x04\x00{3}[\xA1\xE1]\x00{3}.{8}\x86\x80.{9}\x00\$((MN2)|(MAN))', re.DOTALL)
|
19
common/script_get.py
Normal file
19
common/script_get.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
# https://stackoverflow.com/a/22881871 by jfs
|
||||
|
||||
import os
|
||||
import sys
|
||||
import inspect
|
||||
|
||||
def get_script_dir(follow_symlinks=True):
|
||||
if getattr(sys, 'frozen', False):
|
||||
path = os.path.abspath(sys.executable)
|
||||
else:
|
||||
path = inspect.getabsfile(get_script_dir)
|
||||
|
||||
if follow_symlinks:
|
||||
path = os.path.realpath(path)
|
||||
|
||||
return os.path.dirname(path)
|
24
common/struct_ops.py
Normal file
24
common/struct_ops.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
# https://github.com/skochinsky/me-tools/blob/master/me_unpack.py by Igor Skochinsky
|
||||
|
||||
import ctypes
|
||||
|
||||
char = ctypes.c_char
|
||||
uint8_t = ctypes.c_ubyte
|
||||
uint16_t = ctypes.c_ushort
|
||||
uint32_t = ctypes.c_uint
|
||||
uint64_t = ctypes.c_uint64
|
||||
|
||||
def get_struct(buffer, start_offset, class_name, param_list=None):
|
||||
if param_list is None: param_list = []
|
||||
|
||||
structure = class_name(*param_list) # Unpack parameter list
|
||||
struct_len = ctypes.sizeof(structure)
|
||||
struct_data = buffer[start_offset:start_offset + struct_len]
|
||||
fit_len = min(len(struct_data), struct_len)
|
||||
|
||||
ctypes.memmove(ctypes.addressof(structure), struct_data, fit_len)
|
||||
|
||||
return structure
|
79
common/system.py
Normal file
79
common/system.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
import sys
|
||||
import ctypes
|
||||
import traceback
|
||||
|
||||
# Get Python Version (tuple)
|
||||
def get_py_ver():
|
||||
return sys.version_info
|
||||
|
||||
# Get OS Platform (string)
|
||||
def get_os_ver():
|
||||
sys_os = sys.platform
|
||||
|
||||
is_win = sys_os == 'win32'
|
||||
is_lnx = sys_os.startswith('linux') or sys_os == 'darwin' or sys_os.find('bsd') != -1
|
||||
|
||||
return sys_os, is_win, is_win or is_lnx
|
||||
|
||||
# Check for --auto-exit|-e
|
||||
def is_auto_exit():
|
||||
return '--auto-exit' in sys.argv or '-e' in sys.argv
|
||||
|
||||
# Check Python Version
|
||||
def check_sys_py():
|
||||
sys_py = get_py_ver()
|
||||
|
||||
if sys_py < (3,7):
|
||||
sys.stdout.write('\nError: Python >= 3.7 required, not %d.%d!' % (sys_py[0], sys_py[1]))
|
||||
|
||||
if not is_auto_exit():
|
||||
# noinspection PyUnresolvedReferences
|
||||
(raw_input if sys_py[0] <= 2 else input)('\nPress enter to exit') # pylint: disable=E0602
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
# Check OS Platform
|
||||
def check_sys_os():
|
||||
os_tag,os_win,os_sup = get_os_ver()
|
||||
|
||||
if not os_sup:
|
||||
print('\nError: Unsupported platform "%s"!' % os_tag)
|
||||
|
||||
if not is_auto_exit():
|
||||
input('\nPress enter to exit')
|
||||
|
||||
sys.exit(2)
|
||||
|
||||
# Fix Windows Unicode console redirection
|
||||
if os_win: sys.stdout.reconfigure(encoding='utf-8')
|
||||
|
||||
# Show Script Title
|
||||
def show_title(title):
|
||||
print('\n' + title)
|
||||
|
||||
_,os_win,_ = get_os_ver()
|
||||
|
||||
# Set console/shell window title
|
||||
if os_win: ctypes.windll.kernel32.SetConsoleTitleW(title)
|
||||
else: sys.stdout.write('\x1b]2;' + title + '\x07')
|
||||
|
||||
# https://stackoverflow.com/a/781074 by Torsten Marek
|
||||
def nice_exc_handler(exc_type, exc_value, tb):
|
||||
if exc_type is KeyboardInterrupt:
|
||||
print('\n')
|
||||
else:
|
||||
print('\nError: 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(3)
|
||||
|
||||
# Print or Input Message based on --auto-exit|-e
|
||||
def print_input(msg):
|
||||
(print if is_auto_exit() else input)(msg)
|
6
common/text_ops.py
Normal file
6
common/text_ops.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
# Generate padding (spaces or tabs)
|
||||
def padder(count, tab=False):
|
||||
return ('\t' if tab else ' ') * count
|
Loading…
Add table
Add a link
Reference in a new issue