1
0
Fork 0
mirror of https://github.com/platomav/BIOSUtilities.git synced 2025-05-23 19:47:05 -04:00

Apple EFI Package Grabber v2.0

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.
This commit is contained in:
platomav 2022-03-28 00:58:07 +03:00
parent 0f05e9b0be
commit 2029ffc8b7
4 changed files with 139 additions and 77 deletions
Apple EFI Package Grabber
Apple EFI Sucatalog Link Grabber
README.md

View file

@ -0,0 +1,4 @@
2021-01-01 00:00:00

View file

@ -0,0 +1,129 @@
#!/usr/bin/env python3
#coding=utf-8
"""
Apple EFI Grab
Apple EFI Package Grabber
Copyright (C) 2018-2021 Plato Mavropoulos
"""
title = 'Apple EFI Package Grabber v2.0'
print('\n' + title)
import sys
sys_ver = sys.version_info
if sys_ver < (3,7):
sys.stdout.write('\n\nError: Python >= 3.7 required, not %d.%d!\n' % (sys_ver[0], sys_ver[1]))
(raw_input if sys_ver[0] <= 2 else input)('\nPress enter to exit') # pylint: disable=E0602
sys.exit(1)
import traceback
def show_exception_and_exit(exc_type, exc_value, tb):
if exc_type is KeyboardInterrupt:
print('\nNote: Keyboard Interrupt!')
else:
print('\nError: %s crashed, please report the following:\n' % title)
traceback.print_exception(exc_type, exc_value, tb)
input('\nPress enter to exit')
sys.exit(1)
sys.excepthook = show_exception_and_exit
import datetime
import urllib.request
from multiprocessing.pool import ThreadPool
def fetch_cat_info(name):
url = cat_url[:-len('others/')] + name if name in ['index.sucatalog','index-1.sucatalog'] else cat_url + name
with urllib.request.urlopen(urllib.request.Request(url, method='HEAD')) as head : mod = head.headers['last-modified']
return name, url, mod
def fetch_cat_links(cat_file):
cat_links = []
with urllib.request.urlopen(cat_file[1]) as link: fdata = link.readlines()
cat_lines = [l.decode('utf-8').strip('\n') for l in fdata]
for line in cat_lines:
if ('.pkg' in line or '.tar' in line) and ('FirmwareUpd' in line or '/BridgeOSUpdateCustomer' in line or 'EFIUpd' in line) \
and 'Bluetooth' not in line and 'DPVGA' not in line and 'Thunderbolt' not in line and 'PMG5' not in line and 'HardDrive' not in line:
down_link = line[line.find('http'):(line.find('.pkg') if '.pkg' in line else line.find('.tar')) + 4]
down_link = down_link.replace('http:','https:')
cat_links.append(down_link)
return cat_links
dat_db = 'Apple_EFI_Grab.dat'
cat_url = 'https://swscan.apple.com/content/catalogs/others/'
apple_cat = []
down_links = []
svr_date = None
thread_num = 2
with open(dat_db, 'r', encoding='utf-8') as dat: db_lines = dat.readlines()
db_lines = [line.strip('\n') for line in db_lines]
db_date = datetime.datetime.strptime(db_lines[0], '%Y-%m-%d %H:%M:%S')
db_links = set([line for line in db_lines if line.startswith('https')])
db_sucat = [line for line in db_lines if line.startswith('index')]
print('\nGetting Catalog Listing...')
if not db_sucat:
input('\nError: Failed to retrieve Catalogs from DB!\n\nDone!')
sys.exit(1)
apple_mod = ThreadPool(thread_num).imap_unordered(fetch_cat_info, db_sucat)
for name, url, mod in apple_mod:
dt = datetime.datetime.strptime(mod, '%a, %d %b %Y %H:%M:%S %Z')
if not svr_date or dt > svr_date : svr_date = dt
apple_cat.append((name, url, dt))
if not svr_date:
input('\nError: Failed to retrieve Current Catalog Datetime!\n\nDone!')
sys.exit(1)
print('\n Previous Catalog Datetime :', db_date)
print(' Current Catalog Datetime :', svr_date)
if svr_date <= db_date:
input('\nNothing new since %s!\n\nDone!' % db_date)
sys.exit()
print('\nGetting Catalog Links...')
down_links = ThreadPool(thread_num).imap_unordered(fetch_cat_links, apple_cat)
down_links = [item for sublist in down_links for item in sublist]
if not down_links:
input('\nError: Failed to retrieve Catalog Links!\n\nDone!')
sys.exit(1)
new_links = sorted(list(dict.fromkeys([link for link in down_links if link not in db_links])))
if new_links:
print('\nFound %d new link(s) between %s and %s!' % (len(new_links), db_date, svr_date))
cur_date = datetime.datetime.utcnow().isoformat(timespec='seconds').replace('-','').replace('T','').replace(':','') # Local UTC Unix
with open('Apple_%s.txt' % cur_date, 'w', encoding='utf-8') as lout: lout.write('\n'.join(map(str, new_links)))
else:
print('\nThere are no new links between %s and %s!' % (db_date, svr_date))
new_db_sucat = '\n'.join(map(str, db_sucat))
new_db_links = '\n'.join(map(str, sorted(list(dict.fromkeys(down_links)))))
new_db_lines = '%s\n\n%s\n\n%s' % (svr_date, new_db_sucat, new_db_links)
with open(dat_db, 'w', encoding='utf-8') as dbout: dbout.write(new_db_lines)
input('\nDone!')

View file

@ -1,71 +0,0 @@
#!/usr/bin/env python3
"""
Apple EFI Links
Apple EFI Sucatalog Link Grabber
Copyright (C) 2018-2019 Plato Mavropoulos
"""
print('Apple EFI Sucatalog Link Grabber v1.2\n')
import os
import sys
import datetime
# Remove previous output files
if os.path.isfile('OUT.txt') : os.remove('OUT.txt')
# Get input catalog file paths
if len(sys.argv) >= 2 :
# Drag & Drop or CLI
catalogs = sys.argv[1:]
else :
# Working directory
catalogs = []
for root, dirs, files in os.walk(os.getcwd()) :
for name in files :
if name.endswith('.sucatalog') :
catalogs.append(os.path.join(root, name))
print('Working...')
# Parse each input xml file
for input_file in catalogs :
input_name,input_extension = os.path.splitext(os.path.basename(input_file))
print('\n%s%s' % (input_name, input_extension))
with open(input_file, 'r') as in_file :
for line in in_file :
# Find EFI Firmware package links
if ('.pkg' in line or '.tar' in line) and ('FirmwareUpd' in line or '/BridgeOSUpdateCustomer' in line or 'EFIUpd' in line) \
and 'Bluetooth' not in line and 'DPVGA' not in line and 'Thunderbolt' not in line and 'PMG5' not in line and 'HardDrive' not in line :
if '.pkg' in line : link = line[line.find('http'):line.find('.pkg') + 4] # Remove xml formatting
else : link = line[line.find('http'):line.find('.tar') + 4]
with open('OUT.txt', 'a') as out_file : out_file.write(link + '\n') # Store links in temporary output file
# Parse temporary output file
if os.path.isfile('OUT.txt') :
with open('OUT.txt', 'r+') as out_file :
parsed_lines = []
final_lines = []
for line in out_file :
if line not in parsed_lines : # Remove duplicate links
final_lines.append(line)
parsed_lines.append(line)
final_lines = ''.join(map(str, sorted(final_lines)))
current_datetime = datetime.datetime.utcnow().isoformat(timespec='seconds').replace('-','').replace('T','').replace(':','')
output_file = 'EFI %s.txt' % current_datetime
with open(output_file, 'w') as efi_file : efi_file.write(final_lines) # Save final output file
print('\nStored %s!' % output_file)
os.remove('OUT.txt') # Remove temporary output file
input('\nDone!')

View file

@ -16,7 +16,7 @@
* [**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 Sucatalog Link Grabber**](#apple-efi-sucatalog-link-grabber)
* [**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)
@ -384,17 +384,17 @@ Some Anti-Virus software may claim that the built/frozen/compiled executable con
![](https://i.imgur.com/EhCzMLk.png)
## **Apple EFI Sucatalog Link Grabber**
## **Apple EFI Package Grabber**
![](https://i.imgur.com/zTVFs4I.png)
![](https://i.imgur.com/BaHrjGi.png)
#### **Description**
Parses Apple Software Update CatalogURL .sucatalog files and saves all 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.
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**
You can either Drag & Drop or let it automatically parse any .sucatalog files within its working directory.
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**
@ -422,7 +422,7 @@ PyInstaller can build/freeze/compile the utility at all three supported platform
3. Build/Freeze/Compile:
> pyinstaller --noupx --onefile Apple_EFI_Links.py
> pyinstaller --noupx --onefile Apple_EFI_Grab.py
At dist folder you should find the final utility executable