Added Insyde iFlash Update Extractor v2.0_a2

Added Toshiba BIOS COM Extractor v2.0_a2
This commit is contained in:
platomav 2022-06-30 01:20:21 +03:00
parent be90f364d2
commit cd2704f743
7 changed files with 359 additions and 10 deletions

View file

@ -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
View 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
View file

@ -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
View 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)

View file

@ -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')

View file

@ -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():

View file

@ -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=')