diff --git a/DeviceSupport/iPad3_1/partition.py b/DeviceSupport/iPad3_1/partition.py index 3af0f41..0399e1a 100644 --- a/DeviceSupport/iPad3_1/partition.py +++ b/DeviceSupport/iPad3_1/partition.py @@ -5,7 +5,6 @@ import time import paramiko -import ioscrypto import osinfo import mountDevice import ssh @@ -18,9 +17,19 @@ SystemPartitionPadding = "" +def decrypt_ramdisk(osInfo: osinfo.OSInfo, key, iv): + print("Trying to get SystemPartitionSize from RestoreRamdisk") + plist = readPlist(os.path.join(os.path.abspath("."), "firmware/Restore.plist")) + print("RestoreRamdisk: " + plist['RestoreRamDisks']['User']) + print("-> Decrypting RestoreRamdisk") + os.system("./tools/" + osInfo.getosplatform() + "/xpwntool firmware/" + + plist['RestoreRamDisks']['User'] + " RestoreRamdisk.dmg -k " + + key + " -iv " + iv) + + def partitionDevice_stage1(osInfo: osinfo.OSInfo, shell, storage: int, key, iv): global guid_data, guid_system, attributeFlags_data, SystemPartitionPadding - shell.send("gptfdisk\n/dev/rdisk0s1\ni\n1\n") + shell.send("gptfdisk /dev/rdisk0s1\ni\n1\n") while True: time.sleep(0.5) line = shell.recv(1024) @@ -54,13 +63,7 @@ def partitionDevice_stage1(osInfo: osinfo.OSInfo, shell, storage: int, key, iv): line = shell.recv(1024) if line: break - print("Trying to get SystemPartitionSize from RestoreRamdisk") - plist = readPlist(os.path.join(os.path.abspath("."), "firmware/Restore.plist")) - print("RestoreRamdisk: " + plist['RestoreRamDisks']['User']) - print("-> Decrypting RestoreRamdisk") - ioscrypto.decryptImg3(osInfo, os.path.join(os.path.abspath("."), - "firmware/" + plist['RestoreRamDisks']['User']), - os.path.abspath(".") + "/RestoreRamdisk.dmg", key, iv) + decrypt_ramdisk(osInfo, key, iv) print("-> Mounting RestoreRamdisk") mountDevice.mountDevice(osInfo, os.path.join(os.path.abspath("."), "RestoreRamdisk.dmg"), "mountpoint") plist = readPlist(os.path.join("./DeviceSupport/iPad3_1", "mountpoint/usr/local/share/restore/options.j1.plist")) @@ -84,7 +87,7 @@ def partitionDevice_stage1(osInfo: osinfo.OSInfo, shell, storage: int, key, iv): line = shell.recv(1024) if line: break - print(line.decode('utf-8')) + # print(line.decode('utf-8')) print("Setting up attribute flags. FLAG=" + attributeFlags_data) if attributeFlags_data == "0000000000000000": shell.send("\n") @@ -108,33 +111,21 @@ def partitionDevice_stage1(osInfo: osinfo.OSInfo, shell, storage: int, key, iv): line = shell.recv(1024) if line: break - # For testing purposes, I commented this. - ''' - choice = input("WARNING: !!! Your data will ALL LOST after this operation. !!!" - "\nHere is a confirmation for this operation. Enter Y to continue, Enter N to abort.\n" - "Your choice (Make sure you know what you are doing): ") - if choice == "Y": - shell.send("w\nY\n") - else: - print("You have Entered N or other content. exiting.") - shell.send("q\n") - exit(1) - ''' - shell.send("q\n") + shell.send("w\nY\n") while True: time.sleep(0.5) line = shell.recv(1024) if line: break print("Scanning partitions.") - shell.send("sync; sync; sync; fsck_hfs -q /dev/disk0s1s1") + shell.send("sync; sync; sync; fsck_hfs -q /dev/disk0s1s1\n") while True: time.sleep(0.5) line = shell.recv(1024) if line or line.endswith(b'# '): break print(line.decode('utf-8')) - shell.send("fsck_hfs -q /dev/disk0s1s2") + shell.send("fsck_hfs -q /dev/disk0s1s2\n") while True: time.sleep(0.5) line = shell.recv(1024) @@ -151,17 +142,19 @@ def partitionDevice_stage2(sshClient: paramiko.SSHClient): while True: time.sleep(0.5) line = shell.recv(1024) - if line: + if line.endswith(b'# '): break ssh.scp_transfer_file(sshClient, os.path.abspath(".") + "/firmware/kernelcache.release.j1", "/mnt1/kernelcache.release.j1") - shell.send("df -B1") + shell.send("df -B1\n") while True: time.sleep(0.5) line = shell.recv(1024) - if line: + if line.endswith(b'# '): + line_stored = line + print(line_stored.decode('utf-8')) break - lines = line.decode('utf-8').split('\n') + lines = line_stored.decode('utf-8').split('\n') fslist = [] try: for i in lines: @@ -170,18 +163,21 @@ def partitionDevice_stage2(sshClient: paramiko.SSHClient): while '' in fslist[x]: fslist[x].remove('') for i in range(0, len(fslist) - 1): - if list[i][0] == "/dev/disk0s1s1": - resizedPartitionSize = int(fslist[i][2]) + SystemPartitionPadding - if resizedPartitionSize == SystemPartitionPadding: + if fslist[i][0] == "/dev/disk0s1s1": + print("/dev/disk0s1s1 used size is " + str(fslist[i][2]) + " bytes") + resizedPartitionSize = int(fslist[i][2]) + int(SystemPartitionPadding) * 1024 * 1024 + if resizedPartitionSize == int(SystemPartitionPadding) * 1024 * 1024: print("Failed to get resized partition size") exit(1) except Exception: print("Unhandled exception occurred when trying to get resized partition size.") + import traceback + print(traceback.format_exc()) resizedPartitionSize = int(input("Please enter it manually.\nSIZE (in bytes): ")) print("Please make sure it is correct! Or you will fail at resizing partition!") print("Resized Partition Size = " + str(resizedPartitionSize)) print("Resizing partition") - shell.send("hfs_resize /mnt1 " + str(resizedPartitionSize)) + shell.send("hfs_resize /mnt1 " + str(resizedPartitionSize) + "\n") while True: time.sleep(0.5) line = shell.recv(1024) @@ -197,7 +193,9 @@ def partitionDevice_stage2(sshClient: paramiko.SSHClient): if line: break print("Creating new partitions") - shell.send("n\n1\n\n" + str(int(resizedPartitionSize)) + + SystemPartitionSizeInSectors = int(resizedPartitionSize) / 4096 + print("Sectors: " + str(int(SystemPartitionSizeInSectors))) + shell.send("n\n1\n\n" + str(int(SystemPartitionSizeInSectors)) + "\n\nc\n1\nSystem\nn\n2\n\n\n\nc\n2\nData\nx\na\n2\n") while True: time.sleep(0.5) @@ -228,33 +226,118 @@ def partitionDevice_stage2(sshClient: paramiko.SSHClient): line = shell.recv(1024) if line: break - choice = input("WARNING: !!! Downgrade may fail after this operation !!!" - "\nHere is a confirmation for this operation. Enter Y to continue, Enter N to abort.\n" - "Your choice (Make sure you know what you are doing): ") - if choice == "Y": - shell.send("w\nY\n") + shell.send("w\nY\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line: + break + print("Scanning partitions.") + shell.send("sync; sync; sync; fsck_hfs -q /dev/disk0s1s1\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line.endswith(b'# '): + break + print(line.decode('utf-8')) + shell.send("fsck_hfs -q /dev/disk0s1s2\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line.endswith(b'# '): + break + print(line.decode('utf-8')) + print("Stage 2 succeed.") + + +def delete_partitions(shell): + print("Copying hfs_resize") + shell.send("cp /usr/bin/hfs_resize /mnt1\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line.endswith(b'# '): + break + print("Copying kloader") + shell.send("cp /usr/bin/kloader /mnt1\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line.endswith(b'# '): + break + global guid_data, guid_system, attributeFlags_data, SystemPartitionPadding + shell.send("gptfdisk /dev/rdisk0s1\n") + print("NOTE: These following operations won't write to disk at this moment.") + print("Deleting partitions") + shell.send("d\n2\nd\n3\nd\n4\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line: + break + print("Creating new partitions") + shell.send("n\n2\n\n\n\nc\n2\nData\nx\na\n2\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line: + break + print(line.decode('utf-8')) + + print("Setting up attribute flags. FLAG=" + attributeFlags_data) + if attributeFlags_data == "0000000000000000": + shell.send("\n") + elif attributeFlags_data == "0001000000000000": + shell.send("48\n\n") + elif attributeFlags_data == "0003000000000000": + shell.send("48\n49\n\n") else: - print("You have Entered N or other content. exiting.") - shell.send("q\n") + print("Unrecognized attribute flags for partition \"Data\".") + print("exiting") exit(1) - shell.send("q\n") while True: time.sleep(0.5) line = shell.recv(1024) if line: break - print("Scanning partitions.") - shell.send("sync; sync; sync; fsck_hfs -q /dev/disk0s1s1") + print("Setting up GUID.") + shell.send("c\n2\n" + guid_data + "\n") while True: time.sleep(0.5) line = shell.recv(1024) - if line or line.endswith(b'# '): + if line: + break + print("Requesting partition size.") + shell.send("i\n2\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line: + pos = line.decode('utf-8').find('Partition size: ') + pos2 = line.decode('utf-8').find(' sectors') + print(line.decode('utf-8')[pos+16:pos2]) + partition_size = int(line.decode('utf-8')[pos+16:pos2]) + if partition_size == 0: + print("Failed to get partition size! Exiting") + exit(1) + break + partition_size_in_bytes = partition_size * 4096 + print("Size for partition \"Data\": " + str(partition_size)) + print(" In bytes: " + str(partition_size_in_bytes)) + shell.send("w\nY\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line: break print(line.decode('utf-8')) - shell.send("fsck_hfs -q /dev/disk0s1s2") + print("Partition has been deleted. The device will freeze! Don't do anything on the device!") + print("Resizing partition") + shell.send("/mnt1/hfs_resize /dev/disk0s1s2 " + str(partition_size_in_bytes) + "\n") while True: time.sleep(0.5) line = shell.recv(1024) if line or line.endswith(b'# '): break - print(line.decode('utf-8')) + print("Successfully resized partition") + print("DONE") \ No newline at end of file diff --git a/DeviceSupport/iPad3_1/recovery.py b/DeviceSupport/iPad3_1/recovery.py index b03761c..ab523cc 100644 --- a/DeviceSupport/iPad3_1/recovery.py +++ b/DeviceSupport/iPad3_1/recovery.py @@ -1,4 +1,5 @@ import os +import time import osinfo @@ -6,6 +7,7 @@ def waitForConnection(osInfo: osinfo.OSInfo): print("Waiting for DFU/Recovery connection. Please unplug and replug your device.") while True: + time.sleep(2) res = os.system("./tools/" + osInfo.getosplatform() + "/irecovery -c /exit") if res == 0: break @@ -29,6 +31,10 @@ def send_iBEC(osInfo: osinfo.OSInfo, path): def tether_boot_up_device(osInfo: osinfo.OSInfo): print("Trying to tether boot up device.") + print("Sending applelogo") + os.system("./tools/" + osInfo.getosplatform() + "/irecovery -c /send applelogo") + print("Setting applelogo") + os.system("./tools/" + osInfo.getosplatform() + "/irecovery -c setpicture") print("Sending DeviceTree") os.system("./tools/" + osInfo.getosplatform() + "/irecovery -c /send DeviceTree") print("Executing DeviceTree") diff --git a/DeviceSupport/iPad3_1/restore.py b/DeviceSupport/iPad3_1/restore.py index 7b522dc..e79e172 100644 --- a/DeviceSupport/iPad3_1/restore.py +++ b/DeviceSupport/iPad3_1/restore.py @@ -16,43 +16,42 @@ def restore(sshClient: paramiko.SSHClient, restoreImage, device): print("Sending Root filesystem to your device. This may take a long time...") ssh.scp_transfer_file(sshClient, restoreImage, "/var/RootFilesystem.dmg") print("Restore new root filesystem to your partition. Please wait with patience.") - shell.send("asr restore -source /var/RootFilesystem.dmg -target " + device + " -erase -noprompt") + shell.send("asr restore -source /var/RootFilesystem.dmg -target " + device + " -erase -noprompt\n") while True: time.sleep(0.5) line = shell.recv(1024) print(line.decode('utf-8')) - if line or line.endswith(b'# '): + if line.endswith(b'# '): break print("Restore: Done") def formatSystem(shell): - shell.send("newfs_hfs -s -v System -J -b 4096 -n a=4096,c=4096,e=4096 /dev/disk0s1s1") + shell.send("newfs_hfs -s -v System -J -b 4096 -n a=4096,c=4096,e=4096 /dev/disk0s1s1\n") while True: time.sleep(0.5) line = shell.recv(1024) - if line or line.endswith(b'# '): + if line.endswith(b'# '): break print(line.decode('utf-8')) def formatData(shell): - shell.send("newfs_hfs -s -v Data -J -P -b 4096 -n a=4096,c=4096,e=4096 /dev/disk0s1s2") + shell.send("newfs_hfs -s -v Data -J -P -b 4096 -n a=4096,c=4096,e=4096 /dev/disk0s1s2\n") while True: time.sleep(0.5) line = shell.recv(1024) - if line or line.endswith(b'# '): + if line.endswith(b'# '): break print(line.decode('utf-8')) def scanPartition(shell, device): - shell.send("fsck_hfs -f " + device) + shell.send("fsck_hfs -f " + device + "\n") while True: time.sleep(0.5) line = shell.recv(1024) - if line or line.endswith(b'# '): + if line.endswith(b'# '): break print(line.decode('utf-8')) - diff --git a/DeviceSupport/iPad3_1/setup.py b/DeviceSupport/iPad3_1/setup.py index be29358..d8f10e1 100644 --- a/DeviceSupport/iPad3_1/setup.py +++ b/DeviceSupport/iPad3_1/setup.py @@ -7,17 +7,14 @@ import ssh -def send_kloader_and_iBSS_iBEC(sshClient: paramiko.SSHClient): +def send_iBSS(sshClient: paramiko.SSHClient): print("Sending iBSS") ssh.scp_transfer_file(sshClient, os.path.abspath(".") + "/pwnediBSS", "/mnt1/pwnediBSS") - print("Sending iBEC") - ssh.scp_transfer_file(sshClient, os.path.abspath(".") + "/pwnediBEC", "/mnt1/pwnediBEC") - print("Sending kloader") - ssh.scp_transfer_file(sshClient, os.path.abspath(".") + "/tools/kloader", "/mnt1/kloader") def createMountPoint(shell, mountpoint): - shell.send("mkdir " + mountpoint) + print("Creating mount point " + mountpoint) + shell.send("mkdir " + mountpoint + "\n") while True: time.sleep(0.5) line = shell.recv(1024) @@ -26,25 +23,30 @@ def createMountPoint(shell, mountpoint): def mountDevice(shell, device, mountpoint): - shell.send("mount -t hfs " + device + " " + mountpoint) + print("Mounting " + mountpoint) + shell.send("mount_hfs " + device + " " + mountpoint + "\n") while True: time.sleep(0.5) line = shell.recv(1024) + print(line.decode('utf-8')) if line or line.endswith(b'# '): break def fixupvar(shell): - shell.send("mv -v /mnt1/private/var/* /mnt2") + print("Fixing up /var") + shell.send("mv -v /mnt1/private/var/* /mnt2\n") while True: time.sleep(0.5) line = shell.recv(1024) - if line or line.endswith(b'# '): + print(line.decode('utf-8')) + if line.endswith(b'# '): break def copyfstab(shell): - shell.send("cp /var/fstab /mnt1/private/etc/fstab") + print("Copying fstab to partition.") + shell.send("cp /var/fstab /mnt1/private/etc/fstab\n") while True: time.sleep(0.5) line = shell.recv(1024) @@ -53,7 +55,8 @@ def copyfstab(shell): def copyfstab_toSecOS(shell): - shell.send("cp /mnt1/private/etc/fstab /var/fstab") + print("Copying fstab.") + shell.send("cp /mnt1/private/etc/fstab /var/fstab\n") while True: time.sleep(0.5) line = shell.recv(1024) @@ -62,16 +65,30 @@ def copyfstab_toSecOS(shell): def unmountDevice(shell, mountpoint): - shell.send("unmount " + mountpoint) + print("Unmounting " + mountpoint) + shell.send("umount " + mountpoint + "\n") + while True: + time.sleep(0.5) + line = shell.recv(1024) + if line or line.endswith(b'# '): + break + + +def send_keybag(sshClient: paramiko.SSHClient): + print("Sending keybag.") + shell = sshClient.invoke_shell() + shell.send("mkdir /mnt2/keybags\n") while True: time.sleep(0.5) line = shell.recv(1024) if line or line.endswith(b'# '): break + ssh.scp_transfer_file(sshClient, "systembag.kb", "/mnt2/keybags/systembag.kb") def kloader_iBSS(shell): - shell.send("/mnt1/kloader /mnt1/pwnediBSS") + print("kloader iBSS!") + shell.send("/mnt1/kloader /mnt1/pwnediBSS\n") while True: time.sleep(0.5) line = shell.recv(1024) diff --git a/DeviceSupport/iPad3_1_Support.py b/DeviceSupport/iPad3_1_Support.py index 836b7dd..ccb2273 100644 --- a/DeviceSupport/iPad3_1_Support.py +++ b/DeviceSupport/iPad3_1_Support.py @@ -16,27 +16,30 @@ def startDowngrade(osInfo: osinfo.OSInfo, version, storage: int, sshClient: para if line: break print("Device Support for iPad3,1 version iOS " + version + " started") - setup.createMountPoint("/mnt1") - setup.createMountPoint("/mnt2") + setup.createMountPoint(shell, "/mnt1") + setup.createMountPoint(shell, "/mnt2") setup.mountDevice(shell, "/dev/disk0s1s1", "/mnt1") setup.copyfstab_toSecOS(shell) - setup.unmountDevice("/mnt1") + setup.unmountDevice(shell, "/mnt1") partition.partitionDevice_stage1(osInfo, shell, storage, keys['restoreRamdisk'], ivs['restoreRamdisk']) restore.formatData(shell) restore.formatSystem(shell) restore.restore(sshClient, "RootFileSystem.dmg", "/dev/disk0s1s1") + # The code below hasn't been tested yet. Please stop at here! restore.scanPartition(shell, "/dev/disk0s1s1") - partition.partitionDevice_stage2(sshClient) setup.mountDevice(shell, "/dev/disk0s1s1", "/mnt1") setup.mountDevice(shell, "/dev/disk0s1s2", "/mnt2") setup.fixupvar(shell) setup.copyfstab(shell) - setup.send_kloader_and_iBSS_iBEC(sshClient) + setup.send_keybag(sshClient) + setup.send_iBSS(sshClient) + partition.partitionDevice_stage2(sshClient) + partition.delete_partitions(shell) setup.kloader_iBSS(shell) sshClient.close() - recovery.waitForConnection() - recovery.send_iBEC(osinfo, "pwnediBEC") - recovery.tether_boot_up_device() + recovery.waitForConnection(osInfo) + recovery.send_iBEC(osInfo, "pwnediBEC") + recovery.tether_boot_up_device(osInfo) if __name__ == "__main__": diff --git a/debs/Packages b/debs/Packages index 9288254..5c82a4d 100644 --- a/debs/Packages +++ b/debs/Packages @@ -1,3 +1,20 @@ +Package: com.MyWorkstation.MakeItTethered +Version: 0.1-1 +Architecture: iphoneos-arm +Depends: firmware (>= 5.0), mobilesubstrate +Filename: ./com.MyWorkstation.MakeItTethered_0.1-1_iphoneos-arm.deb +Size: 44240 +MD5sum: 8fd931ce7e17fcd35323c150cbfdb017 +SHA1: d38288363c604d0385804414791c8a649de0714c +SHA256: b84147cb4552d964d857b9f1e27cbfcd0047d96af2908fd2d88913b39e85951f +Section: Tweaks +Priority: important +Homepage: https://github.com/102464/iOS-downgrade-tethered +Description: This tweak will automatically load iBSS using kloader when you are powering down your device. It is helpful for anyone who has downgraded their device using iOS-downgrade-tethered tool. +Author: 102464 +Depiction:
NOTE THIS PACKAGE WILL NOT WORK IN SAFE MODE! DO NOT POWER OFF YOUR DEVICE IN SAFE MODE! +Name: MakeItTethered + Package: com.coolbooter.coolbootercli Version: 0.8.2-release Architecture: iphoneos-arm @@ -29,6 +46,57 @@ Author: @danzatt, @winocm, @xerub, @JonathanSeals, @axi0mX, @Apple, @comex, Rode Depiction: http://nyansatan.github.io/apt/depictions/dualbootstuff.html Name: dualbootstuff +Package: diskdev-cmds +Version: 421.7-4 +Architecture: iphoneos-arm +Maintainer: Jay Freeman (saurik)