Compare commits
37 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7eabc2fa0 | ||
|
|
502d4f61a2 | ||
|
|
6cb0696e7e | ||
|
|
180df7707d | ||
|
|
f9e2cb3186 | ||
|
|
b49769b07f | ||
|
|
1c70d0e71f | ||
|
|
f3e958a331 | ||
|
|
c9a78025d6 | ||
|
|
e441d8c871 | ||
|
|
f2519339d6 | ||
|
|
96055b3b24 | ||
|
|
d3c710aca9 | ||
|
|
81074d5fc9 | ||
|
|
c90d91cd3a | ||
|
|
0ae0e15321 | ||
|
|
69665ca97d | ||
|
|
7cc24d3ca3 | ||
|
|
d71fddc7d2 | ||
|
|
9e9dcc8bdc | ||
|
|
cd56555143 | ||
|
|
e31311a05b | ||
|
|
1b6a25d5f8 | ||
|
|
52fdc582bc | ||
|
|
3591402383 | ||
|
|
6c5599f667 | ||
|
|
8f38477d7f | ||
|
|
6335eb5c17 | ||
|
|
c4d7c0d834 | ||
|
|
70f2b5efcf | ||
|
|
032347484f | ||
|
|
3c99a74ce2 | ||
|
|
27468e64c0 | ||
|
|
1883f27e57 | ||
|
|
1deef89932 | ||
|
|
ea930d09ac | ||
|
|
67b9942b9a |
15 changed files with 268 additions and 487 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,7 +1,5 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*/.DS_Store
|
*/.DS_Store
|
||||||
binaries/Linux/futurerestore
|
|
||||||
binaries/Darwin/futurerestore
|
|
||||||
work
|
work
|
||||||
ramdisk
|
ramdisk
|
||||||
boot*
|
boot*
|
||||||
|
|
|
||||||
35
README.md
35
README.md
|
|
@ -1,12 +1,12 @@
|
||||||
# downr1n
|
# downr1n
|
||||||
Downr1n enables tethered downgrades of checkm8 iOS devices to iOS 15, 14 and 13.
|
Downr1n enables tethered downgrades of checkm8 iOS devices to iOS 15, 14 and 13.4 upper.
|
||||||
|
|
||||||
In general, dual booting is a better option than downgrading if you have the necessary storage. if you activate the localboot path it would be ultra better believe me xd.
|
there is dualra1n too, which is a dualboot for ios like having two different ios [dualra1n](https://github.com/dualra1n/dualra1n), i would recommend more dualra1n as it is very stable.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
1: Download the IPSW file and place it in the ipsw/ directory.
|
1: Download the IPSW file and place it in the ipsw/ directory.
|
||||||
|
|
||||||
2: Execute the script without using 'sudo' on Linux. if it doesn't work please use sudo then.
|
2: execute: ./downr1n.sh --downgrade 14.3.
|
||||||
|
|
||||||
Example: ./downr1n.sh --downgrade 14.3
|
Example: ./downr1n.sh --downgrade 14.3
|
||||||
|
|
||||||
|
|
@ -14,9 +14,7 @@ The various command-line options are as follows:
|
||||||
|
|
||||||
--downgrade : Downgrade your device to iOS 14 tethered.
|
--downgrade : Downgrade your device to iOS 14 tethered.
|
||||||
|
|
||||||
--dfuhelper : A helper tool to transition A11 devices from recovery mode to DFU mode.
|
--jailbreak : Jailbreak with dualra1n-loader. Usage: `./downr1n.sh --jailbreak 14.8`.
|
||||||
|
|
||||||
--jailbreak : Jailbreak with pogo. Usage: `./downr1n.sh --jailbreak 14.8`.
|
|
||||||
|
|
||||||
--taurine : Jailbreak with taurine. Usage: `./downr1n.sh --jailbreak 14.3 --taurine`.
|
--taurine : Jailbreak with taurine. Usage: `./downr1n.sh --jailbreak 14.3 --taurine`.
|
||||||
|
|
||||||
|
|
@ -26,18 +24,15 @@ The various command-line options are as follows:
|
||||||
|
|
||||||
--dont-restore : Avoids using futurerestore, this can be used to only create boot files. Example: `--downgrade 14.3 --dont-restore`.
|
--dont-restore : Avoids using futurerestore, this can be used to only create boot files. Example: `--downgrade 14.3 --dont-restore`.
|
||||||
|
|
||||||
--fixBoot : Boots the device using fsboot.
|
|
||||||
|
|
||||||
--debug : Debug the script.
|
--debug : Debug the script.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
- please execute this command: python3 -m pip install pyimg4[compression] fastapi aiohttp ujson wikitextparser uvicorn.
|
- unzip, python3, libimobiledevice-utils, libusbmuxd-tools, xz-utils, wget, curl, git, libssl-dev, usbmuxd.
|
||||||
- A disabled passcode on A10 and A11 devices.
|
- A disabled passcode on A10 and A11 devices.
|
||||||
- unzip, python3, libimobiledevice-utils, libusbmuxd-tools, xz-utils.
|
- An .iPSW file containing iOS 15, 14, 13.4 upper.
|
||||||
- An .iPSW file containing iOS 15, 14, 13.
|
- A device running macOS or a Linux distro. It is recommended to use macOS, as it is likely more stable and faster. and for linux it is recommended to use ubuntu or debian.
|
||||||
- A device running macOS or a Linux distro. It is recommended to use macOS, as it is likely more stable and faster.
|
|
||||||
|
|
||||||
# Issues Putting Device in PwnDFU Mode
|
# Issues Putting Device in PwnDFU Mode
|
||||||
|
|
||||||
|
|
@ -45,9 +40,13 @@ The various command-line options are as follows:
|
||||||
|
|
||||||
# importants things
|
# importants things
|
||||||
|
|
||||||
- downgrading ios 16 to 14 or another version, you will have to bypass the setup somehow. good luck on it.
|
- A8/A8x devices downr1n is not recommended please instead use dualra1n with --downgrade option (if you don't have enough storage for a dualboot)
|
||||||
|
|
||||||
- on ios 13 the touch id doesn't work so the home button on iphone 7 will not work sadly.
|
- you can't downgrade an iphone x if the device is on ios 16
|
||||||
|
|
||||||
|
- downgrading ios 16 to 14 or another version, you should have backup your activations file in order to after downgrade and boot sucessfully restore them, you can use https://github.com/edwin170/bypassr1n.
|
||||||
|
|
||||||
|
- on ios 13 the touch id doesn't work so the home button will not work sadly.
|
||||||
|
|
||||||
- you can't downgrade to ios 14.2 lower on a11 devices
|
- you can't downgrade to ios 14.2 lower on a11 devices
|
||||||
|
|
||||||
|
|
@ -59,7 +58,7 @@ The various command-line options are as follows:
|
||||||
|
|
||||||
# fix some problems
|
# fix some problems
|
||||||
|
|
||||||
- please execute wikiproxy.py manually if it gives problem with server key. for ex: sudo python3 wikiproxy.py
|
- if it gives problem with server key please execute: 1: python3 -m pip install git+https://github.com/m1stadev/wikiproxy.git 2: wikiproxy &
|
||||||
|
|
||||||
- if the error still after above fix, if this happend to you when you are downgrading with futurerestore again please add this arg --keyServer for example ./downr1n.sh --downgrade 14.5 --keyServer.
|
- if the error still after above fix, if this happend to you when you are downgrading with futurerestore again please add this arg --keyServer for example ./downr1n.sh --downgrade 14.5 --keyServer.
|
||||||
|
|
||||||
|
|
@ -69,11 +68,9 @@ The various command-line options are as follows:
|
||||||
- Join my discord server: [Dualra1nServer](https://discord.gg/Gjs2P7FBuk)
|
- Join my discord server: [Dualra1nServer](https://discord.gg/Gjs2P7FBuk)
|
||||||
|
|
||||||
# How to Jailbreak?
|
# How to Jailbreak?
|
||||||
- Jailbreak with dualra1n-loader: ./downr1n --jailbreak (YourVer = 14.3). Note: this does not actually jailbreak the device. When I say "jailbreak," I'm referring to the process of installing Sileo and bootstrapping the device. Dualra1n-loader only installs Sileo and bootstraps with the kernel patch.
|
- Jailbreak with dualra1n-loader: ./downr1n --jailbreak (YourVer = 14.3). Note: this does not actually jailbreak the device. When I say "jailbreak," I'm referring to the process of installing Sileo and bootstrapping the device. Dualra1n-loader only installs Sileo and bootstraps with the kpf kernel patch. (you will be able to use tweaks and most of things as normal).
|
||||||
|
|
||||||
- Taurine: ./downr1n --jailbreak (YourVer = 14.3) --taurine. Note: this is not recommended.
|
- Taurine: ./downr1n --jailbreak (ex: 14.3 or YouVers) --taurine.
|
||||||
|
|
||||||
# This project was created with love by Edwin :)
|
|
||||||
|
|
||||||
# Credits
|
# Credits
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
BIN
binaries/Darwin/futurerestore
Normal file
BIN
binaries/Darwin/futurerestore
Normal file
Binary file not shown.
Binary file not shown.
BIN
binaries/Linux/futurerestore
Normal file
BIN
binaries/Linux/futurerestore
Normal file
Binary file not shown.
462
downr1n.sh
462
downr1n.sh
File diff suppressed because it is too large
Load diff
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
|
|
||||||
sudo systemctl stop usbmuxd
|
sudo systemctl stop usbmuxd
|
||||||
sudo usbmuxd -p -f
|
sudo usbmuxd -p -f 1>/dev/null
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,29 +0,0 @@
|
||||||
#!/jbin/binpack/bin/bash
|
|
||||||
binpack=/jbin/binpack
|
|
||||||
|
|
||||||
# uicache loader app
|
|
||||||
$binpack/bin/rm -rf /var/.palera1n/loader.app
|
|
||||||
$binpack/usr/bin/uicache -p /Applications/Pogo.app/
|
|
||||||
$binpack/usr/bin/uicache -p /Applications/trollstore.app/
|
|
||||||
|
|
||||||
# remount r/w
|
|
||||||
/sbin/mount -uw /
|
|
||||||
/sbin/mount -uw /private/preboot/
|
|
||||||
|
|
||||||
# lauching daemon automatically
|
|
||||||
/usr/bin/launchctl load /Library/LaunchDaemons/
|
|
||||||
|
|
||||||
# update repo
|
|
||||||
if [ -f /usr/bin/apt ]; then
|
|
||||||
apt-get update
|
|
||||||
fi
|
|
||||||
|
|
||||||
# activating tweaks
|
|
||||||
/etc/rc.d/substitute-launcher
|
|
||||||
|
|
||||||
# respring
|
|
||||||
$binpack/usr/bin/uicache -a
|
|
||||||
$binpack/usr/bin/killall -9 SpringBoard
|
|
||||||
|
|
||||||
echo "[post.sh] done"
|
|
||||||
exit
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,28 +0,0 @@
|
||||||
#!/jbin/binpack/bin/bash
|
|
||||||
binpack=/jbin/binpack
|
|
||||||
|
|
||||||
# uicache loader app
|
|
||||||
$binpack/bin/rm -rf /var/.palera1n/loader.app
|
|
||||||
$binpack/usr/bin/uicache -p /Applications/Pogo.app/
|
|
||||||
|
|
||||||
# remount r/w
|
|
||||||
/sbin/mount -uw /
|
|
||||||
/sbin/mount -uw /private/preboot/
|
|
||||||
|
|
||||||
# lauching daemon automatically
|
|
||||||
/usr/bin/launchctl load /Library/LaunchDaemons/
|
|
||||||
|
|
||||||
# update repo
|
|
||||||
if [ -f /usr/bin/apt ]; then
|
|
||||||
apt-get update
|
|
||||||
fi
|
|
||||||
|
|
||||||
# activating tweaks
|
|
||||||
/etc/rc.d/substitute-launcher
|
|
||||||
|
|
||||||
# respring
|
|
||||||
$binpack/usr/bin/uicache -a
|
|
||||||
$binpack/usr/bin/killall -9 SpringBoard
|
|
||||||
|
|
||||||
echo "[post.sh] done"
|
|
||||||
exit
|
|
||||||
181
wikiproxy.py
181
wikiproxy.py
|
|
@ -1,181 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
from fastapi import FastAPI
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
import aiohttp
|
|
||||||
import asyncio
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
import ujson
|
|
||||||
import wikitextparser as wtp
|
|
||||||
import uvicorn
|
|
||||||
|
|
||||||
DEVICE_REGEX = re.compile(r'(iPhone|AppleTV|iPad|iPod)[0-9]+,[0-9]+')
|
|
||||||
|
|
||||||
# Only allow 100 simultaneous HTTP requests
|
|
||||||
HTTP_SEMAPHORE = asyncio.Semaphore(100)
|
|
||||||
|
|
||||||
|
|
||||||
async def get_key_page(
|
|
||||||
session: aiohttp.ClientSession, identifier: str, buildid: str
|
|
||||||
) -> str:
|
|
||||||
params = {
|
|
||||||
'action': 'query',
|
|
||||||
'list': 'search',
|
|
||||||
'srsearch': f'Keys: {buildid} ({identifier})',
|
|
||||||
'srwhat': 'title',
|
|
||||||
'srlimit': '1',
|
|
||||||
'format': 'json',
|
|
||||||
'srnamespace': '2304',
|
|
||||||
}
|
|
||||||
async with HTTP_SEMAPHORE, session.get(
|
|
||||||
'https://theapplewiki.com/api.php', params=params
|
|
||||||
) as resp:
|
|
||||||
if resp.status != 200:
|
|
||||||
pass # raise error
|
|
||||||
else:
|
|
||||||
search = await resp.json()
|
|
||||||
|
|
||||||
if search['query']['searchinfo']['totalhits'] == 0:
|
|
||||||
raise ValueError(
|
|
||||||
f'No Firmware Keys page for device: {identifier}, buildid: {buildid}.'
|
|
||||||
)
|
|
||||||
|
|
||||||
params = {
|
|
||||||
'action': 'parse',
|
|
||||||
'prop': 'wikitext',
|
|
||||||
'page': search['query']['search'][0]['title'],
|
|
||||||
'format': 'json',
|
|
||||||
'formatversion': 2,
|
|
||||||
}
|
|
||||||
async with HTTP_SEMAPHORE, session.get(
|
|
||||||
'https://theapplewiki.com/api.php', params=params
|
|
||||||
) as resp:
|
|
||||||
if resp.status != 200:
|
|
||||||
pass # raise error
|
|
||||||
|
|
||||||
data = await resp.json()
|
|
||||||
|
|
||||||
return data['parse']['wikitext']
|
|
||||||
|
|
||||||
|
|
||||||
def parse_page(data: str, identifer: str, boardconfig: str = None) -> dict:
|
|
||||||
# Have to coerce wikitextparser into recognizing it as a table for easy parsing
|
|
||||||
data = (
|
|
||||||
' '.join([x for x in data.split(' ') if x != ''])
|
|
||||||
.replace('{{', '{| class="wikitable"')
|
|
||||||
.replace('}}', '|}')
|
|
||||||
)
|
|
||||||
|
|
||||||
page = wtp.parse(data)
|
|
||||||
page_data = {}
|
|
||||||
for entry in page.tables[0].data()[0]:
|
|
||||||
key, item = entry.split(' = ')
|
|
||||||
page_data[key] = item
|
|
||||||
|
|
||||||
if boardconfig is not None:
|
|
||||||
if ('Model' not in page_data.keys()) and ('Model2' not in page_data.keys()):
|
|
||||||
return page_data
|
|
||||||
|
|
||||||
if boardconfig.lower() not in [x.lower() for x in page_data.values()]:
|
|
||||||
raise ValueError(
|
|
||||||
f'Boardconfig: {boardconfig} for device: {identifer} is not valid!'
|
|
||||||
)
|
|
||||||
|
|
||||||
if page_data['Model2'].lower() == boardconfig.lower():
|
|
||||||
for key in page_data:
|
|
||||||
if '2' in key:
|
|
||||||
page_data[key.replace('2', '')] = page_data[key]
|
|
||||||
|
|
||||||
for key in list(page_data.keys()):
|
|
||||||
if '2' in key:
|
|
||||||
del page_data[key]
|
|
||||||
|
|
||||||
response = {
|
|
||||||
'identifier': page_data['Device'],
|
|
||||||
'buildid': page_data['Build'],
|
|
||||||
'codename': page_data['Codename'],
|
|
||||||
'restoreramdiskexists': 'RestoreRamdisk' in page_data,
|
|
||||||
'updateramdiskexists': 'UpdateRamdisk' in page_data,
|
|
||||||
'keys': [],
|
|
||||||
}
|
|
||||||
|
|
||||||
for component in page_data:
|
|
||||||
if component in (
|
|
||||||
'Version',
|
|
||||||
'Build',
|
|
||||||
'Device',
|
|
||||||
'Model',
|
|
||||||
'Codename',
|
|
||||||
'Baseband',
|
|
||||||
'DownloadURL',
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if any(component.endswith(x) for x in ('Key', 'IV', 'KBAG')):
|
|
||||||
continue
|
|
||||||
|
|
||||||
image = {
|
|
||||||
'image': component,
|
|
||||||
'filename': page_data[component],
|
|
||||||
'date': datetime.now().isoformat(),
|
|
||||||
}
|
|
||||||
|
|
||||||
if any(component == x for x in ('RootFS', 'RestoreRamdisk', 'UpdateRamdisk')):
|
|
||||||
image['filename'] += '.dmg'
|
|
||||||
|
|
||||||
for key in ('IV', 'Key') if component != 'RootFS' else ('Key',):
|
|
||||||
if component + key not in page_data.keys():
|
|
||||||
continue
|
|
||||||
|
|
||||||
if all(
|
|
||||||
x not in page_data[component + key]
|
|
||||||
for x in ('Unknown', 'Not Encrypted')
|
|
||||||
):
|
|
||||||
image[key.lower()] = page_data[component + key]
|
|
||||||
|
|
||||||
if (
|
|
||||||
('iv' not in image.keys())
|
|
||||||
and ('key' not in image.keys())
|
|
||||||
and not image['filename'].endswith('.dmg')
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if 'iv' in image and 'key' in image:
|
|
||||||
image['kbag'] = image['iv'] + image['key']
|
|
||||||
|
|
||||||
response['keys'].append(image)
|
|
||||||
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
|
|
||||||
@app.middleware('http')
|
|
||||||
async def add_process_time_header(request, call_next):
|
|
||||||
start_time = time.time()
|
|
||||||
response = await call_next(request)
|
|
||||||
response.headers['X-Process-Time'] = str(f'{time.time() - start_time:0.4f} sec')
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
@app.get('/firmware/{identifier}/{buildid}')
|
|
||||||
async def get_firmware_keys(identifier: str, buildid: str) -> dict:
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
page = await get_key_page(session, identifier, buildid)
|
|
||||||
|
|
||||||
return parse_page(page, identifier)
|
|
||||||
|
|
||||||
|
|
||||||
@app.get('/firmware/{identifier}/{boardconfig}/{buildid}')
|
|
||||||
async def get_firmware_keys(identifier: str, boardconfig: str, buildid: str) -> dict:
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
page = await get_key_page(session, identifier, buildid)
|
|
||||||
|
|
||||||
return parse_page(page, identifier, boardconfig)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
uvicorn.run(app='__main__:app', host='127.0.0.1', port='8888')
|
|
||||||
Loading…
Add table
Reference in a new issue