Skip to content

Instantly share code, notes, and snippets.

@iwalfy
Last active September 29, 2023 10:22
Show Gist options
  • Save iwalfy/eb137b0b705683aa427ed29311ed1b30 to your computer and use it in GitHub Desktop.
Save iwalfy/eb137b0b705683aa427ed29311ed1b30 to your computer and use it in GitHub Desktop.
Simple script to extract PNG image assets from Apple's EFI Firmwares using UEFIExtract and binwalk
#!/usr/bin/env bash
#
# Simple script to extract PNG assets from Apple's Mac EFI Firmware
# Works for all firmwares 2005-2021
#
# Requirements: pkgutil (for pkg firmwares), binwalk, find
#
# (c) Mikhail Lebedinets, 2023
#
set -e
TEMP_DIR="firmware_extract_$RANDOM"
usage() {
echo "Usage: $0 <firmware dump/installaer package> <output images directory>"
}
if [ $# -lt 2 ]; then
usage
exit 1
fi
input_file="$1"
output_dir="$2"
if [ ! -f "$input_file" ]; then
echo "!!! Error: Firmware file does not exists"
exit 1
fi
if [ ! -d "$output_dir" ]; then
echo "-> Output directory created"
mkdir "$output_dir"
fi
mkdir "$TEMP_DIR"
uefi_extract_path=$(whereis UEFIExtract | awk '{print $2}')
if [ ! "$uefi_extract_path" ]; then
echo "-> UEFIExtract not found in your PATH"
echo "--> Downloading latest UEFIExtract..."
wget "https://github.com/LongSoft/UEFITool/releases/download/A67/UEFIExtract_NE_A67_universal_mac.zip" -O "$TEMP_DIR/UEFIExtract.zip"
uefi_extract_path="$TEMP_DIR/UEFIExtract"
echo "---> Unzipping..."
unzip -j "$TEMP_DIR/UEFIExtract.zip" -d "$TEMP_DIR"
chmod +x "$uefi_extract_path"
fi
firmware_file="$input_file"
if [[ $input_file == *.pkg ]]; then
echo "-> Detected package installer"
echo "--> Extracting package..."
pkg_contents="$TEMP_DIR/pkg_contents"
pkgutil --expand "$input_file" "$pkg_contents"
firmware_file=$(find "$pkg_contents" -type f -regex ".*\.scap")
if [ $(echo "$firmware_file" | wc -l) -gt 1 ]; then
echo "!!! This package has more than one image. You should extract required manually"
echo "$firmware_file"
exit 3
fi
if [ ! "$firmware_file" ]; then
echo "-> Firmware file not found (trying to find in Payload)"
tar -xvf $(find "$pkg_contents" -type f -name "Payload") -C "$pkg_contents"
firmware_file=$(find "$pkg_contents" -type f -regex ".*\.scap")
fi
if [ "$firmware_file" ]; then
echo "-> Firmware file found ($firmware_file)"
else
echo "!!! Error: Failed to find firmware file in package"
exit 2
fi
fi
unpack_dir="$TEMP_DIR/unpack"
mkdir "$unpack_dir"
echo "-> Extracting firmware..."
$uefi_extract_path "$firmware_file" dump
mv "$firmware_file.dump" "$unpack_dir"
last_path=$(realpath)
cd "$unpack_dir"
echo -n "-> Appending all parts to single binary..."
find . -type f -exec sh -c 'dd if="$1" status=none >> data.bin; printf "."' sh {} . \;
echo
echo "-> Extracting images..."
binwalk --dd="png image:png:" data.bin
cd "$last_path"
echo "--> Moving images to output directory..."
find "$unpack_dir" -type f -regex ".*\.png" -exec sh -c 'mv "$1" "$2/$RANDOM$RANDOM.png"' sh {} "$output_dir" \;
if [ -z "$(ls -A $output_dir)" ]; then
echo "!!! Extract finished but this firmware probably have no PNG images inside (maybe update?)"
exit 4
fi
echo "-> Deleting temp directory"
rm -rf "$TEMP_DIR"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment