2021-05-29 13:26:08 +02:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
|
|
iDeviceRestore() {
|
|
|
|
Log "Proceeding to idevicerestore... (Enter root password of your PC/Mac when prompted)"
|
|
|
|
[[ $platform == "macos" ]] && sudo codesign --sign - --force --deep $idevicerestore
|
|
|
|
mkdir shsh
|
|
|
|
mv $SHSH shsh/${UniqueChipID}-${ProductType}-${OSVer}.shsh
|
|
|
|
$idevicerestore -ewy $IPSWRestore.ipsw
|
2021-09-30 17:05:25 +02:00
|
|
|
if [[ $? != 0 && $platform != "linux" ]]; then
|
2021-05-29 13:26:08 +02:00
|
|
|
Log "An error seems to have occurred when running idevicerestore."
|
2021-09-30 17:05:25 +02:00
|
|
|
if [[ $platform == "macos" ]]; then
|
|
|
|
Echo "* If this is the \"Killed: 9\" error or similar, try these steps:"
|
|
|
|
Echo "* Using Terminal, cd to where the script is located, then run"
|
|
|
|
Echo "* sudo codesign --sign - --force --deep resources/tools/idevicerestore_macos"
|
|
|
|
elif [[ $platform == "win" ]]; then
|
|
|
|
Echo "* Windows users may encounter errors like \"Unable to send APTicket\" or \"Unable to send iBEC\" in the restore process."
|
2021-10-05 05:24:24 +02:00
|
|
|
Echo "* To fix this, follow troubleshooting steps here: https://github.com/LukeZGD/iOS-OTA-Downgrader/wiki/Troubleshooting#windows"
|
2021-09-30 17:05:25 +02:00
|
|
|
fi
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
FRBaseband() {
|
|
|
|
local BasebandSHA1L
|
|
|
|
|
2021-06-08 05:04:40 +02:00
|
|
|
if [[ $DeviceProc == 7 ]] || [[ $ProductType == "iPhone5,1" && $Baseband5 != 0 ]]; then
|
2021-05-29 13:26:08 +02:00
|
|
|
mkdir -p saved/baseband 2>/dev/null
|
2021-06-06 14:32:29 +02:00
|
|
|
cp -f $IPSWRestore/Firmware/$Baseband saved/baseband
|
2021-05-29 13:26:08 +02:00
|
|
|
elif [[ ! -e saved/baseband/$Baseband ]]; then
|
|
|
|
Log "Downloading baseband..."
|
|
|
|
$partialzip $BasebandURL Firmware/$Baseband $Baseband
|
|
|
|
$partialzip $BasebandURL BuildManifest.plist BuildManifest.plist
|
2021-06-19 09:31:20 +02:00
|
|
|
mkdir -p saved/$ProductType saved/baseband 2>/dev/null
|
2021-05-29 13:26:08 +02:00
|
|
|
mv $Baseband saved/baseband
|
|
|
|
mv BuildManifest.plist saved/$ProductType
|
|
|
|
BuildManifest="saved/$ProductType/BuildManifest.plist"
|
|
|
|
else
|
|
|
|
BuildManifest="saved/$ProductType/BuildManifest.plist"
|
|
|
|
fi
|
|
|
|
|
|
|
|
BasebandSHA1L=$(shasum saved/baseband/$Baseband | awk '{print $1}')
|
|
|
|
if [[ ! -e $(ls saved/baseband/$Baseband) || $BasebandSHA1L != $BasebandSHA1 ]]; then
|
|
|
|
rm -f saved/baseband/$Baseband saved/$ProductType/BuildManifest.plist
|
|
|
|
Error "Downloading/verifying baseband failed. Please run the script again"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
FutureRestore() {
|
2021-10-21 13:42:50 +02:00
|
|
|
local ExtraArgs=()
|
|
|
|
|
|
|
|
[[ $IPSWCustomW != 2 ]] && ExtraArgs=("--use-pwndfu")
|
2021-05-29 13:26:08 +02:00
|
|
|
if [[ $DeviceProc == 7 ]]; then
|
2021-10-21 13:42:50 +02:00
|
|
|
ExtraArgs+=("-s" "$IPSWRestore/Firmware/all_flash/$SEP" "-m" "$BuildManifest")
|
2021-05-29 13:26:08 +02:00
|
|
|
else
|
2021-10-26 05:32:59 +02:00
|
|
|
ExtraArgs+=("--no-ibss")
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
2021-10-21 13:42:50 +02:00
|
|
|
|
2021-05-29 13:26:08 +02:00
|
|
|
Log "Proceeding to futurerestore..."
|
|
|
|
if [[ $Baseband == 0 ]]; then
|
|
|
|
Log "Device $ProductType has no baseband"
|
2021-10-21 13:42:50 +02:00
|
|
|
$futurerestore -t "$SHSH" --no-baseband "${ExtraArgs[@]}" "$IPSWRestore.ipsw"
|
2021-05-29 13:26:08 +02:00
|
|
|
else
|
|
|
|
FRBaseband
|
2021-10-21 13:42:50 +02:00
|
|
|
$futurerestore -t "$SHSH" -b saved/baseband/$Baseband -p $BuildManifest "${ExtraArgs[@]}" "$IPSWRestore.ipsw"
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-10-25 08:57:24 +02:00
|
|
|
SetIPSWCustomW() {
|
|
|
|
if [[ $DeviceProc == 7 ]]; then
|
|
|
|
IPSWCustomW=2
|
|
|
|
futurerestore=$futurerestore2
|
|
|
|
else
|
|
|
|
IPSWCustom="${IPSWCustom}W"
|
|
|
|
IPSWCustomW=1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-05-29 13:26:08 +02:00
|
|
|
Downgrade() {
|
|
|
|
local IPSWExtract
|
|
|
|
local IPSWSHA1
|
|
|
|
local IPSWSHA1L
|
|
|
|
local Jailbreak
|
2021-10-12 09:02:37 +02:00
|
|
|
local JBName
|
2021-10-21 13:42:50 +02:00
|
|
|
local Verify=1
|
2021-05-29 13:26:08 +02:00
|
|
|
|
2021-10-12 09:02:37 +02:00
|
|
|
Log "Select your options when asked. If unsure, go for the defaults (press Enter/Return)."
|
|
|
|
echo
|
|
|
|
|
2021-05-29 13:26:08 +02:00
|
|
|
if [[ $OSVer == "Other" ]]; then
|
2021-09-01 01:57:25 +02:00
|
|
|
if [[ $platform == "linux" ]]; then
|
2021-10-12 09:02:37 +02:00
|
|
|
Input "Select your IPSW file in the file selection window."
|
2021-09-01 01:57:25 +02:00
|
|
|
IPSW="$(zenity --file-selection --file-filter='IPSW | *.ipsw' --title="Select IPSW file")"
|
|
|
|
IPSW="${IPSW%?????}"
|
2021-10-12 09:02:37 +02:00
|
|
|
Log "Selected IPSW file: $IPSW.ipsw"
|
|
|
|
Input "Select your SHSH file in the file selection window."
|
2021-09-01 01:57:25 +02:00
|
|
|
SHSH="$(zenity --file-selection --file-filter='SHSH | *.shsh *.shsh2' --title="Select SHSH file")"
|
|
|
|
Log "Selected SHSH file: $SHSH"
|
|
|
|
else
|
2021-10-12 09:02:37 +02:00
|
|
|
Input "Enter the names of your IPSW and SHSH files below."
|
2021-09-01 01:57:25 +02:00
|
|
|
Echo "* Move/copy the IPSW and SHSH files to the directory where the script is located"
|
|
|
|
Echo "* When entering the names of IPSW and SHSH, enter the full name including the file extension"
|
2021-10-12 09:02:37 +02:00
|
|
|
Echo "* Make sure to create a backup of the SHSH"
|
2021-09-01 01:57:25 +02:00
|
|
|
read -p "$(Input 'Enter name of IPSW file:')" IPSW
|
2021-10-12 09:02:37 +02:00
|
|
|
IPSW="$(basename "$IPSW" .ipsw)"
|
2021-09-01 01:57:25 +02:00
|
|
|
read -p "$(Input 'Enter name of SHSH file:')" SHSH
|
|
|
|
fi
|
|
|
|
|
2021-05-29 13:26:08 +02:00
|
|
|
elif [[ $Mode == "Downgrade" && $DeviceProc != 7 ]]; then
|
2021-10-12 09:02:37 +02:00
|
|
|
Input "Jailbreak Option"
|
|
|
|
Echo "* When this option is enabled, your device will be jailbroken on restore."
|
|
|
|
Echo "* This option is enabled by default (Y)."
|
|
|
|
read -p "$(Input 'Enable this option? (Y/n):')" Jailbreak
|
2021-06-13 13:48:06 +02:00
|
|
|
|
2021-06-20 11:45:53 +02:00
|
|
|
if [[ $Jailbreak != 'N' && $Jailbreak != 'n' ]]; then
|
2021-06-13 13:48:06 +02:00
|
|
|
Jailbreak=1
|
2021-09-06 10:50:29 +02:00
|
|
|
if [[ $ProductType == "iPhone4,1" || $ProductType == "iPad2,4" ||
|
|
|
|
$ProductType == "iPad2,5" || $ProductType == "iPad2,6" ||
|
|
|
|
$ProductType == "iPad2,7" || $ProductType == "iPod5,1" ]] ||
|
|
|
|
[[ $ProductType == "iPad3"* && $DeviceProc == 5 ]]; then
|
2021-10-12 09:02:37 +02:00
|
|
|
[[ $OSVer == "8.4.1" ]] && JBDaibutsu=1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ $JBDaibutsu == 1 ]]; then
|
|
|
|
JBName="daibutsu"
|
|
|
|
elif [[ $OSVer == "8.4.1" ]]; then
|
|
|
|
JBName="EtasonJB"
|
|
|
|
elif [[ $OSVer == "6.1.3" ]]; then
|
|
|
|
JBName="p0sixspwn"
|
2021-06-13 13:48:06 +02:00
|
|
|
fi
|
2021-10-12 09:02:37 +02:00
|
|
|
|
|
|
|
Log "Jailbreak option enabled. Using $JBName for the jailbreak"
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
2021-10-12 09:02:37 +02:00
|
|
|
echo
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
|
|
|
|
2021-05-30 05:03:39 +02:00
|
|
|
if [[ $Mode == "Downgrade" && $ProductType == "iPhone5,1" && $Jailbreak != 1 ]]; then
|
2021-10-12 09:02:37 +02:00
|
|
|
Input "Latest Baseband Option"
|
|
|
|
Echo "* iOS-OTA-Downgrader flashes the iOS 8.4.1 baseband to iPhone5,1."
|
|
|
|
Echo "* When this option is enabled, the latest baseband will be flashed instead, but beware of problems it may cause."
|
|
|
|
Echo "* This option is disabled by default (N)."
|
|
|
|
read -p "$(Input 'Enable this option? (y/N):')" Baseband5
|
2021-05-29 13:26:08 +02:00
|
|
|
if [[ $Baseband5 == 'Y' || $Baseband5 == 'y' ]]; then
|
|
|
|
Baseband5=0
|
|
|
|
else
|
|
|
|
BasebandURL=$(cat $Firmware/12H321/url)
|
|
|
|
Baseband="Mav5-8.02.00.Release.bbfw"
|
|
|
|
BasebandSHA1="db71823841ffab5bb41341576e7adaaeceddef1c"
|
|
|
|
fi
|
2021-10-12 09:02:37 +02:00
|
|
|
echo
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ $OSVer != "Other" ]]; then
|
|
|
|
IPSW="${IPSWType}_${OSVer}_${BuildVer}_Restore"
|
|
|
|
IPSWCustom="${IPSWType}_${OSVer}_${BuildVer}_Custom"
|
2021-10-12 09:02:37 +02:00
|
|
|
|
2021-10-21 13:42:50 +02:00
|
|
|
if [[ $Jailbreak != 1 && $platform == "win" ]]; then
|
2021-10-25 08:57:24 +02:00
|
|
|
SetIPSWCustomW
|
|
|
|
elif [[ $Jailbreak != 1 ]]; then
|
|
|
|
Input "Custom IPSW Option"
|
|
|
|
Echo "* When this option is enabled, a custom IPSW will be made for the restore."
|
|
|
|
Echo "* Enable this option later if you experience issues with futurerestore."
|
|
|
|
Echo "* This option is disabled by default (N)."
|
|
|
|
read -p "$(Input 'Enable this option? (y/N):')" IPSWCustomW
|
|
|
|
if [[ $IPSWCustomW == 'Y' || $IPSWCustomW == 'y' ]]; then
|
|
|
|
SetIPSWCustomW
|
2021-10-12 09:02:37 +02:00
|
|
|
fi
|
2021-10-25 08:57:24 +02:00
|
|
|
echo
|
2021-06-20 11:45:53 +02:00
|
|
|
fi
|
|
|
|
|
2021-10-21 13:42:50 +02:00
|
|
|
if [[ $Jailbreak == 1 || ! -z $IPSWCustomW ]]; then
|
|
|
|
[[ -e "$IPSWCustom.ipsw" ]] && Verify=
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
2021-10-12 09:02:37 +02:00
|
|
|
|
|
|
|
if [[ $Jailbreak == 1 || $IPSWCustomW == 1 ]] &&
|
|
|
|
[[ $Verify == 1 && $platform != "win" ]]; then
|
|
|
|
Input "Memory Option for creating custom IPSW"
|
|
|
|
Echo "* This option makes creating the custom IPSW faster, but it requires at least 8GB of RAM."
|
|
|
|
Echo "* If you do not have enough RAM, disable this option and make sure that you have enough storage space."
|
|
|
|
Echo "* This option is enabled by default (Y)."
|
|
|
|
read -p "$(Input 'Enable this option? (Y/n):')" JBMemory
|
|
|
|
echo
|
|
|
|
fi
|
|
|
|
|
2021-10-21 13:42:50 +02:00
|
|
|
[[ $IPSWCustomW != 2 ]] && SaveOTABlobs
|
|
|
|
|
|
|
|
if [[ ! -e "$IPSW.ipsw" && $Verify == 1 ]]; then
|
2021-10-12 09:02:37 +02:00
|
|
|
Log "iOS $OSVer IPSW for $ProductType cannot be found."
|
|
|
|
Echo "* If you already downloaded the IPSW, move/copy it to the directory where the script is located."
|
|
|
|
Echo "* Do NOT rename the IPSW as the script will fail to detect it."
|
|
|
|
Echo "* The script will now proceed to download it for you. If you want to download it yourself, here is the link: $(cat $Firmware/$BuildVer/url)"
|
|
|
|
Log "Downloading IPSW... (Press Ctrl+C to cancel)"
|
|
|
|
curl -L $(cat $Firmware/$BuildVer/url) -o tmp/$IPSW.ipsw
|
|
|
|
mv tmp/$IPSW.ipsw .
|
|
|
|
fi
|
|
|
|
|
2021-05-29 13:26:08 +02:00
|
|
|
if [[ $Verify == 1 ]]; then
|
|
|
|
Log "Verifying IPSW..."
|
|
|
|
IPSWSHA1=$(cat $Firmware/$BuildVer/sha1sum)
|
2021-08-21 10:53:54 +02:00
|
|
|
Log "Expected SHA1sum: $IPSWSHA1"
|
2021-05-29 13:26:08 +02:00
|
|
|
IPSWSHA1L=$(shasum $IPSW.ipsw | awk '{print $1}')
|
2021-08-21 10:53:54 +02:00
|
|
|
Log "Actual SHA1sum: $IPSWSHA1L"
|
2021-05-29 13:26:08 +02:00
|
|
|
if [[ $IPSWSHA1L != $IPSWSHA1 ]]; then
|
2021-09-29 11:26:04 +02:00
|
|
|
Error "Verifying IPSW failed. Your IPSW may be corrupted or incomplete. Delete/replace the IPSW and run the script again" \
|
|
|
|
"SHA1sum mismatch. Expected $IPSWSHA1, got $IPSWSHA1L"
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
2021-09-29 11:26:04 +02:00
|
|
|
Log "IPSW SHA1sum matches."
|
2021-06-20 11:45:53 +02:00
|
|
|
elif [[ -e "$IPSWCustom.ipsw" ]]; then
|
2021-09-06 10:50:29 +02:00
|
|
|
Log "Found existing Custom IPSW. Skipping IPSW verification."
|
2021-05-29 13:26:08 +02:00
|
|
|
Log "Setting restore IPSW to: $IPSWCustom.ipsw"
|
|
|
|
IPSWRestore=$IPSWCustom
|
|
|
|
fi
|
|
|
|
|
2021-10-12 09:02:37 +02:00
|
|
|
if [[ $DeviceState == "Normal" && $iBSSBuildVer == $BuildVer && -e "$IPSW.ipsw" ]]; then
|
2021-05-29 13:26:08 +02:00
|
|
|
Log "Extracting iBSS from IPSW..."
|
|
|
|
mkdir -p saved/$ProductType 2>/dev/null
|
|
|
|
unzip -o -j $IPSW.ipsw Firmware/dfu/$iBSS.dfu -d saved/$ProductType
|
|
|
|
fi
|
2021-09-01 02:11:07 +02:00
|
|
|
else
|
|
|
|
IPSWCustom=0
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
2021-10-12 09:02:37 +02:00
|
|
|
|
2021-05-29 13:26:08 +02:00
|
|
|
[[ $DeviceState == "Normal" ]] && kDFU
|
2021-09-01 02:11:07 +02:00
|
|
|
|
2021-10-12 09:02:37 +02:00
|
|
|
if [[ $Jailbreak == 1 || $IPSWCustomW == 1 ]]; then
|
|
|
|
IPSW32
|
2021-09-01 02:11:07 +02:00
|
|
|
IPSWExtract="$IPSWCustom"
|
2021-10-25 08:57:24 +02:00
|
|
|
elif [[ $IPSWCustomW == 2 && $Verify != 1 ]]; then
|
|
|
|
IPSWExtract="$IPSWCustom"
|
2021-05-29 13:26:08 +02:00
|
|
|
else
|
2021-09-01 02:11:07 +02:00
|
|
|
IPSWExtract="$IPSW"
|
2021-05-29 13:26:08 +02:00
|
|
|
fi
|
2021-09-01 02:11:07 +02:00
|
|
|
|
2021-05-29 13:26:08 +02:00
|
|
|
Log "Extracting IPSW: $IPSWExtract.ipsw"
|
2021-10-21 13:42:50 +02:00
|
|
|
unzip -oq "$IPSWExtract.ipsw" -d "$IPSWExtract"/
|
|
|
|
|
|
|
|
if [[ $IPSWCustomW == 2 ]]; then
|
2021-05-29 13:26:08 +02:00
|
|
|
IPSW64
|
|
|
|
pwnREC
|
2021-10-21 13:42:50 +02:00
|
|
|
local APNonce=$($irecovery -q | grep "NONC" | cut -c 7-)
|
|
|
|
Log "APNonce: $APNonce"
|
|
|
|
SaveOTABlobs $APNonce
|
2021-06-20 11:45:53 +02:00
|
|
|
elif [[ $Jailbreak != 1 && $OSVer != "Other" && $IPSWCustomW != 1 ]]; then
|
2021-05-29 13:26:08 +02:00
|
|
|
Log "Preparing for futurerestore... (Enter root password of your PC/Mac when prompted)"
|
|
|
|
cd resources
|
2021-06-21 13:53:02 +02:00
|
|
|
[[ $platform == "linux" ]] && $SimpleHTTPServer || $SimpleHTTPServer &
|
2021-05-29 13:26:08 +02:00
|
|
|
ServerRunning=1
|
|
|
|
cd ..
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ ! $IPSWRestore ]]; then
|
|
|
|
Log "Setting restore IPSW to: $IPSW.ipsw"
|
|
|
|
IPSWRestore="$IPSW"
|
|
|
|
fi
|
2021-10-25 08:57:24 +02:00
|
|
|
|
2021-10-26 05:32:59 +02:00
|
|
|
if [[ $DeviceProc == 7 && $IPSWCustomW != 2 ]]; then
|
|
|
|
Log "Sending dummy file"
|
|
|
|
$irecovery -f restore.cmd
|
|
|
|
sleep 2
|
|
|
|
fi
|
|
|
|
|
2021-06-20 11:45:53 +02:00
|
|
|
if [[ $Jailbreak == 1 || $IPSWCustomW == 1 ]]; then
|
2021-05-29 13:26:08 +02:00
|
|
|
iDeviceRestore
|
|
|
|
else
|
|
|
|
FutureRestore
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo
|
|
|
|
Log "Restoring done!"
|
|
|
|
Log "Downgrade script done!"
|
|
|
|
}
|