mirror of
https://github.com/platomav/BIOSUtilities.git
synced 2025-05-13 06:34:42 -04:00
Added Insyde iFlash Update Extractor v2.0_a2
Added Toshiba BIOS COM Extractor v2.0_a2
This commit is contained in:
parent
be90f364d2
commit
cd2704f743
7 changed files with 359 additions and 10 deletions
|
@ -7,7 +7,7 @@ Fujitsu UPC BIOS Extractor
|
|||
Copyright (C) 2021-2022 Plato Mavropoulos
|
||||
"""
|
||||
|
||||
TITLE = 'Fujitsu UPC BIOS Extractor v2.0_a2'
|
||||
TITLE = 'Fujitsu UPC BIOS Extractor v2.0_a3'
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -17,18 +17,18 @@ sys.dont_write_bytecode = True
|
|||
|
||||
from common.comp_efi import efi_decompress, is_efi_compressed
|
||||
from common.path_ops import make_dirs, path_suffixes
|
||||
from common.system import script_init, argparse_init, printer
|
||||
from common.system import argparse_init, printer, script_init
|
||||
from common.text_ops import file_to_bytes
|
||||
|
||||
# Check if input is Fujitsu UPC image
|
||||
def is_fujitsu_upc(in_file):
|
||||
in_buffer = file_to_bytes(in_file)
|
||||
|
||||
is_upc = path_suffixes(in_file)[-1].upper() == '.UPC' if os.path.isfile(in_file) else True
|
||||
is_ext = path_suffixes(in_file)[-1].upper() == '.UPC' if os.path.isfile(in_file) else True
|
||||
|
||||
is_efi = is_efi_compressed(in_buffer)
|
||||
|
||||
return is_upc and is_efi
|
||||
return is_ext and is_efi
|
||||
|
||||
# Parse & Extract Fujitsu UPC image
|
||||
def fujitsu_upc_extract(input_file, output_path, padding=0):
|
||||
|
|
148
Insyde_iFlash_Extract.py
Normal file
148
Insyde_iFlash_Extract.py
Normal file
|
@ -0,0 +1,148 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
"""
|
||||
Insyde iFlash Extract
|
||||
Insyde iFlash Update Extractor
|
||||
Copyright (C) 2022 Plato Mavropoulos
|
||||
"""
|
||||
|
||||
TITLE = 'Insyde iFlash Update Extractor v2.0_a2'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import ctypes
|
||||
|
||||
# Stop __pycache__ generation
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
from common.path_ops import make_dirs, safe_name
|
||||
from common.patterns import PAT_INSYDE_IFL
|
||||
from common.struct_ops import get_struct, char, uint32_t
|
||||
from common.system import script_init, argparse_init, printer
|
||||
from common.text_ops import file_to_bytes
|
||||
|
||||
class IflashHeader(ctypes.LittleEndianStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [
|
||||
('Signature', char*9), # 0x00 $_IFLASH_
|
||||
('ImageTag', char*7), # 0x08
|
||||
('TotalSize', uint32_t), # 0x10 from header end
|
||||
('ImageSize', uint32_t), # 0x14 from header end
|
||||
# 0x18
|
||||
]
|
||||
|
||||
def struct_print(self, p):
|
||||
printer(['Signature :', self.Signature.decode('utf-8','ignore')], p, False)
|
||||
printer(['Image Name:', self.ImageTag.decode('utf-8','ignore')], p, False)
|
||||
printer(['Image Size:', f'0x{self.ImageSize:X}'], p, False)
|
||||
printer(['Total Size:', f'0x{self.TotalSize:X}'], p, False)
|
||||
|
||||
# Parse & Extract Insyde iFlash Update image
|
||||
def insyde_iflash_extract(input_buffer, ins_ifl_all, output_path, padding=0):
|
||||
extract_path = os.path.join(f'{output_path}_extracted')
|
||||
|
||||
make_dirs(extract_path, delete=True)
|
||||
|
||||
for ins_ifl_val in ins_ifl_all:
|
||||
ins_ifl_off,ins_ifl_hdr = ins_ifl_val
|
||||
|
||||
mod_bgn = ins_ifl_off + IFL_HDR_LEN
|
||||
mod_end = mod_bgn + ins_ifl_hdr.ImageSize
|
||||
mod_bin = input_buffer[mod_bgn:mod_end]
|
||||
|
||||
mod_val = [ins_ifl_hdr.ImageTag.decode('utf-8','ignore'), 'bin']
|
||||
mod_tag,mod_ext = IFL_MOD_NAMES.get(mod_val[0], mod_val)
|
||||
|
||||
mod_name = f'{mod_tag} [0x{mod_bgn:08X}-0x{mod_end:08X}]'
|
||||
|
||||
printer(f'{mod_name}\n', padding)
|
||||
|
||||
ins_ifl_hdr.struct_print(padding + 4)
|
||||
|
||||
if mod_val == [mod_tag,mod_ext]:
|
||||
printer(f'Note: Detected new Insyde iFlash image tag {mod_tag}!', padding + 8, pause=True)
|
||||
|
||||
out_name = f'{mod_name}.{mod_ext}'
|
||||
|
||||
out_path = os.path.join(extract_path, safe_name(out_name))
|
||||
|
||||
with open(out_path, 'wb') as out: out.write(mod_bin)
|
||||
|
||||
printer('Succesfull Insyde iFlash image extraction!', padding + 8)
|
||||
|
||||
# Get Insyde iFlash Update image matches
|
||||
def get_insyde_iflash(in_file):
|
||||
ins_ifl_all = []
|
||||
ins_ifl_nan = [0x0,0xFFFFFFFF]
|
||||
|
||||
buffer = file_to_bytes(in_file)
|
||||
|
||||
for ins_ifl_match in PAT_INSYDE_IFL.finditer(buffer):
|
||||
ins_ifl_off = ins_ifl_match.start()
|
||||
|
||||
if len(buffer[ins_ifl_off:]) <= IFL_HDR_LEN:
|
||||
continue
|
||||
|
||||
ins_ifl_hdr = get_struct(buffer, ins_ifl_off, IflashHeader)
|
||||
|
||||
if ins_ifl_hdr.TotalSize in ins_ifl_nan \
|
||||
or ins_ifl_hdr.ImageSize in ins_ifl_nan \
|
||||
or ins_ifl_hdr.TotalSize <= ins_ifl_hdr.ImageSize:
|
||||
continue
|
||||
|
||||
ins_ifl_all.append([ins_ifl_off, ins_ifl_hdr])
|
||||
|
||||
return ins_ifl_all
|
||||
|
||||
# Check if input is Insyde iFlash Update image
|
||||
def is_insyde_iflash(in_file):
|
||||
buffer = file_to_bytes(in_file)
|
||||
|
||||
return bool(get_insyde_iflash(buffer))
|
||||
|
||||
IFL_MOD_NAMES = {
|
||||
'DRV_IMG' : ['isflash', 'efi'],
|
||||
'INI_IMG' : ['platform', 'ini'],
|
||||
'BIOSIMG' : ['BIOS-UEFI', 'bin'],
|
||||
'ME_IMG_' : ['Management Engine', 'bin'],
|
||||
'EC_IMG_' : ['Embedded Controller', 'bin'],
|
||||
'OEM_ID_' : ['OEM Identifier', 'bin'],
|
||||
'BIOSCER' : ['Certificate', 'bin'],
|
||||
'BIOSCR2' : ['Certificate 2nd', 'bin'],
|
||||
}
|
||||
|
||||
# Get common ctypes Structure Sizes
|
||||
IFL_HDR_LEN = ctypes.sizeof(IflashHeader)
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Set argparse Arguments
|
||||
argparser = argparse_init()
|
||||
arguments = argparser.parse_args()
|
||||
|
||||
# Initialize script (must be after argparse)
|
||||
exit_code,input_files,output_path,padding = script_init(TITLE, arguments, 4)
|
||||
|
||||
for input_file in input_files:
|
||||
input_name = os.path.basename(input_file)
|
||||
|
||||
printer(['***', input_name], padding - 4)
|
||||
|
||||
with open(input_file, 'rb') as in_file: input_buffer = in_file.read()
|
||||
|
||||
ins_ifl_all = get_insyde_iflash(input_buffer)
|
||||
|
||||
if not ins_ifl_all:
|
||||
printer('Error: This is not an Insyde iFlash Update image!', padding)
|
||||
|
||||
continue # Next input file
|
||||
|
||||
extract_path = os.path.join(output_path, input_name)
|
||||
|
||||
insyde_iflash_extract(input_buffer, ins_ifl_all, extract_path, padding)
|
||||
|
||||
exit_code -= 1
|
||||
|
||||
printer('Done!', pause=True)
|
||||
|
||||
sys.exit(exit_code)
|
116
README.md
116
README.md
|
@ -8,9 +8,11 @@
|
|||
* [**Award BIOS Module Extractor**](#award-bios-module-extractor)
|
||||
* [**Dell PFS Update Extractor**](#dell-pfs-update-extractor)
|
||||
* [**Fujitsu UPC BIOS Extractor**](#fujitsu-upc-bios-extractor)
|
||||
* [**Insyde iFlash Update Extractor**](#insyde-iflash-update-extractor)
|
||||
* [**Panasonic BIOS Package Extractor**](#panasonic-bios-package-extractor)
|
||||
* [**Phoenix TDK Packer Extractor**](#phoenix-tdk-packer-extractor)
|
||||
* [**Portwell EFI Update Extractor**](#portwell-efi-update-extractor)
|
||||
* [**Toshiba BIOS COM Extractor**](#toshiba-bios-com-extractor)
|
||||
* [**VAIO Packaging Manager Extractor**](#vaio-packaging-manager-extractor)
|
||||
|
||||
## **AMI BIOS Guard Extractor**
|
||||
|
@ -263,11 +265,11 @@ Some Anti-Virus software may claim that the built/frozen/compiled executable con
|
|||
|
||||
#### **Description**
|
||||
|
||||
Parses Fujitsu UPC images and extracts their EFI compressed SPI/BIOS/UEFI firmware component. The output comprises only a final firmware component which is directly usable by end users.
|
||||
Parses Fujitsu UPC BIOS images and extracts their EFI compressed SPI/BIOS/UEFI 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 Panasonic BIOS Package executable file(s). Optional arguments:
|
||||
You can either Drag & Drop or manually enter Fujitsu UPC BIOS image file(s). Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -v or --version : show utility name and version
|
||||
|
@ -315,6 +317,58 @@ Some Anti-Virus software may claim that the built/frozen/compiled executable con
|
|||
|
||||
![]()
|
||||
|
||||
## **Insyde iFlash Update Extractor**
|
||||
|
||||
![]()
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Insyde iFlash Update images and extracts their firmware (e.g. SPI, BIOS/UEFI, EC, ME etc) and utilities (e.g. Flasher, Configuration etc) components. The output comprises only final firmware components which are directly usable by end users.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter Insyde iFlash Update image file(s). Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -v or --version : show utility name and version
|
||||
* -i or --input-dir : extract from given input directory
|
||||
* -o or --output-dir : extract in given output directory
|
||||
* -e or --auto-exit : skip press enter to exit prompts
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.8 support.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the utility, you do not need any prerequisites.
|
||||
|
||||
#### **Build/Freeze/Compile with PyInstaller**
|
||||
|
||||
PyInstaller can build/freeze/compile the utility at all three supported platforms, it is simple to run and gets updated often.
|
||||
|
||||
1. Make sure Python 3.8.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --noupx --onefile \<path-to-project\>\/Insyde_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**
|
||||
|
||||
![]()
|
||||
|
||||
## **Panasonic BIOS Package Extractor**
|
||||
|
||||
![]()
|
||||
|
@ -508,6 +562,64 @@ Some Anti-Virus software may claim that the built/frozen/compiled executable con
|
|||
|
||||
![]()
|
||||
|
||||
## **Toshiba BIOS COM Extractor**
|
||||
|
||||
![]()
|
||||
|
||||
#### **Description**
|
||||
|
||||
Parses Toshiba BIOS COM images and extracts their raw or compressed SPI/BIOS/UEFI firmware component. This utility is basically an easy to use python wrapper around [ToshibaComExtractor by LongSoft](https://github.com/LongSoft/ToshibaComExtractor). The output comprises only a final firmware component which is directly usable by end users.
|
||||
|
||||
#### **Usage**
|
||||
|
||||
You can either Drag & Drop or manually enter Toshiba BIOS COM image file(s). Optional arguments:
|
||||
|
||||
* -h or --help : show help message and exit
|
||||
* -v or --version : show utility name and version
|
||||
* -i or --input-dir : extract from given input directory
|
||||
* -o or --output-dir : extract in given output directory
|
||||
* -e or --auto-exit : skip press enter to exit prompts
|
||||
|
||||
#### **Compatibility**
|
||||
|
||||
Should work at all Windows, Linux or macOS operating systems which have Python 3.8 support.
|
||||
|
||||
#### **Prerequisites**
|
||||
|
||||
To run the utility, you must have the following 3rd party tool at the "external" project directory:
|
||||
|
||||
* [ToshibaComExtractor](https://github.com/LongSoft/ToshibaComExtractor) (e.g. comextract.exe for Windows or comextract for Linux)
|
||||
|
||||
#### **Build/Freeze/Compile with PyInstaller**
|
||||
|
||||
PyInstaller can build/freeze/compile the utility at all three supported platforms, it is simple to run and gets updated often.
|
||||
|
||||
1. Make sure Python 3.8.0 or newer is installed:
|
||||
|
||||
> python --version
|
||||
|
||||
2. Use pip to install PyInstaller:
|
||||
|
||||
> pip3 install pyinstaller
|
||||
|
||||
3. Place prerequisite at the "external" project directory:
|
||||
|
||||
> ToshibaComExtractor
|
||||
|
||||
4. Build/Freeze/Compile:
|
||||
|
||||
> pyinstaller --add-data="external/*;external/" --noupx --onefile \<path-to-project\>\/Toshiba_COM_Extract.py
|
||||
|
||||
You should find the final utility executable at "dist" folder
|
||||
|
||||
#### **Anti-Virus False Positives**
|
||||
|
||||
Some Anti-Virus software may claim that the built/frozen/compiled executable contains viruses. Any such detections are false positives, usually of PyInstaller. You can switch to a better Anti-Virus software, report the false positive to their support, add the executable to the exclusions, build/freeze/compile yourself or use the Python script directly.
|
||||
|
||||
#### **Pictures**
|
||||
|
||||
![]()
|
||||
|
||||
## **VAIO Packaging Manager Extractor**
|
||||
|
||||
![]()
|
||||
|
|
89
Toshiba_COM_Extract.py
Normal file
89
Toshiba_COM_Extract.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python3
|
||||
#coding=utf-8
|
||||
|
||||
"""
|
||||
Toshiba COM Extract
|
||||
Toshiba BIOS COM Extractor
|
||||
Copyright (C) 2018-2022 Plato Mavropoulos
|
||||
"""
|
||||
|
||||
TITLE = 'Toshiba BIOS COM Extractor v2.0_a2'
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
# Stop __pycache__ generation
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
from common.path_ops import make_dirs, path_stem, path_suffixes, project_root, safe_path
|
||||
from common.patterns import PAT_TOSHIBA_COM
|
||||
from common.system import argparse_init, get_os_ver, printer, script_init
|
||||
from common.text_ops import file_to_bytes
|
||||
|
||||
# Check if input is Toshiba BIOS COM image
|
||||
def is_toshiba_com(in_file):
|
||||
buffer = file_to_bytes(in_file)
|
||||
|
||||
is_ext = path_suffixes(in_file)[-1].upper() == '.COM' if os.path.isfile(in_file) else True
|
||||
|
||||
is_com = PAT_TOSHIBA_COM.search(buffer)
|
||||
|
||||
return is_ext and is_com
|
||||
|
||||
# Get ToshibaComExtractor path
|
||||
def get_comextract_path():
|
||||
exec_name = 'comextract.exe' if get_os_ver()[1] else 'comextract'
|
||||
|
||||
return safe_path(project_root(), ['external',exec_name])
|
||||
|
||||
# Parse & Extract Toshiba BIOS COM image
|
||||
def toshiba_com_extract(input_file, output_path, padding=0):
|
||||
extract_path = os.path.join(f'{output_path}_extracted')
|
||||
|
||||
make_dirs(extract_path, delete=True)
|
||||
|
||||
output_name = path_stem(input_file)
|
||||
output_file = os.path.join(extract_path, f'{output_name}.bin')
|
||||
|
||||
try:
|
||||
subprocess.run([get_comextract_path(), input_file, output_file], check=True, stdout=subprocess.DEVNULL)
|
||||
|
||||
if not os.path.isfile(output_file): raise Exception('EXTRACT_FILE_MISSING')
|
||||
except:
|
||||
printer(f'Error: ToshibaComExtractor could not extract file {input_file}!', padding)
|
||||
|
||||
return 1
|
||||
|
||||
printer(f'Succesfull {output_name} extraction via ToshibaComExtractor!', padding)
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Set argparse Arguments
|
||||
argparser = argparse_init()
|
||||
arguments = argparser.parse_args()
|
||||
|
||||
# Initialize script (must be after argparse)
|
||||
exit_code,input_files,output_path,padding = script_init(TITLE, arguments, 4)
|
||||
|
||||
for input_file in input_files:
|
||||
input_name = os.path.basename(input_file)
|
||||
|
||||
printer(['***', input_name], padding - 4)
|
||||
|
||||
with open(input_file, 'rb') as in_file: input_buffer = in_file.read()
|
||||
|
||||
if not is_toshiba_com(input_file):
|
||||
printer('Error: This is not a Toshiba BIOS COM image!', padding)
|
||||
|
||||
continue # Next input file
|
||||
|
||||
extract_path = os.path.join(output_path, input_name)
|
||||
|
||||
if toshiba_com_extract(input_file, extract_path, padding) == 0:
|
||||
exit_code -= 1
|
||||
|
||||
printer('Done!', pause=True)
|
||||
|
||||
sys.exit(exit_code)
|
|
@ -9,8 +9,7 @@ import os
|
|||
import subprocess
|
||||
|
||||
from common.path_ops import project_root, safe_path
|
||||
from common.system import get_os_ver
|
||||
from common.system import printer
|
||||
from common.system import get_os_ver, printer
|
||||
|
||||
def get_compress_sizes(data):
|
||||
size_compress = int.from_bytes(data[0x0:0x4], 'little')
|
||||
|
|
|
@ -9,8 +9,7 @@ import os
|
|||
import subprocess
|
||||
|
||||
from common.path_ops import project_root, safe_path
|
||||
from common.system import get_os_ver
|
||||
from common.system import printer
|
||||
from common.system import get_os_ver, printer
|
||||
|
||||
# Get 7-Zip path
|
||||
def get_szip_path():
|
||||
|
|
|
@ -13,12 +13,14 @@ PAT_AWARD_LZH = re.compile(br'-lh[04567]-')
|
|||
PAT_DELL_FTR = re.compile(br'\xEE\xAA\xEE\x8F\x49\x1B\xE8\xAE\x14\x37\x90')
|
||||
PAT_DELL_HDR = re.compile(br'\xEE\xAA\x76\x1B\xEC\xBB\x20\xF1\xE6\x51.\x78\x9C', re.DOTALL)
|
||||
PAT_DELL_PKG = re.compile(br'\x72\x13\x55\x00.{45}7zXZ', re.DOTALL)
|
||||
PAT_INSYDE_IFL = re.compile(br'\$_IFLASH_')
|
||||
PAT_INTEL_ENG = re.compile(br'\x04\x00{3}[\xA1\xE1]\x00{3}.{8}\x86\x80.{9}\x00\$((MN2)|(MAN))', re.DOTALL)
|
||||
PAT_MICROSOFT_CAB = re.compile(br'MSCF\x00{4}')
|
||||
PAT_MICROSOFT_MZ = re.compile(br'MZ')
|
||||
PAT_MICROSOFT_PE = re.compile(br'PE\x00{2}')
|
||||
PAT_PHOENIX_TDK = re.compile(br'\$PACK\x00{3}..\x00{2}.\x00{3}', re.DOTALL)
|
||||
PAT_PORTWELL_EFI = re.compile(br'<U{2}>')
|
||||
PAT_TOSHIBA_COM = re.compile(br'\x00{2}[\x00-\x02]BIOS.{20}[\x00\x01]', re.DOTALL)
|
||||
PAT_VAIO_CAB = re.compile(br'\xB2\xAC\xBC\xB9\xFF{4}.{4}\xFF{4}.{4}\xFF{4}\xFC\xFE', re.DOTALL)
|
||||
PAT_VAIO_CFG = re.compile(br'\[Setting]\x0D\x0A')
|
||||
PAT_VAIO_CHK = re.compile(br'\x0AUseVAIOCheck=')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue