Added AMI PFAT RSA 3K signed blocks support

Added AMI PFAT nested detection at each file

Added Award BIOS payload naming at each file

Switched Panasonic BIOS LZNT1 external library

Improved Panasonic LZNT1 detection and length

Improved Dell PFS code structure and fixed bugs

Improved code exception handling (raise, catch)

Improved code definitions (PEP8, docs, types)

Fixed some arguments missing from help screens
This commit is contained in:
Plato Mavropoulos 2024-04-24 01:22:53 +03:00
parent 03ae0cf070
commit d85a7f82dc
37 changed files with 2897 additions and 2174 deletions

View file

@ -1,154 +1,213 @@
#!/usr/bin/env python3
#coding=utf-8
#!/usr/bin/env python3 -B
# coding=utf-8
"""
Copyright (C) 2022 Plato Mavropoulos
Copyright (C) 2022-2024 Plato Mavropoulos
"""
import os
import re
import sys
import stat
import shutil
import stat
import sys
from pathlib import Path, PurePath
from common.system import get_os_ver
from common.text_ops import is_encased, to_string
# Fix illegal/reserved Windows characters
MAX_WIN_COMP_LEN = 255
def safe_name(in_name):
"""
Fix illegal/reserved Windows characters
Can also be used to nuke dangerous paths
"""
name_repr = repr(in_name).strip("'")
return re.sub(r'[\\/:"*?<>|]+', '_', name_repr)
# Check and attempt to fix illegal/unsafe OS path traversals
def safe_path(base_path, user_paths):
""" Check and attempt to fix illegal/unsafe OS path traversals """
# Convert base path to absolute path
base_path = real_path(base_path)
# Merge user path(s) to string with OS separators
user_path = to_string(user_paths, os.sep)
# Create target path from base + requested user path
target_path = norm_path(base_path, user_path)
# Check if target path is OS illegal/unsafe
if is_safe_path(base_path, target_path):
return target_path
# Re-create target path from base + leveled/safe illegal "path" (now file)
nuked_path = norm_path(base_path, safe_name(user_path))
# Check if illegal path leveling worked
if is_safe_path(base_path, nuked_path):
return nuked_path
# Still illegal, raise exception to halt execution
raise Exception(f'ILLEGAL_PATH_TRAVERSAL: {user_path}')
# Check for illegal/unsafe OS path traversal
# Still illegal, raise exception to halt execution
raise OSError(f'Encountered illegal path traversal: {user_path}')
def is_safe_path(base_path, target_path):
""" Check for illegal/unsafe OS path traversal """
base_path = real_path(base_path)
target_path = real_path(target_path)
common_path = os.path.commonpath((base_path, target_path))
return base_path == common_path
# Create normalized base path + OS separator + user path
def norm_path(base_path, user_path):
""" Create normalized base path + OS separator + user path """
return os.path.normpath(base_path + os.sep + user_path)
# Get absolute path, resolving any symlinks
def real_path(in_path):
""" Get absolute path, resolving any symlinks """
return os.path.realpath(in_path)
# Get Windows/Posix OS agnostic path
def agnostic_path(in_path):
""" Get Windows/Posix OS agnostic path """
return PurePath(in_path.replace('\\', os.sep))
# Get absolute parent of path
def path_parent(in_path):
""" Get absolute parent of path """
return Path(in_path).parent.absolute()
# Get final path component, with suffix
def path_name(in_path):
return PurePath(in_path).name
# Get final path component, w/o suffix
def path_name(in_path, limit=False):
""" Get final path component, with suffix """
comp_name = PurePath(in_path).name
if limit and get_os_ver()[1]:
comp_name = comp_name[:MAX_WIN_COMP_LEN - len(extract_suffix())]
return comp_name
def path_stem(in_path):
""" Get final path component, w/o suffix """
return PurePath(in_path).stem
# Get list of path file extensions
def path_suffixes(in_path):
""" Get list of path file extensions """
return PurePath(in_path).suffixes or ['']
# Check if path is absolute
def is_path_absolute(in_path):
""" Check if path is absolute """
return Path(in_path).is_absolute()
# Create folder(s), controlling parents, existence and prior deletion
def make_dirs(in_path, parents=True, exist_ok=False, delete=False):
""" Create folder(s), controlling parents, existence and prior deletion """
if delete:
del_dirs(in_path)
Path.mkdir(Path(in_path), parents=parents, exist_ok=exist_ok)
# Delete folder(s), if present
def del_dirs(in_path):
if Path(in_path).is_dir():
shutil.rmtree(in_path, onerror=clear_readonly)
# Copy file to path with or w/o metadata
def del_dirs(in_path):
""" Delete folder(s), if present """
if Path(in_path).is_dir():
shutil.rmtree(in_path, onerror=clear_readonly_callback)
def copy_file(in_path, out_path, meta=False):
""" Copy file to path with or w/o metadata """
if meta:
shutil.copy2(in_path, out_path)
else:
shutil.copy(in_path, out_path)
# Clear read-only file attribute (on shutil.rmtree error)
def clear_readonly(in_func, in_path, _):
def clear_readonly(in_path):
""" Clear read-only file attribute """
os.chmod(in_path, stat.S_IWRITE)
def clear_readonly_callback(in_func, in_path, _):
""" Clear read-only file attribute (on shutil.rmtree error) """
clear_readonly(in_path)
in_func(in_path)
# Walk path to get all files
def get_path_files(in_path):
""" Walk path to get all files """
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 path without leading/trailing quotes
def get_dequoted_path(in_path):
""" Get path without leading/trailing quotes """
out_path = to_string(in_path).strip()
if len(out_path) >= 2 and is_encased(out_path, ("'",'"')):
if len(out_path) >= 2 and is_encased(out_path, ("'", '"')):
out_path = out_path[1:-1]
return out_path
# Set utility extraction stem
def extract_suffix():
""" Set utility extraction stem """
return '_extracted'
# Get utility extraction path
def get_extract_path(in_path, suffix=extract_suffix()):
""" Get utility extraction path """
return f'{in_path}{suffix}'
# Get project's root directory
def project_root():
root = Path(__file__).parent.parent
return real_path(root)
# Get runtime's root directory
def project_root():
""" Get project's root directory """
return real_path(Path(__file__).parent.parent)
def runtime_root():
""" Get runtime's root directory """
if getattr(sys, 'frozen', False):
root = Path(sys.executable).parent
else:
root = project_root()
return real_path(root)