Skip to content

Instantly share code, notes, and snippets.

@ForceBru
Created March 11, 2019 19:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ForceBru/e0f3a3d2be15d668353ac43688c16f83 to your computer and use it in GitHub Desktop.
Save ForceBru/e0f3a3d2be15d668353ac43688c16f83 to your computer and use it in GitHub Desktop.
Save iOS 12.1.1~b3 SHSH blobs automatically when Apple randomly opens the signing window.
import socket
import requests
from bs4 import BeautifulSoup
import time, datetime
import subprocess
import re
import os
# This script works on macOS and Linux only!
#
# Usage:
# 1. DOWNLOAD tsschecker (https://github.com/tihmstar/tsschecker)
# 2. Unzip the zip file and change directory to the unzipped directory
# 3. Copy this file to this directory
# 4. Make tsschecker executable with `chmod +x tsschecker_<whatever>
# 5. SET SETTINGS BELOW
# 6. Run `python3 SHSH_saver.py` from the same directory
# ---------- BEGIN SETTINGS ----------
model = 'iPhone7,1' # your iDevice model
ECID = 'xxxxxxxxxxxxx'
platform = 'NXXAP'
save_path = 'blobs'
wait = 1 # check every `wait` seconds
# ---------- END SETTINGS ----------
try:
os.mkdir(save_path)
except FileExistsError:
...
socket.setdefaulttimeout(5)
url = "https://tsssaver.1conan.com/isitsigned.php"
regex_success = re.compile('Saved shsh blobs![^i]*iOS 12.1.1 (.*) IS signed!')
regex_fail = re.compile('iOS 12.1.1 (.*) IS NOT signed!')
started = datetime.datetime.now()
while True:
print(f'[{datetime.datetime.now()}: QUERY] Querying {url}...')
try:
l = requests.get(url)
except Exception as e:
print(f'[{datetime.datetime.now()}: FAIL CONN] Failed to connect ({e}). Retrying in {wait} seconds')
time.sleep(wait)
continue
soup = BeautifulSoup(l.content.decode(), features="lxml")
try:
is_signed = soup.find(text=model).findPrevious('tr').find_all('td')[-1].text
except Exception as e:
print(f'[{datetime.datetime.now()}: FAIL PARSE] Failed to find element ({e}). Retrying in {wait} seconds')
time.sleep(wait)
continue
if is_signed == 'no':
print(f'[{datetime.datetime.now()}: FAIL NOT SIGNED] iOS 12.1.1 is not signed! Retrying in {wait} seconds')
time.sleep(wait)
continue
print(f'\t[{datetime.datetime.now()}: SUCCESS SIGNED] iOS 12.1.1b3 IS signed for {model}! Saving to {save_path}...')
retries = 5
saved = False
try:
for x in range(retries):
# ./tsschecker_macos -d iPhone7,1 -i 12.1.1 -B N56AP -s -e xxxxxxxxxxxxx --beta -o --save-path blobs
ret = subprocess.run(['./tsschecker_macos', '-d', model, '-i', '12.1.1', '-B', platform, '-s', '-e', ECID, '--beta', '-o', '--save-path', save_path], capture_output=True)
stdout = ret.stdout.decode()
m = regex_success.findall(stdout)
if not m:
print(f'\t[{datetime.datetime.now()}: FAIL SAVE] Not signed/failed to save, retrying...')
m = regex_fail.findall(stdout)
if not m:
print("\t\tFAILED TO PARSE!")
print(ret.stdout.decode(), '\n\n\n')
else:
for x in m:
print(f"\t[{datetime.datetime.now()}: FAIL NOT signed] {x}")
else:
for x in m:
print(f"\t[{datetime.datetime.now()}: SUCCESS SAVED] {x}")
saved = True
break
except Exception as e:
print(f"[{datetime.datetime.now()}: FAIL INTERRUPT] Interrupted: {e}")
if saved:
break
print(f'\t\t[{datetime.datetime.now()}: SUCCESS] Saved blobs for model {model}, platform {platform}, ECID {ECID} successfully! Path: {save_path!r}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment