From 8c552cf998c5cdf9b21ac63eeb5e59df54cee5a4 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 29 Dec 2021 15:50:45 -0300 Subject: [PATCH] Add ICL/Fujitsu analyzer --- README.md | 3 ++- biostools/__main__.py | 1 + biostools/analyzers.py | 41 +++++++++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6fe1072..75b0cc0 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,9 @@ python3 -m biostools -a roms/0 | tee bioslist.csv * EPA (Award) and PCX (AMI) images are automatically converted to PNG if the aforementioned optional dependency is installed. * Some Intel motherboard BIOSes (particularly from the AMIBIOS 6 era) will not be extracted properly due to a different address line inversion mechanism. This is a known issue with the Intel update format concatenator which may eventually be solved. * Extraction of the following BIOS distribution formats is **not implemented** due to the use of unknown compression methods: - * Evergreen ETI (an ugly hack exists) + * Evergreen `.ETI` (an ugly hack exists) * IBM Sydex floppy self-extractor (it looks like CopyQM RLE but isn't) + * ICL `.LDB` ## Analysis notes diff --git a/biostools/__main__.py b/biostools/__main__.py index 644cdad..ae30964 100644 --- a/biostools/__main__.py +++ b/biostools/__main__.py @@ -469,6 +469,7 @@ def analyze_process(queue, formatter, scan_base): analyzers.DTKGoldStarAnalyzer(), analyzers.GeneralSoftwareAnalyzer(), analyzers.IBMAnalyzer(), + analyzers.ICLAnalyzer(), analyzers.InsydeAnalyzer(), analyzers.IntelUEFIAnalyzer(), analyzers.JukoAnalyzer(), diff --git a/biostools/analyzers.py b/biostools/analyzers.py index 38b9eb7..fde7e9c 100644 --- a/biostools/analyzers.py +++ b/biostools/analyzers.py @@ -724,7 +724,7 @@ class AMIUEFIAnalyzer(Analyzer): super().__init__('AMI', *args, **kwargs) self.vendor_id = 'AMIUEFI' - self._identifier_regex = re.compile(b'''Version %x\.%02x\.%04x\.|ALASKAA M I''') + self._identifier_pattern = re.compile(b'''Version %x\.%02x\.%04x\.|ALASKAA M I''') self.register_check_list([ (self._string_csm, RegexChecker), @@ -747,7 +747,7 @@ class AMIUEFIAnalyzer(Analyzer): return False # Check for version format string or "ALASKA" ACPI table identifier. - if not self._identifier_regex.search(file_data): + if not self._identifier_pattern.search(file_data): return False self.version = 'UEFI' @@ -1352,11 +1352,40 @@ class IBMAnalyzer(Analyzer): return False +class ICLAnalyzer(Analyzer): + def __init__(self, *args, **kwargs): + super().__init__('ICL', *args, **kwargs) + + self._version_pattern = re.compile(b'''(?:ROM|System) BIOS (#[\\x20-\\x7E]+) Version ([\\x20-\\x7E]+)\\x0D\\x0A\\(c\\) Copyright [\\x20-\\x7E]+(?:\\x0D\\x0A\\x0A\\x00([\\x20-\\x7E]+))?''') + + def can_handle(self, file_data, header_data): + # Update files use unknown compression. + if file_data[:8] == b'OKICL1\x01\x00': + self.version = '?' + return True + + # Determine location of the identification block. + match = self._version_pattern.search(file_data) + if not match: + return False + + # Extract version. + self.version = match.group(2).decode('cp437', 'ignore') + + # Extract identifier as a string. + self.string = match.group(1).decode('cp437', 'ignore') + + # Extract sign-on if present. + self.signon = (match.group(3) or b'').decode('cp437', 'ignore') + + return True + + class InsydeAnalyzer(Analyzer): def __init__(self, *args, **kwargs): super().__init__('Insyde', *args, **kwargs) - self._identifier_regex = re.compile(b'''InsydeH2O Version ''') + self._version_pattern = re.compile(b'''InsydeH2O Version ''') def can_handle(self, file_data, header_data): # Only handle files sent through UEFIExtractor. @@ -1364,7 +1393,7 @@ class InsydeAnalyzer(Analyzer): return False # Check for InsydeH2O version string. - if not self._identifier_regex.search(file_data): + if not self._version_pattern.search(file_data): return False self.version = '?' @@ -1377,7 +1406,7 @@ class IntelUEFIAnalyzer(Analyzer): super().__init__('Intel', *args, **kwargs) self.vendor_id = 'IntelUEFI' - self._identifier_regex = re.compile(b'''\$(?:IBIOSI\$|FID)[0-9A-Z]{8}\.''') + self._identifier_pattern = re.compile(b'''\$(?:IBIOSI\$|FID)[0-9A-Z]{8}\.''') self.register_check_list([ (self._signon, RegexChecker), @@ -1389,7 +1418,7 @@ class IntelUEFIAnalyzer(Analyzer): return False # Check for any Intel version code identifiers. - if not self._identifier_regex.search(file_data): + if not self._identifier_pattern.search(file_data): return False self.version = 'UEFI'