-
-
Save JamesHopbourn/e3c9dbd265835eeb5ecfd79dc56d3257 to your computer and use it in GitHub Desktop.
| #!/bin/bash | |
| #!/bin/sh | |
| # Download script written by Wowfunhappy. Last updated 2025/03/07. | |
| # Thank you to Krackers, Jazzzny, and others for helping analyze Apple's download process and debug this script. | |
| # Thank you to dosdude1 for donating identifiers from a broken Mac. | |
| # Any mistakes are mine alone. | |
| BOARD_SERIAL_NUMBER="C0243070168G3M91F" | |
| BOARD_ID="Mac-3CBD00234E554E41" | |
| ROM="003EE1E6AC14" | |
| # Helper functions | |
| save_create_bootable_installer_script() { | |
| cat << 'EOF' > "$1" | |
| #!/bin/sh | |
| set -e | |
| cd "`dirname "$0"`" | |
| asr imagescan --source InstallMacOSXMavericks.dmg | |
| did_find_volume="false" | |
| while [ $did_find_volume == "false" ] | |
| do | |
| printf "Please enter the volume name of your USB flash drive: " | |
| read target_volname | |
| if [ ! -z $target_volname ] && df -l | grep -q "/Volumes/$target_volname" | |
| then | |
| did_find_volume=true | |
| elif [ ! -z $target_volname ] | |
| then | |
| echo | |
| echo "Could not find a volume named $target_volname. Found these volumes:" | |
| df -l | awk -F'/Volumes/' '{print $2}' | grep -v '^$' | |
| echo | |
| fi | |
| done | |
| printf "WARNING: All data on $target_volname will be erased. Continue? (yes/no) " | |
| read confirmation | |
| if [ "$confirmation" != "y" ] && [ "$confirmation" != "yes" ] | |
| then | |
| echo "Exiting. No changes have been made." | |
| exit 1 | |
| fi | |
| disk_identifier=$(diskutil list /Volumes/"$target_volname" | head -n 1) | |
| sudo diskutil partitionDisk $disk_identifier GPT jhfs+ "$target_volname" 100% | |
| sudo asr restore --source InstallMacOSXMavericks.dmg --noprompt --target /Volumes/"$target_volname" --erase | |
| EOF | |
| chmod +x "$1" | |
| } | |
| hex_to_bin() { | |
| printf "%s" "$1" | xxd -r -p | |
| } | |
| check_for_utility() { | |
| if ! command -v "$1" > /dev/null | |
| then | |
| echo "Error: Required utility '$1' is not available on your system." 1>&2 | |
| exit 1 | |
| fi | |
| } | |
| # Start here! | |
| set -e | |
| check_for_utility "hdiutil" | |
| check_for_utility "curl" | |
| check_for_utility "openssl" | |
| if ! openssl dgst -sha256 < /dev/null > /dev/null 2>&1 | |
| then | |
| echo "Error: The version of OpenSSL on your system does not support SHA-256." 1>&2 | |
| exit 1 | |
| fi | |
| # To retrieve the installation payload from Apple, we must provide: | |
| # 1. A server ID, retrieved from osrecovery.apple.com. | |
| # 2. A client ID, randomly generated. | |
| # 3. The board serial number and matching board id of a Mavericks-era Mac. | |
| # 4. A key, a SHA-256 hash derived from: | |
| # - The aforementioned client id. | |
| # - The aforementioned server id. | |
| # - A ROM matching the aforementioned board serial number and board id. | |
| # - The SHA-256 hash of the aforementioned board serial number and board id. | |
| # 1. Retrieve the server ID from Apple. | |
| SERVER_ID=$(curl -fs -c - http://osrecovery.apple.com/ | tail -1 | awk '{print $NF}') | |
| # 2. Generate the client ID. | |
| CLIENT_ID=$(dd if=/dev/urandom bs=8 count=1 2>/dev/null | od -An -tx1 | tr -d ' \n' | tr '[:lower:]' '[:upper:]') | |
| # 4. Generate the key. | |
| { | |
| hex_to_bin "$CLIENT_ID" | |
| hex_to_bin "$(echo $SERVER_ID | awk -F'~' '{print $2}')" | |
| hex_to_bin "$ROM" | |
| printf "%s" "${BOARD_SERIAL_NUMBER}${BOARD_ID}" | iconv -t utf-8 | openssl dgst -sha256 -binary | |
| printf '\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC' | |
| } > key_info | |
| # Hash key_info using SHA-256, then convert raw binary output to uppercase hex. | |
| KEY=$(openssl dgst -sha256 -binary < key_info | od -An -tx1 | tr -d ' \n' | tr '[:lower:]' '[:upper:]') | |
| rm key_info | |
| # Finally, retrieve the installation payload, which contains the asset token needed to download InstallESD.dmg. | |
| INSTALLATION_PAYLOAD=$(curl -fs 'http://osrecovery.apple.com/InstallationPayload/OSInstaller' -X POST \ | |
| -H 'Content-Type: text/plain' \ | |
| --cookie "session=$SERVER_ID" \ | |
| -d "cid=$CLIENT_ID | |
| sn=$BOARD_SERIAL_NUMBER | |
| bid=$BOARD_ID | |
| k=$KEY") | |
| ASSET_URL=$(echo "$INSTALLATION_PAYLOAD" | grep AU | awk -F': ' '{print $2}') | |
| ASSET_TOKEN=$(echo "$INSTALLATION_PAYLOAD" | grep AT | awk -F': ' '{print $2}') | |
| if [ "$ASSET_URL" != "http://oscdn.apple.com/content/downloads/33/62/031-10295/gho4r94w66f5v4ujm0sz7k1m0hua68i6oo/OSInstaller/InstallESD.dmg" ] | |
| then | |
| echo "Error: Server did not provide the Mavericks InstallESD URL." 1>&2 | |
| exit 1 | |
| fi | |
| echo "Downloading InstallESD.dmg..." | |
| curl --progress-bar "$ASSET_URL" -H "Cookie: AssetToken=$ASSET_TOKEN" > InstallESD.dmg | |
| # Verify the checksum of InstallESD.dmg because it was downloaded over unencrypted HTTP. | |
| echo "Verifying integrity of InstallESD.dmg..." | |
| if [ $(openssl dgst -sha256 InstallESD.dmg | awk -F'= ' '{print $2}') != "c861fd59e82bf777496809a0d2a9b58f66691ee56738031f55874a3fe1d7c3ff" ] | |
| then | |
| rm InstallESD.dmg | |
| echo "Error: Download failed (mismatched checksum)" 1>&2 | |
| exit 1 | |
| fi | |
| echo "Building InstallMacOSXMavericks.dmg..." | |
| # Inside InstallESD.dmg is another image, BaseSystem.dmg, which contains a minimal Mac OS X recovery environment. | |
| # Additional data from InstallESD.dmg must be copied into BaseSystem.dmg to build a complete Mavericks installer. | |
| # Ensure no volumes with these names are already mounted. | |
| hdiutil detach "/Volumes/OS X Base System" 2> /dev/null && sleep 2 || true | |
| hdiutil detach "/Volumes/OS X Install ESD" 2> /dev/null && sleep 2 || true | |
| # Convert BaseSystem.dmg to a modifiable image with sufficient free space for the additional data. | |
| hdiutil attach InstallESD.dmg -nobrowse | |
| hdiutil convert -ov "/Volumes/OS X Install ESD/BaseSystem.dmg" -format UDSP -o "InstallMacOSXMavericks.sparseimage" | |
| hdiutil resize -size 6550020096 "InstallMacOSXMavericks.sparseimage" | |
| # Copy additional data into BaseSystem. | |
| hdiutil attach "InstallMacOSXMavericks.sparseimage" -nobrowse | |
| rm -rf "/Volumes/OS X Base System/System/Installation/Packages" | |
| cp -R "/Volumes/OS X Install ESD/Packages" "/Volumes/OS X Base System/System/Installation/" | |
| cp "/Volumes/OS X Install ESD/BaseSystem.chunklist" "/Volumes/OS X Base System/System/Installation/" | |
| cp "/Volumes/OS X Install ESD/BaseSystem.dmg" "/Volumes/OS X Base System/System/Installation/" | |
| hdiutil detach "/Volumes/OS X Base System" | |
| hdiutil detach "/Volumes/OS X Install ESD" | |
| # Pause before converting so hdiutil won't fail with `hdiutil: convert failed - Resource temporarily unavailable` | |
| sleep 2 | |
| hdiutil convert -ov "InstallMacOSXMavericks.sparseimage" -format UDZO -o "InstallMacOSXMavericks.dmg" | |
| rm InstallMacOSXMavericks.sparseimage | |
| rm InstallESD.dmg | |
| echo "InstallMacOSXMavericks.dmg successfully created." | |
| if [ "$(uname)" = "Darwin" ] | |
| then | |
| save_create_bootable_installer_script "Create Bootable Installer.command" | |
| open -R "InstallMacOSXMavericks.dmg" | |
| fi |
This is some excellent work , I've been trying to create an installer from the Internet Recovery of a 2011 MacMini , which defaults to downloading Mavericks even in 2025. Ive had limited success. I managed to create a OS X Base System from the Internet Recovery using the Terminal utility and dd , and additionally found that if I start to install the OS to a USB drive and stop it rebooting after it has authenticated and downloaded the chunks then I have the missing Packages folder.
However the downloaded InstallESD.dmg files is missing the hidden BaseSystem.dmg file.
I was working on a method of creating a OS X Base System.dmg large enough to replace the Alias 'Package' folder with the real folder obtained from the halted installation , this worked but I never managed to get it to boot.
Also I managed to download the Install OS X Mavericks.app from the App Store using an old version of OSX , but the InstallESD.dmg says it is corrupted , so that stopped me in my tracks.
Then I came across this which looks to work a treat but I have just tried the Create Bootable Media Installer shell command and it stops after verifying the resulting image saying :-
Checksum Failed.
Expected 343510FE
but got 2C66917B
Could Not Restore : Invalid Argument
I have no idea why this is? , any insight would be really helpful.
But there is hope , as the InstallESD.dmg file that this script creates has a valid BaseSystem.dmg file so I can use that to restore to a USB and then replace the missing package directory. Well that's the theory.
Any help or advice would be great , I have a sinking feeling that the checksum failed for one of two reasons.
The certificates and dates don't match up?
The InstallESD.dmg now being served by Apple is corrupted in some way.
The only way so far I have been able to create a working installer in 2025 entirely from apple downloads , is to use an old BaseSystem.dmg from an installer I made in 2014 and use that along with the packages downloaded by Internet Recovery to replace the missing .pkg files. All a bit of a faff.
Hope you can give me some insight, thanks for the amazing work you have done with this.
I can supply a link to download my BaseSystem.dmg from 2014 if anyone wants or needs it.
Kindest Regards,
Alex.
nicely done! the only reason I could find this (on Google) is the hash part of the download, I queried for that, because A log file entry was made during a recovery install for 10.9, entry for that recovery URL, and I found it. I already had the InstallESD from Apple, the Wizard of OZ version (behind the curtain) of your tricky efforts. thanks....
(really I am trying to understand the different data speed rates I get with my SSD, 200, 300, 500, & 700Mbs roughly, depending upon which kexts are loaded, SimpleMSR is a must it seems in order for me to get to the highest of the transmission rates. FYI. on my 14,1 iMac, that came with MountainLion 10.8.5). peace.