Code refactoring, split to multiple scripts, general improvements (#96)

Lots of changes from this PR!
This commit is contained in:
LukeeGD 2021-05-29 19:26:08 +08:00 committed by GitHub
parent dc694d49cf
commit a2923a575e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 868 additions and 2954 deletions

2
.gitignore vendored
View File

@ -13,6 +13,6 @@ saved/
resources/FirmwareBundles resources/FirmwareBundles
resources/firmware/ resources/firmware/
resources/ipwndfu/ resources/ipwndfu/
resources/libimobiledevice/ resources/libimobiledevice*/
resources/libirecovery/ resources/libirecovery/
tmp/ tmp/

12
README.md Executable file → Normal file
View File

@ -74,11 +74,11 @@
6. Follow instructions 6. Follow instructions
## Supported OS versions/distros: ## Supported OS versions/distros:
- **Ubuntu** [18.04](https://releases.ubuntu.com/bionic/), [20.04](https://releases.ubuntu.com/focal/), [20.10](https://releases.ubuntu.com/groovy/), [21.04](https://releases.ubuntu.com/hirsute/); and Ubuntu-based distros like [Linux Mint](https://www.linuxmint.com/) - **Ubuntu** [20.04](https://releases.ubuntu.com/focal/), [20.10](https://releases.ubuntu.com/groovy/), [21.04](https://releases.ubuntu.com/hirsute/); and Ubuntu-based distros like [Linux Mint](https://www.linuxmint.com/)
- [**Arch Linux**](https://www.archlinux.org/) and Arch-based distros like [EndeavourOS](https://endeavouros.com/) - [**Arch Linux**](https://www.archlinux.org/) and Arch-based distros like [EndeavourOS](https://endeavouros.com/)
- [**Fedora** 32 to 34](https://getfedora.org/) - [**Fedora** 33 to 34](https://getfedora.org/)
- [**Debian** Buster, Bullseye, Sid](https://www.debian.org/); and Debian-based distros like [MX Linux](https://mxlinux.org/) - [**Debian** Bullseye, Sid](https://www.debian.org/); and Debian-based distros like [MX Linux](https://mxlinux.org/)
- **openSUSE** [Tumbleweed](https://software.opensuse.org/distributions/tumbleweed), [Leap 15.2](https://software.opensuse.org/distributions/leap) - **openSUSE** [Tumbleweed](https://software.opensuse.org/distributions/tumbleweed)
- **macOS** 10.12 to 11 - **macOS** 10.12 to 11
## Other notes: ## Other notes:
@ -118,7 +118,7 @@
- The jailbreak option **might not work** on A5 Rev A devices (see issue [#70](https://github.com/LukeZGD/iOS-OTA-Downgrader/issues/70)) - The jailbreak option **might not work** on A5 Rev A devices (see issue [#70](https://github.com/LukeZGD/iOS-OTA-Downgrader/issues/70))
- For users that downgraded **without** jailbreak option, and have manually jailbroken with the EtasonJB app, it is recommended to install "EtasonJB Disable Bootloop Protection" from my Cydia repo - For users that downgraded **without** jailbreak option, and have manually jailbroken with the EtasonJB app, it is recommended to install "EtasonJB Disable Bootloop Protection" from my Cydia repo
- For users that downgraded **with** the jailbreak option, and to users that have installed "EtasonJB Disable Bootloop Protection", your device might take a very long time to boot, possibly 20 minutes or more - For users that downgraded **with** the jailbreak option, and to users that have installed "EtasonJB Disable Bootloop Protection", your device might take a very long time to boot, possibly 20 minutes or more
- **My Cydia repo**: https://lukezgd.github.io/repo/ - for installing Dropbear, Jailbreak App Icons Fix, EtasonJB Disable Bootloop Protection - **My Cydia repo**: https://lukezgd.github.io/repo/ - for installing Dropbear, Jailbreak App Icons Fix, EtasonJB Disable Bootloop Protection, kDFUApp
## Tools and other stuff used by this script: ## Tools and other stuff used by this script:
- cURL - cURL
@ -139,7 +139,7 @@
- [kloader5 for iOS 5](https://mtmdev.org/pmbonneau-archive) - [kloader5 for iOS 5](https://mtmdev.org/pmbonneau-archive)
- [kloader_hgsp for iOS 10](https://twitter.com/nyan_satan/status/945203180522045440) - [kloader_hgsp for iOS 10](https://twitter.com/nyan_satan/status/945203180522045440)
- [partial-zip](https://github.com/matteyeux/partial-zip) - [partial-zip](https://github.com/matteyeux/partial-zip)
- 32-bit iBSS patches are from [OdysseusOTA](https://www.youtube.com/watch?v=Wo7mGdMcjxw), [OdysseusOTA2](https://www.youtube.com/watch?v=fh0tB6fp0Sc), [alitek12](https://www.mediafire.com/folder/b1z64roy512wd/FirmwareBundles), [gjest](https://files.fm/u/fcbqqdnw) - 32-bit iBSS patches are from [OdysseusOTA](https://www.youtube.com/watch?v=Wo7mGdMcjxw), [OdysseusOTA2](https://www.youtube.com/watch?v=fh0tB6fp0Sc), [alitek12](https://www.mediafire.com/folder/b1z64roy512wd/FirmwareBundles), [gjest](https://www.reddit.com/r/jailbreak/comments/6yrzzj/release_firmware_bundles_for_ios_841_ipad21234567/)
- A7 iBSS and iBEC patches are from [MatthewPierson](https://github.com/MatthewPierson/iPhone-5s-OTA-Downgrade-Patches) - A7 iBSS and iBEC patches are from [MatthewPierson](https://github.com/MatthewPierson/iPhone-5s-OTA-Downgrade-Patches)
- [EtasonJB](https://www.theiphonewiki.com/wiki/EtasonJB) - [EtasonJB](https://www.theiphonewiki.com/wiki/EtasonJB)
- [p0sixspwn](https://www.theiphonewiki.com/wiki/p0sixspwn) - [p0sixspwn](https://www.theiphonewiki.com/wiki/p0sixspwn)

32
resources/blobs.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
SaveOTABlobs() {
local SHSHChk
local SHSHExisting
Log "Saving $OSVer blobs with tsschecker..."
BuildManifest="resources/manifests/BuildManifest_${ProductType}_${OSVer}.plist"
if [[ $DeviceProc == 7 ]]; then
APNonce=$($irecovery -q | grep "NONC" | cut -c 7-)
Log "APNonce: $APNonce"
$tsschecker -d $ProductType -B ${HWModel}ap -i $OSVer -e $UniqueChipID -m $BuildManifest --apnonce $APNonce -o -s
SHSHChk=${UniqueChipID}_${ProductType}_${HWModel}ap_${OSVer}-${BuildVer}_${APNonce}.shsh*
else
$tsschecker -d $ProductType -i $OSVer -e $UniqueChipID -m $BuildManifest -o -s
SHSHChk=${UniqueChipID}_${ProductType}_${OSVer}-${BuildVer}*.shsh*
fi
SHSH=$(ls $SHSHChk)
SHSHExisting=$(ls saved/shsh/$SHSHChk 2>/dev/null)
if [[ ! $SHSH && ! $SHSHExisting ]]; then
Error "Saving $OSVer blobs failed. Please run the script again" \
"It is also possible that $OSVer for $ProductType is no longer signed"
elif [[ ! $SHSH ]]; then
Log "Saving $OSVer blobs failed, but detected existing saved SHSH blobs. Continuing..."
cp $SHSHExisting .
SHSH=$(ls $SHSHChk)
else
mkdir -p saved/shsh 2>/dev/null
[[ ! $SHSHExisting ]] && cp "$SHSH" saved/shsh
Log "Successfully saved $OSVer blobs."
fi
}

146
resources/depends.sh Executable file
View File

@ -0,0 +1,146 @@
#!/bin/bash
SetToolPaths() {
if [[ $OSTYPE == "linux"* ]]; then
. /etc/os-release 2>/dev/null
platform="linux"
futurerestore1="sudo LD_PRELOAD=./resources/lib/libcurl.so.3 LD_LIBRARY_PATH=resources/lib ./resources/tools/futurerestore1_linux"
futurerestore2="sudo LD_LIBRARY_PATH=resources/lib ./resources/tools/futurerestore2_linux"
idevicerestore="sudo LD_LIBRARY_PATH=resources/lib ./resources/tools/idevicerestore_linux"
ipsw="env LD_LIBRARY_PATH=./lib ./tools/ipsw_linux"
partialzip="./resources/tools/partialzip_linux"
python="$(which python2)"
tsschecker="./resources/tools/tsschecker_linux"
ipwndfu="sudo $python ipwndfu"
rmsigchks="sudo $python rmsigchks.py"
SimpleHTTPServer="sudo $python -m SimpleHTTPServer 80"
elif [[ $OSTYPE == "darwin"* ]]; then
macver=${1:-$(sw_vers -productVersion)}
platform="macos"
futurerestore1="./resources/tools/futurerestore1_macos"
futurerestore2="./resources/tools/futurerestore2_macos"
idevicerestore="./resources/tools/idevicerestore_macos"
ipsw="./tools/ipsw_macos"
ipwnder32="./resources/tools/ipwnder32_macos"
partialzip="./resources/tools/partialzip_macos"
python="/usr/bin/python"
tsschecker="./resources/tools/tsschecker_macos"
ipwndfu="$python ipwndfu"
rmsigchks="$python rmsigchks.py"
SimpleHTTPServer="$python -m SimpleHTTPServer 80"
fi
bspatch="$(which bspatch)"
git="$(which git)"
ideviceenterrecovery="./resources/libimobiledevice_$platform/ideviceenterrecovery"
ideviceinfo="./resources/libimobiledevice_$platform/ideviceinfo"
iproxy="./resources/libimobiledevice_$platform/iproxy"
irecoverychk="./resources/libimobiledevice_$platform/irecovery"
irecovery="$irecoverychk"
[[ $platform == "linux" ]] && irecovery="sudo $irecovery"
SSH="-F ./resources/ssh_config"
SCP="$(which scp) $SSH"
SSH="$(which ssh) $SSH"
Log "Running on platform: $platform $macver"
}
SaveExternal() {
ExternalURL="https://github.com/LukeZGD/$1.git"
External=$1
[[ $1 == "iOS-OTA-Downgrader-Keys" ]] && External="firmware"
cd resources
if [[ ! -d $External || ! -d $External/.git ]]; then
Log "Downloading $External..."
rm -rf $External
$git clone $ExternalURL $External
fi
if [[ ! -e $External/README.md || ! -d $External/.git ]]; then
rm -rf $External
Error "Downloading/updating $1 failed. Please run the script again"
fi
cd ..
}
SaveFile() {
curl -L $1 -o $2
if [[ $(shasum $2 | awk '{print $1}') != $3 ]]; then
Error "Verifying failed. Please run the script again" "./restore.sh Install"
fi
}
SavePkg() {
if [[ ! -d ../saved/lib ]]; then
Log "Downloading packages..."
SaveFile https://github.com/LukeZGD/iOS-OTA-Downgrader-Keys/releases/download/tools/depends2_linux.zip depends_linux.zip 38cf1db21c9aba88f0de95a1a7959ac2ac53c464
mkdir -p ../saved/lib
unzip depends_linux.zip -d ../saved/lib
fi
cp ../saved/lib/* .
}
InstallDepends() {
local iproxy
local libimobiledevice
mkdir resources/lib tmp 2>/dev/null
cd resources
rm -rf firmware ipwndfu lib/*
cd ../tmp
Log "Installing dependencies..."
if [[ $ID == "arch" || $ID_LIKE == "arch" ]]; then
sudo pacman -Syu --noconfirm --needed base-devel bsdiff curl libcurl-compat libpng12 libimobiledevice libzip openssh openssl-1.0 python2 unzip usbutils
ln -sf /usr/lib/libcurl.so.3 ../resources/lib/libcurl.so.3
ln -sf /usr/lib/libzip.so.5 ../resources/lib/libzip.so.4
elif [[ $UBUNTU_CODENAME == "focal" || $UBUNTU_CODENAME == "groovy" ||
$UBUNTU_CODENAME == "hirsute" || $PRETTY_NAME == "Debian GNU/Linux bullseye/sid" ]]; then
[[ ! -z $UBUNTU_CODENAME ]] && sudo add-apt-repository -y universe
sudo apt update
sudo apt install -y bsdiff curl git libimobiledevice6 openssh-client python2 usbmuxd usbutils
SavePkg
cp libcrypto.so.1.0.0 libcurl.so.3 libpng12.so.0 libssl.so.1.0.0 ../resources/lib
if [[ $PRETTY_NAME == "Debian GNU/Linux bullseye/sid" || $UBUNTU_CODENAME == "hirsute" ]]; then
sudo apt install -y libzip4
else
cp libzip.so.4 ../resources/lib
fi
elif [[ $ID == "fedora" ]] && (( $VERSION_ID >= 33 )); then
sudo dnf install -y bsdiff git libimobiledevice libpng12 libzip perl-Digest-SHA python2
SavePkg
cp libcrypto.so.1.0.0 libssl.so.1.0.0 ../resources/lib
ln -sf /usr/lib64/libzip.so.5 ../resources/lib/libzip.so.4
ln -sf /usr/lib64/libbz2.so.1.* ../resources/lib/libbz2.so.1.0
elif [[ $ID == "opensuse-tumbleweed" ]]; then
sudo zypper -n in git imobiledevice-tools libusbmuxd-tools libimobiledevice libpng12-0 libopenssl1_0_0 python-base
ln -sf /usr/lib64/libzip.so.5 ../resources/lib/libzip.so.4
elif [[ $platform == "macos" ]]; then
xcode-select --install
libimobiledevice=("https://github.com/libimobiledevice-win32/imobiledevice-net/releases/download/v1.3.14/libimobiledevice.1.2.1-r1116-osx-x64.zip" "328e809dea350ae68fb644225bbf8469c0f0634b")
else
Error "Distro not detected/supported by the install script." "See the repo README for supported OS versions/distros"
fi
if [[ $platform == "linux" ]]; then
libimobiledevice=("https://github.com/LukeZGD/iOS-OTA-Downgrader-Keys/releases/download/tools/libimobiledevice_linux.zip" "4344b3ca95d7433d5a49dcacc840d47770ba34c4")
fi
if [[ ! -d ../resources/libimobiledevice_$platform ]]; then
SaveFile ${libimobiledevice[0]} libimobiledevice.zip ${libimobiledevice[1]}
mkdir ../resources/libimobiledevice_$platform
unzip libimobiledevice.zip -d ../resources/libimobiledevice_$platform
chmod +x ../resources/libimobiledevice_$platform/*
fi
cd ..
Log "Install script done! Please run the script again to proceed"
exit
}

287
resources/device.sh Executable file
View File

@ -0,0 +1,287 @@
#!/bin/bash
FindDevice() {
local USB
[[ $1 == "DFU" ]] && USB=1227 || USB=1281
Log "Finding device in $1 mode..."
while [[ $DeviceState != "$1" ]]; do
[[ $platform == "linux" ]] && DeviceState=$(lsusb | grep -c $USB)
[[ $platform == "macos" && $($irecovery -q 2>/dev/null | grep "MODE" | cut -c 7-) == "$1" ]] && DeviceState=1
[[ $DeviceState == 1 ]] && DeviceState="$1"
sleep 1
done
Log "Found device in $1 mode."
}
GetDeviceValues() {
local ideviceinfo2
Log "Finding device in Normal mode..."
ideviceinfo2=$($ideviceinfo -s)
if [[ $? != 0 ]]; then
Log "Finding device in DFU/recovery mode..."
DeviceState="$($irecovery -q 2>/dev/null | grep "MODE" | cut -c 7-)"
else
DeviceState="Normal"
fi
if [[ $DeviceState == "DFU" || $DeviceState == "Recovery" ]]; then
local ProdCut=7
ProductType=$($irecovery -qv 2>&1 | grep "iP" | cut -c 14-)
[[ $(echo $ProductType | cut -c 3) == 'h' ]] && ProdCut=9
ProductType=$(echo $ProductType | cut -c -$ProdCut)
UniqueChipID=$((16#$(echo $($irecovery -q | grep "ECID" | cut -c 7-) | cut -c 3-)))
ProductVer="Unknown"
else
ProductType=$(echo "$ideviceinfo2" | grep "ProductType" | cut -c 14-)
[[ ! $ProductType ]] && ProductType=$($ideviceinfo | grep "ProductType" | cut -c 14-)
ProductVer=$(echo "$ideviceinfo2" | grep "ProductVer" | cut -c 17-)
UniqueChipID=$(echo "$ideviceinfo2" | grep "UniqueChipID" | cut -c 15-)
UniqueDeviceID=$(echo "$ideviceinfo2" | grep "UniqueDeviceID" | cut -c 17-)
fi
if [[ ! $ProductType ]]; then
Error "No device detected. Please put the device in normal mode before proceeding. Recovery or DFU mode is also applicable" \
"For more details regarding alternative methods, read the 'Other Notes' section of the README"
fi
Firmware=resources/firmware/$ProductType
Baseband=0
BasebandURL=$(cat $Firmware/13G37/url 2>/dev/null)
if [[ $ProductType == "iPad2,2" ]]; then
BasebandURL=$(cat $Firmware/13G36/url)
Baseband="ICE3_04.12.09_BOOT_02.13.Release.bbfw"
BasebandSHA1="e6f54acc5d5652d39a0ef9af5589681df39e0aca"
elif [[ $ProductType == "iPad2,3" ]]; then
Baseband="Phoenix-3.6.03.Release.bbfw"
BasebandSHA1="8d4efb2214344ea8e7c9305392068ab0a7168ba4"
elif [[ $ProductType == "iPad2,6" || $ProductType == "iPad2,7" ]]; then
Baseband="Mav5-11.80.00.Release.bbfw"
BasebandSHA1="aa52cf75b82fc686f94772e216008345b6a2a750"
elif [[ $ProductType == "iPad3,2" || $ProductType == "iPad3,3" ]]; then
Baseband="Mav4-6.7.00.Release.bbfw"
BasebandSHA1="a5d6978ecead8d9c056250ad4622db4d6c71d15e"
elif [[ $ProductType == "iPhone4,1" ]]; then
Baseband="Trek-6.7.00.Release.bbfw"
BasebandSHA1="22a35425a3cdf8fa1458b5116cfb199448eecf49"
elif [[ $ProductType == "iPad3,5" || $ProductType == "iPad3,6" ||
$ProductType == "iPhone5,1" || $ProductType == "iPhone5,2" ]]; then
BasebandURL=$(cat $Firmware/14G61/url)
Baseband="Mav5-11.80.00.Release.bbfw"
BasebandSHA1="8951cf09f16029c5c0533e951eb4c06609d0ba7f"
elif [[ $ProductType == "iPad4,2" || $ProductType == "iPad4,3" || $ProductType == "iPad4,5" ||
$ProductType == "iPhone6,1" || $ProductType == "iPhone6,2" ]]; then
BasebandURL=$(cat $Firmware/14G60/url)
Baseband="Mav7Mav8-7.60.00.Release.bbfw"
BasebandSHA1="f397724367f6bed459cf8f3d523553c13e8ae12c"
elif [[ $ProductType != "iPad2"* && $ProductType != "iPad3"* && $ProductType != "iPad4,1" &&
$ProductType != "iPad4,4" && $ProductType != "iPod5,1" && $ProductType != "iPhone5"* ]]; then
Error "Your device $ProductType is not supported."
else
BasebandURL=0
fi
if [[ $ProductType == "iPad2"* || $ProductType == "iPad3,1" || $ProductType == "iPad3,2" ||
$ProductType == "iPad3,3" || $ProductType == "iPhone4,1" || $ProductType == "iPod5,1" ]]; then
DeviceProc=5
elif [[ $ProductType == "iPad3,4" || $ProductType == "iPad3,5" ||
$ProductType == "iPad3,6" || $ProductType == "iPhone5"* ]]; then
DeviceProc=6
elif [[ $ProductType == "iPhone6"* || $ProductType == "iPad4"* ]]; then
DeviceProc=7
fi
HWModel=$(cat $Firmware/hwmodel)
if [[ ! $BasebandURL || ! $HWModel ]]; then
Error "GetDeviceValues: Missing BasebandURL and/or HWModel values. Is the firmware folder missing?" \
"Reinstall dependencies and try again. For more details, read the 'Other Notes' section of the README"
fi
if [[ $ProductType == "iPod5,1" ]]; then
iBSS="${HWModel}ap"
iBSSBuildVer="10B329"
elif [[ $ProductType == "iPad3,1" ]]; then
iBSS="${HWModel}ap"
iBSSBuildVer="11D257"
elif [[ $ProductType == "iPhone6"* ]]; then
iBSS="iphone6"
IPSWType="iPhone_4.0_64bit"
elif [[ $ProductType == "iPad4"* ]]; then
iBSS="ipad4"
IPSWType="iPad_64bit"
else
iBSS="$HWModel"
iBSSBuildVer="12H321"
fi
[[ ! $IPSWType ]] && IPSWType="$ProductType"
iBEC="iBEC.$iBSS.RELEASE"
iBECb="iBEC.${iBSS}b.RELEASE"
iBSSb="iBSS.${iBSS}b.RELEASE"
iBSS="iBSS.$iBSS.RELEASE"
SEP="sep-firmware.$HWModel.RELEASE.im4p"
Log "Found $ProductType in $DeviceState mode."
}
CheckM8() {
local pwnDFUTool
[[ $platform == macos ]] && pwnDFUTool="iPwnder32" || pwnDFUTool="ipwndfu"
Log "Entering pwnDFU mode with $pwnDFUTool..."
if [[ $pwnDFUTool == "ipwndfu" ]]; then
cd resources/ipwndfu
$ipwndfu -p
elif [[ $pwnDFUTool == "iPwnder32" ]]; then
$ipwnder32 -p
cd resources/ipwndfu
fi
if [[ $DeviceProc == 7 ]]; then
Log "Running rmsigchks.py..."
$rmsigchks
pwnDFUDevice=$?
cd ../..
else
cd ../..
[[ $pwnDFUTool == "ipwndfu" ]] && kDFU iBSS || echo
pwnDFUDevice=$?
fi
if [[ $pwnDFUDevice == 1 || $pwnDFUDevice == 255 ]]; then
echo -e "\n${Color_R}[Error] Failed to enter pwnDFU mode. Please run the script again: ./restore.sh Downgrade ${Color_N}"
echo "${Color_Y}* This step may fail a lot, especially on Linux, and unfortunately there is nothing I can do about the low success rates. ${Color_N}"
echo "${Color_Y}* The only option is to make sure you are using an Intel device, and to try multiple times ${Color_N}"
Echo "* For more details, read the 'Other Notes' section of the README"
exit 1
elif [[ $pwnDFUDevice == 0 ]]; then
Log "Device in pwnDFU mode detected."
fi
}
Recovery() {
local RecoveryDFU
if [[ $DeviceState != "Recovery" ]]; then
Log "Entering recovery mode..."
$ideviceenterrecovery $UniqueDeviceID >/dev/null
FindDevice "Recovery"
fi
Log "Get ready to enter DFU mode."
read -p "$(Input 'Select Y to continue, N to exit recovery (Y/n)')" RecoveryDFU
if [[ $RecoveryDFU == 'N' || $RecoveryDFU == 'n' ]]; then
Log "Exiting recovery mode."
$irecovery -n
exit
fi
Echo "* Hold POWER and HOME button for 8 seconds."
for i in {08..01}; do
echo -n "$i "
sleep 1
done
echo -e "\n$(Echo '* Release POWER and hold HOME button for 8 seconds.')"
for i in {08..01}; do
echo -n "$i "
sleep 1
done
echo
FindDevice "DFU"
CheckM8
}
kDFU() {
local kloader
local VerDetect=$(echo $ProductVer | cut -c 1)
if [[ ! -e saved/$ProductType/$iBSS.dfu ]]; then
Log "Downloading iBSS..."
$partialzip $(cat $Firmware/$iBSSBuildVer/url) Firmware/dfu/$iBSS.dfu $iBSS.dfu
mkdir -p saved/$ProductType 2>/dev/null
mv $iBSS.dfu saved/$ProductType
fi
if [[ ! -e saved/$ProductType/$iBSS.dfu ]]; then
Error "Failed to save iBSS. Please run the script again"
fi
Log "Patching iBSS..."
$bspatch saved/$ProductType/$iBSS.dfu tmp/pwnediBSS resources/patches/$iBSS.patch
if [[ $1 == iBSS ]]; then
cd resources/ipwndfu
Log "Sending iBSS..."
$ipwndfu -l ../../tmp/pwnediBSS
local ret=$?
cd ../..
return $ret
fi
[[ $VerDetect == 1 ]] && kloader="kloader_hgsp"
[[ $VerDetect == 5 ]] && kloader="kloader5"
[[ ! $kloader ]] && kloader="kloader"
$iproxy 2222 22 &
iproxyPID=$!
Log "Copying stuff to device via SSH..."
Echo "* Make sure OpenSSH/Dropbear is installed on the device and running!"
Echo "* Dropbear is only needed for devices on iOS 10"
Echo "* To make sure that SSH is successful, try these steps:"
Echo "* Reinstall OpenSSH/Dropbear, reboot and rejailbreak, then reinstall them again"
echo
Input "Enter the root password of your iOS device when prompted"
Echo "* The default password is 'alpine'"
$SCP -P 2222 resources/tools/$kloader tmp/pwnediBSS root@127.0.0.1:/tmp
if [[ $? == 0 ]]; then
$SSH -p 2222 root@127.0.0.1 "/tmp/$kloader /tmp/pwnediBSS" &
else
Log "Cannot connect to device via USB SSH."
Echo "* Please try the steps above to make sure that SSH is successful"
Echo "* Alternatively, you may use kDFUApp by tihmstar (from my repo, see README)"
Input "Press Enter/Return to continue anyway (or press Ctrl+C to cancel and try again)"
read -s
Log "Will try again with Wi-Fi SSH..."
Echo "* Make sure that the device and your PC/Mac are on the same network!"
Echo "* You can check for your device's IP Address in: Settings > WiFi/WLAN > tap the 'i' next to your network name"
read -p "$(Input 'Enter the IP Address of your device:')" IPAddress
Log "Copying stuff to device via SSH..."
$SCP resources/tools/$kloader tmp/pwnediBSS root@$IPAddress:/tmp
[[ $? == 1 ]] && Error "Cannot connect to device via SSH." "Please try the steps above to make sure that SSH is successful"
$SSH root@$IPAddress "/tmp/$kloader /tmp/pwnediBSS" &
fi
Log "Entering kDFU mode..."
Echo "* Press POWER or HOME button when screen goes black on the device"
FindDevice "DFU"
}
pwnREC() {
if [[ $ProductType == "iPad4,4" || $ProductType == "iPad4,5" ]]; then
Log "iPad mini 2 device detected. Setting iBSS and iBEC to 'ipad4b'"
iBEC=$iBECb
iBSS=$iBSSb
fi
Log "Entering pwnREC mode..."
Log "Sending iBSS..."
$irecovery -f $IPSWCustom/Firmware/dfu/$iBSS.im4p
$irecovery -f $IPSWCustom/Firmware/dfu/$iBSS.im4p
Log "Sending iBEC..."
$irecovery -f $IPSWCustom/Firmware/dfu/$iBEC.im4p
sleep 5
Echo "* If your device has backlight turned on, you may try unplugging and re-plugging in your device to attempt to continue"
Echo "* If not, you may have to hard-reset your device and start over entering pwnDFU mode again"
Echo "* You can press Ctrl+C to cancel finding device"
FindDevice "Recovery"
}

186
resources/downgrade.sh Executable file
View File

@ -0,0 +1,186 @@
#!/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
if [[ $platform == "macos" && $? != 0 ]]; then
Log "An error seems to have occurred when running idevicerestore."
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"
fi
}
FRBaseband() {
local BasebandSHA1L
if [[ $DeviceProc == 7 ]]; then
mkdir -p saved/baseband 2>/dev/null
cp -f $IPSW/Firmware/$Baseband saved/baseband
elif [[ $ProductType == "iPhone5,1" && $Baseband5 != 0 ]]; then
unzip -o -j $IPSW.ipsw Firmware/$Baseband -d .
elif [[ ! -e saved/baseband/$Baseband ]]; then
Log "Downloading baseband..."
$partialzip $BasebandURL Firmware/$Baseband $Baseband
$partialzip $BasebandURL BuildManifest.plist BuildManifest.plist
mkdir -p saved/$ProductType 2>/dev/null
mkdir -p saved/baseband 2>/dev/null
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() {
local ExtraArgs
local futurerestore
if [[ $DeviceProc == 7 ]]; then
ExtraArgs="-s $IPSWCustom/Firmware/all_flash/$SEP -m $BuildManifest"
futurerestore=$futurerestore2
else
ExtraArgs="--use-pwndfu"
futurerestore=$futurerestore1
fi
Log "Proceeding to futurerestore..."
if [[ $Baseband == 0 ]]; then
Log "Device $ProductType has no baseband"
$futurerestore -t $SHSH --no-baseband $ExtraArgs $IPSWRestore.ipsw
else
FRBaseband
$futurerestore -t $SHSH -b saved/baseband/$Baseband -p $BuildManifest $ExtraArgs "$IPSWRestore.ipsw"
fi
}
Downgrade() {
local IPSWExtract
local IPSWSHA1
local IPSWSHA1L
local Jailbreak
local Verify
if [[ $OSVer == "Other" ]]; then
Echo "* Move/copy the IPSW and SHSH to the directory where the script is located"
Echo "* Remember to create a backup of the SHSH"
read -p "$(Input 'Path to IPSW (drag IPSW to terminal window):')" IPSW
IPSW="$(basename $IPSW .ipsw)"
read -p "$(Input 'Path to SHSH (drag SHSH to terminal window):')" SHSH
elif [[ $Mode == "Downgrade" && $DeviceProc != 7 ]]; then
read -p "$(Input 'Jailbreak the selected iOS version? (y/N):')" Jailbreak
[[ $Jailbreak == 'Y' || $Jailbreak == 'y' ]] && Jailbreak=1
if [[ $ProductType == "iPad2,5" || $ProductType == "iPad2,6" ||
$ProductType == "iPad2,7" || $ProductType == "iPod5,1" ]]; then
Log "Warning - A5 Rev A device detected. Enabling the jailbreak option might not work for you"
read -p "$(Input 'Select Y to continue anyway, N to cancel and exit (y/N):')" Jailbreak
[[ $Jailbreak == 'Y' || $Jailbreak == 'y' ]] && Jailbreak=1 || exit
fi
fi
if [[ $Mode == "Downgrade" && $ProductType == iPhone5,1 && $Jailbreak != 1 ]]; then
Echo "* By default, iOS-OTA-Downgrader now flashes the iOS 8.4.1 baseband to iPhone5,1"
Echo "* Flashing the latest baseband is still available as an option but beware of problems it may cause"
Echo "* There are potential network issues that with the latest baseband when used on iOS 8.4.1"
read -p "$(Input 'Flash the latest baseband? (y/N) (press Enter/Return if unsure):')" Baseband5
if [[ $Baseband5 == 'Y' || $Baseband5 == 'y' ]]; then
Baseband5=0
else
BasebandURL=$(cat $Firmware/12H321/url)
Baseband="Mav5-8.02.00.Release.bbfw"
BasebandSHA1="db71823841ffab5bb41341576e7adaaeceddef1c"
fi
fi
if [[ $OSVer != "Other" ]]; then
[[ $DeviceProc != 7 ]] && SaveOTABlobs
IPSW="${IPSWType}_${OSVer}_${BuildVer}_Restore"
IPSWCustom="${IPSWType}_${OSVer}_${BuildVer}_Custom"
if [[ ! -e "$IPSW.ipsw" && ! -e "$IPSWCustom.ipsw" ]]; then
Log "iOS $OSVer IPSW cannot be found."
Echo "* If you already downloaded the IPSW, did you put it in the same directory as the script?"
Echo "* Do NOT rename the IPSW as the script will fail to detect it"
Log "Downloading IPSW... (Press Ctrl+C to cancel)"
curl -L $(cat $Firmware/$BuildVer/url) -o tmp/$IPSW.ipsw
mv tmp/$IPSW.ipsw .
fi
if [[ $Jailbreak == 1 || $DeviceProc == 7 ]]; then
[[ ! -e "$IPSWCustom.ipsw" ]] && Verify=1
elif [[ -z $Jailbreak ]]; then
Verify=1
fi
if [[ $Verify == 1 ]]; then
Log "Verifying IPSW..."
IPSWSHA1=$(cat $Firmware/$BuildVer/sha1sum)
IPSWSHA1L=$(shasum $IPSW.ipsw | awk '{print $1}')
if [[ $IPSWSHA1L != $IPSWSHA1 ]]; then
Error "Verifying IPSW failed. Your IPSW may be corrupted or incomplete." \
"Delete/replace the IPSW and run the script again"
fi
elif [[ -e "$IPSWCustom.ipsw" ]]; then
Log "Found existing Custom IPSW. Skipping verification."
Log "Setting restore IPSW to: $IPSWCustom.ipsw"
IPSWRestore=$IPSWCustom
fi
if [[ $DeviceState == "Normal" && $iBSSBuildVer == $BuildVer ]]; then
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
fi
[[ $DeviceState == "Normal" ]] && kDFU
if [[ $Jailbreak == 1 || $IPSWRestore == $IPSWCustom ]]; then
[[ $Jailbreak == 1 ]] && IPSW32
IPSWExtract=$IPSWCustom
else
IPSWExtract=$IPSW
fi
Log "Extracting IPSW: $IPSWExtract.ipsw"
unzip -q $IPSWExtract.ipsw -d $IPSWExtract/
if [[ $DeviceProc == 7 ]]; then
IPSW64
pwnREC
SaveOTABlobs
elif [[ $Jailbreak != 1 && $OSVer != "Other" ]]; then
Log "Preparing for futurerestore... (Enter root password of your PC/Mac when prompted)"
cd resources
$SimpleHTTPServer &
ServerRunning=1
cd ..
fi
if [[ ! $IPSWRestore ]]; then
Log "Setting restore IPSW to: $IPSW.ipsw"
IPSWRestore="$IPSW"
fi
if [[ $Jailbreak == 1 ]]; then
iDeviceRestore
else
FutureRestore
fi
echo
Log "Restoring done!"
Log "Downgrade script done!"
}

View File

@ -1,48 +0,0 @@
#!/bin/bash
trap 'echo "Exiting..."' EXIT
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig:/usr/lib64/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig
echo "This script can be used to compile tools used by iOS-OTA-Downgrader for Linux"
Clone() {
git clone $3 https://github.com/$1/$2
}
Compile() {
[[ $3 == --recursive ]] && Clone $1 $2 $3 || Clone $1 $2
cd $2
[[ -e autogen.sh ]] && ./autogen.sh $3 $4
make
sudo make install
cd ..
}
. /etc/os-release
if [[ $UBUNTU_CODENAME != "focal" ]]; then
echo "This compile script supports Ubuntu 20.04 only"
exit 1
fi
sudo apt update
sudo apt install -y libtool automake g++ python-dev libzip-dev libcurl4-openssl-dev cmake libssl-dev libusb-1.0-0-dev libreadline-dev libbz2-dev libpng-dev pkg-config git
Compile matteyeux partial-zip #partialzip_linux
Compile lzfse lzfse
Compile libimobiledevice libplist
Compile libimobiledevice libusbmuxd
Compile libimobiledevice libimobiledevice
Compile LukeZGD libirecovery #irecovery_linux
Compile LukeZGD libgeneral --enable-static --disable-shared
Compile LukeZGD libfragmentzip --enable-static --disable-shared
Compile LukeZGD img4tool --enable-static --disable-shared
Compile tihmstar tsschecker --recursive #tsschecker_linux
Compile LukeeGD futurerestore --recursive #futurerestore2_linux
mkdir tools
cp partial-zip/partialzip tools/partialzip_linux
cp libirecovery/tools/irecovery tools/irecovery_linux
cp tsschecker/tsschecker/tsschecker tools/tsschecker_linux
cp futurerestore/futurerestore/futurerestore tools/futurerestore2_linux
echo "Done"

74
resources/ipsw.sh Executable file
View File

@ -0,0 +1,74 @@
#!/bin/bash
IPSW32() {
local JBFiles
local JBMemory
local JBSHA1
local JBS
if [[ $IPSWRestore == $IPSWCustom ]]; then
Log "Found existing Custom IPSW. Skipping IPSW creation."
return
fi
if [[ $OSVer == 8.4.1 ]]; then
JBFiles=(fstab.tar etasonJB-untether.tar Cydia8.tar)
JBSHA1=6459dbcbfe871056e6244d23b33c9b99aaeca970
JBS=2305
else
JBFiles=(fstab_rw.tar p0sixspwn.tar Cydia6.tar)
JBSHA1=1d5a351016d2546aa9558bc86ce39186054dc281
JBS=1260
fi
if [[ ! -e resources/jailbreak/${JBFiles[2]} ]]; then
cd tmp
Log "Downloading jailbreak files..."
SaveFile https://github.com/LukeZGD/iOS-OTA-Downgrader-Keys/releases/download/jailbreak/${JBFiles[2]} ${JBFiles[2]} $JBSHA1
mv ${JBFiles[2]} ../resources/jailbreak
cd ..
fi
for i in {0..2}; do
JBFiles[$i]=jailbreak/${JBFiles[$i]}
done
if [[ ! -e $IPSWCustom.ipsw ]]; then
Echo "* By default, memory option is set to Y, you may select N later if you encounter problems"
Echo "* If it doesn't work with both, you might not have enough RAM and/or tmp storage"
read -p "$(Input 'Memory option? (press Enter/Return if unsure) (Y/n):')" JBMemory
[[ $JBMemory != 'N' && $JBMemory != 'n' ]] && JBMemory="-memory" || JBMemory=
Log "Preparing custom IPSW..."
cd resources
ln -sf firmware/FirmwareBundles FirmwareBundles
$ipsw ../$IPSW.ipsw ../$IPSWCustom.ipsw $JBMemory -bbupdate -s $JBS ${JBFiles[@]}
cd ..
fi
if [[ ! -e $IPSWCustom.ipsw ]]; then
Error "Failed to find custom IPSW. Please run the script again" \
"You may try selecting N for memory option"
fi
Log "Setting restore IPSW to: $IPSWCustom.ipsw"
IPSWRestore=$IPSWCustom
}
IPSW64() {
if [[ $IPSWRestore == $IPSWCustom ]]; then
Log "Found existing Custom IPSW. Skipping IPSW creation."
return
fi
Log "Preparing custom IPSW..."
$bspatch $IPSW/Firmware/dfu/$iBSS.im4p $iBSS.im4p resources/patches/$iBSS.patch
$bspatch $IPSW/Firmware/dfu/$iBEC.im4p $iBEC.im4p resources/patches/$iBEC.patch
if [[ $ProductType == "iPad4"* ]]; then
$bspatch $IPSW/Firmware/dfu/$iBSSb.im4p $iBSSb.im4p resources/patches/$iBSSb.patch
$bspatch $IPSW/Firmware/dfu/$iBECb.im4p $iBECb.im4p resources/patches/$iBECb.patch
mv -f $iBSSb.im4p $iBECb.im4p $IPSW/Firmware/dfu
fi
mv -f $iBSS.im4p $iBEC.im4p $IPSW/Firmware/dfu
cd $IPSW
zip ../$IPSWCustom.ipsw -rq0 *
cd ..
mv $IPSW $IPSWCustom
[[ ! -e $IPSWCustom.ipsw ]] && Error "Failed to find custom IPSW. Please run the script again"
Log "Setting restore IPSW to: $IPSWCustom.ipsw"
IPSWRestore=$IPSWCustom
}

View File

0
resources/manifests/BuildManifest_iPad4,1_10.3.3.plist Executable file → Normal file
View File

0
resources/manifests/BuildManifest_iPad4,2_10.3.3.plist Executable file → Normal file
View File

0
resources/manifests/BuildManifest_iPad4,3_10.3.3.plist Executable file → Normal file
View File

0
resources/manifests/BuildManifest_iPad4,4_10.3.3.plist Executable file → Normal file
View File

0
resources/manifests/BuildManifest_iPad4,5_10.3.3.plist Executable file → Normal file
View File

File diff suppressed because it is too large Load Diff

View File

View File

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,13 @@
#!/bin/bash #!/bin/bash
trap 'Clean; exit' INT TERM EXIT trap "Clean; exit" INT TERM EXIT
if [[ $1 != 'NoColor' ]] && [[ $2 != 'NoColor' ]]; then
. ./resources/blobs.sh
. ./resources/depends.sh
. ./resources/device.sh
. ./resources/downgrade.sh
. ./resources/ipsw.sh
if [[ $1 != 'NoColor' && $2 != 'NoColor' ]]; then
Color_R=$(tput setaf 9) Color_R=$(tput setaf 9)
Color_G=$(tput setaf 10) Color_G=$(tput setaf 10)
Color_B=$(tput setaf 12) Color_B=$(tput setaf 12)
@ -9,7 +16,19 @@ if [[ $1 != 'NoColor' ]] && [[ $2 != 'NoColor' ]]; then
fi fi
Clean() { Clean() {
rm -rf iP*/ shsh/ tmp/ ${UniqueChipID}_${ProductType}_*.shsh2 ${UniqueChipID}_${ProductType}_${HWModel}ap_*.shsh *.im4p *.bbfw BuildManifest.plist rm -rf iP*/ shsh/ tmp/ *.im4p *.bbfw ${UniqueChipID}_${ProductType}_*.shsh2 \
${UniqueChipID}_${ProductType}_${HWModel}ap_*.shsh BuildManifest.plist
kill $iproxyPID 2>/dev/null
if [[ $ServerRunning == 1 ]]; then
Log "Stopping local server..."
if [[ $platform == "macos" ]]; then
ps aux | awk '/python/ {print "kill -9 "$2" 2>/dev/null"}' | bash
elif [[ $platform == "linux" ]]; then
Echo "* Enter root password of your PC when prompted"
ps aux | awk '/python/ {print "sudo kill -9 "$2" 2>/dev/null"}' | bash
fi
fi
echo
} }
Echo() { Echo() {
@ -32,810 +51,175 @@ Log() {
} }
Main() { Main() {
local SkipMainMenu
clear clear
Echo "******* iOS-OTA-Downgrader *******" Echo "******* iOS-OTA-Downgrader *******"
Echo " Downgrader script by LukeZGD " Echo " Downgrader script by LukeZGD "
echo echo
if [[ $OSTYPE == "linux"* ]]; then SetToolPaths
. /etc/os-release 2>/dev/null
platform="linux"
ideviceenterrecovery="ideviceenterrecovery"
ideviceinfo="ideviceinfo"
idevicerestore="sudo LD_LIBRARY_PATH=resources/lib resources/tools/idevicerestore_linux"
iproxy="iproxy"
ipsw="env LD_LIBRARY_PATH=lib tools/ipsw_linux"
irecoverychk="resources/libirecovery/bin/irecovery"
irecovery="sudo LD_LIBRARY_PATH=resources/lib $irecoverychk"
partialzip="resources/tools/partialzip_linux"
python="python2"
futurerestore1="sudo LD_PRELOAD=resources/lib/libcurl.so.3 LD_LIBRARY_PATH=resources/lib resources/tools/futurerestore1_linux"
futurerestore2="sudo LD_LIBRARY_PATH=resources/lib resources/tools/futurerestore2_linux"
tsschecker="env LD_LIBRARY_PATH=resources/lib resources/tools/tsschecker_linux"
if [[ $UBUNTU_CODENAME == "bionic" ]] || [[ $VERSION == "10 (buster)" ]] ||
[[ $PRETTY_NAME == "openSUSE Leap 15.2" ]]; then
futurerestore2="${futurerestore2}_bionic"
idevicerestore="${idevicerestore}_bionic"
fi
elif [[ $OSTYPE == "darwin"* ]]; then if [[ ! $platform ]]; then
macver=${1:-$(sw_vers -productVersion)} Error "Platform unknown/not supported."
platform="macos"
ideviceenterrecovery="resources/libimobiledevice/ideviceenterrecovery"
ideviceinfo="resources/libimobiledevice/ideviceinfo"
idevicerestore="resources/tools/idevicerestore_macos"
iproxy="resources/libimobiledevice/iproxy"
ipsw="tools/ipsw_macos"
ipwnder32="resources/tools/ipwnder32_macos"
irecovery="resources/libimobiledevice/irecovery"
irecoverychk=$irecovery
partialzip="resources/tools/partialzip_macos"
python="python"
futurerestore1="resources/tools/futurerestore1_macos"
futurerestore2="resources/tools/futurerestore2_macos"
tsschecker="resources/tools/tsschecker_macos"
fi fi
SSH="-F resources/ssh_config"
SCP="scp $SSH"
SSH="ssh $SSH"
[[ ! -d resources ]] && Error "resources folder cannot be found. Replace resources folder and try again" "If resources folder is present try removing spaces from path/folder name" if [[ ! -d ./resources ]]; then
[[ ! $platform ]] && Error "Platform unknown/not supported." Error "resources folder cannot be found. Replace resources folder and try again" \
chmod +x resources/tools/* "If resources folder is present try removing spaces from path/folder name"
[ $? == 1 ] && Log "An error occurred in chmod. This might cause problems..." fi
[[ ! $(ping -c1 8.8.8.8 2>/dev/null) ]] && Error "Please check your Internet connection before proceeding."
if [[ $plaform == macos ]] && [[ $(uname -m) != 'x86_64' ]]; then chmod +x ./resources/*.sh ./resources/tools/*
if [[ $? == 1 ]]; then
Log "Warning - An error occurred in chmod. This might cause problems..."
fi
if [[ ! $(ping -c1 1.1.1.1 2>/dev/null) ]]; then
Error "Please check your Internet connection before proceeding."
fi
if [[ $platform == "macos" && $(uname -m) != "x86_64" ]]; then
Log "M1 Mac detected. Support is limited, the script may or may not work for you" Log "M1 Mac detected. Support is limited, the script may or may not work for you"
Echo "* M1 macs can still proceed but I cannot support it if things break" Echo "* M1 macs can still proceed but I cannot support it if things break"
Echo "* Proceed at your own risk." Echo "* Proceed at your own risk."
Input "Press Enter/Return to continue (or press Ctrl+C to cancel)" Input "Press Enter/Return to continue (or press Ctrl+C to cancel)"
read -s read -s
elif [[ $(uname -m) != 'x86_64' ]]; then elif [[ $(uname -m) != "x86_64" ]]; then
Error "Only x86_64 distributions are supported. Use a 64-bit distro and try again" Error "Only 64-bit (x86_64) distributions are supported."
fi fi
if [[ $1 == Install ]] || [ ! $(which $irecoverychk) ] || [ ! $(which $ideviceinfo) ] || if [[ $1 == "Install" || ! $bspatch || ! $git || ! $ideviceinfo ||! $irecoverychk || ! $python ||
[ ! $(which git) ] || [ ! $(which bspatch) ] || [ ! $(which $python) ]; then ! -d ./resources/libimobiledevice_$platform ]]; then
InstallDependencies Clean
InstallDepends
fi fi
SaveExternal iOS-OTA-Downgrader-Keys SaveExternal iOS-OTA-Downgrader-Keys
SaveExternal ipwndfu SaveExternal ipwndfu
Log "Finding device in normal mode..." GetDeviceValues
ideviceinfo2=$($ideviceinfo -s)
if [[ $? != 0 ]]; then
Log "Finding device in DFU/recovery mode..."
irecovery2=$($irecovery -q 2>/dev/null | grep 'MODE' | cut -c 7-)
fi
[[ $irecovery2 == "DFU" ]] && DFUDevice=1
[[ $irecovery2 == "Recovery" ]] && RecoveryDevice=1
if [[ $DFUDevice == 1 ]] || [[ $RecoveryDevice == 1 ]]; then
ProductType=$($irecovery -q | grep 'PTYP' | cut -c 7-)
[ ! $ProductType ] && read -p "[Input] Enter ProductType (eg. iPad2,1): " ProductType
UniqueChipID=$((16#$(echo $($irecovery -q | grep 'ECID' | cut -c 7-) | cut -c 3-)))
ProductVer='Unknown'
[[ $RecoveryDevice == 1 ]] && Echo "* Your $ProductType is currently in recovery mode. If you want to exit recovery, select Downgrade device, then select N to exit recovery"
else
ProductType=$(echo "$ideviceinfo2" | grep 'ProductType' | cut -c 14-)
[ ! $ProductType ] && ProductType=$($ideviceinfo | grep 'ProductType' | cut -c 14-)
ProductVer=$(echo "$ideviceinfo2" | grep 'ProductVer' | cut -c 17-)
VersionDetect=$(echo $ProductVer | cut -c 1)
UniqueChipID=$(echo "$ideviceinfo2" | grep 'UniqueChipID' | cut -c 15-)
UniqueDeviceID=$(echo "$ideviceinfo2" | grep 'UniqueDeviceID' | cut -c 17-)
fi
[ ! $ProductType ] && ProductType=0
BasebandDetect
Clean Clean
mkdir tmp mkdir tmp
Echo "* Platform: $platform $macver" if [[ $DeviceProc == 7 ]]; then
Echo "* HardwareModel: ${HWModel}ap" if [[ $DeviceState == "Normal" ]]; then
Echo "* ProductType: $ProductType" Echo "* The device needs to be in recovery/DFU mode before proceeding."
Echo "* ProductVersion: $ProductVer" read -p "$(Input 'Send device to recovery mode? (y/N):')" Selection
Echo "* UniqueChipID (ECID): $UniqueChipID" [[ $Selection == 'Y' || $Selection == 'y' ]] && Recovery || exit
echo elif [[ $DeviceState == "Recovery" ]]; then
Recovery
elif [[ $DeviceState == "DFU" ]]; then
CheckM8
fi
if [[ $DFUDevice == 1 ]] && [[ $A7Device != 1 ]]; then elif [[ $DeviceState == "DFU" ]]; then
DFUManual=1 Mode="Downgrade"
Mode='Downgrade'
Log "32-bit device in DFU mode detected."
Echo "* Advanced Options Menu" Echo "* Advanced Options Menu"
Input "This device is in:" Input "This device is in:"
select opt in "kDFU mode" "DFU mode (A6)" "pwnDFU mode (A5)" "(Any other key to exit)"; do Selection=("kDFU mode")
case $opt in [[ $DeviceProc == 5 ]] && Selection+=("pwnDFU mode (A5)")
"kDFU mode" ) break;; [[ $DeviceProc == 6 ]] && Selection+=("DFU mode (A6)")
"DFU mode (A6)" ) CheckM8; break;; Selection+=("Any other key to exit")
"pwnDFU mode (A5)" ) select opt in "${Selection[@]}"; do
Echo "* Make sure that your device is in pwnDFU mode using an Arduino+USB Host Shield!"; case $opt in
Echo "* This option will NOT work if your device is not in pwnDFU mode."; "kDFU mode" ) break;;
Input "Press Enter/Return to continue (or press Ctrl+C to cancel)"; "DFU mode (A6)" ) CheckM8; break;;
read -s; "pwnDFU mode (A5)" )
kDFU iBSS; break;; Echo "* Make sure that your device is in pwnDFU mode using an Arduino+USB Host Shield!";
* ) exit;; Echo "* This option will NOT work if your device is not in pwnDFU mode.";
esac Input "Press Enter/Return to continue (or press Ctrl+C to cancel)";
read -s;
kDFU iBSS; break;;
* ) exit;;
esac
done done
Log "Downgrading $ProductType in kDFU/pwnDFU mode..." Log "Downgrading $ProductType in kDFU/pwnDFU mode..."
SelectVersion Mode="Downgrade"
elif [[ $RecoveryDevice == 1 ]] && [[ $A7Device != 1 ]]; then SkipMainMenu=1
read -p "$(Input 'Is this an A6 device in recovery mode? (y/N) ')" DFUManual
if [[ $DFUManual == y ]] || [[ $DFUManual == Y ]]; then elif [[ $DeviceState == "Recovery" ]]; then
if [[ $DeviceProc == 6 ]]; then
Recovery Recovery
else else
Error "32-bit device detected in recovery mode. Please put the device in normal mode and jailbroken before proceeding" "For usage of 32-bit ipwndfu, put the device in Recovery/DFU mode (A6) or pwnDFU mode (A5 using Arduino)" Log "32-bit A5 device detected in recovery mode."
Echo "* Please put the device in normal mode and jailbroken before proceeding."
Echo "* For usage of advanced DFU options, put the device in kDFU mode (or pwnDFU mode using Arduino + USB Host Shield)"
read -p "$(Input 'Attempt to exit recovery mode? (Y/n)')" Selection
if [[ $Selection != 'N' && $Selection != 'n' ]]; then
Log "Exiting recovery mode."
$irecovery -n
fi
exit
fi fi
Log "Downgrading $ProductType in pwnDFU mode..."
Mode="Downgrade"
SkipMainMenu=1
fi fi
if [[ $1 ]] && [[ $1 != 'NoColor' ]]; then [[ ! -z $1 ]] && SkipMainMenu=1
Mode="$1"
if [[ $SkipMainMenu == 1 && $1 != "NoColor" ]]; then
[[ ! -z $1 ]] && Mode="$1"
else else
Selection=("Downgrade device") Selection=("Downgrade device")
[[ $A7Device != 1 ]] && Selection+=("Save OTA blobs" "Just put device in kDFU mode") [[ $DeviceProc != 7 ]] && Selection+=("Save OTA blobs" "Just put device in kDFU mode")
Selection+=("(Re-)Install Dependencies" "(Any other key to exit)") Selection+=("(Re-)Install Dependencies" "(Any other key to exit)")
Echo "*** Main Menu ***" Echo "*** Main Menu ***"
Input "Select an option:" Input "Select an option:"
select opt in "${Selection[@]}"; do select opt in "${Selection[@]}"; do
case $opt in case $opt in
"Downgrade device" ) Mode='Downgrade'; break;; "Downgrade device" ) Mode="Downgrade"; break;;
"Save OTA blobs" ) Mode='SaveOTABlobs'; break;; "Save OTA blobs" ) Mode="SaveOTABlobs"; break;;
"Just put device in kDFU mode" ) Mode='kDFU'; break;; "Just put device in kDFU mode" ) Mode="kDFU"; break;;
"(Re-)Install Dependencies" ) InstallDependencies;; "(Re-)Install Dependencies" ) InstallDepends;;
* ) exit;; * ) exit;;
esac esac
done done
fi fi
SelectVersion SelectVersion
Log "Option: $Mode"
[[ $Mode == "Downgrade" ]] && Downgrade
[[ $Mode == "SaveOTABlobs" ]] && SaveOTABlobs
[[ $Mode == "kDFU" ]] && kDFU
exit
} }
SelectVersion() { SelectVersion() {
if [[ $ProductType == iPad4* ]] || [[ $ProductType == iPhone6* ]]; then if [[ $Mode == "kDFU" ]]; then
OSVer='10.3.3' return
BuildVer='14G60' elif [[ $ProductType == "iPad4"* || $ProductType == "iPhone6"* ]]; then
Action OSVer="10.3.3"
elif [[ $Mode == 'kDFU' ]]; then BuildVer="14G60"
Action return
fi fi
if [ $ProductType == iPhone5,3 ] || [ $ProductType == iPhone5,4 ]; then
if [[ $ProductType == "iPhone5,3" || $ProductType == "iPhone5,4" ]]; then
Selection=() Selection=()
else else
Selection=("iOS 8.4.1") Selection=("iOS 8.4.1")
fi fi
if [ $ProductType == iPad2,1 ] || [ $ProductType == iPad2,2 ] ||
[ $ProductType == iPad2,3 ] || [ $ProductType == iPhone4,1 ]; then if [[ $ProductType == "iPad2,1" || $ProductType == "iPad2,2" ||
$ProductType == "iPad2,3" || $ProductType == "iPhone4,1" ]]; then
Selection+=("iOS 6.1.3") Selection+=("iOS 6.1.3")
fi fi
[[ $Mode == 'Downgrade' ]] && Selection+=("Other (use SHSH blobs)")
[[ $Mode == "Downgrade" ]] && Selection+=("Other (use SHSH blobs)")
Selection+=("(Any other key to exit)") Selection+=("(Any other key to exit)")
Input "Select iOS version:" Input "Select iOS version:"
select opt in "${Selection[@]}"; do select opt in "${Selection[@]}"; do
case $opt in case $opt in
"iOS 8.4.1" ) OSVer='8.4.1'; BuildVer='12H321'; break;; "iOS 8.4.1" ) OSVer="8.4.1"; BuildVer="12H321"; break;;
"iOS 6.1.3" ) OSVer='6.1.3'; BuildVer='10B329'; break;; "iOS 6.1.3" ) OSVer="6.1.3"; BuildVer="10B329"; break;;
"Other (use SHSH blobs)" ) OSVer='Other'; break;; "Other (use SHSH blobs)" ) OSVer="Other"; break;;
*) exit;; *) exit;;
esac esac
done done
Action
}
Action() {
Log "Option: $Mode"
if [[ $OSVer == 'Other' ]]; then
Echo "* Move/copy the IPSW and SHSH to the directory where the script is located"
Echo "* Remember to create a backup of the SHSH"
read -p "$(Input 'Path to IPSW (drag IPSW to terminal window): ')" IPSW
IPSW="$(basename $IPSW .ipsw)"
read -p "$(Input 'Path to SHSH (drag SHSH to terminal window): ')" SHSH
elif [[ $Mode == 'Downgrade' ]] && [[ $A7Device != 1 ]]; then
read -p "$(Input 'Jailbreak the selected iOS version? (y/N): ')" Jailbreak
[[ $Jailbreak == y ]] || [[ $Jailbreak == Y ]] && Jailbreak=1
elif [[ $A7Device == 1 ]] && [[ $pwnDFUDevice != 0 ]]; then
[[ $DFUDevice == 1 ]] && CheckM8 || Recovery
fi
if [[ $Mode == 'Downgrade' ]] && [[ $ProductType == iPhone5,1 ]] && [[ $Jailbreak != 1 ]]; then
Echo "* By default, iOS-OTA-Downgrader now flashes the iOS 8.4.1 baseband to iPhone5,1"
Echo "* Flashing the latest baseband is still available as an option but beware of problems it may cause"
Echo "* There are potential network issues that with the latest baseband when used on iOS 8.4.1"
read -p "$(Input 'Flash the latest baseband? (y/N) (press Enter/Return if unsure): ')" Baseband5
if [[ $Baseband5 == y ]] || [[ $Baseband5 == Y ]]; then
Baseband5=0
else
BasebandURL=$(cat $Firmware/12H321/url)
Baseband=Mav5-8.02.00.Release.bbfw
BasebandSHA1=db71823841ffab5bb41341576e7adaaeceddef1c
fi
fi
[[ $Mode == 'Downgrade' ]] && Downgrade
[[ $Mode == 'SaveOTABlobs' ]] && SaveOTABlobs
[[ $Mode == 'kDFU' ]] && kDFU
exit
}
SaveOTABlobs() {
Log "Saving $OSVer blobs with tsschecker..."
BuildManifest="resources/manifests/BuildManifest_${ProductType}_${OSVer}.plist"
if [[ $A7Device == 1 ]]; then
APNonce=$($irecovery -q | grep 'NONC' | cut -c 7-)
Echo "* APNonce: $APNonce"
$tsschecker -d $ProductType -B ${HWModel}ap -i $OSVer -e $UniqueChipID -m $BuildManifest --apnonce $APNonce -o -s
SHSHChk=${UniqueChipID}_${ProductType}_${HWModel}ap_${OSVer}-${BuildVer}_${APNonce}.shsh*
else
$tsschecker -d $ProductType -i $OSVer -e $UniqueChipID -m $BuildManifest -o -s
SHSHChk=${UniqueChipID}_${ProductType}_${OSVer}-${BuildVer}*.shsh*
fi
SHSH=$(ls $SHSHChk)
SHSHExisting=$(ls saved/shsh/$SHSHChk 2>/dev/null)
if [ ! $SHSH ] && [ ! $SHSHExisting ]; then
Error "Saving $OSVer blobs failed. Please run the script again" "It is also possible that $OSVer for $ProductType is no longer signed"
elif [ ! $SHSH ]; then
Log "Saving $OSVer blobs failed, but detected existing saved SHSH blobs. Continuing..."
cp $SHSHExisting .
SHSH=$(ls $SHSHChk)
else
mkdir -p saved/shsh 2>/dev/null
[[ ! $SHSHExisting ]] && cp "$SHSH" saved/shsh
Log "Successfully saved $OSVer blobs."
fi
}
kDFU() {
if [ ! -e saved/$ProductType/$iBSS.dfu ]; then
Log "Downloading iBSS..."
$partialzip $(cat $Firmware/$iBSSBuildVer/url) Firmware/dfu/$iBSS.dfu $iBSS.dfu
mkdir -p saved/$ProductType 2>/dev/null
mv $iBSS.dfu saved/$ProductType
fi
[[ ! -e saved/$ProductType/$iBSS.dfu ]] && Error "Failed to save iBSS. Please run the script again"
Log "Patching iBSS..."
bspatch saved/$ProductType/$iBSS.dfu tmp/pwnediBSS resources/patches/$iBSS.patch
if [[ $1 == iBSS ]]; then
cd resources/ipwndfu
Log "Sending iBSS..."
sudo $python ipwndfu -l ../../tmp/pwnediBSS
ret=$?
cd ../..
return $ret
fi
[[ $VersionDetect == 1 ]] && kloader='kloader_hgsp'
[[ $VersionDetect == 5 ]] && kloader='kloader5'
[[ ! $kloader ]] && kloader='kloader'
[ ! $(which $iproxy) ] && Error "iproxy cannot be found. Please re-install dependencies and try again" "./restore.sh Install"
$iproxy 2222 22 &
iproxyPID=$!
Log "Copying stuff to device via SSH..."
Echo "* Make sure OpenSSH/Dropbear is installed on the device and running!"
Echo "* Dropbear is only needed for devices on iOS 10"
Echo "* To make sure that SSH is successful, try these steps:"
Echo "* Reinstall OpenSSH/Dropbear, reboot and rejailbreak, then reinstall them again"
echo
Input "Enter the root password of your iOS device when prompted, default is 'alpine'"
$SCP -P 2222 resources/tools/$kloader tmp/pwnediBSS root@127.0.0.1:/tmp
if [ $? == 1 ]; then
Log "Cannot connect to device via USB SSH."
Echo "* Please try the steps above to make sure that SSH is successful"
Input "Press Enter/Return to continue anyway (or press Ctrl+C to cancel and try again)"
read -s
Log "Will try again with Wi-Fi SSH..."
Echo "* Make sure that the device and your PC/Mac are on the same network!"
Echo "* You can check for your device's IP Address in: Settings > WiFi/WLAN > tap the 'i' next to your network name"
read -p "$(Input 'Enter the IP Address of your device: ')" IPAddress
Log "Copying stuff to device via SSH..."
$SCP resources/tools/$kloader tmp/pwnediBSS root@$IPAddress:/tmp
[ $? == 1 ] && Error "Cannot connect to device via SSH." "Please try the steps above to make sure that SSH is successful"
$SSH root@$IPAddress "/tmp/$kloader /tmp/pwnediBSS" &
else
$SSH -p 2222 root@127.0.0.1 "/tmp/$kloader /tmp/pwnediBSS" &
fi
Log "Entering kDFU mode..."
echo
Echo "* Press POWER or HOME button when screen goes black on the device"
Log "Finding device in DFU mode..."
while [[ $DFUDevice != 1 ]]; do
[[ $platform == linux ]] && DFUDevice=$(lsusb | grep -c '1227')
[[ $platform == macos ]] && [[ $($irecovery -q 2>/dev/null | grep 'MODE' | cut -c 7-) == "DFU" ]] && DFUDevice=1
sleep 1
done
Log "Found device in DFU mode."
kill $iproxyPID
}
Recovery() {
[[ $($irecovery -q 2>/dev/null | grep 'MODE' | cut -c 7-) == "Recovery" ]] && RecoveryDevice=1
if [[ $RecoveryDevice != 1 ]]; then
Log "Entering recovery mode..."
$ideviceenterrecovery $UniqueDeviceID >/dev/null
while [[ $RecoveryDevice != 1 ]]; do
[[ $($irecovery -q 2>/dev/null | grep 'MODE' | cut -c 7-) == "Recovery" ]] && RecoveryDevice=1
done
fi
Log "Device in recovery mode detected. Get ready to enter DFU mode"
read -p "$(Input 'Select Y to continue, N to exit recovery (Y/n) ')" RecoveryDFU
if [[ $RecoveryDFU == n ]] || [[ $RecoveryDFU == N ]]; then
Log "Exiting recovery mode."
$irecovery -n
exit
fi
Echo "* Hold POWER and HOME button for 8 seconds."
for i in {08..01}; do
echo -n "$i "
sleep 1
done
echo -e "\n$(Echo '* Release POWER and hold HOME button for 8 seconds.')"
for i in {08..01}; do
echo -n "$i "
sleep 1
done
[[ $($irecovery -q 2>/dev/null | grep 'MODE' | cut -c 7-) == "DFU" ]] && DFUDevice=1
[[ $DFUDevice == 1 ]] && CheckM8
Error "Failed to detect device in DFU mode. Please run the script again"
}
CheckM8() {
DFUManual=1
[[ $A7Device == 1 ]] && echo -e "\n$(Log 'Device in DFU mode detected.')"
if [[ $platform == macos ]]; then
Selection=("iPwnder32" "ipwndfu")
Input "Select pwnDFU tool to use (Select 1 if unsure):"
select opt in "${Selection[@]}"; do
case $opt in
"ipwndfu" ) pwnDFUTool="ipwndfu"; break;;
*) pwnDFUTool="iPwnder32"; break;;
esac
done
else
pwnDFUTool="ipwndfu"
fi
Log "Entering pwnDFU mode with $pwnDFUTool..."
if [[ $pwnDFUTool == "ipwndfu" ]]; then
cd resources/ipwndfu
sudo $python ipwndfu -p
elif [[ $pwnDFUTool == "iPwnder32" ]]; then
if [ ! -e $ipwnder32 ]; then
SaveFile https://dora2ios.web.app/iPwnder32/iPwnder32_v3.1.2.zip tmp/iPwnder32.zip 79a64133e11b1c60569aba422fa1b5046aa33d83
unzip -o -j tmp/iPwnder32.zip iPwnder32_macosx/iPwnder32 -d resources/tools
mv resources/tools/iPwnder32 $ipwnder32
fi
$ipwnder32 -p
cd resources/ipwndfu
fi
if [[ $A7Device == 1 ]]; then
Log "Running rmsigchks.py..."
sudo $python rmsigchks.py
pwnDFUDevice=$?
Echo $pwnDFUDevice
cd ../..
else
cd ../..
[[ $pwnDFUTool == "ipwndfu" ]] && kDFU iBSS || echo
pwnDFUDevice=$?
fi
if [[ $pwnDFUDevice == 1 ]] || [[ $pwnDFUDevice == 255 ]]; then
echo -e "\n${Color_R}[Error] Failed to enter pwnDFU mode. Please run the script again: ./restore.sh Downgrade ${Color_N}"
echo "${Color_Y}* This step may fail a lot, especially on Linux, and unfortunately there is nothing I can do about the low success rates. ${Color_N}"
echo "${Color_Y}* The only option is to make sure you are using an Intel device, and to try multiple times ${Color_N}"
exit 1
elif [[ $pwnDFUDevice == 0 ]]; then
Log "Device in pwnDFU mode detected."
Log "Downgrading device $ProductType in pwnDFU mode..."
Mode='Downgrade'
SelectVersion
fi
}
Downgrade() {
if [[ $OSVer != 'Other' ]]; then
[[ $ProductType == iPad4* ]] && IPSWType="iPad_64bit"
[[ $ProductType == iPhone6* ]] && IPSWType="iPhone_4.0_64bit"
[[ ! $IPSWType ]] && IPSWType="$ProductType" && SaveOTABlobs
IPSW="${IPSWType}_${OSVer}_${BuildVer}_Restore"
IPSWCustom="${IPSWType}_${OSVer}_${BuildVer}_Custom"
if [ ! -e $IPSW.ipsw ] && [ ! -e $IPSWCustom.ipsw ]; then
Log "iOS $OSVer IPSW cannot be found."
Echo "* If you already downloaded the IPSW, did you put it in the same directory as the script?"
Echo "* Do NOT rename the IPSW as the script will fail to detect it"
Log "Downloading IPSW... (Press Ctrl+C to cancel)"
curl -L $(cat $Firmware/$BuildVer/url) -o tmp/$IPSW.ipsw
mv tmp/$IPSW.ipsw .
fi
[[ $Jailbreak == 1 ]] && [ -e $IPSWCustom.ipsw ] && Verify=0
if [[ $Verify != 0 ]]; then
Log "Verifying IPSW..."
IPSWSHA1=$(cat $Firmware/$BuildVer/sha1sum)
IPSWSHA1L=$(shasum $IPSW.ipsw | awk '{print $1}')
[[ $IPSWSHA1L != $IPSWSHA1 ]] && Error "Verifying IPSW failed. Your IPSW may be corrupted or incomplete." "Delete/replace the IPSW and run the script again"
else
IPSW=$IPSWCustom
fi
if [ ! $DFUManual ] && [[ $iBSSBuildVer == $BuildVer ]]; then
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
fi
[ ! $DFUManual ] && kDFU
# uses ipsw tool from OdysseusOTA/2 to create custom IPSW with jailbreak
if [[ $Jailbreak == 1 ]]; then
if [[ $OSVer == 8.4.1 ]]; then
JBFiles=(fstab.tar etasonJB-untether.tar Cydia8.tar)
JBSHA1=6459dbcbfe871056e6244d23b33c9b99aaeca970
JBS=2305
else
JBFiles=(fstab_rw.tar p0sixspwn.tar Cydia6.tar)
JBSHA1=1d5a351016d2546aa9558bc86ce39186054dc281
JBS=1260
fi
if [[ ! -e resources/jailbreak/${JBFiles[2]} ]]; then
cd tmp
Log "Downloading jailbreak files..."
SaveFile https://github.com/LukeZGD/iOS-OTA-Downgrader-Keys/releases/download/jailbreak/${JBFiles[2]} ${JBFiles[2]} $JBSHA1
cp ${JBFiles[2]} ../resources/jailbreak
cd ..
fi
for i in {0..2}; do
JBFiles[$i]=jailbreak/${JBFiles[$i]}
done
if [ ! -e $IPSWCustom.ipsw ]; then
Echo "* By default, memory option is set to Y, you may select N later if you encounter problems"
Echo "* If it doesn't work with both, you might not have enough RAM and/or tmp storage"
read -p "$(Input 'Memory option? (press Enter/Return if unsure) (Y/n): ')" JBMemory
[[ $JBMemory != n ]] && [[ $JBMemory != N ]] && JBMemory="-memory" || JBMemory=
Log "Preparing custom IPSW..."
cd resources
ln -sf firmware/FirmwareBundles FirmwareBundles
$ipsw ../$IPSW.ipsw ../$IPSWCustom.ipsw $JBMemory -bbupdate -s $JBS ${JBFiles[@]}
cd ..
fi
[ ! -e $IPSWCustom.ipsw ] && Error "Failed to find custom IPSW. Please run the script again" "You may try selecting N for memory option"
IPSW=$IPSWCustom
fi
Log "Extracting IPSW..."
unzip -q $IPSW.ipsw -d $IPSW/
# create custom IPSW for 10.3.3
if [[ $A7Device == 1 ]]; then
if [ ! -e $IPSWCustom.ipsw ]; then
Log "Preparing custom IPSW..."
cp $IPSW/Firmware/all_flash/$SEP .
bspatch $IPSW/Firmware/dfu/$iBSS.im4p $iBSS.im4p resources/patches/$iBSS.patch
bspatch $IPSW/Firmware/dfu/$iBEC.im4p $iBEC.im4p resources/patches/$iBEC.patch
if [[ $ProductType == iPad4* ]]; then
bspatch $IPSW/Firmware/dfu/$iBSSb.im4p $iBSSb.im4p resources/patches/$iBSSb.patch
bspatch $IPSW/Firmware/dfu/$iBECb.im4p $iBECb.im4p resources/patches/$iBECb.patch
cp -f $iBSSb.im4p $iBECb.im4p $IPSW/Firmware/dfu
fi
cp -f $iBSS.im4p $iBEC.im4p $IPSW/Firmware/dfu
cd $IPSW
zip ../$IPSWCustom.ipsw -rq0 *
cd ..
mv $IPSW $IPSWCustom
IPSW=$IPSWCustom
else
cp $IPSW/Firmware/dfu/$iBSS.im4p $IPSW/Firmware/dfu/$iBEC.im4p .
[[ $ProductType == iPad4* ]] && cp $IPSW/Firmware/dfu/$iBSSb.im4p $IPSW/Firmware/dfu/$iBECb.im4p .
cp $IPSW/Firmware/all_flash/$SEP .
fi
[ ! -e $IPSW.ipsw ] && Error "Failed to create custom IPSW. Please run the script again"
if [[ $ProductType == iPad4,4 ]] || [[ $ProductType == iPad4,5 ]]; then
iBEC=$iBECb
iBSS=$iBSSb
fi
Log "Entering pwnREC mode..."
$irecovery -f $iBSS.im4p
$irecovery -f $iBEC.im4p
sleep 5
[[ $($irecovery -q 2>/dev/null | grep 'MODE' | cut -c 7-) == "Recovery" ]] && RecoveryDevice=1
if [[ $RecoveryDevice != 1 ]]; then
echo -e "\n$(Log 'Failed to detect device in pwnREC mode.')"
Echo "* If your device has backlight turned on, you may try unplugging and re-plugging in your device, and attempt to continue"
Echo "* If not, you may have to hard-reset your device and attempt to start over entering pwnDFU mode again"
Input "Press Enter/Return to continue anyway (or press Ctrl+C to cancel)"
read -s
else
Log "Found device in pwnREC mode."
fi
SaveOTABlobs
fi
if [[ $Jailbreak != 1 ]] && [[ $A7Device != 1 ]] && [[ $OSVer != 'Other' ]]; then
Log "Preparing for futurerestore... (Enter root password of your PC/Mac when prompted)"
cd resources
sudo bash -c "$python -m SimpleHTTPServer 80 &"
cd ..
fi
if [[ $Jailbreak == 1 ]]; then
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 -y -e -w $IPSW.ipsw
elif [ $Baseband == 0 ]; then
Log "Device $ProductType has no baseband"
Log "Proceeding to futurerestore..."
if [[ $A7Device == 1 ]]; then
$futurerestore2 -t $SHSH -s $SEP -m $BuildManifest --no-baseband $IPSW.ipsw
else
$futurerestore1 -t $SHSH --no-baseband --use-pwndfu $IPSW.ipsw
fi
else
if [[ $A7Device == 1 ]]; then
cp $IPSW/Firmware/$Baseband .
elif [ $ProductType == iPhone5,1 ] && [[ $Baseband5 != 0 ]]; then
unzip -o -j $IPSW.ipsw Firmware/$Baseband -d .
cp $BuildManifest BuildManifest.plist
elif [ ! -e saved/baseband/$Baseband ]; then
Log "Downloading baseband..."
$partialzip $BasebandURL Firmware/$Baseband $Baseband
$partialzip $BasebandURL BuildManifest.plist BuildManifest.plist
mkdir -p saved/$ProductType 2>/dev/null
mkdir -p saved/baseband 2>/dev/null
cp $Baseband saved/baseband
cp BuildManifest.plist saved/$ProductType
else
cp saved/baseband/$Baseband saved/$ProductType/BuildManifest.plist .
fi
BasebandSHA1L=$(shasum $Baseband | awk '{print $1}')
Log "Proceeding to futurerestore..."
if [ ! -e *.bbfw ] || [[ $BasebandSHA1L != $BasebandSHA1 ]]; then
rm -f saved/$ProductType/*.bbfw saved/$ProductType/BuildManifest.plist
Log "Downloading/verifying baseband failed."
Echo "* Your device is still in kDFU mode and you may run the script again"
Echo "* You can also continue and futurerestore can attempt to download the baseband again"
Input "Press Enter/Return to continue (or press Ctrl+C to cancel)"
read -s
$futurerestore1 -t $SHSH --latest-baseband --use-pwndfu $IPSW.ipsw
elif [[ $A7Device == 1 ]]; then
$futurerestore2 -t $SHSH -s $SEP -m $BuildManifest -b $Baseband -p $BuildManifest $IPSW.ipsw
else
$futurerestore1 -t $SHSH -b $Baseband -p BuildManifest.plist --use-pwndfu $IPSW.ipsw
fi
fi
echo
Log "Restoring done!"
if [[ $Jailbreak != 1 ]] && [[ $A7Device != 1 ]] && [[ $OSVer != 'Other' ]]; then
Log "Stopping local server... (Enter root password of your PC/Mac when prompted)"
ps aux | awk '/python/ {print "sudo kill -9 "$2" 2>/dev/null"}' | bash
fi
Log "Downgrade script done!"
}
InstallDependencies() {
mkdir tmp 2>/dev/null
cd resources
rm -rf firmware ipwndfu lib/* libimobiledevice* libirecovery
cd ../tmp
Log "Installing dependencies..."
if [[ $ID == "arch" ]] || [[ $ID_LIKE == "arch" ]]; then
# Arch
sudo pacman -Syu --noconfirm --needed base-devel bsdiff curl libcurl-compat libpng12 libimobiledevice libusbmuxd libzip openssh openssl-1.0 python2 unzip usbmuxd usbutils
ln -sf /usr/lib/libcurl.so.3 ../resources/lib/libcurl.so.3
ln -sf /usr/lib/libzip.so.5 ../resources/lib/libzip.so.4
elif [[ $UBUNTU_CODENAME == "bionic" ]] || [[ $UBUNTU_CODENAME == "focal" ]] ||
[[ $UBUNTU_CODENAME == "groovy" ]] || [[ $UBUNTU_CODENAME == "hirsute" ]] ||
[[ $VERSION == "10 (buster)" ]] || [[ $PRETTY_NAME == "Debian GNU/Linux bullseye/sid" ]]; then
# Ubuntu, Debian
[[ ! -z $UBUNTU_CODENAME ]] && sudo add-apt-repository universe
sudo apt update
sudo apt install -y autoconf automake bsdiff build-essential curl git libglib2.0-dev libimobiledevice6 libimobiledevice-utils libreadline-dev libtool-bin libusb-1.0-0-dev libusbmuxd-tools openssh-client usbmuxd usbutils
SavePkg
cp libcrypto.so.1.0.0 libcurl.so.3 libssl.so.1.0.0 ../resources/lib
if [[ $UBUNTU_CODENAME == "bionic" ]] || [[ $VERSION == "10 (buster)" ]]; then
sudo apt install -y libzip4 python
cp libpng12.so.0 libzip.so.5 ../resources/lib
SaveFile https://github.com/LukeZGD/iOS-OTA-Downgrader-Keys/releases/download/tools/tools_linux_bionic.zip tools_linux_bionic.zip 959abbafacfdaddf87dd07683127da1dab6c835f
unzip tools_linux_bionic.zip -d ../resources/tools
elif [[ $PRETTY_NAME == "Debian GNU/Linux bullseye/sid" ]] || [[ $UBUNTU_CODENAME == "hirsute" ]]; then
sudo apt install -y libzip4 python2
cp libpng12.so.0 libzip.so.5 ../resources/lib
else
sudo apt install -y libzip5 python2
cp libpng12.so.0 libzip.so.4 ../resources/lib
fi
if [[ $UBUNTU_CODENAME == "focal" ]]; then
ln -sf /usr/lib/x86_64-linux-gnu/libimobiledevice.so.6 ../resources/lib/libimobiledevice-1.0.so.6
ln -sf /usr/lib/x86_64-linux-gnu/libplist.so.3 ../resources/lib/libplist-2.0.so.3
ln -sf /usr/lib/x86_64-linux-gnu/libusbmuxd.so.6 ../resources/lib/libusbmuxd-2.0.so.6
fi
elif [[ $ID == "fedora" ]]; then
# Fedora
sudo dnf install -y automake binutils bsdiff git libimobiledevice-utils libpng12 libtool libusb-devel libusbmuxd-utils make libzip perl-Digest-SHA python2 readline-devel
SavePkg
cp libcrypto.so.1.0.0 libssl.so.1.0.0 ../resources/lib
if (( $VERSION_ID <= 32 )); then
ln -sf /usr/lib64/libimobiledevice.so.6 ../resources/lib/libimobiledevice-1.0.so.6
ln -sf /usr/lib64/libplist.so.3 ../resources/lib/libplist-2.0.so.3
ln -sf /usr/lib64/libusbmuxd.so.6 ../resources/lib/libusbmuxd-2.0.so.6
fi
ln -sf /usr/lib64/libzip.so.5 ../resources/lib/libzip.so.4
ln -sf /usr/lib64/libbz2.so.1.* ../resources/lib/libbz2.so.1.0
elif [[ $ID == "opensuse-tumbleweed" ]] || [[ $PRETTY_NAME == "openSUSE Leap 15.2" ]]; then
# openSUSE
[[ $ID == "opensuse-tumbleweed" ]] && iproxy="libusbmuxd-tools" || iproxy="iproxy libzip5"
sudo zypper -n in automake bsdiff gcc git imobiledevice-tools $iproxy libimobiledevice libpng12-0 libopenssl1_0_0 libusb-1_0-devel libtool make python-base readline-devel
ln -sf /usr/lib64/libimobiledevice.so.6 ../resources/lib/libimobiledevice-1.0.so.6
ln -sf /usr/lib64/libplist.so.3 ../resources/lib/libplist-2.0.so.3
ln -sf /usr/lib64/libusbmuxd.so.6 ../resources/lib/libusbmuxd-2.0.so.6
ln -sf /usr/lib64/libzip.so.5 ../resources/lib/libzip.so.4
elif [[ $OSTYPE == "darwin"* ]]; then
# macOS
#imobiledevicenet=$(curl -s https://api.github.com/repos/libimobiledevice-win32/imobiledevice-net/releases/latest | grep browser_download_url | cut -d '"' -f 4 | awk '/osx-x64/ {print $1}')
xcode-select --install
#curl -L $imobiledevicenet -o libimobiledevice.zip
SaveFile https://github.com/libimobiledevice-win32/imobiledevice-net/releases/download/v1.3.14/libimobiledevice.1.2.1-r1116-osx-x64.zip libimobiledevice.zip 328e809dea350ae68fb644225bbf8469c0f0634b
else
Error "Distro not detected/supported by the install script." "See the repo README for supported OS versions/distros"
fi
if [[ $platform == linux ]]; then
Compile LukeZGD libirecovery
ln -sf ../libirecovery/lib/libirecovery.so.3 ../resources/lib/libirecovery-1.0.so.3
ln -sf ../libirecovery/lib/libirecovery.so.3 ../resources/lib/libirecovery.so.3
else
mkdir ../resources/libimobiledevice
unzip libimobiledevice.zip -d ../resources/libimobiledevice
chmod +x ../resources/libimobiledevice/*
fi
Log "Install script done! Please run the script again to proceed"
exit
}
Compile() {
git clone --depth 1 https://github.com/$1/$2.git
cd $2
./autogen.sh --prefix="$(cd ../.. && pwd)/resources/$2"
make install
cd ..
sudo rm -rf $2
}
SaveExternal() {
ExternalURL="https://github.com/LukeZGD/$1.git"
External=$1
[[ $1 == "iOS-OTA-Downgrader-Keys" ]] && External="firmware"
cd resources
if [[ ! -d $External ]] || [[ ! -d $External/.git ]]; then
Log "Downloading $External..."
rm -rf $External
git clone $ExternalURL $External
#else
# Log "Updating $External..."
# cd $External
# git pull 2>/dev/null
# cd ..
fi
if [[ ! -e $External/README.md ]] || [[ ! -d $External/.git ]]; then
rm -rf $External
Error "Downloading/updating $1 failed. Please run the script again"
fi
cd ..
}
SaveFile() {
curl -L $1 -o $2
if [[ $(shasum $2 | awk '{print $1}') != $3 ]]; then
Error "Verifying failed. Please run the script again" "./restore.sh Install"
fi
}
SavePkg() {
if [[ ! -d ../saved/lib ]]; then
Log "Downloading packages..."
SaveFile https://github.com/LukeZGD/iOS-OTA-Downgrader-Keys/releases/download/tools/depends2_linux.zip depends_linux.zip 38cf1db21c9aba88f0de95a1a7959ac2ac53c464
mkdir -p ../saved/lib
unzip depends_linux.zip -d ../saved/lib
fi
cp ../saved/lib/* .
}
BasebandDetect() {
Firmware=resources/firmware/$ProductType
BasebandURL=$(cat $Firmware/13G37/url 2>/dev/null) # iOS 9.3.6
Baseband=0
if [ $ProductType == iPad2,2 ]; then
BasebandURL=$(cat $Firmware/13G36/url) # iOS 9.3.5
Baseband=ICE3_04.12.09_BOOT_02.13.Release.bbfw
BasebandSHA1=e6f54acc5d5652d39a0ef9af5589681df39e0aca
elif [ $ProductType == iPad2,3 ]; then
Baseband=Phoenix-3.6.03.Release.bbfw
BasebandSHA1=8d4efb2214344ea8e7c9305392068ab0a7168ba4
elif [ $ProductType == iPad2,6 ] || [ $ProductType == iPad2,7 ]; then
Baseband=Mav5-11.80.00.Release.bbfw
BasebandSHA1=aa52cf75b82fc686f94772e216008345b6a2a750
elif [ $ProductType == iPad3,2 ] || [ $ProductType == iPad3,3 ]; then
Baseband=Mav4-6.7.00.Release.bbfw
BasebandSHA1=a5d6978ecead8d9c056250ad4622db4d6c71d15e
elif [ $ProductType == iPhone4,1 ]; then
Baseband=Trek-6.7.00.Release.bbfw
BasebandSHA1=22a35425a3cdf8fa1458b5116cfb199448eecf49
elif [ $ProductType == iPad3,5 ] || [ $ProductType == iPad3,6 ] ||
[ $ProductType == iPhone5,1 ] || [ $ProductType == iPhone5,2 ]; then
BasebandURL=$(cat $Firmware/14G61/url) # iOS 10.3.4
Baseband=Mav5-11.80.00.Release.bbfw
BasebandSHA1=8951cf09f16029c5c0533e951eb4c06609d0ba7f
elif [ $ProductType == iPad4,2 ] || [ $ProductType == iPad4,3 ] || [ $ProductType == iPad4,5 ] ||
[ $ProductType == iPhone6,1 ] || [ $ProductType == iPhone6,2 ]; then
BasebandURL=$(cat $Firmware/14G60/url)
Baseband=Mav7Mav8-7.60.00.Release.bbfw
BasebandSHA1=f397724367f6bed459cf8f3d523553c13e8ae12c
A7Device=1
elif [ $ProductType == iPad4,1 ] || [ $ProductType == iPad4,4 ]; then
A7Device=1
elif [ $ProductType == 0 ]; then
Error "No device detected. Please put the device in normal mode (and jailbroken for 32-bit) before proceeding" "Recovery or DFU mode is also applicable for A7 devices"
elif [ $ProductType != iPad2,1 ] && [ $ProductType != iPad2,4 ] && [ $ProductType != iPad2,5 ] &&
[ $ProductType != iPad3,1 ] && [ $ProductType != iPad3,4 ] && [ $ProductType != iPod5,1 ] &&
[ $ProductType != iPhone5,3 ] && [ $ProductType != iPhone5,4 ]; then
Error "Your device $ProductType is not supported."
fi
[ $ProductType == iPad2,1 ] && HWModel=k93
[ $ProductType == iPad2,2 ] && HWModel=k94
[ $ProductType == iPad2,3 ] && HWModel=k95
[ $ProductType == iPad2,4 ] && HWModel=k93a
[ $ProductType == iPad2,5 ] && HWModel=p105
[ $ProductType == iPad2,6 ] && HWModel=p106
[ $ProductType == iPad2,7 ] && HWModel=p107
[ $ProductType == iPad3,1 ] && HWModel=j1
[ $ProductType == iPad3,2 ] && HWModel=j2
[ $ProductType == iPad3,3 ] && HWModel=j2a
[ $ProductType == iPad3,4 ] && HWModel=p101
[ $ProductType == iPad3,5 ] && HWModel=p102
[ $ProductType == iPad3,6 ] && HWModel=p103
[ $ProductType == iPad4,1 ] && HWModel=j71
[ $ProductType == iPad4,2 ] && HWModel=j72
[ $ProductType == iPad4,3 ] && HWModel=j73
[ $ProductType == iPad4,4 ] && HWModel=j85
[ $ProductType == iPad4,5 ] && HWModel=j86
[ $ProductType == iPhone4,1 ] && HWModel=n94
[ $ProductType == iPhone5,1 ] && HWModel=n41
[ $ProductType == iPhone5,2 ] && HWModel=n42
[ $ProductType == iPhone5,3 ] && HWModel=n48
[ $ProductType == iPhone5,4 ] && HWModel=n49
[ $ProductType == iPhone6,1 ] && HWModel=n51
[ $ProductType == iPhone6,2 ] && HWModel=n53
[ $ProductType == iPod5,1 ] && HWModel=n78
if [ $ProductType == iPod5,1 ]; then
iBSS="${HWModel}ap"
iBSSBuildVer='10B329'
elif [ $ProductType == iPad3,1 ]; then
iBSS="${HWModel}ap"
iBSSBuildVer='11D257'
elif [ $ProductType == iPhone6,1 ] || [ $ProductType == iPhone6,2 ]; then
iBSS="iphone6"
elif [ $ProductType == iPad4,1 ] || [ $ProductType == iPad4,2 ] || [ $ProductType == iPad4,3 ] ||
[ $ProductType == iPad4,4 ] || [ $ProductType == iPad4,5 ]; then
iBSS="ipad4"
else
iBSS="$HWModel"
iBSSBuildVer='12H321'
fi
iBEC="iBEC.$iBSS.RELEASE"
iBECb="iBEC.${iBSS}b.RELEASE"
iBSSb="iBSS.${iBSS}b.RELEASE"
iBSS="iBSS.$iBSS.RELEASE"
SEP="sep-firmware.$HWModel.RELEASE.im4p"
} }
cd "$(dirname $0)" cd "$(dirname $0)"